EvilJagaGenius / jagoombacolor

Jaga's Goomba Color fork
102 stars 9 forks source link

Mid-frame BG palette change/"hi-color" support #20

Open EvilJagaGenius opened 2 years ago

EvilJagaGenius commented 2 years ago

Multiple GBC games change background palettes per-frame to display more colors, but Goomba Color/Jagoomba doesn't support this yet. When a screen shows up that uses this technique, it looks patchy and garbled.

Examples I know of: Alone in the Dark: Just about everything Crystalis: Title screen Donkey Kong Country: Title screen Tomb Raider: Intro menus, title screen, cutscenes V-Rally '99: Menus, possibly road graphics?

@minucce mentioned this while we were working out HDMA and using DKC to test it. https://github.com/EvilJagaGenius/jagoombacolor/issues/3#issuecomment-964667539

This page might have useful documentation

EvilJagaGenius commented 2 years ago

Took a quick look today, further thoughts.

lcd.s:22

@TODO:
@* = written, + = tested
...
@Palette changes per line using vcount, may up to 4 palettes per frame total

So nobody's gotten around to this yet. (Speaking of which I should probably update this to-do list since some of the issues on it are fixed now.)

lcd.s:1621

0:
    mov r0,#1
    strb_ r0,vblank_happened

    bl display_frame  @ Commenting out this line keeps the BG layers and UI from rendering
        ...

lcd.s:2346 display_frame: @called at vblank

GBC palettes are written to IWRAM, then written to the GBA's palette RAM sometime during display_frame. display_frame is only called once per frame. So palettes only get changed at the end of the frame, and I believe the entire frame is rendered with the last palettes written to RAM before vblank.

I still don't know how to fix this but I have ideas. Would it be possible to... render the screen piecemeal, instead of all at once at the end of each frame? Say we add a variable like scanlines_since_render, which starts at 0 and increments every scanline, and a function called render_scanlines. If scanlines_since_render > 0, render_scanlines would render those next scanlines and reset scanlines_since_render to 0. Might need another var to keep track of the scanline we're on. Then call render_scanlines every BG palette change (FF69_W) and at the end of every frame.

I don't know if it's possible to do something like that on the GBA though. And it might require a lot of modification to how Goomba Color/Jagoomba renders. Use the hicolor branch to work on any drastic changes without screwing up master.