More preparation for scan line rendering.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2017-10-01 11:32:41 +01:00
parent 88117398ef
commit 63f7216341
4 changed files with 38 additions and 15 deletions

View File

@ -6,6 +6,7 @@
#include "GameBoyBus.h"
#include "AbstractColourPalette.h"
#include "ObjectAttribute.h"
namespace EightBit {
namespace GameBoy {
@ -29,11 +30,13 @@ namespace EightBit {
void initialise();
void render();
void loadObjectAttributes();
private:
std::vector<uint32_t> m_pixels;
Bus& m_bus;
const AbstractColourPalette* m_colours;
std::array<ObjectAttribute, 40> m_objectAttributes;
std::array<int, 4> createPalette(int address);

View File

@ -123,6 +123,7 @@ namespace EightBit {
Bus();
Signal<int> InterruptGenerated;
Signal<int> DisplayStatusModeUpdated;
void reset();
@ -209,6 +210,7 @@ namespace EightBit {
void updateLcdStatusMode(int mode) {
const auto current = m_ioPorts.peek(STAT) & ~Processor::Mask2;
m_ioPorts.poke(STAT, current | mode);
DisplayStatusModeUpdated.fire(mode);
}
void disableBootRom() { m_disableBootRom = true; }

View File

@ -48,6 +48,18 @@ void EightBit::GameBoy::Display::renderObjects() {
renderObjects(objBlockHeight);
}
void EightBit::GameBoy::Display::loadObjectAttributes() {
auto oamAddress = 0xfe00;
const auto control = m_bus.peekRegister(Bus::LCDC);
const auto objBlockHeight = (control & Bus::ObjectBlockCompositionSelection) ? 16 : 8;
for (int i = 0; i < 40; ++i) {
m_objectAttributes[i] = ObjectAttribute(m_bus, oamAddress + 4 * i, objBlockHeight);
}
}
void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) {
std::vector<std::array<int, 4>> palettes(2);
@ -59,21 +71,28 @@ void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) {
for (int i = 0; i < 40; ++i) {
const auto current = ObjectAttribute(m_bus, oamAddress + 4 * i, objBlockHeight);
const auto& current = m_objectAttributes[i];
const auto sprite = current.pattern();
const auto definition = CharacterDefinition(m_bus, objDefinitionAddress + 16 * sprite, objBlockHeight);
const auto spriteX = current.positionX();
const auto spriteY = current.positionY();
const auto& palette = palettes[current.palette()];
const auto flipX = current.flipX();
const auto flipY = current.flipY();
renderTile(
objBlockHeight,
spriteX, spriteY, -8, -16,
flipX, flipY, true,
palette,
definition);
const auto hidden = (spriteX == 0) && (spriteY == 0);
if (!hidden) {
const auto definition = CharacterDefinition(m_bus, objDefinitionAddress + 16 * sprite, objBlockHeight);
const auto& palette = palettes[current.palette()];
const auto flipX = current.flipX();
const auto flipY = current.flipY();
renderTile(
objBlockHeight,
spriteX, spriteY, -8, -16,
flipX, flipY, true,
palette,
definition);
}
}
}

View File

@ -373,14 +373,17 @@ int EightBit::GameBoy::LR35902::runRasterLine(int limit) {
if ((m_bus.peekRegister(Bus::STAT) & Bit6) && (m_bus.peekRegister(Bus::LYC) == m_bus.peekRegister(Bus::LY)))
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
// Mode 2, OAM unavailable
m_bus.updateLcdStatusMode(Bus::LcdStatusMode::SearchingOamRam);
if (m_bus.peekRegister(Bus::STAT) & Bit5)
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
count += run(80); // ~19us
// Mode 3, OAM/VRAM unavailable
m_bus.updateLcdStatusMode(Bus::LcdStatusMode::TransferringDataToLcd);
count += run(170); // ~41us
// Mode 0
m_bus.updateLcdStatusMode(Bus::LcdStatusMode::HBlank);
if (m_bus.peekRegister(Bus::STAT) & Bit3)
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
@ -392,10 +395,6 @@ int EightBit::GameBoy::LR35902::runRasterLine(int limit) {
count += run(Bus::CyclesPerLine);
}
assert(count > 0);
assert(count >= Bus::CyclesPerLine);
assert((count - Bus::CyclesPerLine) - 16);
return count;
}