Mickey Mania emulator comparison

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis »

considering all that has been said above, can we say that THIS is the correct sprite masking implementation (i.e ignoring the first sprite for sprite masking) ?
Not quite. My notes from testing:
-Sprite masks at x=0 only work correctly when there's at least one higher priority sprite on the same line which is not at x=0. (This is what Galaxy Force II relies on)
-Sprite masks at x=0 are never effective when not proceeded by a higher priority sprite not at x=0 on the same line, unless the previous line ended with a sprite pixel overflow, in which case, the mask becomes effective for that line only. If that line also causes a dot overflow, the mask will also be effective on the following line, and so on.
-A sprite mask does contribute to the pixel overflow count for a line according to its given dimensions just like any other sprite. Note that sprite masks still count towards the pixel count for a line when sprite masks are the first sprites on a line and are ignored. (This is what Mickey Mania relies on)
-A sprite mask at x=0 does NOT stop the VDP from parsing the remainder of sprites for that line, it just prevents it from displaying any more pixels as a result of the sprites it locates on that line. As a result, a sprite pixel overflow can still occur on a line where all sprites were masked, but there were enough dots in the sprites given after the masking sprite on that line to cause a dot overflow.

Note point number 2. Nothing emulates that, and my test ROM will be checking for it. I haven't yet confirmed whether a sprite count overflow on the previous line causes this behaviour, or whether only a sprite dot overflow on the previous line triggers it.
Snake
Very interested
Posts: 206
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake »

I can confirm what Nemesis says here is absolutely correct.
Nemesis wrote:Note point number 2. Nothing emulates that
Indeed. In Fusion, this is mainly because I jump to the wrong place at the wrong time, and now that I've realised this it's something I plan to fix, when I actually get the chance.

I actually think the 'sprite masking' thing is a side effect of something else/hardware bug rather than a feature. That'd seem to be backed up by the fact Sega didn't document it immediately, and then when they did, they got it completely wrong. It doesn't make any sense at all that it would continue to process, but not draw, the rest of the sprites.

Anyway - I only looked at this briefly, and after TascoDLX's comments I had another quick look at the sprite table. I actually think there is something *else* going on in this game because the phenomenon is still not completely explained...
TmEE co.(TM)
Very interested
Posts: 2452
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) »

this masking is extremely useful so all info regarding it is highly welcome :)
I stumbled upon it accidently when I was making Glass Breaker MD, I placed all things that weren't active outside screen to x coord 0 and I noticed that my sprites got "sliced"... now I'm using it on statusbar in one game I'm making so pther sprites would not end up on it in any case :D
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen
TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX »

Snake wrote:Anyway - I only looked at this briefly, and after TascoDLX's comments I had another quick look at the sprite table. I actually think there is something *else* going on in this game because the phenomenon is still not completely explained...
You mean... I'm NOT crazy?!? Oh thank god! :D
Eke
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke »

Nemesis wrote:
considering all that has been said above, can we say that THIS is the correct sprite masking implementation (i.e ignoring the first sprite for sprite masking) ?
Not quite. My notes from testing:
-Sprite masks at x=0 only work correctly when there's at least one higher priority sprite on the same line which is not at x=0. (This is what Galaxy Force II relies on)
-Sprite masks at x=0 are never effective when not proceeded by a higher priority sprite not at x=0 on the same line, unless the previous line ended with a sprite pixel overflow, in which case, the mask becomes effective for that line only. If that line also causes a dot overflow, the mask will also be effective on the following line, and so on.
-A sprite mask does contribute to the pixel overflow count for a line according to its given dimensions just like any other sprite. Note that sprite masks still count towards the pixel count for a line when sprite masks are the first sprites on a line and are ignored. (This is what Mickey Mania relies on)
-A sprite mask at x=0 does NOT stop the VDP from parsing the remainder of sprites for that line, it just prevents it from displaying any more pixels as a result of the sprites it locates on that line. As a result, a sprite pixel overflow can still occur on a line where all sprites were masked, but there were enough dots in the sprites given after the masking sprite on that line to cause a dot overflow.

Note point number 2. Nothing emulates that, and my test ROM will be checking for it. I haven't yet confirmed whether a sprite count overflow on the previous line causes this behaviour, or whether only a sprite dot overflow on the previous line triggers it.
well, I took some time to analyse MickeyMania sprites on each line
and it seems this is not only a case of handling non-visible sprite for pixel overflow (which genesis plus already did correctly despite the fact the bug still occured)

