|
Joined: May 2004
Posts: 1,772 Likes: 34
Very Senior Member
|
Very Senior Member
Joined: May 2004
Posts: 1,772 Likes: 34 |
Sega never does something once. Which is why Cool Riders is such an interesting puzzle. I'm pretty sure they only did that sprite compression once ;-) but yeah, there's something weird going on with that.. I wouldn't be surprised if that port where it writes ou the details for the front tilemaps / sprites wasn't some kind of comms port to be used with the other cpu (which doesn't do much yet, unless it's really just for the linkup) I couldn't understand it, nor does it seem to send enough data to tell me which parts of the sprites I need to decompress anyway. Really, I'm surprised Luca or somebody similar hasn't picked it up, that kind of pseudo-blitter weirdness is usually right down his street. (which is why I mentioned those 4 games to him)
|
|
|
|
Joined: Sep 2009
Posts: 15
Member
|
Member
Joined: Sep 2009
Posts: 15 |
The remaining OAM priority issues can be fixed by only checking the priority of the topmost sprite against the backgrounds. Passage in Anomie's Register Doc:
Note that only the priority of the topmost sprite is
considered relative to the backgrounds. Thus, if FirstSprite+3 and
FirstSprite+4 are identical except FirstSprite+3 has priority 0 and
FirstSprite+4 has priority 3, they will both be hidden by any backgrounds that
hide priority 0 sprites. This may seem counterintuitive, since FirstSprite+4
would normally go in front of these BGs, but many games depend on this
behavior.
|
|
|
|
Joined: Dec 2005
Posts: 330
Senior Member
|
Senior Member
Joined: Dec 2005
Posts: 330 |
That's exactly the same behaviour as the NES, only extrapolated to multiple BG layers and more than two levels of sprite priority. On the NES, IIRC either Super Mario Bros or SMB3 (or both) relies on it to produce the effect of a powerup item rising out of a block.
|
|
|
|
Joined: May 2004
Posts: 1,772 Likes: 34
Very Senior Member
|
Very Senior Member
Joined: May 2004
Posts: 1,772 Likes: 34 |
That's exactly the same behaviour as the NES, only extrapolated to multiple BG layers and more than two levels of sprite priority. On the NES, IIRC either Super Mario Bros or SMB3 (or both) relies on it to produce the effect of a powerup item rising out of a block. on a similar note, can somebody on good terms with the regen guys get the proper megadrive sprite masking algorithm? the one I have works with many of the difficult cases (pirates gold, galaxy force 2 etc.), but falls apart for some simple ones like the SOR status bar. None of the documentation I have seems accurate and able to handle all cases.
|
|
|
|
Joined: Jan 2006
Posts: 3,691
Very Senior Member
|
Very Senior Member
Joined: Jan 2006
Posts: 3,691 |
The remaining OAM priority issues can be fixed by only checking the priority of the topmost sprite against the backgrounds. Passage in Anomie's Register Doc:
Note that only the priority of the topmost sprite is
considered relative to the backgrounds. Thus, if FirstSprite+3 and
FirstSprite+4 are identical except FirstSprite+3 has priority 0 and
FirstSprite+4 has priority 3, they will both be hidden by any backgrounds that
hide priority 0 sprites. This may seem counterintuitive, since FirstSprite+4
would normally go in front of these BGs, but many games depend on this
behavior.
I spent quite some time in the past few days on this, but I'm not sure how this should work exactly. In particular, what does "topmost" means here? If I use the priority of FirstSprite only for all sprites, in each line, then all the sprites will use the same priority w.r.t. the bg, i.e. all sprites become OAM0, OAM1, OAM2 or OAM3 depending on the priority of FirstSprite. While this indeed fixes the current priority problems in Chrono Trigger intro, it also introduces many brand new priority problems. Look at the following snap, from Chrono Trigger intro, and in particular to the half-hidden character on the right: the snap only shows Mode1 BG1A (the one with higher priority) and sprites, to better isolate the issue: FristSprite is OAM2, i.e. priority 6; BG1A has priority 8; the sprite of the jumping/rolling Goku-like character is OAM3, i.e. it would have priority 9. By using FirstSprite priority for all the sprites, you end up with OAM3 to become OAM2 and with the OAM3 sprites hidden below the BG1 layer, as the snap shows... Another example is again in Chrono Trigger intro: the judge with the hammer disappears below its seat (which has higher priority than FirstSprite)... I guess the problem it's me not understanding the docs, but could anyone explain me how this should work exactly? EDIT: for whoever wants to try the code, I simply changed line 1265 of video/snes.c from priority = oam_spritelist[active_sprite].priority_bits; to priority = oam_spritelist[0].priority_bits; so that all the sprites in a line get the FirstSprite priority...
|
|
|
|
Joined: Jan 2006
Posts: 3,691
Very Senior Member
|
Very Senior Member
Joined: Jan 2006
Posts: 3,691 |
on a similar note, can somebody on good terms with the regen guys get the proper megadrive sprite masking algorithm? the one I have works with many of the difficult cases (pirates gold, galaxy force 2 etc.), but falls apart for some simple ones like the SOR status bar. None of the documentation I have seems accurate and able to handle all cases. did you check eke's genplus-gx source the guy has done a lot of work on it (and he's always sharing back info, like Arbee well knows for the sound findings)
|
|
|
|
Joined: Mar 2001
Posts: 17,215 Likes: 234
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,215 Likes: 234 |
Yeah, I would post at the Spritesmind board asking. If they don't know it, there's several people there that frequently run tests on hardware.
|
|
|
|
Joined: Dec 2005
Posts: 330
Senior Member
|
Senior Member
Joined: Dec 2005
Posts: 330 |
I spent quite some time in the past few days on this, but I'm not sure how this should work exactly. In particular, what does "topmost" means here? The best way to understand it is that sprite-to-sprite priority (which depends on the sprite's index) is always completely evaluated before sprite-to-BG priority (which depends on the sprite's priority bits in OAM). Say you have an opaque pixel from sprite 0 with priority 0, from sprite 1 with priority 3, and from a background tile all overlapping at the same screen position. Sprite 0 takes priority over sprite 1 because it is a lower-numbered sprite. Then, the background takes priority over Sprite 0 because that sprite is priority 0. The pixel color that gets outputted at that position is the background tile pixel. The fact that Sprite 1 has priority over the background is irrelevant because Sprite 1 has already been masked by Sprite 0 before sprite-to-background priority is evaluated. Many games on the NES and especially on the SNES take advantage of this quirk to selectively mask out parts of sprites and to simulate finer-grained levels of priority than the hardware natively provides.
|
|
|
|
Joined: May 2004
Posts: 1,772 Likes: 34
Very Senior Member
|
Very Senior Member
Joined: May 2004
Posts: 1,772 Likes: 34 |
on a similar note, can somebody on good terms with the regen guys get the proper megadrive sprite masking algorithm? the one I have works with many of the difficult cases (pirates gold, galaxy force 2 etc.), but falls apart for some simple ones like the SOR status bar. None of the documentation I have seems accurate and able to handle all cases. did you check eke's genplus-gx source the guy has done a lot of work on it (and he's always sharing back info, like Arbee well knows for the sound findings) Not wanting to drag this further off-topic, but this looks to me like the 'classic' first theory implementation, which causes problems in some games. I'll need to test the win32 build of the emulator at some point, but I have a feeling it won't handle several known cases.
|
|
|
|
Joined: Jan 2006
Posts: 3,691
Very Senior Member
|
Very Senior Member
Joined: Jan 2006
Posts: 3,691 |
The best way to understand it is that sprite-to-sprite priority (which depends on the sprite's index) is always completely evaluated before sprite-to-BG priority (which depends on the sprite's priority bits in OAM).
Say you have an opaque pixel from sprite 0 with priority 0, from sprite 1 with priority 3, and from a background tile all overlapping at the same screen position. Sprite 0 takes priority over sprite 1 because it is a lower-numbered sprite. Then, the background takes priority over Sprite 0 because that sprite is priority 0. The pixel color that gets outputted at that position is the background tile pixel.
The fact that Sprite 1 has priority over the background is irrelevant because Sprite 1 has already been masked by Sprite 0 before sprite-to-background priority is evaluated.
Many games on the NES and especially on the SNES take advantage of this quirk to selectively mask out parts of sprites and to simulate finer-grained levels of priority than the hardware natively provides. Ok. In other words, it means that it's "topmost" in each pixel and not in each line. that makes sense and for sure it fixes the new problem in the screen I posted above. I thought I had already tried to implement the priorities in the way you described, without properly fixing all the problems... but probably that was due to some different mistake of mine. I'll go back and try it again now that I know it is the correct approach. Thanks a lot for clearing out the matter!
|
|
|
2 members (Heihachi_73, 1 invisible),
526
guests, and
1
robot. |
Key:
Admin,
Global Mod,
Mod
|
|
Forums9
Topics9,320
Posts121,930
Members5,074
|
Most Online1,283 Dec 21st, 2022
|
|
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!
|
|
|
|