diff --git a/Core/Ppu.cpp b/Core/Ppu.cpp index f0be58b..06d0a4f 100644 --- a/Core/Ppu.cpp +++ b/Core/Ppu.cpp @@ -244,6 +244,8 @@ void Ppu::RenderSprites() } if(forMainScreen) { + uint16_t outBaseAddress = (_scanline << 8); + for(int x = 0; x < 256; x++) { if(!_rowPixelFlags[x] && _spritePriority[x] == priority) { if(activeWindowCount && ProcessMaskWindow(activeWindowCount, x)) { @@ -251,7 +253,7 @@ void Ppu::RenderSprites() continue; } - _currentBuffer[(_scanline << 8) | x] = _spritePixels[x]; + _currentBuffer[outBaseAddress | x] = _spritePixels[x]; _rowPixelFlags[x] |= PixelFlags::Filled | (((_colorMathEnabled & 0x10) && _spritePalette[x] > 3) ? PixelFlags::AllowColorMath : 0); } } @@ -427,11 +429,12 @@ void Ppu::RenderBgColor() } uint16_t bgColor = _cgram[0] | (_cgram[1] << 8); + uint16_t outBaseAddress = (_scanline << 8); for(int x = 0; x < 256; x++) { if(forMainScreen) { if(!_rowPixelFlags[x]) { uint8_t pixelFlags = PixelFlags::Filled | ((_colorMathEnabled & 0x20) ? PixelFlags::AllowColorMath : 0); - _currentBuffer[(_scanline << 8) | x] = bgColor; + _currentBuffer[outBaseAddress | x] = bgColor; _rowPixelFlags[x] = pixelFlags; } } else { @@ -445,14 +448,57 @@ void Ppu::RenderBgColor() template void Ppu::RenderTilemap() { + uint8_t activeWindowCount = 0; + if((forMainScreen && _windowMaskMain[layerIndex]) || (!forMainScreen && _windowMaskSub[layerIndex])) { + activeWindowCount = (uint8_t)_window[0].ActiveLayers[layerIndex] + (uint8_t)_window[1].ActiveLayers[layerIndex]; + } + + bool applyMosaic = forMainScreen && ((_mosaicEnabled >> layerIndex) & 0x01) != 0; + if(_layerConfig[layerIndex].LargeTiles) { - RenderTilemap(); + if(activeWindowCount == 0) { + if(applyMosaic) { + RenderTilemap(); + } else { + RenderTilemap(); + } + } else if(activeWindowCount == 1) { + if(applyMosaic) { + RenderTilemap(); + } else { + RenderTilemap(); + } + } else { + if(applyMosaic) { + RenderTilemap(); + } else { + RenderTilemap(); + } + } } else { - RenderTilemap(); + if(activeWindowCount == 0) { + if(applyMosaic) { + RenderTilemap(); + } else { + RenderTilemap(); + } + } else if(activeWindowCount == 1) { + if(applyMosaic) { + RenderTilemap(); + } else { + RenderTilemap(); + } + } else { + if(applyMosaic) { + RenderTilemap(); + } else { + RenderTilemap(); + } + } } } -template +template void Ppu::RenderTilemap() { if(forMainScreen) { @@ -467,12 +513,6 @@ void Ppu::RenderTilemap() } } - uint8_t activeWindowCount = 0; - if((forMainScreen && _windowMaskMain[layerIndex]) || (!forMainScreen && _windowMaskSub[layerIndex])) { - activeWindowCount = (uint8_t)_window[0].ActiveLayers[layerIndex] + (uint8_t)_window[1].ActiveLayers[layerIndex]; - } - - bool applyMosaic = forMainScreen && ((_mosaicEnabled >> layerIndex) & 0x01) != 0; bool mosaicScanline = applyMosaic && (_scanline - _mosaicStartScanline) % _mosaicSize != 0; uint8_t pixelFlags = PixelFlags::Filled | (((_colorMathEnabled >> layerIndex) & 0x01) ? PixelFlags::AllowColorMath : 0); @@ -486,6 +526,8 @@ void Ppu::RenderTilemap() uint16_t addrVerticalScrollingOffset = config.VerticalMirroring ? ((row & 0x20) << (config.HorizontalMirroring ? 6 : 5)) : 0; uint16_t baseOffset = tilemapAddr + addrVerticalScrollingOffset + ((row & 0x1F) << 5); + uint16_t outBaseAddress = (_scanline << 8); + for(int x = 0; x < 256; x++) { uint16_t column = (x + config.HScroll) >> (largeTiles ? 4 : 3); uint32_t addr = (baseOffset + (column & 0x1F) + (config.HorizontalMirroring ? ((column & 0x20) << 5) : 0)) << 1; @@ -505,9 +547,9 @@ void Ppu::RenderTilemap() continue; } - if(mosaicScanline || (applyMosaic && x % _mosaicSize != 0)) { + if(applyMosaic && (mosaicScanline || x % _mosaicSize != 0)) { //If this is not the top-left pixels in the mosaic pattern, override it with the top-left pixel data - _currentBuffer[(_scanline << 8) | x] = _mosaicColor[x]; + _currentBuffer[outBaseAddress | x] = _mosaicColor[x]; _rowPixelFlags[x] = pixelFlags; if(forMainScreen) { _pixelsDrawn++; @@ -564,7 +606,7 @@ void Ppu::RenderTilemap() uint16_t paletteColor = _cgram[paletteRamOffset] | (_cgram[paletteRamOffset + 1] << 8); if(forMainScreen) { - _currentBuffer[(_scanline << 8) | x] = paletteColor; + _currentBuffer[outBaseAddress | x] = paletteColor; _rowPixelFlags[x] = pixelFlags; if(applyMosaic && x % _mosaicSize == 0) { //This is the source for the mosaic pattern, store it for use in the next scanlines @@ -589,11 +631,12 @@ void Ppu::ApplyColorMath() } uint8_t activeWindowCount = (uint8_t)_window[0].ActiveLayers[Ppu::ColorWindowIndex] + (uint8_t)_window[1].ActiveLayers[Ppu::ColorWindowIndex]; + uint16_t outBaseAddress = (_scanline << 8); for(int x = 0; x < 256; x++) { if(_rowPixelFlags[x] & PixelFlags::AllowColorMath) { uint8_t halfShift = _colorMathHalveResult ? 1 : 0; - uint16_t &mainPixel = _currentBuffer[(_scanline << 8) | x]; + uint16_t &mainPixel = _currentBuffer[outBaseAddress | x]; bool isInsideWindow = activeWindowCount && ProcessMaskWindow(activeWindowCount, x); //Set color to black as needed based on clip mode @@ -671,8 +714,10 @@ void Ppu::ApplyColorMath() void Ppu::ApplyBrightness() { if(_screenBrightness != 15) { + uint16_t outBaseAddress = (_scanline << 8); + for(int x = 0; x < 256; x++) { - uint16_t &pixel = _currentBuffer[(_scanline << 8) | x]; + uint16_t &pixel = _currentBuffer[outBaseAddress | x]; uint16_t r = (pixel & 0x1F) * _screenBrightness / 15; uint16_t g = ((pixel >> 5) & 0x1F) * _screenBrightness / 15; uint16_t b = ((pixel >> 10) & 0x1F) * _screenBrightness / 15; diff --git a/Core/Ppu.h b/Core/Ppu.h index bc35837..c0e140e 100644 --- a/Core/Ppu.h +++ b/Core/Ppu.h @@ -160,7 +160,7 @@ private: template void RenderTilemap(); - template + template void RenderTilemap(); void ApplyColorMath();