Obj_MechaSonicHead: lea ObjDat_MechaSonicHead(pc),a1 jsr (SetUp_ObjAttributes).l move.l #Obj_MechaSonicHeadMain,(a0) lea (ArtKosM_MechaSonicHead).l,a1 move.w #-$5A40,d2 jmp (Queue_Kos_Module).l ; --------------------------------------------------------------------------- Obj_MechaSonicHeadMain: jsr (Refresh_ChildPositionAdjusted).l ...In the example above, Obj_MechaSonicHead replaces its own pointer with the address for Obj_MechaSonicHeadMain. Starting the very next frame, the object processor will instead jump to that address, so the init code will no longer run.
Objects that follow this pattern frequently let control fall through directly to the main bit of code, as seen in the example below. This ensures the object is running the moment it is created.
Obj_AIZHollowTree: move.b #$D0,width_pixels(a0) move.l #loc_1F752,(a0) loc_1F752: bsr.w sub_1F7B8 ...An alternative pattern is to use the routine attribute, stored in the 5th byte of an object's SST. The overall convention is shown below: the routine byte, which must always be even, is used as an index to an offset table stored directly below. The resulting offset is then used to perform a relative jump from the table to the appropriate routine, hence the name.
Obj_MonitorContents: moveq #0,d0 move.b 5(a0),d0 move.w off_1D7C8(pc,d0.w),d1 jmp off_1D7C8(pc,d1.w) ; --------------------------------------------------------------------------- off_1D7C8: dc.w loc_1D7CE-off_1D7C8 dc.w loc_1D81A-off_1D7C8 dc.w loc_1DB2E-off_1D7C8 ; --------------------------------------------------------------------------- loc_1D7CE: addq.b #2,5(a0) move.w #$84C4,$A(a0) ...This pattern is frequent in bosses and similarly complicated objects which cycle through a large number of states. It is also common to see it in "old" objects, such as rings and monitors, because this was the only pattern in Sonic 1 and 2. In those games, SSTs did not directly store a code pointer: it was read from the object list every time.
No comments:
Post a Comment