here's what I got on the incriminated line:
*** LINE 110 (53688 / 53680 cycles) ***
Sprite Parsing line 239 :
0: sprite 20(21): xpos= 0x0, ypos = 0xe9, size=32x32
1: sprite 21(22): xpos= 0x0, ypos = 0xe9, size=32x32
2: sprite 22(23): xpos= 0x0, ypos = 0xe9, size=32x32
3: sprite 23(24): xpos= 0x0, ypos = 0xe9, size=32x32
4: sprite 24(25): xpos= 0x0, ypos = 0xe9, size=32x32
5: sprite 30(31): xpos= 0x104, ypos = 0xd1, size=32x32
6: sprite 35(36): xpos= 0x124, ypos = 0xe1, size=16x24
as you can see, the amount of pixels is less than 320 so no pixel overflow should stop sprite rendering
if we apply rule #1 which genesis plus originally used, the masking should not occur for sprite 30 and 35 which is wrong (same thing for the following lines)


now, if we look at the previous line to check for rule #2:
*** LINE 109 (53158 / 53156 cycles) ***
109(53158): HINT (OFF) pending (0001ac30)
Sprite Parsing line 238 :
0: sprite 2(3): xpos= 0x15a, ypos = 0xdf, size=16x16
1: sprite 20(21): xpos= 0x0, ypos = 0xe9, size=32x32
2: sprite 21(22): xpos= 0x0, ypos = 0xe9, size=32x32
3: sprite 22(23): xpos= 0x0, ypos = 0xe9, size=32x32
4: sprite 23(24): xpos= 0x0, ypos = 0xe9, size=32x32
5: sprite 24(25): xpos= 0x0, ypos = 0xe9, size=32x32
6: sprite 30(31): xpos= 0x104, ypos = 0xd1, size=32x32
7: sprite 35(36): xpos= 0x124, ypos = 0xe1, size=16x24
we can figure that:

- rule #1 applies and sprites 30/35 are indeed masked (same for previous lines)

- there is no sprite overflow neither pixel overflow

so rule #2 does not apply for the next line

sure this is one line among other and values probably differs from frame to frame but this somehow contradicts what you tested, no ?


PS: using the simple rule "sprite masking occurs when a low priority sprite with xpos=0 is found" , which is also the test case used in official Sega document, works for all game I tried so far, including Galaxy Force 2
TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX »

Unfortunately I've been unable to recreate Mickey Mania's sprite masking on real hardware (at least based on VRAM), but I'm wondering if the game's disabling the display and DMAing through the hsync period is somehow messing with sprite processing? Has anyone done any hacking with the game and a game genie? I only have the latter.
Snake
Very interested
Posts: 206
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake »

Eke wrote:PS: using the simple rule "sprite masking occurs when a low priority sprite with xpos=0 is found"
I think what Nemesis meant by 'high priority' was a sprite earlier in the list, i.e. high priority with respect to the current sprite - and not the background priority settings, which have no effect.

But I still don't think this is sprite masking. It'd be interesting to hack the ROM to move all those X=0 sprites to X=8 - and see if it still works...
TascoDLX wrote:You mean... I'm NOT crazy?!? Oh thank god! :D
No, Sir, you're still very much on the right side of Genius.
TascoDLX wrote:Unfortunately I've been unable to recreate Mickey Mania's sprite masking on real hardware (at least based on VRAM), but I'm wondering if the game's disabling the display and DMAing through the hsync period is somehow messing with sprite processing? Has anyone done any hacking with the game and a game genie? I only have the latter.
This is the only explanation I have so far. We know that writing to VRAM during active scan is limited, and we know that the writes happen 99% during the visible area, and not during H-SYNC. Therefore, the VDP must be busy doing something important during H-SYNC. So, if you steal the H-SYNC by blanking the screen for most of it, *something* bad is going to happen. I've always wondered about this but have never found a specific effect before...

I think in this case what happens is it halves (or at least cuts down significantly, due to the amount of time stolen from the VDP) the amount of sprite pixels you can show on a line - so only 5 32x32s, rather than 10, are needed.

Obviously testing is needed, I was working on a test ROM to post here but I got sidetracked.

