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.
GBC Marble Madness window position [solved]
GBC Marble Madness window position [solved]
Last edited by zeroone on Mon Dec 04, 2017 10:07 am, edited 1 time in total.
-
- Posts: 173
- Joined: Wed Jun 15, 2016 11:49 am
Re: GBC Marble Madness window position
I agree. Is Gambatte able to reveal what the WY value? As far as I can tell, it is always 0.Alyosha_TAS wrote:The window text is definitely at the top of the window ($9C00).
If the Window is turned on mid-frame, does the turn-on scanline become the window origin coordinates?
Re: GBC Marble Madness window position
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
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
Re: GBC Marble Madness window position
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).zeroone wrote:I think I found a clue.
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.
Re: GBC Marble Madness window position
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 (1.21 KiB) Viewed 5011 times
-
- wx_split.gb
- (32 KiB) Downloaded 271 times
Re: GBC Marble Madness window position
This is brilliant and my emulator replicates your output image. Thanks so much for creating this.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.
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?
Re: GBC Marble Madness window position
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.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?
Re: GBC Marble Madness window position
Does the background also have similar behavior?
Re: GBC Marble Madness window position
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).
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).