Language…
8 users online: Aeon, Apple Boy, Cape, figuiDOS,  Losoall, Murilo9450, NovaDelta, Nowieso - Guests: 603 - Bots: 143
Users: 70,894 (2,286 active)
Latest user: Bettyfelony

Update Player Animation During Overworld Load

UberASM Repository → Update Player Animation During Overworld Load

Submission Details

Name: Update Player Animation During Overworld Load
Authors: Kevin, zuccha
Added:
Type: Game Mode
Includes GFX: No
Includes Hijack: No
Featured: No
Description: Update the current player animation while loading the overworld.

In practice, this code fixes an issue where if Mario is placed on a water level tile on the overworld as his starting position, he has the walking animation instead of the swimming animation right after starting a new game (you need to move to start using the correct animation). This UberASM checks if the current tile the player is standing on is water, in which case we set the swimming animation, otherwise we set the walking animation.

Known issue: in two-players mode, Luigi's animation will only be updated after he enters and exits a level.
Tags: animation bug fix game mode 0d lorom overworld sa-1 swim
Comments: 5 (jump to comments)
Rating:
0.0 (0 ratings)
No rating
Download 2.24 KiB | 86 downloads

Screenshots

Comments (5)

MarkAlarm Link
Moderated with:
- Lunar Magic 3.40
- UberASMTool 1.6
- SA-1 Pack 1.40 (also tested without)
- Snes9x v1.60, bsnes-plus v05

The known issue is minor enough to where I don't think it warrants a rejection (though it would obviously be nice to have it be fixed in the future). Due to the original bug (incorrect animation) being minor as it is as well as the issue only appearing in a mode that rarely gets usage, I believe this is fine as is to accept.
 Kevin Author Link
To fix the animation being wrong during fadein you can call the Mario drawing routine in your code right after .return:
Code
.return:
    phb
    lda.b #$04|!bank8 : pha : plb
    phk : pea.w (+)-1
    pea.w $048414-1
    jml $04862E|!bank
+   plb
    rtl
zuccha Author Link
Thanks!
I will update the submission in a couple of days when I find the time.
I still need to learn how to deal with different banks and invoking (jumping to?) original routines. From what I understand, instead of invoking $04862E (which ends with RTS, so you cannot JSL), you jump long to it? But it's still obscure to me how the routine actually returns to your code, does the entire bank setup you did serves that purpose? I don't actually expect an answer, since I suspect it's quite complex. I will read the ASM workshop document an hope to find my answers ;)
 Kevin Author Link
Basically you trick the processor into RTSing to an RTL instruction, so that it can then return to your code.

Code
    phb
    lda.b #$04|!bank8 : pha : plb
This preserves the current DB and then sets it to $04 ($84 on lorom/fastrom), just because the routine likely uses tables in the same bank (it this wasn't the case, you wouldn't need to do this).

Code
phk : pea.w (+)-1
This pushes the (long) return address to the stack, which is what the RTL will use.

Code
pea.w $048414-1
This pushes the (word) address of an RTL in bank 4 to the stack, which is where the RTS will return to (needs to be in bank 4 since RTS can only jump to the same bank).

Code
jml $04862E|!bank
+
Now you jump to the routine (not JSL, as that would also push the long return address to the stack but we needed to setup the stack ourselves). Now when the routine ends it will do: RTS -> return to $048414 -> RTL -> return to "+" label in our code.

Code
plb
Now just restore the DB to the original value that was pushed at the beginning.
zuccha Author Link
Oof, I completely overlooked the fact that when you do JSR/JSL the return address is automatically pushed on the stack (which in retrospect is obvious, RTS/RTL need to retrieve it from somewhere). That clarifies a lot, thanks again!