Navigation

Mario gets a Divine Hand: creating a new collision routine (Gameshark code)


Code on the bottom of the page.

This is an ASM hack which replaces the 0x0A (death at the bottom routine) with a custom function.

Here is it in Pseudo-c so you can understand better the ASM. First it calculates the distance between Mario and the ground.
If Mario is near enough, it will set the variable going_up = 1, so Mario will start floating.

Whenever he steps out of the collision triangle 0x0A, the going_up variable is set to 0.



void MarioGoesUp
{
mario.y = mario.y + 85;             /* gravity = about 75 */
}

int MarioGetsaDivineHand
{

  if ( ! (going_up) )   {
   
            if (mario.y < ground.y + 2048)    {
              
               going_up = 1;
               MarioGoesUp();
               }
   
     }

        else  {
        MarioGoesUp();
        }

}

void ResetsGoingUp           /*  Called from the collision processing routine */
{

  if ( ! (collision == 0x0A) )     {
     going_up = 0;
     }

}




In MIPS ASM:


.ORG 802505D8

802505D8: LUI AT, 0x803F
802505DC: LW T1, 0x7FFC (AT)
802505E0: BNE T1, R0, 0x80250618 # if ( (going_up) )
802505E4: NOP

# check if Mario is near the Ground:
802505E8: LUI AT, 0x4500
802505EC: MTC1 AT, F8
802505F0: LWC1 F6, 0x0070 (T6)
802505F4: LWC1 F4, 0x0040 (T6)
802505F8: ADD.S F10, F6, F8
802505FC: C.LT.S F4, F10
80250600: NOP
80250604: BC1F 0x80250634
80250608: NOP

# sets going_up = 1;
8025060C: LUI AT, 0x803F
80250610: ADDIU T1, R0, 0x0001
80250614: SB T1, 0x7FFF (AT)

# MarioGoesUp
80250618: LUI AT, 0x42AA
8025061C: MTC1 AT, F6
80250620: LWC1 F4, 0x0040 (T6)
80250624: ADD.S F4, F4, F6
80250628: SWC1 F4, 0x0040 (T6)
8025062C: BEQ R0, R0, 0x80250634
80250630: NOP

#End
80250634: LW RA, 0x0014 (SP)
80250638: ADDIU SP, SP, 0x0018
8025063C: JR RA
80250640: NOP

# Resets going_up byte (called from collision processor)

80250644:  LUI AT, 0x803F
80250648: SW R0, 0x7FFC (AT)
8025064C: LUI AT, 0x8025  # Not a good option. Better was a simple "J 0x8025085C"
80250650: ORI AT, AT, 0x085C
80250654: JR AT
80250658: NOP

# Patches collision processing rountine

.ORG 80250850

ADDIU AT, R0, 0x000A
BNE S0, AT, 0x80250644 # if (collision != 0x0A) 
NOP
ADDIU AT, R0, 0x000A
BEQ S0, AT, 0x80250894 # if (collision = 0x0A)
NOP
ADDIU AT, R0, 0x0032
BEQ S0, AT, 0x802508A4 # if (collision = 0x32)
NOP
ADDIU AT, R0, 0x0033
BEQ S0, AT, 0x802508B8 # if (collision = 0x33)
NOP
ADDIU AT, R0, 0x0034
BEQ S0, AT, 0x802508C8 # if (collision = 0x34)
NOP



# Gameshark code (part 1)

812505D8 3C01
812505DA 803F
812505DC 8C29
812505DE 7FFC
812505E0 1409
812505E2 000D
812505E4 2400
812505E6 0000
812505E8 3C01
812505EA 4500
812505EC 4481
812505EE 4000
812505F0 C5C6
812505F2 0070
812505F4 C5C4
812505F6 0040
812505F8 4608
812505FA 3280
812505FC 460A
812505FE 203C
81250600 2400
81250602 0000
81250604 4500
81250606 000B
81250608 2400
8125060A 0000
8125060C 3C01
8125060E 803F
81250610 2409
81250612 0001
81250614 A029
81250616 7FFF
81250618 3C01
8125061A 42AA
8125061C 4481
8125061E 3000
81250620 C5C4
81250622 0040
81250624 4606
81250626 2100
81250628 E5C4
8125062A 0040
8125062C 1000
8125062E 0001
81250630 2400
81250632 0000
81250634 8FBF
81250636 0014
81250638 27BD
8125063A 0018

# Gameshark code (part2)

8125063C 03E0
8125063E 0008
81250640 2400
81250642 0000
81250644 3C01
81250646 803F
81250648 AC20
8125064A 7FFC
8125064C 3C1F
8125064E 8025
81250650 37FF
81250652 085C
81250654 03E0
81250656 0008
81250658 2400
8125065A 0000
81250850 2401
81250852 000A
81250854 1430
81250856 FF7B
81250858 2400
8125085A 0000
8125085C 2401
8125085E 000A
81250860 1030
81250862 000C
81250864 2400
81250866 0000
81250868 2401
8125086A 0032
8125086C 1030
8125086E 000D
81250870 2400
81250872 0000
81250874 2401
81250876 0033
81250878 1030
8125087A 000F
8125087C 2400
8125087E 0000
81250880 2401
81250882 0034
81250884 1030
81250886 0010
81250888 2400
8125088A 0000
Comments