"Openable Grills" object ASM fix for custom levels
Users browsing this thread: 1 Guest(s)

So I was helping MrGreenThunder out on IRC because he was having some issues with the openable grills object crashing his custom level when he got near it. The crash was caused by the game trying to process collision data that didn't exist. The grills collision data was stored with the level data of BBB and HMC. So to fix this issue, I created my own custom collision data that the object will use. You do need to know how to hex edit and have a basic understanding of level scripts to modify the position of the doors. The 0x24 command you're looking for should end with [ 13 00 25 E0 ].

Once you found it, make the following changes to the code (colored parts):
24 18 1F 00 02 66 ED AE 09 1A 00 00 01 0E 00 00 00 3C 01 90 13 00 25 E0

The 0x3C value is the model ID your going to use for the doors. The 0x190 value is the spacing along the X-axis between the doors. Unfortunately, you have to use a hex editor as TT64 can't modify that 0x190 value. If you don't modify that value, then it will be set to 0x190 by default.

Pros:
* Works with custom levels
* Works with the 8 MB ROM
Cons:
* Only 1 fixed collision box for all doors (based on the HMC grill doors)
* Requires a little bit of hex editing to change the x-position offsets of the doors

You will have to use the latest version of CajeASM (v7.24) to import the ASM code into the ROM. ASM Code download is in the attachments.
Spoiler: ASM Code
// BehBobHmcCageDoorLoop: begin 802C263C (07D63C)
​.org 0x07D63C
 ADDIU SP, SP, 0xFFE8
 SW S0, 0x10(sp)
 LUI S0, 0x8036
 LW S0, 0x1160(s0)
 LW T7, 0x14c(s0)
 BNEZ T7, GrillDoorLoop_state1
 NOP 
 LW T9, 0x68(s0)
 LW T0, 0x88(t9)
// t0 == 1 if the switch has been activated
 BEQZ T0, GrillDoorLoop_end
 NOP 
 BEQZ R0, GrillDoorLoop_increment
 NOP
GrillDoorLoop_state1:
// 802C2684
 ADDIU AT, R0, 0x1
 LW T5, 0x14c(s0)
 BNE T5, AT, GrillDoorLoop_end
 NOP 
 LW T7, 0x154(s0)
// door->0x154 = timer
 SLTI AT, T7, 0x40
// if (timer < 0x40) then at = 1
 BEQZ AT, GrillDoorLoop_increment
 NOP 
 LW T0, 0x144(s0)
 LW T9, 0xc8(s0)
 SLL T2, T0, 0x8
 SUBU T3, T9, T2
// Rotate cage door by (door->0x144) * 256
 BEQZ R0, GrillDoorLoop_end
 SW T3, 0xc8(s0)
GrillDoorLoop_increment:
// 802C26D4
 LW T4, 0x14c(s0)
 ADDIU T5, T4, 0x1
 SW T5, 0x14c(s0)
GrillDoorLoop_end:
// 802C26E8
 LW S0, 0x10(sp)
 JR RA
 ADDIU SP, SP, 0x18
// end BehBobHmcCageDoorLoop

​// New behavior for doors, seg address: 002C26C0
​.org 0x07D6C0
​hex
{
00 09 00 00
11 01 00 09
2A 00 00 00 00 2C 28 98
08 00 00 00
0C 00 00 00 80 2C 26 3C
0C 00 00 00 80 38 39 CC
09 00 00 00 
}


​.org 0x405A90
// Fix gate in Bob-omb Battlefield
​hex

24 18 1F 00 F7 FE 00 00 F4 03 00 00 00 19 00 00 00 38 01 40 13 00 25 E0
}

​.org 0x3E6C44
// Fix gate in Hazy Maze Cave
​hex

24 18 1F 00 02 66 ED AE 09 1A 00 00 01 0E 00 00 00 3C 01 90 13 00 25 E0
}


​// BehOpenableGrillLoop: begin 802C26F8 (07D6F8)
​.org 0x07D6F8
 ADDIU SP, SP, 0xFFC0
 SW RA, 0x2c(sp)
 SW S0, 0x28(sp)
 LUI S0, 0x8036
 LW S0, 0x1160(s0)
// s0 = pointer to current object
 LW T0, 0x14c(s0)
// object->0x14C = current state
 BEQZ T0, OpenableGrillLoop_init
 NOP 
 ADDIU AT, R0, 0x1
 BEQ T0, AT, OpenableGrillLoop_check
 NOP 
 ADDIU AT, R0, 0x2
 BEQ T0, AT, OpenableGrillLoop_open
 NOP
 BEQZ R0, OpenableGrillLoop_end
 NOP 
OpenableGrillLoop_init:
// state 0, initizalize
 LW T1, 0x144(s0)
 SW T1, 0x14(sp)