All this is, of course, assuming that this actually does happen on real hardware... there will, of course, be some masking due to the area where there ARE 10 sprites on a line, but it really needs to be watched closely to make absolutely sure ALL the sprites are masked.
TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX »

I can confirm that the CD version (at least the EUR version) shows exactly the same: same code, same problem in Fusion, but works on real hardware.
Snake
Very interested
Posts: 206
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake »

TascoDLX wrote:I can confirm that the CD version (at least the EUR version) shows exactly the same: same code, same problem in Fusion, but works on real hardware.
Ok, well that's a good start, means I'm not wasting my time ;)
But I still don't think this is sprite masking. It'd be interesting to hack the ROM to move all those X=0 sprites to X=8 - and see if it still works...
..hint hint... ;) You already know how to do this, right? I assume your IPS patch does something like this? Info please, Sir :)
TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX »

Snake wrote:
But I still don't think this is sprite masking. It'd be interesting to hack the ROM to move all those X=0 sprites to X=8 - and see if it still works...
..hint hint... ;) You already know how to do this, right? I assume your IPS patch does something like this? Info please, Sir :)
Oh yes, that's right.

019EF4:0008 (BCSA-CAHY) for the sprites at y=233
019F0C:0008 (BCST-CAAN) for the sprites at y=253

Can't get much simpler than that.
Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis »

Ok, so I think I've finished messing around with my sprite test rom for the time being. Here's the ROM:
http://nemesis.hacking-cult.org/MegaDri ... estRom.bin

And here's the source:
http://nemesis.hacking-cult.org/MegaDri ... estRom.zip

I've ended up with a set of 9 tests, which I've engineered to be as evil as possible. Here's a short description of each test:
1. Max sprites per line. This test checks that the correct number of sprites are being displayed on a given line. The first result verifies that the last visible sprite is displayed correctly. The second result verifies that the first discarded sprite is not displayed.
2. Max sprite dots - basic. This test checks that new sprites are being displayed up until the sprite dot count for the line is reached, and that new sprites stop being displayed once the maximum number of sprite dots for the line have been exceeded.
3. Max sprite dots - complex. More thorough than the basic test. Verifies that sprite dot overflow cuts off a sprite partway through when the sprite dot count is reached, and that sprite masks contribute to the dot count, amoung other things.
4. Sprite masking. Verifies that basic sprite masking is working when the sprite mask is not the first sprite on the line.
5. Sprite masking in slot 1. Verifies that sprite masks are ignored when they appear before any other sprites on a line.
6. Sprite masking in slot 1 on dot overflow. Verifies that sprite masks at the beginning of a line become effective when a sprite dot overflow occurs on the previous line.
7/8. Verifies that the emulator is not implementing the non-existant sprite masking mode 2.
9. Max sprites per frame. Verifies that the "sprite limits" for the frame are being followed. Actually, most emulators fail this test. Per-frame sprite limits actually determine the number of entries which are read from the sprite table. Under H32 mode, only the first 64 entries of the table are read. Under H40 mode, only the first 80 entries of the table are read. All sprite entries after these maximums are ignored. If you try and, for example, jump to sprite entry 65 under H32 mode, that sprite entry will not be processed and the sprite list will terminate, even if you jump to it directly from the first sprite.


Here's what you get on the real system:
ImageImage

Here's what you get on Kega:
ImageImage
Kega is the only emulator which passes the complex sprite dot overflow test.

Here's what you get on Gens:
ImageImage
That isn't a pass for the sprite masking on dot overflow. Note the red line at the bottom. This test is conditional on the above test passing, which it doesn't.

Here's what you get on Regen:
ImageImage
Regen is the only emulator which passes the per-frame sprite limits in H32 mode.

Here's what I currently get on my emulator:
ImageImage
Looks like I've got some work to do. Note that I followed the sprite masking mode 2 info, which causes test 8 to fail.

And just for the fun of it, here's Genecyst:
ImageImage
Could be worse.

So yeah, hopefully this test ROM will help everyone to verify their sprite overflow/masking code.
Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis »

