More scanline changes. Try to render only what we need to see.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2017-10-04 01:28:33 +01:00
parent d5a724fdb4
commit 2b5324cb43

View File

@ -22,13 +22,15 @@ void EightBit::GameBoy::Display::initialise() {
} }
void EightBit::GameBoy::Display::render() { void EightBit::GameBoy::Display::render() {
m_control = m_bus.peekRegister(Bus::LCDC); m_scanLine = m_bus.peekRegister(Bus::LY);
if (m_control & Bus::LcdEnable) { if (m_scanLine < RasterHeight) {
m_scanLine = m_bus.peekRegister(Bus::LY); m_control = m_bus.peekRegister(Bus::LCDC);
if (m_control & Bus::DisplayBackground) if (m_control & Bus::LcdEnable) {
renderBackground(); if (m_control & Bus::DisplayBackground)
if (m_control & Bus::ObjectEnable) renderBackground();
renderObjects(); 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& current = m_objectAttributes[i];
const auto sprite = current.pattern(); const auto sprite = current.pattern();
const auto spriteX = current.positionX();
const auto spriteY = current.positionY(); 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 definition = CharacterDefinition(&m_bus, objDefinitionAddress + 16 * sprite, objBlockHeight);
const auto& palette = palettes[current.palette()]; const auto& palette = palettes[current.palette()];
@ -85,7 +88,7 @@ void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) {
renderTile( renderTile(
objBlockHeight, objBlockHeight,
spriteX - 8, spriteY - 16, drawX, drawY,
flipX, flipY, true, flipX, flipY, true,
palette, palette,
definition); definition);
@ -119,10 +122,11 @@ void EightBit::GameBoy::Display::renderBackground(
const std::array<int, 4>& palette) { const std::array<int, 4>& palette) {
const int row = (m_scanLine - offsetY) / 8; const int row = (m_scanLine - offsetY) / 8;
const auto baseAddress = bgArea + row * BufferCharacterWidth;
for (int column = 0; column < BufferCharacterWidth; ++column) { 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 character = m_bus.peek(address);
const auto definition = CharacterDefinition(&m_bus, bgCharacters + 16 * character, 8); const auto definition = CharacterDefinition(&m_bus, bgCharacters + 16 * character, 8);
@ -136,9 +140,9 @@ void EightBit::GameBoy::Display::renderBackground(
} }
void EightBit::GameBoy::Display::renderTile( void EightBit::GameBoy::Display::renderTile(
int height, const int height,
int drawX, int drawY, const int drawX, const int drawY,
bool flipX, bool flipY, bool allowTransparencies, const bool flipX, const bool flipY, const bool allowTransparencies,
const std::array<int, 4>& palette, const std::array<int, 4>& palette,
const CharacterDefinition& definition) { const CharacterDefinition& definition) {
@ -147,30 +151,25 @@ void EightBit::GameBoy::Display::renderTile(
const auto flipMaskX = width - 1; const auto flipMaskX = width - 1;
const auto flipMaskY = height - 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); auto cy = y - drawY;
if (y >= RasterHeight) if (flipY)
continue; cy = ~cy & flipMaskY;
if (y != m_scanLine) const auto rowDefinition = definition.get(cy);
continue;
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); const auto colour = rowDefinition[cx];
if (x >= RasterWidth) if (!allowTransparencies || (allowTransparencies && (colour > 0))) {
break; const auto outputPixel = lineAddress + x;
m_pixels[outputPixel] = m_colours->getColour(palette[colour]);
const auto colour = rowDefinition[cx];
if (!allowTransparencies || (allowTransparencies && (colour > 0))) {
const auto outputPixel = y * RasterWidth + x;
m_pixels[outputPixel] = m_colours->getColour(palette[colour]);
}
} }
break;
} }
} }