Game Boy Color bug - Oracle of Ages transitions [fixed]

Discussion of programming and development for the original Game Boy and Game Boy Color.
Post Reply
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Game Boy Color bug - Oracle of Ages transitions [fixed]

Post by Near »

During the transition scenes during the Legend of Zelda - Oracle of Ages intro, graphical corruption (well, technically it's tiledata from the new scene while the tilemap hasn't been updated yet) is briefly flashed on screen with my GBC emulator. Here's an example:

Image

Image

Image

Image

Other emulators also show two screens of corruption, whereas in higan it's about 30 screens or so (eg half a second.)

Other emulators tend to show an all orange screen between this transition for the bulk of it.

However, I'm 99.9% certain I have screen disable and layer disable flags implemented ... so I really can't imagine what's going on.

Has any Game Boy Color emudevs come across this issue before? Anyone have any ideas on what might be the issue? Seems like it could be any number of things, and I'm not sure how to go about debugging this >_>
Last edited by Near on Tue Aug 01, 2017 3:33 am, edited 1 time in total.
Shonumi
Posts: 342
Joined: Sun Jan 26, 2014 9:31 am

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by Shonumi »

This looks like it's DMA related. I think the overwhelming majority of GBC specific graphical issues are related to the new HDMA or GDMA in some way (not doing them at the right time or not doing them correctly, mostly the former imo). My guess here is that maybe you trigger only one GDMA where you need multiple. I haven't touched Oracle of Ages in a while, so I'm just throwing something out there.

Having said that, you really should double-check LCD enabling/disabling, at least for the fact that most GBC emulators get the glitched screen wrong. When I say that, I mean, you shouldn't even really be seeing it in something like BGB or Gambatte or whatever you're using as a reference. Generally, when VRAM corruption could potentially appear on-screen, the game shuts off the LCD briefly and displays a white screen. When you enable the LCD again, it "skips" the next frame and continues drawing the white screen instead. The 2nd frame after re-enabling the LCD is the expected frame, however. A lot of emulators ignore this behavior because it's so hard to actually see that single frame acting up. So ultimately, your goal with higan should be zero corruption displayed (unless it's verified like that on hardware, in which case the game was improperly programmed to begin with).

As far as debugging goes, I'd log all DMAs per frame and log whenever any LCDC write happens (to check for LCD enable/disable, but also any errant tile-map switching).
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by Near »

Looks like Cydrak may have found it =^-^=

The game is turning LCDC off at LY=148 ($00), then turning it back on again 44 scanlines later ($e7).

So the trick is probably that I am still internally hard-driven around a 60fps loop of cycles and don't actually stop all PPU rendering when LY is turned off.

I'll have to do some reworking to get this going with higan, but I have a good idea of how to proceed. I'll post again once I have it implemented, and see if it works.

Thank you for the input, Shonumi! :D

Side note: seems Mednafen is likely wrong to have an orange screen during this part. Should be white as in when LCDC is off.
nitro2k01
Posts: 252
Joined: Sat Aug 28, 2010 9:01 am

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by nitro2k01 »

byuu wrote:The game is turning LCDC off at LY=148 ($00), then turning it back on again 44 scanlines later ($e7).
To nitpick/correct you, whichever is correct, it does not happens 44 scanlines later per se. When LCDC is off, no rendering is happening and LY is not incremented and (afair) locked to a value of 00. If I'm understanding for example the SNES PPU correctly, you cannot turn off the PPU like this on SNES. You can blank it, but it will still output a video signal, as not to lose sync with the TV or display. Gameboy has no such considerations and the PPU can be turned off at any time (with the optional Nintendo guideline restriction to only turn it off during VBlank to avoid physical damage to the LCD) and can likewise be turned on at any time, which restarts drawing the frame from the top. Including being out of sync with the host system, on an emulator that aims for perfect frame sync, which I assume is the case with Higan-GB.

Will be interesting to see your approach to this issue. You might simply resync the frame output to the host frame rate, but then you will need to drop or insert 1 frame sometimes when the LCD is turned on to ensure that the long term timing doesn't drift, if you care about that. (This is the sort of thing speedrunners care about, so that emulator play times are comparable to hardware play times.)
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by tepples »

You may need to duplicate a frame anyway because 59.73 Hz (GB, GBC, GBA frame rate) is less than 59.94, 60, 60.10, etc.
nitro2k01
Posts: 252
Joined: Sat Aug 28, 2010 9:01 am

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by nitro2k01 »

tepples wrote:You may need to duplicate a frame anyway because 59.73 Hz (GB, GBC, GBA frame rate) is less than 59.94, 60, 60.10, etc.
The usual strategy of Higan is to lock the emulated console's frame rate to the host frame rate, and repitch the sound to fit. I don't know if it can be made to emulate the timing realistically. But even so, there might be value in keeping the emulated speed at least internally consistent long term.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by tepples »

Good luck doing anything like that if you're emulating a Game Boy and a Super Game Boy 2 linked together. Both Game Boy systems are running at a nominal 59.73 Hz, thanks in part to the second oscillator in the SGB2, but the SGB2 has to upconvert that to 60.10 Hz for display.
gekkio
Posts: 49
Joined: Fri Oct 16, 2015 6:18 am

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by gekkio »

