From 2b5324cb438dd4388a07c1a08a7cc62c72c93ed4 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Wed, 4 Oct 2017 01:28:33 +0100 Subject: [PATCH] More scanline changes. Try to render only what we need to see. Signed-off-by: Adrian Conlon --- LR35902/src/Display.cpp | 67 ++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/LR35902/src/Display.cpp b/LR35902/src/Display.cpp index bf3e5bf..cf4d6e7 100644 --- a/LR35902/src/Display.cpp +++ b/LR35902/src/Display.cpp @@ -22,13 +22,15 @@ void EightBit::GameBoy::Display::initialise() { } void EightBit::GameBoy::Display::render() { - m_control = m_bus.peekRegister(Bus::LCDC); - if (m_control & Bus::LcdEnable) { - m_scanLine = m_bus.peekRegister(Bus::LY); - if (m_control & Bus::DisplayBackground) - renderBackground(); - if (m_control & Bus::ObjectEnable) - renderObjects(); + m_scanLine = m_bus.peekRegister(Bus::LY); + if (m_scanLine < RasterHeight) { + m_control = m_bus.peekRegister(Bus::LCDC); + if (m_control & Bus::LcdEnable) { + if (m_control & Bus::DisplayBackground) + renderBackground(); + if (m_control & Bus::ObjectEnable) + renderObjects(); + } } } @@ -71,12 +73,13 @@ void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) { const auto& current = m_objectAttributes[i]; const auto sprite = current.pattern(); - const auto spriteX = current.positionX(); const auto spriteY = current.positionY(); + const auto drawY = spriteY - 16; - const auto hidden = (spriteX == 0) && (spriteY == 0); + if ((m_scanLine >= drawY) && (m_scanLine < (drawY + objBlockHeight))) { - if (!hidden) { + const auto spriteX = current.positionX(); + const auto drawX = spriteX - 8; const auto definition = CharacterDefinition(&m_bus, objDefinitionAddress + 16 * sprite, objBlockHeight); const auto& palette = palettes[current.palette()]; @@ -85,7 +88,7 @@ void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) { renderTile( objBlockHeight, - spriteX - 8, spriteY - 16, + drawX, drawY, flipX, flipY, true, palette, definition); @@ -119,10 +122,11 @@ void EightBit::GameBoy::Display::renderBackground( const std::array& palette) { const int row = (m_scanLine - offsetY) / 8; + const auto baseAddress = bgArea + row * BufferCharacterWidth; for (int column = 0; column < BufferCharacterWidth; ++column) { - const auto address = bgArea + row * BufferCharacterWidth + column; + const auto address = baseAddress + column; const auto character = m_bus.peek(address); const auto definition = CharacterDefinition(&m_bus, bgCharacters + 16 * character, 8); @@ -136,9 +140,9 @@ void EightBit::GameBoy::Display::renderBackground( } void EightBit::GameBoy::Display::renderTile( - int height, - int drawX, int drawY, - bool flipX, bool flipY, bool allowTransparencies, + const int height, + const int drawX, const int drawY, + const bool flipX, const bool flipY, const bool allowTransparencies, const std::array& palette, const CharacterDefinition& definition) { @@ -147,30 +151,25 @@ void EightBit::GameBoy::Display::renderTile( const auto flipMaskX = width - 1; const auto flipMaskY = height - 1; - for (int cy = 0; cy < height; ++cy) { + const auto y = m_scanLine; - const uint8_t y = drawY + (flipY ? ~cy & flipMaskY : cy); - if (y >= RasterHeight) - continue; + auto cy = y - drawY; + if (flipY) + cy = ~cy & flipMaskY; - if (y != m_scanLine) - continue; + const auto rowDefinition = definition.get(cy); - const auto rowDefinition = definition.get(cy); + const auto lineAddress = y * RasterWidth; + for (int cx = 0; cx < width; ++cx) { - for (int cx = 0; cx < width; ++cx) { + const uint8_t x = drawX + (flipX ? ~cx & flipMaskX : cx); + if (x >= RasterWidth) + break; - const uint8_t x = drawX + (flipX ? ~cx & flipMaskX : cx); - if (x >= RasterWidth) - break; - - const auto colour = rowDefinition[cx]; - if (!allowTransparencies || (allowTransparencies && (colour > 0))) { - const auto outputPixel = y * RasterWidth + x; - m_pixels[outputPixel] = m_colours->getColour(palette[colour]); - } + const auto colour = rowDefinition[cx]; + if (!allowTransparencies || (allowTransparencies && (colour > 0))) { + const auto outputPixel = lineAddress + x; + m_pixels[outputPixel] = m_colours->getColour(palette[colour]); } - - break; } }