Mickey Mania emulator comparison

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX »

Consider the way Galaxy Force 2 uses sprite masking. It must be able to mask out a single line. But, the smallest possible sprite covers eight lines. So, if it stopped on the first sprite (xpos = 0), it couldn't mask less than eight consecutive lines at a time.

Not checking the first sprite for xpos = 0 allows for the possibility of an overlap where only one line of an off-screen sprite (xpos = 1) is processed before that of the masking sprite (xpos = 0). It's certainly not the most versatile system but it allows for that kind of detail while keeping things relatively simple.
Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis »

It's not as simple as the first sprite being ignored for sprite masking. I've started writing a "Sprite masking/overflow test rom", and I'm currently debugging it on the hardware. Yes, if you have a masking sprite at x=0 as the first sprite on a line, then follow it by a visible sprite, the masking sprite will not take effect, and the second sprite will be visible. It's not only the first sprite that causes this however. According to tests I did last night, if you have two masking sprites at x=0 at the start of a line, masking still doesn't take effect. We know that masking does take effect with 5 masking sprites at the start of a line however, as this is what Mickey Mania uses, and we know that if you have a sprite with x=1 (or probably anything that's not 0) at the start of the line, and follow it by a sprite with x=0, masking does take effect, as this is what Galaxy Force II does (I've confirmed there's no switch to a "mode 2" sprite masking for the remainder of the frame).

I don't think any of the current implementations of sprite masking are fully emulating the behaviour of the hardware. I'll be doing more tests today.
mickagame
Very interested
Posts: 256
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame »

Very interesting Nemesis :-)
Snake
Very interested
Posts: 206
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake »

TascoDLX wrote:So, I highly doubt there exists a "mode 2".
No, there doesn't. It's much simpler than Charles describes.

Never seen this problem before - and looking at the shots, and the description of what it's doing/what's happening... I have no idea at all why this wouldn't work in Fusion already. It must be a very silly bug. When I actually get a chance to look at my code (:cry:) I'll see what's going on...
TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX »

Nemesis wrote:It's not as simple as the first sprite being ignored for sprite masking.
I kinda figured there was more to it. I haven't a clue why Mickey Mania uses the five masking sprites instead of just masking the normal way (as it appears to do for the top border).
Nemesis wrote:I don't think any of the current implementations of sprite masking are fully emulating the behaviour of the hardware. I'll be doing more tests today.
I hope your tests end better than mine did, though I am very limited in my setup. The only thing I managed to find is that the horizontal size of the masking sprite likely gets added to the pixel count of the line (I didn't get a chance to confirm that). Other than that, I couldn't get hardware to do anything different than Fusion does, so I don't know why Mickey Mania works right.
Snake
Very interested
Posts: 206
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake »

Nemesis wrote:It's not as simple as the first sprite being ignored for sprite masking.
Nemesis wrote:I don't think any of the current implementations of sprite masking are fully emulating the behaviour of the hardware.
Both incorrect :)

This has nothing whatsoever to do with sprite masking, and everything to do with the fact there are more than 10 32x32 sprites on a single line. This is not taken into account properly in Fusion due to a silly bug.

I can confirm that sticking multiple sprites at zero does nothing. Neither does sticking the last one at 1,1.
TascoDLX
Very interested
Posts: 262
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX »

Snake wrote:This has nothing whatsoever to do with sprite masking, and everything to do with the fact there are more than 10 32x32 sprites on a single line. This is not taken into account properly in Fusion due to a silly bug.
I can see how that's true for y=253 but how is it true for y=233? I must be missing something.

EDIT: Nevermind -- I misunderstood. So very tired.
Snake wrote:I can confirm that sticking multiple sprites at zero does nothing. Neither does sticking the last one at 1,1.
That's a relief. :D
Last edited by TascoDLX on Thu Mar 26, 2009 5:54 pm, edited 1 time in total.
Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis »

Snake wrote:
Nemesis wrote:It's not as simple as the first sprite being ignored for sprite masking.
Nemesis wrote:I don't think any of the current implementations of sprite masking are fully emulating the behaviour of the hardware.
Both incorrect :)

This has nothing whatsoever to do with sprite masking, and everything to do with the fact there are more than 10 32x32 sprites on a single line. This is not taken into account properly in Fusion due to a silly bug.

I can confirm that sticking multiple sprites at zero does nothing. Neither does sticking the last one at 1,1.
Yep, I finally figured that out half an hour ago. I messed up a test yesterday, and spent the entire evening working from a false premise. :roll:

I have found two different ways to break sprite handling/masking in Kega Fusion however (and yeah, a lot more than two in every other emulator :)). I'm going to finish off this test ROM and post it here when it's done. I think it'll help everyone to have a single ROM that validates everything, rather than testing 100 different games and still missing some stuff.
Eke
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke »

TascoDLX wrote:
mickagame wrote:It's like the sprite with x_pos = 0 is the first sprite of the list...
Yes, indeed it is (and, in this case, the second, third, fourth, and fifth as well). Any sprite, no matter what the x_pos, should set the sol_flag. Therefore, it should look like this:

Code: Select all

if(xpos == 0 && sol_flag) return; /* stop rendering sprites */ 
sol_flag = 1;
you're right... I didn't notice before because I didn't wait enough but the bug was indeed here :oops:

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) ?

I now do something like this and this indeed works (count being the counter in the sprite list):

Code: Select all

    if(!xpos && count) return;
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.
Post Reply