Gericom / GBARunner3

205 stars 28 forks source link

Some games have sprite priority issues due to a GBA OAM HW bug #32

Open Dartz150 opened 11 months ago

Dartz150 commented 11 months ago

This happens on the Swamp area. When Link tries to walk on mud, it should look like this:

image

But instead it becomes invisible, making this area hard to play.

Gericom commented 11 months ago

Did this already happen in gbarunner2? It could be a sprite priority bug.

Dartz150 commented 11 months ago

Did this already happen in gbarunner2? It could be a sprite priority bug.

I've tested this on GBARunner2 and yes, the issue is also there. This may be also related to Link disappearing when the climbing stairs animations starts.

Dartz150 commented 11 months ago

This issue happens because of a hardware bug present in real GBA hardware that can't be replicated in NDS hardware despite the similarities, since it was fixed in the later, NO$GBA can replicate the issue as well as it doesn't have this bug emulation implemented yet, and there's not enough documentation on this.

Basically, the GBA applies masking effects backwards, I'll try to explain how it happens:

Castor Wilds Area makes the lower half of link invisible to simulate that his body is sinking, so for that, in theory, we should apply a mask layer like this:

image

So, if we mask that zone, it should look like this, right?:

image

Well, as I said, the GBA does it backwards. Instead of applying the masking object to the zone that you want to become invisible, it applies the mask to the area you want to be visible, like this:

image

And of course, since the DS makes the masking effects correctly, it ends up covering up link's head instead of the opposite:

image

By removing the code responsible for the creation of the sprites used for masking, with help of the decompilation project, I made a temporary fix for this, because, at least for Castor Wilds, it would be better to add an offset for the Y coordinate of this object, so it only makes the lower half of link invisible. I'll take a look into this later, but if you want to try, the line that has this object for Castor Wilds is here:

https://github.com/zeldaret/tmc/blob/755f26dc7238e1af8c824d40e88b8f891fe6450f/src/player.c#L3562

This xDelta patch is a temporary fix for this issue, It is for the EUR rom with SHA-1 cff199b36ff173fb6faf152653d1bccf87c26fb7

tmc_eu_no_sprite_fix.zip

Gericom commented 11 months ago

I'll also mention this issue which is about the same hw bug https://github.com/MiSTer-devel/GBA_MiSTer/issues/38

Dartz150 commented 9 months ago

You can reproduce a similar issue by using this, which is documented here:

prio_demo.zip

Pressing select should reproduce the GBA Sprite Priority bug on real hardware, which obviously doesn't happen in GBARunner3 which is running using the NDS hardware, see the pictures below:

Real GBA hardware: image

GBArunner3: image

Dartz150 commented 9 months ago

Golden Sun has a similar issue in certain areas, such as this one:

image

Golden.Sun.U.zip