Navigation

Solid & Moving Behavior 0x04B1C: Initialization


This behavior is used by objects such as the Tilting Bridge in Bob-omb Battlefield. Unlike most
solid objects, it doesn't uses a 0x2A collision pointer in its behavior, but has it hardcoded
in the ASM, because its code it's shared by many moving objects.


ROM Addr: 0021E91C Hex Behav: 13004B1C
Description: Solid & Moving
21E91C/004B1C 00 09 00 00
21E920/004B20 11 01 20 49
21E924/004B24 0C 00 00 00 80 30 5C 14 (initialization)
21E92C/004B2C 08 00 00 00
21E930/004B30 0C 00 00 00 80 30 5C 90 (main loop)
21E938/004B38 0C 00 00 00 80 38 39 CC
21E940/004B40 09 00 00 00


To get rid of the hardcoded pointer for this behavior, just replace the "0C 00 00 00 80 30 5C 14"
with a 0x2a collision pointer (or 0x12 'flexible collision' if you are using it).


Disassembly:

80305C14: ADDIU SP, SP, 0xFFE8        # Behavior 0x4B1C (Solid & Moving)
80305C18: SW RA, 0x0014 (SP)
80305C1C: LUI T6, 0x8036
80305C20: LW T6, 0x1160 (T6)
80305C24: LUI A0, 0x8033
80305C28: LW T7, 0x0144 (T6)          # arg = obj->0x144 (from 0x24 level command)
80305C2C: SLL T8, T7, 0x2             # (arg * 4)
80305C30: ADDU A0, A0, T8
80305C34: JAL 0x80277F50              # segmented_to_virtual function
80305C38: LW A0, 0x2A00 (A0)          # read from pointer list  [collision = 80332A00 + (arg*4) ]
80305C3C: LUI T9, 0x8036
80305C40: LW T9, 0x1160 (T9)
80305C44: SW V0, 0x0218 (T9)          # Write collision pointer (virtual memory address)
80305C48: LUI T0, 0x8036
80305C4C: LW T0, 0x1160 (T0)
80305C50: ADDIU AT, R0, 0x0002
80305C54: LW T1, 0x0144 (T0)
80305C58: BNE T1, AT, 0x80305C78      # if ( !(arg == 2) ) {
80305C5C: NOP
80305C60: LUI AT, 0x44FA              # (dec 2000)
80305C64: LUI T2, 0x8036
80305C68: LW T2, 0x1160 (T2)
80305C6C: MTC1 AT, F4
80305C70: NOP
80305C74: SWC1 F4, 0x0194 (T2)        # drawing distance = 2000 }
80305C78: BEQ R0, R0, 0x80305C80
80305C7C: NOP
80305C80: LW RA, 0x0014 (SP)
80305C84: ADDIU SP, SP, 0x0018
80305C88: JR RA
80305C8C: NOP

In pseudo-C:

{

arg = obj -> 0x144         /* B. Param 2 from 0x24 level command*/ 

obj -> 0x21c = segmented_to_virtual( 0x80332a00 + (arg * 4) );   /* segmented collision pointer = 0xEDA00 + (arg *4)   */

if ( ! (arg == 2)
      {
      obj ->   0x194 = 2000;      /* drawing distance = 2000 (dec) */
      }


}

Comments