// Model ID
 LW A1, 0x188(s0)
// X-offset
 ANDI A1, A1, 0xFFFF
 BNEZ A1, OpenableGrillLoop_skipXFix
// branch if X-offset does not equal zero.
 NOP
 ORI A1, R0, 0x190
 SH A1, 0x18A(s0)
// Fixes X-offset, if it equals zero.
 OpenableGrillLoop_skipXFix:
 SW S0, 0x10(sp)
 LUI T5, 0x002C
 ADDIU T5, T5, 0x26c0
//002C26C0
 SW T5, 0x18(sp)
 ADDIU A0, R0, 0xFFFF
 MOV A2, R0
 JAL 0x8029EF64
// SpawnObjAdv(-1, obj->0x188, 0, 0, obj, obj->0x144, 0x130025C0);
 MOV A3, R0
 ORI AT, R0, 0x8000
 LW T7, 0xc8(v0)
 ADDU T8, T7, AT
 SW T8, 0xc8(v0)
// Rotate first gate 180 degrees
 LW T1, 0x144(s0)
 SW T1, 0x14(sp)
// Model ID
 LW A1, 0x188(s0)
// X-offset
 ANDI A1, A1, 0xFFFF
 SW S0, 0x10(sp)
 LUI T8, 0x002C
 ADDIU T8, T8, 0x26c0
//002C26C0
 SW T8, 0x18(sp)
 ADDIU A0, R0, 0x1
 MOV A2, R0
 SUBU A1, R0, A1
 JAL 0x8029EF64
// SpawnObjAdv(1, -obj->0x188, 0, 0, obj, obj->0x144, 0x130025C0);
 MOV A3, R0
 LW T1, 0x14c(s0)
 ADDIU T3, T1, 0x1
 BEQZ R0, OpenableGrillLoop_end
 SW T3, 0x14c(s0)
// increment state value
OpenableGrillLoop_check:
// state 1, check for floor switch press.
 LUI A0, 0x1300 
 JAL 0x8029F95C 
 ADDIU A0, A0, 0x1478
// a0 = 0x13001478 = beh_floor_switch_grills
 BEQZ V0, OpenableGrillLoop_end
 SW V0, 0xf4(s0)
 LW T4, 0x14c(s0)
// increment state value
 ADDIU T7, T4, 0x1
 BEQZ R0, OpenableGrillLoop_end
 SW T7, 0x14c(s0)
OpenableGrillLoop_open:
// state 2, open doors
 LW T6, 0xf4(s0)
 ADDIU AT, R0, 0x2
 LW T1, 0x14c(t6)
 BNE T1, AT, OpenableGrillLoop_end
 NOP 
 SW T1, 0x88(s0)
// Store 0x2 to (object->0x88)
 LUI A0, 0x303f
 JAL 0x802CA1E0
// PlaySound2
 ORI A0, A0, 0xa081
 LW T4, 0x14c(s0)
 ADDIU T7, T4, 0x1
// increment state value
 SW T7, 0x14c(s0)
 LW T8, 0x144(s0)
 ORI AT, R0, 0x3C
 BNE T8, AT, OpenableGrillLoop_end
 NOP 
 JAL 0x803220F0
// Sets fanfare music for HMC.
 NOP 
OpenableGrillLoop_end:
// end of function
 LW RA, 0x2c(sp)
 LW S0, 0x28(sp)
 ADDIU SP, SP, 0x40
 JR RA
 NOP 

 
// Collision Data (0x84 bytes long), seg address: 002C2898
 .org 0x7D898
 hex
{
0040 0008
019A 0000 0033
019A 02CF FFCE
019A 02CF 0033
0000 02CF 0033
0000 0000 0033
0000 02CF FFCE
019A 0000 FFCE
0000 0000 FFCE
0000 000C
0000 0001 0002
0002 0003 0004
0002 0004 0000
0002 0001 0005
0002 0005 0003
0006 0005 0001
0000 0006 0001
0006 0007 0005
0003 0005 0007
0003 0007 0004
0004 0007 0006
0004 0006 0000
0041 0042
 }
Once your import the source code, the object should now work with custom levels  Smile

[Image: KcwPeNS.png]
(This post was last modified: 23-06-2017, 08:02 PM by queueRAM. Edit Reason: wiki links )


Attached Files
Size: 4.39 KB / Downloads: 266 .txt   OpenableGrillsFix.txt


I've updated the ASM code to set the spacing between the doors (obj->0x188) to be 0x190 by default, so now no hex editing is required to make this object work in custom levels. You still need to set the B.Param 2 value to be the Model ID for the doors in TT64 though.
(This post was last modified: 21-05-2016, 09:07 PM by David.)

"Openable Grills" object ASM fix for custom levels
Users browsing this thread: 1 Guest(s)