I'd also like to add that the Nintendo guideline about turning the PPU off in vblank applies to DMG/MGB only, so CGB-only games like Oracle of Ages are free to do whatever they please.
Real SGB/SGB2 devices seem to use a form of double-buffering or something like that, because adjusting the SGB/SGB2 CPU speed doesn't seem to cause tearing or other unwanted side-effects. So basically it buffers and draws full frames only on the SNES/SFC side.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by Near »

Actually, higan has moved toward embracing adaptive sync after dealing with the 75hz WonderSwan, 50hz PAL games, etc.

It's quite within the realm of possibility now for higan to simply leave the display blanked for a while and throw off the timing.

The much harder question is ... what do we do once the display is off? I presume the screen shown on the Game Boy will slowly fade away if you leave the LCD off. It would be quite an abuse bottleneck potential to flush out a solid white screen the instant the dispay is disabled.

Imagine a bastard writing a loop that just does "LCDC.d7=0, LCDC.d7=1" ... they'd skyrocket the framerate into the thousands, which neither higan nor any monitor couldt keep up with :P (could keep an is_dirty flag after first pixel render from a white screen flush, but this is a cat and mouse game I'd rather not have.)

But you know, emulators can't protect against EVERY stupid thing a user might try, so maybe I'll just do that and say, "don't abuse my emulator, please."

One thing I'm going to have to do as well is extend libco to be able to restart threads without reallocating the thread memory. Something like co_recreate(entrypoint, cothread_t). We'll see.
nitro2k01
Posts: 252
Joined: Sat Aug 28, 2010 9:01 am

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by nitro2k01 »

byuu wrote:Imagine a bastard writing a loop that just does "LCDC.d7=0, LCDC.d7=1" ... they'd skyrocket the framerate into the thousands, which neither higan nor any monitor couldt keep up with :P (could keep an is_dirty flag after first pixel render from a white screen flush, but this is a cat and mouse game I'd rather not have.)
I can confirm that this is a thing. Made about half of the emulators I tested it on hang. I stumbled upon that by accident, though, when researching whether you could draw only half the screen (on hardware) for an effective 120 FPS output but using only the top half of the LCD. Wasn't too successful though...
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by Near »

Okay, I've changed higan's implementation to set LY=0 on LCDC.d7 1->0 (disable) transitions, instead of on 0->1 transitions. And now the PPU stays frozen until the display is enabled again.

This does indeed make Oracle of Ages run very well with far less corruption. Thank you very much, everyone! :D

So now I'm left with two questions to finish the implementation:

1. how soon does the image on the LCD fade to blank (white)? 16ms or so?

2. when you enable the LCD again via LCDC.d7 0->1, how long does it take before the LCD starts rendering again? Can it start plotting pixels at the top left of the display again immediately? Does it take 16ms or so?

If anyone knows the answer, please state your degree of confidence in your timing numbers, so I can comment appropriately in the code, thanks :3
Shonumi
Posts: 342
Joined: Sun Jan 26, 2014 9:31 am

Re: Game Boy Color bug - Oracle of Ages transitions [fixed]

Post by Shonumi »

2. when you enable the LCD again via LCDC.d7 0->1, how long does it take before the LCD starts rendering again? Can it start plotting pixels at the top left of the display again immediately? Does it take 16ms or so?
Can't verify the 1st question, but the second question has been settled for a while, based on AntonioND's timing docs. It takes a full frame after you turn on the LCD to display anything besides the white screen. So approximately 16ms from whenever you turn it back on. A good test would be to draw something during that first blank screen ("Your emulator sucks"), then during VBlank change it (maybe draw nothing, or at least an animated icon to let people know it's not frozen) for the next frame that appears. Wait until the next VBlank and disable/re-enable the LCD, and repeat. You'd get that psuedo-transparency effect with everything drawn, but emulators that fail the test would display that message.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: Game Boy Color bug - Oracle of Ages transitions [fixed]

Post by Near »

So to be clear, the entire time the LCD is warminig up again, LY is read back as zero, yes?

So on an LCDC.d7 0->1 transition, I should set a "sleep for one frame" flag, and then the PPU should just call step(frequency()/60) /*~16ms*/ before it starts rendering at 0,0 again. Yeesh.
Shonumi
Posts: 342
Joined: Sun Jan 26, 2014 9:31 am

Re: Game Boy Color bug - Oracle of Ages transitions [fixed]

Post by Shonumi »

So to be clear, the entire time the LCD is warminig up again, LY is read back as zero, yes?
Not sure. Maybe someone else knows. If you turn it on, I'm assuming that it functionally "works" in the sense that interrupts and DMAs and anything related to the LCD starts up again, just that the LCD won't pull data from VRAM. I'm also assuming you still get the same VRAM write-protections during scanlines that you'd normally have, but it would be interesting to see if you still had unlimited VRAM access during that blank frame. Both cases are easy enough to test with some modifications to my proposed test ROM.
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: [Help needed] Game Boy Color bug - Oracle of Ages

Post by lidnariq »

byuu wrote:1. how soon does the image on the LCD fade to blank (white)? 16ms or so?
That should be an physical process rather than an electronic one, and should be roughly the same speed as what you see when you turn the relevant era game boy off.
Post Reply