Difference between revisions of "Sandbox"
From Sonic Retro
Tailsguy24 (talk | contribs) |
Tailsguy24 (talk | contribs) |
||
Line 655: | Line 655: | ||
rts | rts | ||
; End of function Obj4C_MdNormal | ; End of function Obj4C_MdNormal | ||
+ | </asm> | ||
And we're done with the Obj4C_MdNormal_Checks subroutine! Now we can get the rest of the code in without worrying about errors, provided you're following this guide correctly. | And we're done with the Obj4C_MdNormal_Checks subroutine! Now we can get the rest of the code in without worrying about errors, provided you're following this guide correctly. | ||
====Step 4: Part 3: Obj4C_MdAir==== | ====Step 4: Part 3: Obj4C_MdAir==== |
Revision as of 10:23, 13 January 2013
The following guide was made by Tailsguy24, and is not yet complete. DO NOT edit/delete it for any reason.
Contents
How to Port Knuckles into Sonic 2
It surprises me that nobody else took up responsibility for making this guide, considering I, as a major fan of hacks, have seen Knuckles implemented in Sonic 2 on more than one occasion. Today, I'll be explaining how you, too, can implement Knuckles in your Sonic 2 hack.
What You'll Need
- This guide (no duh, really)
- The Hg disassembly of Sonic 2
- The one known disassembly of Knuckles in Sonic 2, found on the long list of disassemblies. [1]
- The ConTEXT text editor (because Notepad will take WAY too long to process anything)
- Your favorite Genesis emulator (I recommend Kega Fusion but you can use any Genesis emulator you'd like)
IMPORTANT NOTE
DO NOT try to rebuild the ROM once you've started this guide or you will get build errors.
Also, there is quite a lot of code added in this tutorial and it will make the ASM file's size (and to an extent, the ROM's size) a lot bigger than they were before. You may want to consider porting Sonic 1's sound driver to Sonic 2 first, as it can take the amount of data shifting caused by extending the level index past $10 in Sonic 2 and still work properly.
Step 1: Creating the Knuckles object
First, open up s2.asm in ConTEXT and search for "dc.l ObjNull." This should come up: <asm>
dc.l ObjNull ; Obj4C dc.l ObjNull ; Obj4D dc.l ObjNull ; Obj4E dc.l ObjNull ; Obj4F
</asm> Change this line: <asm>
dc.l ObjNull ; Obj4C
</asm>
To this: <asm>
dc.l Obj4C ; Knuckles
</asm>
We've created our Knuckles object. Now let's get started.
Step 2: Creating the offset table
Now that you have created your Knuckles object, go to whatever folder you saved the Knuckles in Sonic 2 disassembly to, open s2k.asm in ConTEXT, and scroll down or search until you find the following code: <asm> Obj01_Index: dc.w Obj01_Init-Obj01_Index ; 0 ; ... dc.w Obj01_Control-Obj01_Index ; 1 dc.w Obj01_Hurt-Obj01_Index ; 2 dc.w Obj01_Dead-Obj01_Index ; 3 dc.w Obj01_Gone-Obj01_Index ; 4 dc.w Obj01_Respawning-Obj01_Index ; 5 </asm> Back in s2.asm, copy and paste the following piece of code above the description of the Masher object: <asm>
- ----------------------------------------------------------------------------
- Object 01 - Knuckles
- ----------------------------------------------------------------------------
Obj01: ; a0=character tst.w (Debug_placement_mode).w ; is debug mode being used? beq.s Obj01_Normal ; if not, branch jmp (DebugMode).l
- ---------------------------------------------------------------------------
- loc_19F5C
Obj01_Normal: moveq #0,d0 move.b routine(a0),d0 move.w Obj01_Index(pc,d0.w),d1 jmp Obj01_Index(pc,d1.w)
- End of function Obj01
- ----------------------------------------------------------------------------
</asm> Now copy the code I mentioned earlier in this step, and paste it below the code displayed above. Then, replace all of the "dc.w"'s with "offsetTableEntry.w"'s, delete the "-Obj01_Index" on the end of each line, move all of the entries down one line, add "offsetTable" to the top, and change all of the 01's in the whole section of code to 4C's. If you're following this guide correctly, your code should look like this: <asm>
- ----------------------------------------------------------------------------
- Object 4C - Knuckles
- ----------------------------------------------------------------------------
Obj4C: ; a0=character tst.w (Debug_placement_mode).w ; is debug mode being used? beq.s Obj4C_Normal ; if not, branch jmp (DebugMode).l
- ---------------------------------------------------------------------------
- loc_19F5C
Obj4C_Normal: moveq #0,d0 move.b routine(a0),d0 move.w Obj4C_Index(pc,d0.w),d1 jmp Obj4C_Index(pc,d1.w)
- End of function Obj4C
- ----------------------------------------------------------------------------
Obj4C_Index: offsetTable
offsetTableEntry.w Obj4C_Init ; 0
offsetTableEntry.w Obj4C_Control ; 2 offsetTableEntry.w Obj4C_Hurt ; 4 offsetTableEntry.w Obj4C_Dead ; 6 offsetTableEntry.w Obj4C_Gone ; 8 offsetTableEntry.w Obj4C_Respawning ; $A ... </asm> Now that THAT is done and over with, let's continue to importing Knuckles' many modes (or whatever you people call them).
Step 3: Obj4C_Init
Going back to s2k.asm , you should see this piece of code right below the code I mentioned earlier in Step 2: <asm>
- ---------------------------------------------------------------------------
Obj01_Init: ; ... addq.b #2,$24(a0) move.b #$13,$16(a0) move.b #9,$17(a0) move.l #SK_Map_Knuckles,4(a0) ; SK_Map_Knuckles move.b #2,$18(a0) move.b #$18,$19(a0) move.b #4,1(a0) move.w #$600,($FFFFF760).w move.w #$C,($FFFFF762).w move.w #$80,($FFFFF764).w tst.b ($FFFFFE30).w bne.s Obj01_Init_Continued move.w #$780,2(a0) bsr.w Adjust2PArtPointer2_Useless move.b #$C,$3E(a0) move.b #$D,$3F(a0) move.w 8(a0),($FFFFFE32).w move.w $C(a0),($FFFFFE34).w move.w 2(a0),($FFFFFE3C).w move.w $3E(a0),($FFFFFE3E).w
Obj01_Init_Continued: ; ... move.b #0,$2C(a0) move.b #4,$2D(a0) move.b #0,($FFFFFE19).w move.b #$1E,$28(a0) sub.w #$20,8(a0) add.w #4,$C(a0) move.w #0,($FFFFEED2).w move.w #$3F,d2
loc_3153EC: ; ... bsr.w Knuckles_RecordPositions subq.w #4,a1 move.l #0,(a1) dbf d2,loc_3153EC add.w #$20,8(a0) sub.w #4,$C(a0) </asm> All we need to do is copy this, paste it below our already ported code, and change all of the 01's to 4C's. Now you should have this below the offset table: <asm>
- ---------------------------------------------------------------------------
Obj4C_Init: ; ... addq.b #2,$24(a0) move.b #$13,$16(a0) move.b #9,$17(a0) move.l #SK_Map_Knuckles,4(a0) ; SK_Map_Knuckles move.b #2,$18(a0) move.b #$18,$19(a0) move.b #4,1(a0) move.w #$600,($FFFFF760).w move.w #$C,($FFFFF762).w move.w #$80,($FFFFF764).w tst.b ($FFFFFE30).w bne.s Obj4C_Init_Continued move.w #$780,2(a0) bsr.w Adjust2PArtPointer2_Useless move.b #$C,$3E(a0) move.b #$D,$3F(a0) move.w 8(a0),($FFFFFE32).w move.w $C(a0),($FFFFFE34).w move.w 2(a0),($FFFFFE3C).w move.w $3E(a0),($FFFFFE3E).w
Obj4C_Init_Continued: ; ... move.b #0,$2C(a0) move.b #4,$2D(a0) move.b #0,($FFFFFE19).w move.b #$1E,$28(a0) sub.w #$20,8(a0) add.w #4,$C(a0) move.w #0,($FFFFEED2).w move.w #$3F,d2
loc_3153EC: ; ... bsr.w Knuckles_RecordPositions subq.w #4,a1 move.l #0,(a1) dbf d2,loc_3153EC add.w #$20,8(a0) sub.w #4,$C(a0) </asm>
Step 4: Obj4C_Control
This one is the most important. It actually makes up approximately 90% of the code for Knuckles. Therefore, we definitely need to port this.
Step 4: Part 1: Starting off
First, we have to modify the Obj01_Modes offset table from s2k.asm so we can use it for our Knuckles. Below the code mentioned above, you should see this: <asm> Obj01_Control: ; ... tst.w ($FFFFFFDA).w beq.s loc_315422 btst #4,($FFFFF605).w beq.s loc_315422 move.w #1,($FFFFFE08).w clr.b ($FFFFF7CC).w rts
- ---------------------------------------------------------------------------
loc_315422: ; ... tst.b ($FFFFF7CC).w bne.s loc_31542E move.w ($FFFFF604).w,($FFFFF602).w
loc_31542E: ; ... btst #0,$2A(a0) beq.s loc_31543E move.b #0,$21(a0) bra.s loc_315450
- ---------------------------------------------------------------------------
loc_31543E: ; ... moveq #0,d0 move.b $22(a0),d0
and.w #6,d0 move.w Obj01_Modes(pc,d0.w),d1 jsr Obj01_Modes(pc,d1.w)
loc_315450: ; ... cmp.w #$FF00,($FFFFEECC).w bne.s loc_31545E and.w #$7FF,$C(a0)
loc_31545E: ; ... bsr.s Knuckles_Display bsr.w Knuckles_Super bsr.w Knuckles_RecordPositions bsr.w Knuckles_Water move.b ($FFFFF768).w,$36(a0) move.b ($FFFFF76A).w,$37(a0) tst.b ($FFFFF7C7).w beq.s loc_31548A tst.b $1C(a0) bne.s loc_31548A move.b $1D(a0),$1C(a0)
loc_31548A: ; ... bsr.w Knuckles_Animate tst.b $2A(a0) bmi.s loc_31549A jsr TouchResponse
loc_31549A: ; ... bra.w LoadKnucklesDynPLC
- ---------------------------------------------------------------------------
Obj01_Modes: dc.w Obj01_MdNormal-Obj01_Modes ; 0 ; ... dc.w Obj01_MdAir-Obj01_Modes ; 1 dc.w Obj01_MdRoll-Obj01_Modes ; 2 dc.w Obj01_MdJump-Obj01_Modes ; 3 </asm> Do the same thing that was done with the code in Step 1. It should now look like this: <asm> Obj4C_Control: ; ... tst.w ($FFFFFFDA).w beq.s loc_315422 btst #4,($FFFFF605).w beq.s loc_315422 move.w #1,($FFFFFE08).w clr.b ($FFFFF7CC).w rts
- ---------------------------------------------------------------------------
loc_315422: ; ... tst.b ($FFFFF7CC).w bne.s loc_31542E move.w ($FFFFF604).w,($FFFFF602).w
loc_31542E: ; ... btst #0,$2A(a0) beq.s loc_31543E move.b #0,$21(a0) bra.s loc_315450
- ---------------------------------------------------------------------------
loc_31543E: ; ... moveq #0,d0 move.b $22(a0),d0 and.w #6,d0 move.w Obj4C_Modes(pc,d0.w),d1 jsr Obj4C_Modes(pc,d1.w)
loc_315450: ; ... cmp.w #$FF00,($FFFFEECC).w bne.s loc_31545E and.w #$7FF,$C(a0)
loc_31545E: ; ... bsr.s Knuckles_Display bsr.w Knuckles_Super bsr.w Knuckles_RecordPositions bsr.w Knuckles_Water move.b ($FFFFF768).w,$36(a0) move.b ($FFFFF76A).w,$37(a0) tst.b ($FFFFF7C7).w beq.s loc_31548A tst.b $1C(a0) bne.s loc_31548A move.b $1D(a0),$1C(a0)
loc_31548A: ; ... bsr.w Knuckles_Animate tst.b $2A(a0) bmi.s loc_31549A jsr TouchResponse
loc_31549A: ; ... bra.w LoadKnucklesDynPLC
- ---------------------------------------------------------------------------
Obj4C_Modes: offsetTable
offsetTableEntry.w Obj4C_MdNormal_Checks ; 0 ; not airborne or rolling
offsetTableEntry.w Obj4C_MdAir ; 2 ; airborne offsetTableEntry.w Obj4C_MdRoll ; 4 ; rolling offsetTableEntry.w Obj4C_MdJump ; 6 ; jumping </asm>
Step 4: Part 2: Obj4C_MdNormal
Back to s2k.asm! The next bit of code you'll want to find is this: <asm>
- =============== S U B R O U T I N E =======================================
Knuckles_Display: ; ...
move.w $30(a0),d0
beq.s Obj01_Display
subq.w #1,$30(a0)
lsr.w #3,d0
bcc.s Obj01_CheckInvincibility
Obj01_Display: ; ... jsr DisplaySprite
Obj01_CheckInvincibility: ; ... btst #1,$2B(a0) beq.s Obj01_CheckSpeedShoes tst.w $32(a0) beq.s Obj01_CheckSpeedShoes subq.w #1,$32(a0) bne.s Obj01_CheckSpeedShoes tst.b ($FFFFF7AA).w bne.s Obj01_RemoveInvincibility cmp.b #$C,$28(a0) bcs.s Obj01_RemoveInvincibility move.w ($FFFFFF90).w,d0 jsr PlayMusic
Obj01_RemoveInvincibility: ; ... bclr #1,$2B(a0)
Obj01_CheckSpeedShoes: ; ... btst #2,$2B(a0) beq.s Obj01_ExitCheck tst.w $34(a0) beq.s Obj01_ExitCheck subq.w #1,$34(a0) bne.s Obj01_ExitCheck move.w #$600,($FFFFF760).w move.w #$C,($FFFFF762).w move.w #$80,($FFFFF764).w tst.b ($FFFFFE19).w beq.s Obj01_RemoveSpeedShoes move.w #$800,($FFFFF760).w move.w #$18,($FFFFF762).w move.w #$C0,($FFFFF764).w
Obj01_RemoveSpeedShoes: ; ... bclr #2,$2B(a0) move.w #$FC,d0 jmp PlayMusic
- ---------------------------------------------------------------------------
Obj01_ExitCheck: ; ... rts
- End of function Knuckles_Display
- =============== S U B R O U T I N E =======================================
Knuckles_RecordPositions: ; ...
move.w ($FFFFEED2).w,d0
lea ($FFFFE500).w,a1
lea (a1,d0.w),a1
move.w 8(a0),(a1)+
move.w $C(a0),(a1)+
addq.b #4,($FFFFEED3).w
lea ($FFFFE400).w,a1
lea (a1,d0.w),a1
move.w ($FFFFF602).w,(a1)+
move.w $22(a0),(a1)+
rts
- End of function Knuckles_RecordPositions
- =============== S U B R O U T I N E =======================================
Knuckles_Water: ; ...
tst.b ($FFFFF730).w
bne.s Obj01_InWater
return_31556C: ; ... rts
- ---------------------------------------------------------------------------
Obj01_InWater: ; ... move.w ($FFFFF646).w,d0 cmp.w $C(a0),d0 bge.s Obj01_OutWater bset #6,$22(a0) bne.s return_31556C move.l a0,a1 bsr.w ResumeMusic move.b #$A,($FFFFD080).w move.b #$81,($FFFFD0A8).w move.l a0,($FFFFD0BC).w move.w #$300,($FFFFF760).w move.w #6,($FFFFF762).w move.w #$40,($FFFFF764).w tst.b ($FFFFFE19).w beq.s loc_3155C0 move.w #$400,($FFFFF760).w move.w #$C,($FFFFF762).w move.w #$60,($FFFFF764).w
loc_3155C0: ; ... asr $10(a0) asr $12(a0) asr $12(a0) beq.s return_31556C move.w #$100,($FFFFD11C).w move.w #$AA,d0 jmp PlaySound
- ---------------------------------------------------------------------------
Obj01_OutWater: ; ... bclr #6,$22(a0) beq.s return_31556C move.l a0,a1 bsr.w ResumeMusic move.w #$600,($FFFFF760).w move.w #$C,($FFFFF762).w move.w #$80,($FFFFF764).w tst.b ($FFFFFE19).w beq.s loc_315616 move.w #$800,($FFFFF760).w move.w #$18,($FFFFF762).w move.w #$C0,($FFFFF764).w
loc_315616: ; ... cmp.b #4,$24(a0) beq.s loc_315622 asl $12(a0)
loc_315622: ; ... tst.w $12(a0) beq.w return_31556C move.w #$100,($FFFFD11C).w move.l a0,a1 bsr.w ResumeMusic cmp.w #$F000,$12(a0) bgt.s loc_315644 move.w #$F000,$12(a0)
loc_315644: ; ... move.w #$AA,d0 jmp PlaySound
- End of function Knuckles_Water
- =============== S U B R O U T I N E =======================================
Obj01_MdNormal: ; ...
bsr.w Knuckles_Spindash
bsr.w Knuckles_Jump
bsr.w Knuckles_SlopeResist
bsr.w Knuckles_Move
bsr.w Knuckles_Roll
bsr.w Knuckles_LevelBoundaries
jsr ObjectMove ; AKA SpeedToPos in Sonic 1
bsr.w AnglePos
bsr.w Knuckles_SlopeRepel
rts
- End of function Obj01_MdNormal
Put that below the code we've already ported, then go through it and replace each and every "Obj01" with "Obj4C." You should get this: <asm>
- =============== S U B R O U T I N E =======================================
Knuckles_Display: ; ...
move.w $30(a0),d0
beq.s Obj4C_Display
subq.w #1,$30(a0)
lsr.w #3,d0
bcc.s Obj4C_CheckInvincibility
Obj4C_Display: ; ... jsr DisplaySprite
Obj4C_CheckInvincibility: ; ... btst #1,$2B(a0) beq.s Obj4C_CheckSpeedShoes tst.w $32(a0) beq.s Obj4C_CheckSpeedShoes subq.w #1,$32(a0) bne.s Obj4C_CheckSpeedShoes tst.b ($FFFFF7AA).w bne.s Obj4C_RemoveInvincibility cmp.b #$C,$28(a0) bcs.s Obj4C_RemoveInvincibility move.w ($FFFFFF90).w,d0 jsr PlayMusic
Obj4C_RemoveInvincibility: ; ... bclr #1,$2B(a0)
Obj4C_CheckSpeedShoes: ; ... btst #2,$2B(a0) beq.s Obj4C_ExitCheck tst.w $34(a0) beq.s Obj4C_ExitCheck subq.w #1,$34(a0) bne.s Obj4C_ExitCheck move.w #$600,($FFFFF760).w move.w #$C,($FFFFF762).w move.w #$80,($FFFFF764).w tst.b ($FFFFFE19).w beq.s Obj4C_RemoveSpeedShoes move.w #$800,($FFFFF760).w move.w #$18,($FFFFF762).w move.w #$C0,($FFFFF764).w
Obj4C_RemoveSpeedShoes: ; ... bclr #2,$2B(a0) move.w #$FC,d0 jmp PlayMusic
- ---------------------------------------------------------------------------
Obj4C_ExitCheck: ; ... rts
- End of function Knuckles_Display
- =============== S U B R O U T I N E =======================================
Knuckles_RecordPositions: ; ...
move.w ($FFFFEED2).w,d0
lea ($FFFFE500).w,a1
lea (a1,d0.w),a1
move.w 8(a0),(a1)+
move.w $C(a0),(a1)+
addq.b #4,($FFFFEED3).w
lea ($FFFFE400).w,a1
lea (a1,d0.w),a1
move.w ($FFFFF602).w,(a1)+
move.w $22(a0),(a1)+
rts
- End of function Knuckles_RecordPositions
- =============== S U B R O U T I N E =======================================
Knuckles_Water: ; ...
tst.b ($FFFFF730).w
bne.s Obj4C_InWater
return_31556C: ; ... rts
- ---------------------------------------------------------------------------
Obj4C_InWater: ; ... move.w ($FFFFF646).w,d0 cmp.w $C(a0),d0 bge.s Obj4C_OutWater bset #6,$22(a0) bne.s return_31556C move.l a0,a1 bsr.w ResumeMusic move.b #$A,($FFFFD080).w move.b #$81,($FFFFD0A8).w move.l a0,($FFFFD0BC).w move.w #$300,($FFFFF760).w move.w #6,($FFFFF762).w move.w #$40,($FFFFF764).w tst.b ($FFFFFE19).w beq.s loc_3155C0 move.w #$400,($FFFFF760).w move.w #$C,($FFFFF762).w move.w #$60,($FFFFF764).w
loc_3155C0: ; ... asr $10(a0) asr $12(a0) asr $12(a0) beq.s return_31556C move.w #$100,($FFFFD11C).w move.w #$AA,d0 jmp PlaySound
- ---------------------------------------------------------------------------
Obj4C_OutWater: ; ... bclr #6,$22(a0) beq.s return_31556C move.l a0,a1 bsr.w ResumeMusic move.w #$600,($FFFFF760).w move.w #$C,($FFFFF762).w move.w #$80,($FFFFF764).w tst.b ($FFFFFE19).w beq.s loc_315616 move.w #$800,($FFFFF760).w move.w #$18,($FFFFF762).w move.w #$C0,($FFFFF764).w
loc_315616: ; ... cmp.b #4,$24(a0) beq.s loc_315622 asl $12(a0)
loc_315622: ; ... tst.w $12(a0) beq.w return_31556C
move.w #$100,($FFFFD11C).w
move.l a0,a1 bsr.w ResumeMusic cmp.w #$F000,$12(a0) bgt.s loc_315644 move.w #$F000,$12(a0)
loc_315644: ; ... move.w #$AA,d0 jmp PlaySound
- End of function Knuckles_Water
- =============== S U B R O U T I N E =======================================
Obj4C_MdNormal: ; ...
bsr.w Knuckles_Spindash
bsr.w Knuckles_Jump
bsr.w Knuckles_SlopeResist
bsr.w Knuckles_Move
bsr.w Knuckles_Roll
bsr.w Knuckles_LevelBoundaries
jsr ObjectMove ; AKA SpeedToPos in Sonic 1
bsr.w AnglePos
bsr.w Knuckles_SlopeRepel
rts
- End of function Obj4C_MdNormal
</asm> And we're done with the Obj4C_MdNormal_Checks subroutine! Now we can get the rest of the code in without worrying about errors, provided you're following this guide correctly.
Step 4: Part 3: Obj4C_MdAir
Not very complicated, just find this, place it below the ported code and replace each "Obj01" with a "Obj4C." <asm>
- =============== S U B R O U T I N E =======================================
Obj01_MdAir: ; ...
tst.b $21(a0)
bne.s Obj01_MdAir_Gliding
bsr.w Knuckles_JumpHeight
bsr.w Knuckles_ChgJumpDir
bsr.w Knuckles_LevelBoundaries
jsr ObjectMoveAndFall
btst #6,$22(a0)
beq.s loc_31569C
sub.w #$28,$12(a0)
loc_31569C: ; ... bsr.w Knuckles_JumpAngle bsr.w Knuckles_DoLevelCollision rts
- ---------------------------------------------------------------------------
Obj01_MdAir_Gliding: ; ... bsr.w Knuckles_GlideSpeedControl bsr.w Knuckles_LevelBoundaries jsr ObjectMove ; AKA SpeedToPos in Sonic 1 bsr.w Knuckles_GlideControl
return_3156B8: ; ... rts
- End of function Obj01_MdAir
</asm> You should end up with this: <asm>
- =============== S U B R O U T I N E =======================================
Obj4C_MdAir: ; ...
tst.b $21(a0)
bne.s Obj4C_MdAir_Gliding
bsr.w Knuckles_JumpHeight
bsr.w Knuckles_ChgJumpDir
bsr.w Knuckles_LevelBoundaries
jsr ObjectMoveAndFall
btst #6,$22(a0)
beq.s loc_31569C
sub.w #$28,$12(a0)
loc_31569C: ; ... bsr.w Knuckles_JumpAngle bsr.w Knuckles_DoLevelCollision rts
- ---------------------------------------------------------------------------
Obj4C_MdAir_Gliding: ; ... bsr.w Knuckles_GlideSpeedControl bsr.w Knuckles_LevelBoundaries jsr ObjectMove ; AKA SpeedToPos in Sonic 1 bsr.w Knuckles_GlideControl
return_3156B8: ; ... rts
- End of function Obj4C_MdAir
</asm> I told you it wasn't complicated.
Step 4: Part 4: Everything having to do with Knuckles' gliding
And we don't even need to change anything. WOOHOO! <asm>
- =============== S U B R O U T I N E =======================================
Knuckles_GlideControl: ; ...
- FUNCTION CHUNK AT 00315C40 SIZE 0000003C BYTES
move.b $21(a0),d0 beq.s return_3156B8 cmp.b #2,d0 beq.w Knuckles_FallingFromGlide cmp.b #3,d0 beq.w Knuckles_Sliding cmp.b #4,d0 beq.w Knuckles_Climbing_Wall cmp.b #5,d0 beq.w Knuckles_Climbing_Up
Knuckles_NormalGlide: move.b #$A,$16(a0) move.b #$A,$17(a0) bsr.w Knuckles_DoLevelCollision2 btst #5,($FFFFF7AC).w bne.w Knuckles_BeginClimb move.b #$13,$16(a0) move.b #9,$17(a0) btst #1,($FFFFF7AC).w beq.s Knuckles_BeginSlide move.b ($FFFFF602).w,d0 and.b #$70,d0 bne.s loc_31574C move.b #2,$21(a0) move.b #$21,$1C(a0) bclr #0,$22(a0) tst.w $10(a0) bpl.s loc_315736 bset #0,$22(a0)
loc_315736: ; ... asr $10(a0) asr $10(a0) move.b #$13,$16(a0) move.b #9,$17(a0) rts
- ---------------------------------------------------------------------------
loc_31574C: ; ... bra.w sub_315C7C
- ---------------------------------------------------------------------------
Knuckles_BeginSlide: ; ... bclr #0,$22(a0) tst.w $10(a0) bpl.s loc_315762 bset #0,$22(a0)
loc_315762: ; ... move.b $26(a0),d0 add.b #$20,d0 and.b #$C0,d0 beq.s loc_315780 move.w $14(a0),$10(a0) move.w #0,$12(a0) bra.w Knuckles_ResetOnFloor_Part2
- ---------------------------------------------------------------------------
loc_315780: ; ... move.b #3,$21(a0) move.b #$CC,$1A(a0) move.b #$7F,$1E(a0) move.b #0,$1B(a0) cmp.b #$C,$28(a0) bcs.s return_3157AC move.b #6,($FFFFD124).w move.b #$15,($FFFFD11A).w
return_3157AC: ; ... rts
- ---------------------------------------------------------------------------
Knuckles_BeginClimb: ; ... tst.b ($FFFFF7AD).w bmi.w loc_31587A move.b $3F(a0),d5 move.b $1F(a0),d0 add.b #$40,d0 bpl.s loc_3157D8 bset #0,$22(a0) bsr.w CheckLeftCeilingDist or.w d0,d1 bne.s Knuckles_FallFromGlide addq.w #1,8(a0) bra.s loc_3157E8
- ---------------------------------------------------------------------------
loc_3157D8: ; ... bclr #0,$22(a0) bsr.w CheckRightCeilingDist or.w d0,d1 bne.w loc_31586A
loc_3157E8: ; ... move.b #$13,$16(a0) move.b #9,$17(a0) tst.b ($FFFFFE19).w beq.s loc_315804 cmp.w #$480,$14(a0) bcs.s loc_315804 nop
loc_315804: ; ... move.w #0,$14(a0) move.w #0,$10(a0) move.w #0,$12(a0) move.b #4,$21(a0) move.b #$B7,$1A(a0) move.b #$7F,$1E(a0) move.b #0,$1B(a0) move.b #3,$1F(a0) move.w 8(a0),$A(a0) rts
- ---------------------------------------------------------------------------
Knuckles_FallFromGlide: ; ... move.w 8(a0),d3 move.b $16(a0),d0 ext.w d0 sub.w d0,d3 subq.w #1,d3
loc_31584A: ; ... move.w $C(a0),d2 sub.w #$B,d2 jsr ChkFloorEdge_Part2 tst.w d1 bmi.s loc_31587A cmp.w #$C,d1 bcc.s loc_31587A add.w d1,$C(a0) bra.w loc_3157E8
- ---------------------------------------------------------------------------
loc_31586A: ; ... move.w 8(a0),d3 move.b $16(a0),d0 ext.w d0 add.w d0,d3 addq.w #1,d3 bra.s loc_31584A
- ---------------------------------------------------------------------------
loc_31587A: ; ... move.b #2,$21(a0) move.b #$21,$1C(a0) move.b #$13,$16(a0) move.b #9,$17(a0) bset #1,($FFFFF7AC).w rts
- ---------------------------------------------------------------------------
Knuckles_FallingFromGlide: ; ... bsr.w Knuckles_ChgJumpDir add.w #$38,$12(a0) btst #6,$22(a0) beq.s loc_3158B2 sub.w #$28,$12(a0)
loc_3158B2: ; ... bsr.w Knuckles_DoLevelCollision2 btst #1,($FFFFF7AC).w bne.s return_315900 move.w #0,$14(a0) move.w #0,$10(a0) move.w #0,$12(a0) move.b $16(a0),d0 sub.b #$13,d0 ext.w d0 add.w d0,$C(a0) move.b $26(a0),d0 add.b #$20,d0 and.b #$C0,d0 beq.s loc_3158F0 bra.w Knuckles_ResetOnFloor_Part2
- ---------------------------------------------------------------------------
loc_3158F0: ; ... bsr.w Knuckles_ResetOnFloor_Part2 move.w #$F,$2E(a0) move.b #$23,$1C(a0)
return_315900: ; ... rts
- ---------------------------------------------------------------------------
Knuckles_Sliding: ; ... move.b ($FFFFF602).w,d0 and.b #$70,d0 beq.s loc_315926 tst.w $10(a0) bpl.s loc_31591E add.w #$20,$10(a0) bmi.s loc_31591C bra.s loc_315926
- ---------------------------------------------------------------------------
loc_31591C: ; ... bra.s loc_315958
- ---------------------------------------------------------------------------
loc_31591E: ; ... sub.w #$20,$10(a0) bpl.s loc_315958
loc_315926: ; ... move.w #0,$14(a0) move.w #0,$10(a0) move.w #0,$12(a0) move.b $16(a0),d0 sub.b #$13,d0 ext.w d0 add.w d0,$C(a0) bsr.w Knuckles_ResetOnFloor_Part2 move.w #$F,$2E(a0) move.b #$22,$1C(a0) rts
- ---------------------------------------------------------------------------
loc_315958: ; ... move.b #$A,$16(a0) move.b #$A,$17(a0) bsr.w Knuckles_DoLevelCollision2 bsr.w Player_CheckFloor cmp.w #$E,d1 bge.s loc_315988 add.w d1,$C(a0) move.b d3,$26(a0) move.b #$13,$16(a0) move.b #9,$17(a0) rts
- ---------------------------------------------------------------------------
loc_315988: ; ... move.b #2,$21(a0) move.b #$21,$1C(a0) move.b #$13,$16(a0) move.b #9,$17(a0) bset #1,($FFFFF7AC).w rts
- ---------------------------------------------------------------------------
Knuckles_Climbing_Wall: ; ... tst.b ($FFFFF7AD).w bmi.w loc_315BAE move.w 8(a0),d0 cmp.w $A(a0),d0 bne.w loc_315BAE btst #3,$22(a0) bne.w loc_315BAE move.w #0,$14(a0) move.w #0,$10(a0) move.w #0,$12(a0) move.l #$FFFFD600,($FFFFF796).w cmp.b #$D,$3F(a0) beq.s loc_3159F0 move.l #$FFFFD900,($FFFFF796).w
loc_3159F0: ; ... move.b $3F(a0),d5 move.b #$A,$16(a0) move.b #$A,$17(a0) moveq #0,d1 btst #0,($FFFFF602).w beq.w loc_315A76 move.w $C(a0),d2 sub.w #$B,d2 bsr.w sub_315C22 cmp.w #4,d1 bge.w Knuckles_ClimbUp ; Climb onto the floor above you tst.w d1 bne.w loc_315B30 move.b $3F(a0),d5 move.w $C(a0),d2 subq.w #8,d2 move.w 8(a0),d3 bsr.w sub_3192E6 ; Doesn't exist in S2 tst.w d1 bpl.s loc_315A46 sub.w d1,$C(a0) moveq #1,d1 bra.w loc_315B04
- ---------------------------------------------------------------------------
loc_315A46: ; ... subq.w #1,$C(a0) tst.b ($FFFFFE19).w beq.s loc_315A54 subq.w #1,$C(a0)
loc_315A54: ; ... moveq #1,d1 move.w ($FFFFEECC).w,d0 cmp.w #-$100,d0 beq.w loc_315B04 add.w #$10,d0 cmp.w $C(a0),d0 ble.w loc_315B04 move.w d0,$C(a0) bra.w loc_315B04
- ---------------------------------------------------------------------------
loc_315A76: ; ... btst #1,($FFFFF602).w beq.w loc_315B04 cmp.b #$BD,$1A(a0) bne.s loc_315AA2 move.b #$B7,$1A(a0) addq.w #3,$C(a0) subq.w #3,8(a0) btst #0,$22(a0) beq.s loc_315AA2 addq.w #6,8(a0)
loc_315AA2: ; ... move.w $C(a0),d2 add.w #$B,d2 bsr.w sub_315C22 tst.w d1 bne.w loc_315BAE move.b $3E(a0),d5 move.w $C(a0),d2 add.w #9,d2 move.w 8(a0),d3 bsr.w sub_318FF6 tst.w d1 bpl.s loc_315AF4 add.w d1,$C(a0) move.b ($FFFFF768).w,$26(a0) move.w #0,$14(a0) move.w #0,$10(a0) move.w #0,$12(a0) bsr.w Knuckles_ResetOnFloor_Part2 move.b #5,$1C(a0) rts
- ---------------------------------------------------------------------------
loc_315AF4: ; ... addq.w #1,$C(a0) tst.b ($FFFFFE19).w beq.s loc_315B02 addq.w #1,$C(a0)
loc_315B02: ; ... moveq #-1,d1
loc_315B04: ; ... tst.w d1 beq.s loc_315B30 subq.b #1,$1F(a0) bpl.s loc_315B30 move.b #3,$1F(a0) add.b $1A(a0),d1 cmp.b #$B7,d1 bcc.s loc_315B22 move.b #$BC,d1
loc_315B22: ; ... cmp.b #$BC,d1 bls.s loc_315B2C move.b #$B7,d1
loc_315B2C: ; ... move.b d1,$1A(a0)
loc_315B30: ; ... move.b #$20,$1E(a0) move.b #0,$1B(a0) move.b #$13,$16(a0) move.b #9,$17(a0) move.w ($FFFFF602).w,d0 and.w #$70,d0 beq.s return_315B94 move.w #$FC80,$12(a0) move.w #$400,$10(a0) bchg #0,$22(a0) bne.s loc_315B6A neg.w $10(a0)
loc_315B6A: ; ... bset #1,$22(a0) move.b #1,$3C(a0) move.b #$E,$16(a0) move.b #7,$17(a0) move.b #2,$1C(a0) bset #2,$22(a0) move.b #0,$21(a0)
return_315B94: ; ... rts
- ---------------------------------------------------------------------------
Knuckles_ClimbUp: ; ... move.b #5,$21(a0) ; Climb up to the floor above you cmp.b #$BD,$1A(a0) beq.s return_315BAC move.b #0,$1F(a0) bsr.s sub_315BDA
return_315BAC: ; ... rts
- ---------------------------------------------------------------------------
loc_315BAE: ; ... move.b #2,$21(a0) move.w #$2121,$1C(a0) move.b #$CB,$1A(a0) move.b #7,$1E(a0) move.b #1,$1B(a0) move.b #$13,$16(a0) move.b #9,$17(a0) rts
- End of function Knuckles_GlideControl
- =============== S U B R O U T I N E =======================================
sub_315BDA: ; ...
moveq #0,d0
move.b $1F(a0),d0
lea word_315C12(pc,d0.w),a1
move.b (a1)+,$1A(a0)
move.b (a1)+,d0
ext.w d0
btst #0,$22(a0)
beq.s loc_315BF6
neg.w d0
loc_315BF6: ; ... add.w d0,8(a0) move.b (a1)+,d1 ext.w d1 add.w d1,$C(a0) move.b (a1)+,$1E(a0) addq.b #4,$1F(a0) move.b #0,$1B(a0) rts
- End of function sub_315BDA
- ---------------------------------------------------------------------------
word_315C12: dc.w $BD03,$FD06,$BE08,$F606,$BFF8,$F406,$D208,$FB06; 0 ; ...
- =============== S U B R O U T I N E =======================================
sub_315C22: ; ...
- FUNCTION CHUNK AT 00319208 SIZE 00000020 BYTES
- FUNCTION CHUNK AT 003193D2 SIZE 00000024 BYTES
move.b $3F(a0),d5 btst #0,$22(a0) bne.s loc_315C36 move.w 8(a0),d3 bra.w loc_319208
- ---------------------------------------------------------------------------
loc_315C36: ; ... move.w 8(a0),d3 subq.w #1,d3 bra.w loc_3193D2
- End of function sub_315C22
- ---------------------------------------------------------------------------
- START OF FUNCTION CHUNK FOR Knuckles_GlideControl
Knuckles_Climbing_Up: ; ... tst.b $1E(a0) bne.s return_315C7A bsr.w sub_315BDA cmp.b #$10,$1F(a0) bne.s return_315C7A move.w #0,$14(a0) move.w #0,$10(a0) move.w #0,$12(a0) btst #0,$22(a0) beq.s loc_315C70 subq.w #1,8(a0)
loc_315C70: ; ... bsr.w Knuckles_ResetOnFloor_Part2 move.b #5,$1C(a0)
return_315C7A: ; ... rts
- END OF FUNCTION CHUNK FOR Knuckles_GlideControl
- =============== S U B R O U T I N E =======================================
sub_315C7C: ; ...
move.b #$20,$1E(a0)
move.b #0,$1B(a0)
move.w #$2020,$1C(a0)
bclr #5,$22(a0)
bclr #0,$22(a0)
moveq #0,d0
move.b $1F(a0),d0
add.b #$10,d0
lsr.w #5,d0
move.b byte_315CC2(pc,d0.w),d1
move.b d1,$1A(a0)
cmp.b #$C4,d1
bne.s return_315CC0
bset #0,$22(a0)
move.b #$C0,$1A(a0)
return_315CC0: ; ... rts
- End of function sub_315C7C
- ---------------------------------------------------------------------------
byte_315CC2: dc.b $C0,$C1,$C2,$C3,$C4,$C3,$C2,$C1; 0 ; ...
- =============== S U B R O U T I N E =======================================
Knuckles_GlideSpeedControl: ; ...
cmp.b #1,$21(a0)
bne.w loc_315D88
move.w $14(a0),d0
cmp.w #$400,d0
bcc.s loc_315CE2
addq.w #8,d0
bra.s loc_315CFC
- ---------------------------------------------------------------------------
loc_315CE2: ; ... cmp.w #$1800,d0 bcc.s loc_315CFC move.b $1F(a0),d1 and.b #$7F,d1 bne.s loc_315CFC addq.w #4,d0 tst.b ($FFFFFE19).w beq.s loc_315CFC addq.w #8,d0
loc_315CFC: ; ... move.w d0,$14(a0) move.b $1F(a0),d0 btst #2,($FFFFF602).w beq.s loc_315D1C cmp.b #$80,d0 beq.s loc_315D1C tst.b d0 bpl.s loc_315D18 neg.b d0
loc_315D18: ; ... addq.b #2,d0 bra.s loc_315D3A
- ---------------------------------------------------------------------------
loc_315D1C: ; ... btst #3,($FFFFF602).w beq.s loc_315D30 tst.b d0 beq.s loc_315D30 bmi.s loc_315D2C neg.b d0
loc_315D2C: ; ... addq.b #2,d0 bra.s loc_315D3A
- ---------------------------------------------------------------------------
loc_315D30: ; ... move.b d0,d1 and.b #$7F,d1 beq.s loc_315D3A addq.b #2,d0
loc_315D3A: ; ... move.b d0,$1F(a0) move.b $1F(a0),d0 jsr CalcSine muls.w $14(a0),d1 asr.l #8,d1 move.w d1,$10(a0) cmp.w #$80,$12(a0) blt.s loc_315D62 sub.w #$20,$12(a0) bra.s loc_315D68
- ---------------------------------------------------------------------------
loc_315D62: ; ... add.w #$20,$12(a0)
loc_315D68: ; ... move.w ($FFFFEECC).w,d0 cmp.w #$FF00,d0 beq.w loc_315D88 add.w #$10,d0 cmp.w $C(a0),d0 ble.w loc_315D88 asr $10(a0) asr $14(a0)
loc_315D88: ; ... cmp.w #$60,($FFFFEED8).w beq.s return_315D9A bcc.s loc_315D96 addq.w #4,($FFFFEED8).w
loc_315D96: ; ... subq.w #2,($FFFFEED8).w
return_315D9A: ; ... rts
- End of function Knuckles_GlideSpeedControl
- ---------------------------------------------------------------------------
</asm>