diff --git a/Core/Ppu.cpp b/Core/Ppu.cpp index 6c49bd3..1983bcc 100644 --- a/Core/Ppu.cpp +++ b/Core/Ppu.cpp @@ -218,54 +218,6 @@ void Ppu::EvaluateNextLineSprites() } } -template -void Ppu::RenderSprites() -{ - uint8_t activeWindowCount = 0; - if(forMainScreen) { - if(_pixelsDrawn == 256 || (_mainScreenLayers & 0x10) == 0) { - return; - } - if(_windowMaskMain[Ppu::SpriteLayerIndex]) { - activeWindowCount = (uint8_t)_window[0].ActiveLayers[Ppu::SpriteLayerIndex] + (uint8_t)_window[1].ActiveLayers[Ppu::SpriteLayerIndex]; - } - } else { - if(_subPixelsDrawn == 256 || (_subScreenLayers & 0x10) == 0) { - return; - } - - if(_windowMaskSub[Ppu::SpriteLayerIndex]) { - activeWindowCount = (uint8_t)_window[0].ActiveLayers[Ppu::SpriteLayerIndex] + (uint8_t)_window[1].ActiveLayers[Ppu::SpriteLayerIndex]; - } - } - - if(forMainScreen) { - for(int x = 0; x < 256; x++) { - if(!_rowPixelFlags[x] && _spritePriority[x] == priority) { - if(activeWindowCount && ProcessMaskWindow(activeWindowCount, x)) { - //This pixel was masked - continue; - } - - _mainScreenBuffer[x] = _spritePixels[x]; - _rowPixelFlags[x] |= PixelFlags::Filled | (((_colorMathEnabled & 0x10) && _spritePalette[x] > 3) ? PixelFlags::AllowColorMath : 0); - } - } - } else { - for(int x = 0; x < 256; x++) { - if(!_subScreenFilled[x] && _spritePriority[x] == priority) { - if(activeWindowCount && ProcessMaskWindow(activeWindowCount, x)) { - //This pixel was masked - continue; - } - - _subScreenBuffer[x] = _spritePixels[x]; - _subScreenFilled[x] = true; - } - } - } -} - template void Ppu::RenderMode0() { @@ -464,6 +416,51 @@ void Ppu::RenderBgColor() } } +template +void Ppu::RenderSprites() +{ + if(!IsRenderRequired(Ppu::SpriteLayerIndex)) { + return; + } + + uint8_t activeWindowCount = 0; + if(forMainScreen) { + if(_windowMaskMain[Ppu::SpriteLayerIndex]) { + activeWindowCount = (uint8_t)_window[0].ActiveLayers[Ppu::SpriteLayerIndex] + (uint8_t)_window[1].ActiveLayers[Ppu::SpriteLayerIndex]; + } + } else { + if(_windowMaskSub[Ppu::SpriteLayerIndex]) { + activeWindowCount = (uint8_t)_window[0].ActiveLayers[Ppu::SpriteLayerIndex] + (uint8_t)_window[1].ActiveLayers[Ppu::SpriteLayerIndex]; + } + } + + if(forMainScreen) { + for(int x = 0; x < 256; x++) { + if(!_rowPixelFlags[x] && _spritePriority[x] == priority) { + if(activeWindowCount && ProcessMaskWindow(activeWindowCount, x)) { + //This pixel was masked + continue; + } + + _mainScreenBuffer[x] = _spritePixels[x]; + _rowPixelFlags[x] |= PixelFlags::Filled | (((_colorMathEnabled & 0x10) && _spritePalette[x] > 3) ? PixelFlags::AllowColorMath : 0); + } + } + } else { + for(int x = 0; x < 256; x++) { + if(!_subScreenFilled[x] && _spritePriority[x] == priority) { + if(activeWindowCount && ProcessMaskWindow(activeWindowCount, x)) { + //This pixel was masked + continue; + } + + _subScreenBuffer[x] = _spritePixels[x]; + _subScreenFilled[x] = true; + } + } + } +} + template void Ppu::RenderTilemap() { @@ -527,16 +524,8 @@ void Ppu::RenderTilemap() template void Ppu::RenderTilemap() { - if(forMainScreen) { - if(_pixelsDrawn == 256 || ((_mainScreenLayers >> layerIndex) & 0x01) == 0) { - //This screen is disabled, or we've drawn all pixels already - return; - } - } else { - if(_subPixelsDrawn == 256 || ((_subScreenLayers >> layerIndex) & 0x01) == 0) { - //This screen is disabled, or we've drawn all pixels already - return; - } + if(!IsRenderRequired(layerIndex)) { + return; } /* Current scanline (in interlaced mode, switches between even and odd rows every frame */ @@ -633,27 +622,7 @@ void Ppu::RenderTilemap() uint8_t xOffset = (realX + config.HScroll) & 0x07; uint8_t shift = hMirror ? xOffset : (7 - xOffset); - uint16_t color = 0; - if(bpp == 2) { - color |= (((_vram[pixelStart + 0] >> shift) & 0x01) << 0); - color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1); - } else if(bpp == 4) { - color |= (((_vram[pixelStart + 0] >> shift) & 0x01) << 0); - color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1); - color |= (((_vram[pixelStart + 16] >> shift) & 0x01) << 2); - color |= (((_vram[pixelStart + 17] >> shift) & 0x01) << 3); - } else if(bpp == 8) { - color |= (((_vram[pixelStart + 0] >> shift) & 0x01) << 0); - color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1); - color |= (((_vram[pixelStart + 16] >> shift) & 0x01) << 2); - color |= (((_vram[pixelStart + 17] >> shift) & 0x01) << 3); - color |= (((_vram[pixelStart + 32] >> shift) & 0x01) << 4); - color |= (((_vram[pixelStart + 33] >> shift) & 0x01) << 5); - color |= (((_vram[pixelStart + 48] >> shift) & 0x01) << 6); - color |= (((_vram[pixelStart + 49] >> shift) & 0x01) << 7); - } else { - throw std::runtime_error("unsupported bpp"); - } + uint16_t color = GetTilePixelColor(pixelStart, shift); if(color > 0) { /* Ignore palette bits for 256-color layers */ @@ -681,6 +650,50 @@ void Ppu::RenderTilemap() } } +template +bool Ppu::IsRenderRequired(uint8_t layerIndex) +{ + if(forMainScreen) { + if(_pixelsDrawn == 256 || ((_mainScreenLayers >> layerIndex) & 0x01) == 0) { + //This screen is disabled, or we've drawn all pixels already + return false; + } + } else { + if(_subPixelsDrawn == 256 || ((_subScreenLayers >> layerIndex) & 0x01) == 0) { + //This screen is disabled, or we've drawn all pixels already + return false; + } + } + return true; +} + +template +uint16_t Ppu::GetTilePixelColor(const uint16_t pixelStart, const uint8_t shift) +{ + uint16_t color; + if(bpp == 2) { + color = (((_vram[pixelStart + 0] >> shift) & 0x01) << 0); + color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1); + } else if(bpp == 4) { + color = (((_vram[pixelStart + 0] >> shift) & 0x01) << 0); + color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1); + color |= (((_vram[pixelStart + 16] >> shift) & 0x01) << 2); + color |= (((_vram[pixelStart + 17] >> shift) & 0x01) << 3); + } else if(bpp == 8) { + color = (((_vram[pixelStart + 0] >> shift) & 0x01) << 0); + color |= (((_vram[pixelStart + 1] >> shift) & 0x01) << 1); + color |= (((_vram[pixelStart + 16] >> shift) & 0x01) << 2); + color |= (((_vram[pixelStart + 17] >> shift) & 0x01) << 3); + color |= (((_vram[pixelStart + 32] >> shift) & 0x01) << 4); + color |= (((_vram[pixelStart + 33] >> shift) & 0x01) << 5); + color |= (((_vram[pixelStart + 48] >> shift) & 0x01) << 6); + color |= (((_vram[pixelStart + 49] >> shift) & 0x01) << 7); + } else { + throw std::runtime_error("unsupported bpp"); + } + return color; +} + template void Ppu::RenderTilemapMode7() { @@ -706,16 +719,8 @@ void Ppu::RenderTilemapMode7() template void Ppu::RenderTilemapMode7() { - if(forMainScreen) { - if(_pixelsDrawn == 256 || ((_mainScreenLayers >> layerIndex) & 0x01) == 0) { - //This screen is disabled, or we've drawn all pixels already - return; - } - } else { - if(_subPixelsDrawn == 256 || ((_subScreenLayers >> layerIndex) & 0x01) == 0) { - //This screen is disabled, or we've drawn all pixels already - return; - } + if(!IsRenderRequired(layerIndex)) { + return; } constexpr auto clip = [](int32_t val) { return (val & 0x2000) ? (val | ~0x3ff) : (val & 0x3ff); }; diff --git a/Core/Ppu.h b/Core/Ppu.h index 02315ad..6561542 100644 --- a/Core/Ppu.h +++ b/Core/Ppu.h @@ -167,6 +167,12 @@ private: template void RenderTilemap(); + template + __forceinline bool IsRenderRequired(uint8_t layerIndex); + + template + __forceinline uint16_t GetTilePixelColor(const uint16_t pixelStart, const uint8_t shift); + template __forceinline void RenderTilemapMode7();