GBC Marble Madness window position [solved]

Discussion of programming and development for the original Game Boy and Game Boy Color.
Post Reply
User avatar
zeroone
Posts: 939
Joined: Mon Dec 29, 2014 1:46 pm
Location: New York, NY
Contact:

GBC Marble Madness window position [solved]

Post by zeroone »

In the GBC version of Marble Madness, the window is used to display the score at the bottom of the frame during gameplay. This is accomplished by setting WX to 7 on scanline 136. The window is hidden above that scanline with WX set to 167. WY is set to 0 throughout the frame, but the text to be displayed appears in memory at what should be the top of the window. Consequentially, if I force WY to 136 in my emulator, the text properly appears at the bottom of the frame. Leaving WY as 0 draws the wrong strip of tiles.

I assume that either WY is not getting set correctly or that the text was injected into the wrong location in VRAM. Or, perhaps the PPU is reading the wrong piece of VRAM that just happens to line up when I force WY to 136. Any suggestions? Thanks.
Last edited by zeroone on Mon Dec 04, 2017 10:07 am, edited 1 time in total.
Alyosha_TAS
Posts: 173
Joined: Wed Jun 15, 2016 11:49 am

Re: GBC Marble Madness window position

Post by Alyosha_TAS »

If it helps here is what Gambatte shows in VRAM. The window text is definitely at the top of the window ($9C00).

Image
User avatar
zeroone
Posts: 939
Joined: Mon Dec 29, 2014 1:46 pm
Location: New York, NY
Contact:

Re: GBC Marble Madness window position

Post by zeroone »

Alyosha_TAS wrote:The window text is definitely at the top of the window ($9C00).
I agree. Is Gambatte able to reveal what the WY value? As far as I can tell, it is always 0.

If the Window is turned on mid-frame, does the turn-on scanline become the window origin coordinates?
User avatar
zeroone
Posts: 939
Joined: Mon Dec 29, 2014 1:46 pm
Location: New York, NY
Contact:

Re: GBC Marble Madness window position

Post by zeroone »

I think I found a clue. I'll investigate this further.

Update: Marble Madness never disables the window from the LCD Control register. But, it does hide and show the window by modifying WX. I wonder if that has similar consequences. It boils down to: Are the rows of the window always displayed sequentially? Is it ever possible to skip window rows? If the window is always drawn top to bottom, then this would explain the strange effect. And, if that is the case, what about enabling/disabling the background?

Update 2: I plugged that in and it does solve the problem for Marble Madness. That's my best guess on how this is working. If that info is wrong, please let me know :)
Shonumi
Posts: 342
Joined: Sun Jan 26, 2014 9:31 am

Re: GBC Marble Madness window position

Post by Shonumi »

zeroone wrote:I think I found a clue.
The behavior in Marble Madness is the same as Star Trek: The 25th Anniversary in terms of Window graphics. The difference is that where Star Trek disables and re-enables the Window via the LCDC register, Marble Madness disables and re-enables the Window via WX. The end result is still the same, apparently, that is to say the Window "remembers" the last line it was rendering before it was shut off (VBlank seems to reset it to 0 automatically).

So what's happening is that for most of the screen, Marble Madness sets WX to 0xA7. This disables the Window, but when enabled again at the bottom of the screen, it continues rendering from the last line it remembers (which would be 0 since it gets reset on VBlank).

It's possible to do split rendering of the window by messing with WX mid-screen. I tested it on real hardware, and the results are what I expected. I'll post a small test ROM here when I get home demonstrating how it works.
Shonumi
Posts: 342
Joined: Sun Jan 26, 2014 9:31 am

Re: GBC Marble Madness window position

Post by Shonumi »

Alright, here's the test ROM you can use, along with a screen shot of the expected output. Top part is just standard BG rendering (WX = 0xA7), but the bottom part is the actual Window. It starts rendering by setting WX to 0x7, then sets it to 0xA7 a little later, then sets it back to 0x7 to resume rendering. If you can emulate that, you've nailed the real behavior behind Marble Madness.
Attachments
wx_split.png
wx_split.png (1.21 KiB) Viewed 5011 times
wx_split.gb
(32 KiB) Downloaded 271 times
User avatar
zeroone
Posts: 939
Joined: Mon Dec 29, 2014 1:46 pm
Location: New York, NY
Contact:

Re: GBC Marble Madness window position

Post by zeroone »

Shonumi wrote:Alright, here's the test ROM you can use, along with a screen shot of the expected output. Top part is just standard BG rendering (WX = 0xA7), but the bottom part is the actual Window. It starts rendering by setting WX to 0x7, then sets it to 0xA7 a little later, then sets it back to 0x7 to resume rendering. If you can emulate that, you've nailed the real behavior behind Marble Madness.
This is brilliant and my emulator replicates your output image. Thanks so much for creating this.

Does this mean that the window is always drawn row-by-row from top-to-bottom? Or, is there a way to actually hide or skip over a set of rows?
Shonumi
Posts: 342
Joined: Sun Jan 26, 2014 9:31 am

Re: GBC Marble Madness window position

Post by Shonumi »

zeroone wrote: Does this mean that the window is always drawn row-by-row from top-to-bottom? Or, is there a way to actually hide or skip over a set of rows?
Yes, the window appears to be line-by-line, top-to-bottom. I don't think it's possible to skip lines; you can only delay rendering them for a given frame. Whenever the window is enabled, it still draws them in order. I don't think mid-screen WY writes have any immediate affect. I just tried several more quick hardware tests for that behavior. The value the LCD uses is probably latched when it starts rendering after it completes VBlank or something.
User avatar
zeroone
Posts: 939
Joined: Mon Dec 29, 2014 1:46 pm
Location: New York, NY
Contact:

Re: GBC Marble Madness window position

Post by zeroone »

Does the background also have similar behavior?
Shonumi
Posts: 342
Joined: Sun Jan 26, 2014 9:31 am

Re: GBC Marble Madness window position

Post by Shonumi »

No, I don't believe the BG has similar behavior. For example, imagine you have SX and SY set to 0, and the BG is enabled before rendering Line 0. Now let's say at some point, you disable the BG via LCDC at Line 20, then at Line 24 you re-enable the BG. You don't get the same "split" rendering as the Window. Instead, you just skip whatever pixels the BG was disabled for. So on Line 24, the BG renders Line 24 instead of picking up where it last left off (Line 20).

However, if I recall correctly, SY changes mid-screen do have an immediate affect. So you could manually change the offset to create split rendering of the BG to recreate what the Window does. Most games and demos just use dynamic SY changes for psuedo-3D effects (F-1 Race and probably both versions of Road Rash). It can also be used for cheap vertical scaling (like one of the intro logos from Battle Arena Toshinden).
Post Reply