Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
I wrote a game boy emulator in C99 that works and a lot of games can play just fine, including sound.
But there are a few issues and one issue that particular bugs me is that i want to show the background-map in my editor, while running the game - seeing the actual viewport.
I already implemented this and it works great for a lot of games (Super Mario Land 2, R-Type, Mega-Man to name a few).
But not for "Super Mario Land 1"! The Game somehow resets the SCX and SCY register to zero after the frame is rendered - so when i use SCX and SCY to compute the viewport rectangles, it will always be zero or has the correct value, but then gets reset on the next frame - so it flickers around.
Other emulators such as BGB works just fine and displays the background-map with the viewport properly.
My implementation of this stores the current SCX/SCY values into separate fields that are updated, after the frame is rendered.
A frame is rendered when the PPU is in mode VBlank and LY is >= 154:
static void fgb__PPUModeVerticalBlank(fgbGameboy *gameboy) { fgbPPU *ppu = &gameboy->ppu; fgbLCDRegister *lcd = &ppu->lcd; if (ppu->lineTicks >= FGB__PPU_HORIZONTAL_BLANK_DOTS) { fgb__PPUIncrementLine(gameboy); if (lcd->ly >= FGB__PPU_VERTICAL_BLANK_LINE_COUNT) { fgb__PPUSetMode(gameboy, lcd, fgbPPUMode_OAMSearch); fgb__PPUResetLine(gameboy); fgb__PPUStatusInterruptTest(gameboy, false); ppu->frameCount++; ppu->isFrameFinished = true; // Store scroll register for rendering the background-map viewport ppu->backgroundMap.scrollX = ppu->lcd.scx; ppu->backgroundMap.scrollY = ppu->lcd.scy; fgb__Breakpoint(gameboy, fgbBreakpointType_PPUFrameEnd); } ppu->lineTicks = 0; } }
I assume that the problem is, that the registers are set by the game - but it should not should not.
So my question is, when are the game allowed to update the SCX/SCY register and when is it not allowed?
Or do i have to save the SCX/SCY registers much earlier?
My implementation for the SCX/SCY bus read/write is really simple:
static uint8_t fgb__PPULCDRegisterRead(uint16_t address) { switch (address) { ... case 0xFF42: return lcd->scy; case 0xFF43: return lcd->scx; ... } } static void fgb__PPULCDRegisterWrite(const uint16_t address, uint8_t value) { switch (address) { ... case 0xFF42: lcd->scy = value; break; case 0xFF43: lcd->scx = value; break; ... } }
Offline
Ignore it... writing this post actually fixed it for me, because i simply moved the "frame finished" to the mode HBlank when LY >= 144.
This works correctly
Offline