As for Mickey Mania, I think you guys are right, something that Mickey Mania is doing mid-frame (haven't looked at the code at all) is affecting the total number of dots available for sprites, causing a sprite dot overflow when it would normally not occur.

I halted the game in my emulator, and dumped the complete static VDP state out to a test ROM I ran on the real system, and the masking did NOT work. I also tried the rather unscientific method of yanking out the game cart at the appropriate time, and once the game locked, the sprite masking also no longer worked correctly. That says it's an active process the game code is running which is keeping the sprites masked. I also applied those codes you gave Tasco, and it had no noticeable effect, that is, the sprites were still masked. If the game is disabling the display for large blocks of time during hblank as you guys say, it sounds like that's the likely culprit.

I don't have time to run tests on that right at this moment, but that would mean that in order to emulate this game properly, we'll need to get solid info on the exact impact disabling the display mid-frame has on the ability of the system to render sprites. This is only being displayed incorrectly in Kega because it's more accurate than other emulators in how it deals with sprite masking and overflow.
Eke
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke »

Ok, so I think I've finished messing around with my sprite test rom for the time being. Here's the ROM:
http://nemesis.hacking-cult.org/MegaDri ... estRom.bin

And here's the source:
http://nemesis.hacking-cult.org/MegaDri ... estRom.zip

I've ended up with a set of 9 tests, which I've engineered to be as evil as possible. Here's a short description of each test:
1. Max sprites per line. This test checks that the correct number of sprites are being displayed on a given line. The first result verifies that the last visible sprite is displayed correctly. The second result verifies that the first discarded sprite is not displayed.
2. Max sprite dots - basic. This test checks that new sprites are being displayed up until the sprite dot count for the line is reached, and that new sprites stop being displayed once the maximum number of sprite dots for the line have been exceeded.
3. Max sprite dots - complex. More thorough than the basic test. Verifies that sprite dot overflow cuts off a sprite partway through when the sprite dot count is reached, and that sprite masks contribute to the dot count, amoung other things.
4. Sprite masking. Verifies that basic sprite masking is working when the sprite mask is not the first sprite on the line.
5. Sprite masking in slot 1. Verifies that sprite masks are ignored when they appear before any other sprites on a line.
6. Sprite masking in slot 1 on dot overflow. Verifies that sprite masks at the beginning of a line become effective when a sprite dot overflow occurs on the previous line.
7/8. Verifies that the emulator is not implementing the non-existant sprite masking mode 2.
9. Max sprites per frame. Verifies that the "sprite limits" for the frame are being followed. Actually, most emulators fail this test. Per-frame sprite limits actually determine the number of entries which are read from the sprite table. Under H32 mode, only the first 64 entries of the table are read. Under H40 mode, only the first 80 entries of the table are read. All sprite entries after these maximums are ignored. If you try and, for example, jump to sprite entry 65 under H32 mode, that sprite entry will not be processed and the sprite list will terminate, even if you jump to it directly from the first sprite.
Thanks a lot, I hope it's the beginning of a long serie for VDP test programs ;-)

Here's what I originally got in genesis plus:

Image
Image


If I make the change for Mickeymania to "work":

Image
Image


If I try to fix test 6 and add previous line dot overflow detection (note that I also need to take masked sprites width in account for dot overflow instead of simply exiting the sprites rendering function):

Image

Note that even with that (and as expected since no dot overflow occurs *on emulator*), Mickeymani 3D level is still wrong, the only way to get it right being to "cheat" and fail test 5

looks like we have to choose between accuracy and visual correctness :?
It's very probable the "mask S1 on dot overflow" is not used by any games though :roll:
Snake
Very interested
Posts: 206
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake »

That looks like a very nice test ROM :)

As I said earlier, I knew Kega would fail that one particular test, but...
Nemesis wrote:If you try and, for example, jump to sprite entry 65 under H32 mode, that sprite entry will not be processed and the sprite list will terminate, even if you jump to it directly from the first sprite.
I never thought to try that.
Nemesis wrote:I also applied those codes you gave Tasco, and it had no noticeable effect, that is, the sprites were still masked
Exactly what I expected to see, and proves that Mickey Mania does NOT use Sprite Masking. Thanks :)
Eke wrote:It's very probable the "mask S1 on dot overflow" is not used by any games though
No it isn't, in fact a lot of this stuff isn't. But still, your fix for MickeyMania is not accurate. I'll try to work out exactly what's going on, unless Nemesis or TascoDLX beat me to it. But until then, my philosophy is "if it can't be fixed correctly, don't fix it at all." :)
mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame »

Thank you Nemesis for your work :-)
Last edited by mickagame on Sat Mar 28, 2009 8:40 pm, edited 1 time in total.
Post Reply