; ---------------------------------------------------------------------------
; Object 4C - Knuckles
; ---------------------------------------------------------------------------
Obj4C_InitChk:
; a0=character
tst.w (Debug_placement_mode).w ; is debug mode being used?
beq.s Obj4C_Normal ; if not, branch
jmp (DebugMode).l
; ---------------------------------------------------------------------------
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
offsetTableEntry.w Obj4C_Drowned ; $C
; ---------------------------------------------------------------------------
Obj4C_Init:
addq.b #2,routine(a0)
move.b #$13,y_radius(a0)
move.b #9,x_radius(a0)
move.l #SK_Map_Knuckles,mappings(a0) ; SK_Map_Knuckles
move.w #$100,priority(a0)
move.b #$18,width_pixels(a0)
move.b #4,render_flags(a0)
move.w #$600,(Sonic_top_speed).w
move.w #$C,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
tst.b (Last_star_pole_hit).w
bne.s Obj4C_Init_Continued
; only happens when not starting at a checkpoint:
move.w #make_art_tile(ArtTile_ArtUnc_Knuckles,0,0),art_tile(a0)
jsr Adjust2PArtPointer2
move.b #$C,layer(a0)
move.b #$D,layer_plus(a0)
move.w x_pos(a0),(Saved_x_pos).w
move.w y_pos(a0),(Saved_y_pos).w
move.w art_tile(a0),(Saved_art_tile).w
move.w layer(a0),(Saved_layer).w
Obj4C_Init_Continued:
move.b #0,flips_remaining(a0)
move.b #4,flip_speed(a0)
move.b #0,(Super_Sonic_flag).w
move.b #$1E,air_left(a0)
sub.w #$20,x_pos(a0)
add.w #4,y_pos(a0)
move.w #0,(Sonic_Pos_Record_Index).w
move.w #$3F,d2
- bsr.w Knuckles_RecordPos
subq.w #4,a1
move.l #0,(a1)
dbf d2,-
add.w #$20,x_pos(a0)
sub.w #4,y_pos(a0)
Obj4C_Control:
tst.w (Debug_mode_flag).w ; is debug cheat enabled?
beq.s + ; if not, branch
btst #button_B,(Ctrl_1_Press).w ; is button B pressed?
beq.s + ; if not, branch
move.w #1,(Debug_placement_mode).w ; change Sonic into a ring/item
clr.b (Control_Locked).w ; unlock control
rts
; ---------------------------------------------------------------------------
+
tst.b ($FFFFF7CC).w
bne.s +
move.w ($FFFFF604).w,($FFFFF602).w
+
btst #0,obj_control(a0)
beq.s +
move.b #0,$42(a0)
bra.s ++
; ---------------------------------------------------------------------------
+
moveq #0,d0
move.b status(a0),d0
and.w #6,d0
move.w Obj4C_Modes(pc,d0.w),d1
jsr Obj4C_Modes(pc,d1.w)
+
cmpi.w #-$100,(Camera_Min_Y_pos).w ; is vertical wrapping enabled?
bne.s + ; if not, branch
andi.w #$7FF,y_pos(a0) ; perform wrapping of Knuckles' y position
+
bsr.s Knuckles_Display
bsr.w Knuckles_Super
bsr.w Knuckles_RecordPos
bsr.w Knuckles_Water
move.b ($FFFFF768).w,next_tilt(a0)
move.b ($FFFFF76A).w,tilt(a0)
tst.b ($FFFFF7C7).w
beq.s +
tst.b anim(a0)
bne.s +
move.b next_anim(a0),anim(a0)
+
bsr.w Knuckles_Animate
tst.b obj_control(a0)
bmi.s +
jsr TouchResponse
+
bra.w LoadKnucklesDynPLC
; ---------------------------------------------------------------------------
Obj4C_Modes: offsetTable
offsetTableEntry.w Obj4C_MdNormal ; 0
offsetTableEntry.w Obj4C_MdAir ; 1
offsetTableEntry.w Obj4C_MdRoll ; 2
offsetTableEntry.w Obj4C_MdJump ; 3
; =============== S U B R O U T I N E =======================================
Knuckles_Display:
move.b invulnerable_time(a0),d0
beq.s Obj4C_Display
subq.b #1,invulnerable_time(a0)
lsr.w #3,d0
bcc.s Obj4C_ChkInvin
Obj4C_Display:
jsr (DisplaySprite).l
Obj4C_ChkInvin:
btst #1,status_secondary(a0)
beq.s Obj4C_ChkShoes
tst.b invincibility_time(a0)
beq.s Obj4C_ChkShoes
move.b ($FFFFFE05).w,d0
andi.b #7,d0
bne.s Obj4C_ChkShoes
subq.b #1,invincibility_time(a0)
bne.s Obj4C_ChkShoes
tst.b (Current_Boss_ID).w
bne.s Obj4C_RmvInvin
cmp.b #$C,air_left(a0)
bcs.s Obj4C_RmvInvin
move.w (Level_Music).w,d0
jsr PlayMusic
Obj4C_RmvInvin:
bclr #1,status_secondary(a0)
Obj4C_ChkShoes:
btst #2,status_secondary(a0)
beq.s Obj4C_ChkHiJmp
tst.b speedshoes_time(a0)
beq.s Obj4C_ChkHiJmp
move.b ($FFFFFE05).w,d0
andi.b #7,d0
bne.s Obj4C_ChkHiJmp
subq.b #1,speedshoes_time(a0)
bne.s Obj4C_ChkHiJmp
move.w #$600,(Sonic_top_speed).w
move.w #$C,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
tst.b (Super_Sonic_flag).w
beq.s Obj4C_RmvSpeed
move.w #$A00,(Sonic_top_speed).w
move.w #$30,(Sonic_acceleration).w
move.w #$100,(Sonic_deceleration).w
Obj4C_RmvSpeed:
bclr #2,status_secondary(a0)
move.w #$FC,d0
jmp (PlayMusic).l
Obj4C_ChkHiJmp:
btst #3,status_secondary(a0)
beq.s Obj4C_ExitChk
tst.b hijump_time(a0)
beq.s Obj4C_ExitChk
move.b ($FFFFFE05).w,d0
andi.b #7,d0
bne.s Obj4C_ExitChk
subq.b #1,hijump_time(a0)
bne.s Obj4C_ExitChk
move.w #$600,d2 ; set stats
tst.b (Super_Sonic_flag).w ; is Knuckles in his Super form?
beq.s Obj4C_RmvHiJmp ; if not, branch
move.w #$780,d2
Obj4C_RmvHiJmp:
bclr #3,status_secondary(a0)
; ---------------------------------------------------------------------------
Obj4C_ExitChk:
rts
; End of function Knuckles_Display
; =============== S U B R O U T I N E =======================================
Knuckles_RecordPos:
move.w ($FFFFEED2).w,d0
lea ($FFFFE500).w,a1
lea (a1,d0.w),a1
move.w x_pos(a0),(a1)+
move.w y_pos(a0),(a1)+
addq.b #4,($FFFFEED3).w
lea ($FFFFE400).w,a1
lea (a1,d0.w),a1
move.w ($FFFFF602).w,(a1)+
move.w status(a0),(a1)+
rts
; End of function Knuckles_RecordPos
; =============== S U B R O U T I N E =======================================
Knuckles_Water:
tst.b (Water_flag).w ; does level have water?
bne.s Obj4C_InWater ; if so, branch
return_31556C:
rts
; ---------------------------------------------------------------------------
Obj4C_InWater:
move.w (Water_Level_1).w,d0
cmp.w y_pos(a0),d0
bge.s Obj4C_OutWater
tst.w y_vel(a0) ; check if player is moving upward (i.e. from jumping)
bmi.s return_31556C ; if yes, skip routine
bset #6,status(a0) ; set underwater flag
bne.s return_31556C ; if already underwater, branch
move.l a0,a1
jsr ResumeMusic
move.b #$A,($FFFFD080).w
move.b #$81,($FFFFD0A8).w
move.l a0,($FFFFD0BC).w
move.w #$300,(Sonic_top_speed).w
move.w #6,(Sonic_acceleration).w
move.w #$40,(Sonic_deceleration).w
tst.b (Super_Sonic_flag).w
beq.s +
move.w #$500,(Sonic_top_speed).w
move.w #$18,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
+
asr x_vel(a0)
asr y_vel(a0)
asr y_vel(a0)
beq.s return_31556C
move.w #$100,($FFFFD11C).w
move.w #$AA,d0
jmp PlaySound
; ---------------------------------------------------------------------------
Obj4C_OutWater:
bclr #6,status(a0)
beq.s return_31556C
move.l a0,a1
jsr ResumeMusic
move.w #$600,(Sonic_top_speed).w
move.w #$C,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
tst.b (Super_Sonic_flag).w
beq.s +
move.w #$A00,(Sonic_top_speed).w
move.w #$18,(Sonic_acceleration).w
move.w #$100,(Sonic_deceleration).w
+
; cmpi.b #4,routine(a0)
; beq.s +
asl y_vel(a0)
;+
tst.w y_vel(a0)
beq.w return_31556C
move.w #$100,($FFFFD11C).w
move.l a0,a1
jsr ResumeMusic
cmp.w #$F000,y_vel(a0)
bgt.s +
move.w #$F000,y_vel(a0)
+
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_CheckSpindash
bsr.w Knuckles_Jump
bsr.w Knuckles_SlopeResist
bsr.w Knuckles_Move
bsr.w Knuckles_Roll
bsr.w Knuckles_LevelBound
jsr ObjectMove ; AKA SpeedToPos in Sonic 1
jsr AnglePos
bsr.w Knuckles_SlopeRepel
rts
; End of function Obj4C_MdNormal
; =============== S U B R O U T I N E =======================================
Obj4C_MdAir:
tst.b $42(a0)
bne.s Obj4C_MdAir_Gliding
bsr.w Knuckles_JumpHeight
bsr.w Knuckles_ChgJumpDir
bsr.w Knuckles_LevelBound
jsr ObjectMoveAndFall
btst #6,status(a0)
beq.s loc_31569C
sub.w #$28,y_vel(a0)
loc_31569C:
bsr.w Knuckles_JumpAngle
bsr.w Knuckles_DoLevelCollision
rts
; ---------------------------------------------------------------------------
Obj4C_MdAir_Gliding:
bsr.w Knuckles_GlideSpeedControl
bsr.w Knuckles_LevelBound
jsr ObjectMove ; AKA SpeedToPos in Sonic 1
bsr.w Knuckles_GlideControl
return_3156B8:
rts
; End of function Obj4C_MdAir
; =============== S U B R O U T I N E =======================================
Knuckles_GlideControl:
; FUNCTION CHUNK AT 00315C40 SIZE 0000003C BYTES
move.b $42(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,y_radius(a0)
move.b #$A,x_radius(a0)
bsr.w Knuckles_DoLevelCollision2
btst #5,($FFFFF7AC).w
bne.w Knuckles_BeginClimb
move.b #$13,y_radius(a0)
move.b #9,x_radius(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,$42(a0)
move.b #$21,anim(a0)
bclr #0,status(a0)
tst.w x_vel(a0)
bpl.s loc_315736
bset #0,status(a0)
loc_315736:
asr x_vel(a0)
asr x_vel(a0)
move.b #$13,y_radius(a0)
move.b #9,x_radius(a0)
rts
; ---------------------------------------------------------------------------
loc_31574C:
bra.w sub_315C7C
; ---------------------------------------------------------------------------
Knuckles_BeginSlide:
bclr #0,status(a0)
tst.w x_vel(a0)
bpl.s loc_315762
bset #0,status(a0)
loc_315762:
move.b angle(a0),d0
add.b #$20,d0
and.b #$C0,d0
beq.s loc_315780
move.w inertia(a0),x_vel(a0)
move.w #0,y_vel(a0)
bra.w Knuckles_ResetOnFloor_Part2
; ---------------------------------------------------------------------------
loc_315780:
move.b #3,$42(a0)
move.b #$CC,mapping_frame(a0)
move.b #$7F,anim_frame_duration(a0)
move.b #0,anim_frame(a0)
cmp.b #$C,air_left(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 layer_plus(a0),d5
move.b $43(a0),d0
add.b #$40,d0
bpl.s loc_3157D8
bset #0,status(a0)
jsr CheckLeftCeilingDist
or.w d0,d1
bne.s Knuckles_FallFromGlide
addq.w #1,x_pos(a0)
bra.s loc_3157E8
; ---------------------------------------------------------------------------
loc_3157D8:
bclr #0,status(a0)
jsr CheckRightCeilingDist
or.w d0,d1
bne.w loc_31586A
loc_3157E8:
move.b #$13,y_radius(a0)
move.b #9,x_radius(a0)
tst.b (Super_Sonic_flag).w
beq.s loc_315804
cmp.w #$480,inertia(a0)
bcs.s loc_315804
nop
loc_315804:
move.w #0,inertia(a0)
move.w #0,x_vel(a0)
move.w #0,y_vel(a0)
move.b #4,$42(a0)
move.b #$B7,mapping_frame(a0)
move.b #$7F,anim_frame_duration(a0)
move.b #0,anim_frame(a0)
move.b #3,$43(a0)
move.w x_pos(a0),x_sub(a0)
; move.w #SndID_WallGrab,d0
; jmp (PlaySound).l
rts
; ---------------------------------------------------------------------------
Knuckles_FallFromGlide:
move.w x_pos(a0),d3
move.b y_radius(a0),d0
ext.w d0
sub.w d0,d3
subq.w #1,d3
loc_31584A:
move.w y_pos(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,y_pos(a0)
bra.w loc_3157E8
; ---------------------------------------------------------------------------
loc_31586A:
move.w x_pos(a0),d3
move.b y_radius(a0),d0
ext.w d0
add.w d0,d3
addq.w #1,d3
bra.s loc_31584A
; ---------------------------------------------------------------------------
loc_31587A:
move.b #2,$42(a0)
move.b #$21,anim(a0)
move.b #$13,y_radius(a0)
move.b #9,x_radius(a0)
bset #1,($FFFFF7AC).w
rts
; ---------------------------------------------------------------------------
Knuckles_FallingFromGlide:
bsr.w Knuckles_ChgJumpDir
add.w #$38,y_vel(a0)
btst #6,status(a0)
beq.s loc_3158B2
sub.w #$28,y_vel(a0)
loc_3158B2:
bsr.w Knuckles_DoLevelCollision2
btst #1,($FFFFF7AC).w
bne.s return_315900
move.w #0,inertia(a0)
move.w #0,x_vel(a0)
move.w #0,y_vel(a0)
move.b y_radius(a0),d0
sub.b #$13,d0
ext.w d0
add.w d0,y_pos(a0)
move.b angle(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.b #$F,move_lock(a0)
move.b #$23,anim(a0)
; move.w #SndID_Land,d0
; jmp (PlaySound).l
return_315900:
rts
; ---------------------------------------------------------------------------
Knuckles_Sliding:
move.b ($FFFFF602).w,d0
and.b #$70,d0
beq.s loc_315926
tst.w x_vel(a0)
bpl.s loc_31591E
add.w #$20,x_vel(a0)
bmi.s loc_31591C
bra.s loc_315926
; ---------------------------------------------------------------------------
loc_31591C:
bra.s loc_315958
; ---------------------------------------------------------------------------
loc_31591E:
sub.w #$20,x_vel(a0)
bpl.s loc_315958
loc_315926:
move.w #0,inertia(a0)
move.w #0,x_vel(a0)
move.w #0,y_vel(a0)
move.b y_radius(a0),d0
sub.b #$13,d0
ext.w d0
add.w d0,y_pos(a0)
bsr.w Knuckles_ResetOnFloor_Part2
move.b #$F,move_lock(a0)
move.b #$22,anim(a0)
rts
; ---------------------------------------------------------------------------
loc_315958:
move.b #$A,y_radius(a0)
move.b #$A,x_radius(a0)
bsr.w Knuckles_DoLevelCollision2
jsr Sonic_CheckFloor
cmp.w #$E,d1
bge.s loc_315988
add.w d1,y_pos(a0)
move.b d3,angle(a0)
move.b #$13,y_radius(a0)
move.b #9,x_radius(a0)
; move.b (Timer_frames+1).w,d0
; andi.b #7,d0
; bne.s +
; moveq #SndID_Slide,d0
; jmp (PlaySound).l
;+
rts
; ---------------------------------------------------------------------------
loc_315988:
move.b #2,$42(a0)
move.b #$21,anim(a0)
move.b #$13,y_radius(a0)
move.b #9,x_radius(a0)
bset #1,($FFFFF7AC).w
rts
; ---------------------------------------------------------------------------
Knuckles_Climbing_Wall:
tst.b ($FFFFF7AD).w
bmi.w loc_315BAE
move.w x_pos(a0),d0
cmp.w x_sub(a0),d0
bne.w loc_315BAE
btst #3,status(a0)
bne.w loc_315BAE
move.w #0,inertia(a0)
move.w #0,x_vel(a0)
move.w #0,y_vel(a0)
move.l #$FFFFD600,($FFFFF796).w
cmp.b #$D,layer_plus(a0)
beq.s loc_3159F0
move.l #$FFFFD900,($FFFFF796).w
loc_3159F0:
move.b layer_plus(a0),d5
move.b #$A,y_radius(a0)
move.b #$A,x_radius(a0)
moveq #0,d1
btst #0,($FFFFF602).w
beq.w loc_315A76
move.w y_pos(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 layer_plus(a0),d5
move.w y_pos(a0),d2
subq.w #8,d2
move.w x_pos(a0),d3
bsr.w sub_3192E6 ; Doesn't exist in S2
tst.w d1
bpl.s loc_315A46
sub.w d1,y_pos(a0)
moveq #1,d1
bra.w loc_315B04
; ---------------------------------------------------------------------------
loc_315A46:
subq.w #1,y_pos(a0)
tst.b (Super_Sonic_flag).w
beq.s loc_315A54
subq.w #1,y_pos(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 y_pos(a0),d0
ble.w loc_315B04
move.w d0,y_pos(a0)
bra.w loc_315B04
; ---------------------------------------------------------------------------
loc_315A76:
btst #1,($FFFFF602).w
beq.w loc_315B04
cmp.b #$BD,mapping_frame(a0)
bne.s loc_315AA2
move.b #$B7,mapping_frame(a0)
addq.w #3,y_pos(a0)
subq.w #3,x_pos(a0)
btst #0,status(a0)
beq.s loc_315AA2
addq.w #6,x_pos(a0)
loc_315AA2:
move.w y_pos(a0),d2
add.w #$B,d2
bsr.w sub_315C22
tst.w d1
bne.w loc_315BAE
move.b layer(a0),d5
move.w y_pos(a0),d2
add.w #9,d2
move.w x_pos(a0),d3
bsr.w sub_318FF6
tst.w d1
bpl.s loc_315AF4
add.w d1,y_pos(a0)
move.b ($FFFFF768).w,angle(a0)
move.w #0,inertia(a0)
move.w #0,x_vel(a0)
move.w #0,y_vel(a0)
bsr.w Knuckles_ResetOnFloor_Part2
move.b #5,anim(a0)
rts
; ---------------------------------------------------------------------------
loc_315AF4:
addq.w #1,y_pos(a0)
tst.b (Super_Sonic_flag).w
beq.s loc_315B02
addq.w #1,y_pos(a0)
loc_315B02:
moveq #-1,d1
loc_315B04:
tst.w d1
beq.s loc_315B30
subq.b #1,$43(a0)
bpl.s loc_315B30
move.b #3,$43(a0)
add.b mapping_frame(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,mapping_frame(a0)
loc_315B30:
move.b #$20,anim_frame_duration(a0)
move.b #0,anim_frame(a0)
move.b #$13,y_radius(a0)
move.b #9,x_radius(a0)
move.w ($FFFFF602).w,d0
and.w #$70,d0
beq.s return_315B94
move.w #$FC80,y_vel(a0)
move.w #$400,x_vel(a0)
bchg #0,status(a0)
bne.s loc_315B6A
neg.w x_vel(a0)
loc_315B6A:
bset #1,status(a0)
move.b #1,jumping(a0)
move.b #$E,y_radius(a0)
move.b #7,x_radius(a0)
move.b #2,anim(a0)
bset #2,status(a0)
move.b #0,$42(a0)
return_315B94:
rts
; ---------------------------------------------------------------------------
Knuckles_ClimbUp:
move.b #5,$42(a0) ; Climb up to the floor above you
cmp.b #$BD,mapping_frame(a0)
beq.s return_315BAC
move.b #0,$43(a0)
bsr.s sub_315BDA
return_315BAC:
rts
; ---------------------------------------------------------------------------
loc_315BAE:
move.b #2,$42(a0)
move.w #$2121,anim(a0)
move.b #$CB,mapping_frame(a0)
move.b #7,anim_frame_duration(a0)
move.b #1,anim_frame(a0)
move.b #$13,y_radius(a0)
move.b #9,x_radius(a0)
rts
; End of function Knuckles_GlideControl
; =============== S U B R O U T I N E =======================================
sub_315BDA:
moveq #0,d0
move.b $43(a0),d0
lea word_315C12(pc,d0.w),a1
move.b (a1)+,mapping_frame(a0)
move.b (a1)+,d0
ext.w d0
btst #0,status(a0)
beq.s loc_315BF6
neg.w d0
loc_315BF6:
add.w d0,x_pos(a0)
move.b (a1)+,d1
ext.w d1
add.w d1,y_pos(a0)
move.b (a1)+,anim_frame_duration(a0)
addq.b #4,$43(a0)
move.b #0,anim_frame(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 layer_plus(a0),d5
btst #0,status(a0)
bne.s loc_315C36
move.w x_pos(a0),d3
bra.w loc_319208
; ---------------------------------------------------------------------------
loc_315C36:
move.w x_pos(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 anim_frame_duration(a0)
bne.s return_315C7A
bsr.w sub_315BDA
cmp.b #$10,$43(a0)
bne.s return_315C7A
move.w #0,inertia(a0)
move.w #0,x_vel(a0)
move.w #0,y_vel(a0)
btst #0,status(a0)
beq.s loc_315C70
subq.w #1,x_pos(a0)
loc_315C70:
bsr.w Knuckles_ResetOnFloor_Part2
move.b #5,anim(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,anim_frame_duration(a0)
move.b #0,anim_frame(a0)
move.w #$2020,anim(a0)
bclr #5,status(a0)
bclr #0,status(a0)
moveq #0,d0
move.b $43(a0),d0
add.b #$10,d0
lsr.w #5,d0
move.b byte_315CC2(pc,d0.w),d1
move.b d1,mapping_frame(a0)
cmp.b #$C4,d1
bne.s return_315CC0
bset #0,status(a0)
move.b #$C0,mapping_frame(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,$42(a0)
bne.w loc_315D88
move.w inertia(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 $43(a0),d1
and.b #$7F,d1
bne.s loc_315CFC
addq.w #4,d0
tst.b (Super_Sonic_flag).w
beq.s loc_315CFC
addq.w #8,d0
loc_315CFC:
move.w d0,inertia(a0)
move.b $43(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,$43(a0)
move.b $43(a0),d0
jsr CalcSine
muls.w inertia(a0),d1
asr.l #8,d1
move.w d1,x_vel(a0)
cmp.w #$80,y_vel(a0)
blt.s loc_315D62
sub.w #$20,y_vel(a0)
bra.s loc_315D68
; ---------------------------------------------------------------------------
loc_315D62:
add.w #$20,y_vel(a0)
loc_315D68:
move.w ($FFFFEECC).w,d0
cmp.w #$FF00,d0
beq.w loc_315D88
add.w #$10,d0
cmp.w y_pos(a0),d0
ble.w loc_315D88
asr x_vel(a0)
asr inertia(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
; ---------------------------------------------------------------------------
Obj4C_MdRoll:
tst.b spindash_flag(a0)
bne.s loc_315DA6
bsr.w Knuckles_Jump
loc_315DA6:
bsr.w Knuckles_RollRepel
bsr.w Knuckles_RollSpeed
bsr.w Knuckles_LevelBound
jsr ObjectMove ; AKA SpeedToPos in Sonic 1
jsr AnglePos
bsr.w Knuckles_SlopeRepel
rts
; ---------------------------------------------------------------------------
Obj4C_MdJump:
bsr.w Knuckles_JumpHeight
bsr.w Knuckles_ChgJumpDir
bsr.w Knuckles_LevelBound
jsr ObjectMoveAndFall
btst #6,status(a0)
beq.s loc_315DE2
sub.w #$28,y_vel(a0)
loc_315DE2:
bsr.w Knuckles_JumpAngle
bsr.w Knuckles_DoLevelCollision
rts
; =============== S U B R O U T I N E =======================================
Knuckles_Move:
move.w (Sonic_top_speed).w,d6
move.w (Sonic_acceleration).w,d5
move.w (Sonic_deceleration).w,d4
tst.b status_secondary(a0)
bmi.w Obj4C_Traction
tst.b move_lock(a0)
bne.w Obj4C_ResetScreen
btst #2,($FFFFF602).w
beq.s Obj4C_NotLeft
bsr.w Knuckles_MoveLeft
Obj4C_NotLeft:
btst #3,($FFFFF602).w
beq.s Obj4C_NotRight
bsr.w Knuckles_MoveRight
Obj4C_NotRight:
move.b angle(a0),d0
add.b #$20,d0
and.b #$C0,d0 ; is Knuckles on a slope?
bne.w Obj4C_ResetScreen ; if yes, branch
tst.w inertia(a0) ; is Knuckles moving?
bne.w Obj4C_ResetScreen ; if yes, branch
bclr #5,status(a0)
move.b #5,anim(a0)
btst #3,status(a0)
beq.w Knuckles_Balance
moveq #0,d0
move.b interact(a0),d0
lsl.w #6,d0
lea (Object_RAM).w,a1 ; a1=character
lea (a1,d0.w),a1 ; a1=object
tst.b status(a1)
bmi.w Knuckles_LookUp
moveq #0,d1
move.b width_pixels(a1),d1
move.w d1,d2
add.w d2,d2
subq.w #2,d2
add.w x_pos(a0),d1
sub.w y_pos(a1),d1
cmp.w #2,d1
blt.s Knuckles_BalanceOnObjLeft
cmp.w d2,d1
bge.s Knuckles_BalanceOnObjRight
bra.w Knuckles_LookUp
; ---------------------------------------------------------------------------
Knuckles_BalanceOnObjRight:
btst #0,status(a0)
bne.s loc_315E9A
move.b #6,anim(a0)
bra.w Obj4C_ResetScreen
; ---------------------------------------------------------------------------
loc_315E9A:
bclr #0,status(a0)
move.b #0,anim_frame_duration(a0)
move.b #4,anim_frame(a0)
move.w #$606,anim(a0)
bra.w Obj4C_ResetScreen
; ---------------------------------------------------------------------------
Knuckles_BalanceOnObjLeft:
btst #0,status(a0)
beq.s loc_315EC8
move.b #6,anim(a0)
bra.w Obj4C_ResetScreen
; ---------------------------------------------------------------------------
loc_315EC8:
bset #0,status(a0)
move.b #0,anim_frame_duration(a0)
move.b #4,anim_frame(a0)
move.w #$606,anim(a0)
bra.w Obj4C_ResetScreen
; ---------------------------------------------------------------------------
Knuckles_Balance:
jsr (ChkFloorEdge).l
cmp.w #$C,d1
blt.w Knuckles_LookUp
cmp.b #3,next_tilt(a0)
bne.s Knuckles_BalanceLeft
btst #0,status(a0)
bne.s loc_315F0C
move.b #6,anim(a0)
bra.w Obj4C_ResetScreen
; ---------------------------------------------------------------------------
loc_315F0C:
bclr #0,status(a0)
move.b #0,anim_frame_duration(a0)
move.b #4,anim_frame(a0)
move.w #$606,anim(a0)
bra.w Obj4C_ResetScreen
; ---------------------------------------------------------------------------
Knuckles_BalanceLeft:
cmp.b #3,tilt(a0)
bne.s Knuckles_LookUp
btst #0,status(a0)
beq.s loc_315F42
move.b #6,anim(a0)
bra.w Obj4C_ResetScreen
; ---------------------------------------------------------------------------
loc_315F42:
bset #0,status(a0)
move.b #0,anim_frame_duration(a0)
move.b #4,anim_frame(a0)
move.w #$606,anim(a0)
bra.w Obj4C_ResetScreen
; ---------------------------------------------------------------------------
Knuckles_LookUp:
btst #0,($FFFFF602).w
beq.s Knuckles_Duck
move.b #7,anim(a0)
addq.w #1,(Sonic_Look_delay_counter).w
cmpi.w #$78,(Sonic_Look_delay_counter).w
blo.s Obj4C_ResetScreen_Part2
move.w #$78,(Sonic_Look_delay_counter).w
cmpi.w #$C8,(Camera_Y_pos_bias).w
beq.s Obj4C_UpdateSpeedOnGround
addq.w #2,(Camera_Y_pos_bias).w
bra.s Obj4C_UpdateSpeedOnGround
; ---------------------------------------------------------------------------
Knuckles_Duck:
btst #1,($FFFFF602).w
beq.s Obj4C_ResetScreen
move.b #8,anim(a0)
addq.w #1,($FFFFF66C).w
cmp.w #$78,($FFFFF66C).w
bcs.s Obj4C_ResetScreen_Part2
move.w #$78,($FFFFF66C).w
cmp.w #8,($FFFFEED8).w
beq.s Obj4C_UpdateSpeedOnGround
subq.w #2,($FFFFEED8).w
bra.s Obj4C_UpdateSpeedOnGround
; ---------------------------------------------------------------------------
Obj4C_ResetScreen:
move.w #0,($FFFFF66C).w
Obj4C_ResetScreen_Part2:
cmp.w #$60,($FFFFEED8).w
beq.s Obj4C_UpdateSpeedOnGround
bcc.s loc_315FCE
addq.w #4,($FFFFEED8).w
loc_315FCE:
subq.w #2,($FFFFEED8).w
; ---------------------------------------------------------------------------
Obj4C_UpdateSpeedOnGround:
tst.b (Super_Sonic_flag).w
beq.s loc_315FDC
move.w #$C,d5
loc_315FDC:
move.b ($FFFFF602).w,d0
and.b #$C,d0
bne.s Obj4C_Traction
move.w inertia(a0),d0
beq.s Obj4C_Traction
bmi.s Obj4C_SettleLeft
sub.w d5,d0
bcc.s loc_315FF6
move.w #0,d0
loc_315FF6:
move.w d0,inertia(a0)
bra.s Obj4C_Traction
; ---------------------------------------------------------------------------
Obj4C_SettleLeft:
add.w d5,d0
bcc.s loc_316004
move.w #0,d0
loc_316004:
move.w d0,inertia(a0)
Obj4C_Traction:
move.b angle(a0),d0
jsr CalcSine
muls.w inertia(a0),d1
asr.l #8,d1
move.w d1,x_vel(a0)
muls.w inertia(a0),d0
asr.l #8,d0
move.w d0,y_vel(a0)
Obj4C_CheckWallsOnGround:
move.b angle(a0),d0
add.b #$40,d0
bmi.s return_3160A6
move.b #$40,d1
tst.w inertia(a0)
beq.s return_3160A6
bmi.s loc_31603E
neg.w d1
loc_31603E:
move.b angle(a0),d0
add.b d1,d0
move.w d0,-(sp)
jsr CalcRoomInFront ; Also known as Sonic_WalkSpeed in Sonic 1
move.w (sp)+,d0
tst.w d1
bpl.s return_3160A6
asl.w #8,d1
add.b #$20,d0
and.b #$C0,d0
beq.s loc_3160A2
cmp.b #$40,d0
beq.s loc_316088
cmp.b #$80,d0
beq.s loc_316082
add.w d1,x_vel(a0)
move.w #0,inertia(a0)
btst #0,status(a0)
bne.s return_316080
bset #5,status(a0)
return_316080:
rts
; ---------------------------------------------------------------------------
loc_316082:
sub.w d1,y_vel(a0)
rts
; ---------------------------------------------------------------------------
loc_316088:
sub.w d1,x_vel(a0)
move.w #0,inertia(a0)
btst #0,status(a0)
beq.s return_316080
bset #5,status(a0)
rts
; ---------------------------------------------------------------------------
loc_3160A2:
add.w d1,y_vel(a0)
return_3160A6:
rts
; End of function Knuckles_Move
; =============== S U B R O U T I N E =======================================
Knuckles_MoveLeft:
move.w inertia(a0),d0
beq.s loc_3160B0
bpl.s Knuckles_TurnLeft
loc_3160B0:
bset #0,status(a0)
bne.s loc_3160C4
bclr #5,status(a0)
move.b #1,next_anim(a0)
loc_3160C4:
sub.w d5,d0
move.w d6,d1
neg.w d1
cmp.w d1,d0
bgt.s loc_3160D6
add.w d5,d0
cmp.w d1,d0
ble.s loc_3160D6
move.w d1,d0
loc_3160D6:
move.w d0,inertia(a0)
move.b #0,anim(a0)
rts
; ---------------------------------------------------------------------------
Knuckles_TurnLeft:
sub.w d4,d0
bcc.s loc_3160EA
move.w #-$80,d0
loc_3160EA:
move.w d0,inertia(a0)
move.b angle(a0),d1
add.b #$20,d1
and.b #$C0,d1
bne.s return_31612C
cmp.w #$400,d0
blt.s return_31612C
move.b #$D,anim(a0)
bclr #0,status(a0)
move.w #$A4,d0
jsr PlaySound
cmp.b #$C,air_left(a0)
bcs.s return_31612C
move.b #6,($FFFFD124).w
move.b #$15,($FFFFD11A).w
return_31612C:
rts
; End of function Knuckles_MoveLeft
; =============== S U B R O U T I N E =======================================
Knuckles_MoveRight:
move.w inertia(a0),d0
bmi.s Knuckles_TurnRight
bclr #0,status(a0)
beq.s loc_316148
bclr #5,status(a0)
move.b #1,next_anim(a0)
loc_316148:
add.w d5,d0
cmp.w d6,d0
blt.s loc_316156
sub.w d5,d0
cmp.w d6,d0
bge.s loc_316156
move.w d6,d0
loc_316156:
move.w d0,inertia(a0)
move.b #0,anim(a0)
rts
; ---------------------------------------------------------------------------
Knuckles_TurnRight:
add.w d4,d0
bcc.s loc_31616A
move.w #$80,d0
loc_31616A:
move.w d0,inertia(a0)
move.b angle(a0),d1
add.b #$20,d1
and.b #$C0,d1
bne.s return_3161AC
cmp.w #$FC00,d0
bgt.s return_3161AC
move.b #$D,anim(a0)
bset #0,status(a0)
move.w #$A4,d0
jsr PlaySound
cmp.b #$C,air_left(a0)
bcs.s return_3161AC
move.b #6,($FFFFD124).w
move.b #$15,($FFFFD11A).w
return_3161AC:
rts
; End of function Knuckles_MoveRight
; =============== S U B R O U T I N E =======================================
Knuckles_RollSpeed:
move.w (Sonic_top_speed).w,d6
asl.w #1,d6
moveq #6,d5
move.w #$20,d4
tst.b status_secondary(a0)
bmi.w Obj4C_Roll_ResetScreen
tst.b move_lock(a0)
bne.s Knuckles_Apply_RollSpeed
btst #2,($FFFFF602).w
beq.s loc_3161D8
bsr.w Knuckles_RollLeft
loc_3161D8:
btst #3,($FFFFF602).w
beq.s Knuckles_Apply_RollSpeed
bsr.w Knuckles_RollRight
Knuckles_Apply_RollSpeed:
move.w inertia(a0),d0
beq.s Knuckles_CheckRollStop
bmi.s Knuckles_ApplyRollSpeedLeft
sub.w d5,d0
bcc.s loc_3161F4
move.w #0,d0
loc_3161F4:
move.w d0,inertia(a0)
bra.s Knuckles_CheckRollStop
; ---------------------------------------------------------------------------
Knuckles_ApplyRollSpeedLeft:
add.w d5,d0
bcc.s loc_316202
move.w #0,d0
loc_316202:
move.w d0,inertia(a0)
Knuckles_CheckRollStop:
tst.w inertia(a0)
bne.s Obj4C_Roll_ResetScreen
tst.b spindash_flag(a0)
bne.s Knuckles_KeepRolling
bclr #2,status(a0)
move.b #$13,y_radius(a0)
move.b #9,x_radius(a0)
move.b #5,anim(a0)
subq.w #5,y_pos(a0)
bra.s Obj4C_Roll_ResetScreen
; ---------------------------------------------------------------------------
; magically gives Knuckles an extra push if he's going to stop rolling where it's not allowed
; (such as in an S-curve in HTZ or a stopper chamber in CNZ)
Knuckles_KeepRolling:
move.w #$400,inertia(a0)
btst #0,status(a0)
beq.s Obj4C_Roll_ResetScreen
neg.w inertia(a0)
Obj4C_Roll_ResetScreen:
cmp.w #$60,($FFFFEED8).w
beq.s Knuckles_SetRollSpeeds
bcc.s loc_316250
addq.w #4,($FFFFEED8).w
loc_316250:
subq.w #2,($FFFFEED8).w
Knuckles_SetRollSpeeds:
move.b angle(a0),d0
jsr CalcSine
muls.w inertia(a0),d0
asr.l #8,d0
move.w d0,y_vel(a0)
muls.w inertia(a0),d1
asr.l #8,d1
cmp.w #$1000,d1
ble.s loc_316278
move.w #$1000,d1
loc_316278:
cmp.w #-$1000,d1
bge.s loc_316282
move.w #-$1000,d1
loc_316282:
move.w d1,x_vel(a0)
bra.w Obj4C_CheckWallsOnGround
; End of function Knuckles_RollSpeed
; =============== S U B R O U T I N E =======================================
Knuckles_RollLeft:
move.w inertia(a0),d0
beq.s loc_316292
bpl.s Knuckles_BrakeRollingRight
loc_316292:
bset #0,status(a0)
move.b #2,anim(a0)
rts
; ---------------------------------------------------------------------------
Knuckles_BrakeRollingRight:
sub.w d4,d0
bcc.s loc_3162A8
move.w #-$80,d0
loc_3162A8:
move.w d0,inertia(a0)
rts
; End of function Knuckles_RollLeft
; =============== S U B R O U T I N E =======================================
Knuckles_RollRight:
move.w inertia(a0),d0
bmi.s Knuckles_BrakeRollingLeft
bclr #0,status(a0)
move.b #2,anim(a0)
rts
; ---------------------------------------------------------------------------
Knuckles_BrakeRollingLeft:
add.w d4,d0
bcc.s loc_3162CA
move.w #$80,d0
loc_3162CA:
move.w d0,inertia(a0)
rts
; End of function Knuckles_RollRight
; ---------------------------------------------------------------------------
; Subroutine for moving Knuckles left or right when he's in the air
; ---------------------------------------------------------------------------
; =============== S U B R O U T I N E =======================================
Knuckles_ChgJumpDir:
move.w (Sonic_top_speed).w,d6
move.w (Sonic_acceleration).w,d5
asl.w #1,d5
btst #4,status(a0)
bne.s Obj4C_Jump_ResetScreen
move.w x_vel(a0),d0
btst #2,($FFFFF602).w
beq.s ++
bset #0,status(a0)
sub.w d5,d0
move.w d6,d1
neg.w d1
cmp.w d1,d0 ; compare new speed with top speed
bgt.s ++ ; if new speed is less than the maximum, branch
add.w d5,d0 ; remove this frame's acceleration change
cmp.w d1,d0 ; compare speed with top speed
ble.s ++ ; if speed was already greater than the maximum, branch
tst.w ($FFFFFFD0).w
bne.s +
add.w d5,d0
cmp.w d1,d0
ble.s ++
+
move.w d1,d0
+
btst #3,($FFFFF602).w
beq.s ++
bclr #0,status(a0)
add.w d5,d0
cmp.w d6,d0
blt.s ++
sub.w d5,d0 ; remove this frame's acceleration change
cmp.w d1,d0 ; compare speed with top speed
bge.s ++ ; if speed was already greater than the maximum, branch
tst.w ($FFFFFFD0).w
bne.s +
sub.w d5,d0
cmp.w d6,d0
bge.s ++
+
move.w d6,d0
+
move.w d0,x_vel(a0)
Obj4C_Jump_ResetScreen:
cmp.w #$60,($FFFFEED8).w
beq.s Knuckles_JumpPeakDecelerate
bcc.s +
addq.w #4,($FFFFEED8).w
+
subq.w #2,($FFFFEED8).w
Knuckles_JumpPeakDecelerate:
cmp.w #-$400,y_vel(a0)
bcs.s return_316376
move.w x_vel(a0),d0
move.w d0,d1
asr.w #5,d1
beq.s return_316376
bmi.s Knuckles_JumpPeakDecelerateLeft
sub.w d1,d0
bcc.s +
move.w #0,d0
+
move.w d0,x_vel(a0)
rts
; ---------------------------------------------------------------------------
Knuckles_JumpPeakDecelerateLeft:
sub.w d1,d0
bcs.s +
move.w #0,d0
+
move.w d0,x_vel(a0)
return_316376:
rts
; End of function Knuckles_ChgJumpDir
; =============== S U B R O U T I N E =======================================
Knuckles_LevelBound:
move.l x_pos(a0),d1
move.w x_vel(a0),d0
ext.l d0
asl.l #8,d0
add.l d0,d1
swap d1
move.w ($FFFFEEC8).w,d0
add.w #$10,d0
cmp.w d1,d0
bhi.s Knuckles_Boundary_Sides
move.w (Camera_Max_X_pos).w,d0
addi.w #$128,d0
tst.b (Current_Boss_ID).w
bne.s +
addi.w #$40,d0
+
cmp.w d1,d0 ; has Knuckles touched the right boundary?
bls.s Knuckles_Boundary_Sides ; if yes, branch
Knuckles_Boundary_CheckBottom:
move.w (Camera_Max_Y_pos_now).w,d0
addi.w #$E0,d0
cmp.w y_pos(a0),d0
blt.s Knuckles_Boundary_Bottom
rts
; ---------------------------------------------------------------------------
Knuckles_Boundary_Bottom:
addq.l #4,sp
jmp (KillCharacter).l
; ---------------------------------------------------------------------------
Knuckles_Boundary_Sides:
move.w d0,x_pos(a0)
move.w #0,x_sub(a0)
move.w #0,x_vel(a0)
move.w #0,inertia(a0)
bra.s Knuckles_Boundary_CheckBottom
; End of function Knuckles_LevelBound
; =============== S U B R O U T I N E =======================================
Knuckles_Roll:
tst.b status_secondary(a0)
bmi.s Obj4C_NoRoll
move.w inertia(a0),d0
bpl.s loc_3163E6
neg.w d0
loc_3163E6:
cmp.w #$80,d0
bcs.s Obj4C_NoRoll
move.b ($FFFFF602).w,d0
and.b #$C,d0
bne.s Obj4C_NoRoll
btst #1,($FFFFF602).w
bne.s Obj4C_ChkRoll
Obj4C_NoRoll:
rts
; ---------------------------------------------------------------------------
Obj4C_ChkRoll:
btst #2,status(a0)
beq.s Obj4C_DoRoll
rts
; ---------------------------------------------------------------------------
Obj4C_DoRoll:
bset #2,status(a0)
move.b #$E,y_radius(a0)
move.b #7,x_radius(a0)
move.b #2,anim(a0)
addq.w #5,y_pos(a0)
move.w #$BE,d0
jsr PlaySound
tst.w inertia(a0)
bne.s return_31643C
move.w #$200,inertia(a0)
return_31643C:
rts
; End of function Knuckles_Roll
; ---------------------------------------------------------------------------
; Subroutine allowing Knuckles to jump
; ---------------------------------------------------------------------------
; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
Knuckles_Jump:
move.b (Ctrl_1_Press_Logical).w,d0
and.b #button_B_mask|button_C_mask,d0
beq.w return_3164EC
moveq #0,d0
move.b angle(a0),d0
add.b #$80,d0
jsr CalcRoomOverHead
cmp.w #6,d1
blt.w return_3164EC
move.w #$600,d2
tst.b (Super_Sonic_flag).w ; Test if super
beq.s + ; if not, branch
move.w #$780,d2 ; set higher jump speed if super
+
btst #6,status(a0) ; Test if underwater
beq.s + ; if not, branch
move.w #$380,d2 ; set lower jump speed if underwater
+
btst #3,status_secondary(a0) ; Test if high jump powerup is active
beq.s + ; if it isn't, branch
move.w #$700,d2 ; So it is? Set Knuckles' jump height
tst.b (Super_Sonic_flag).w ; Test to see if we're in our Super form
beq.s + ; if we aren't, branch
move.w #$800,d2 ; So we are? Set Knuckles' jump height
+
tst.w (Demo_mode_flag).w ; Check for demo mode
beq.s +
add.w #$80,d2 ; Set the jump height to Sonic's height in Demo mode because Sonic Team were too lazy to record new demos for S2&K.
+
moveq #0,d0
move.b angle(a0),d0
sub.b #$40,d0
jsr CalcSine
muls.w d2,d1
asr.l #8,d1
add.w d1,x_vel(a0) ; make Knuckles jump (in X... this adds nothing on level ground)
muls.w d2,d0
asr.l #8,d0
add.w d0,y_vel(a0) ; make Knuckles jump (in Y)
bset #1,status(a0)
bclr #5,status(a0)
addq.l #4,sp
move.b #1,jumping(a0)
clr.b stick_to_convex(a0)
move.w #$A0,d0
jsr (PlaySound).l ; play jumping sound
; move.b #$13,y_radius(a0)
; move.b #9,x_radius(a0)
btst #2,status(a0)
bne.s Knuckles_RollJump
move.b #$E,y_radius(a0)
move.b #7,x_radius(a0)
move.b #2,anim(a0) ; use "jumping" animation
bset #2,status(a0)
addq.w #5,y_pos(a0)
return_3164EC:
rts
; ---------------------------------------------------------------------------
Knuckles_RollJump:
bset #4,status(a0)
rts
; End of function Knuckles_Jump
; =============== S U B R O U T I N E =======================================
Knuckles_JumpHeight:
tst.b jumping(a0)
beq.s Knuckles_UpwardsVelocityCap
move.w #-$400,d1
btst #6,status(a0)
beq.s loc_31650C
move.w #-$200,d1
loc_31650C:
cmp.w y_vel(a0),d1
ble.w Knuckles_CheckGlide ; Check if Knuckles should begin a glide
move.b (Ctrl_1_Held_Logical).w,d0
andi.b #button_B_mask|button_C_mask,d0 ; is a jump button pressed?
bne.s return_316522 ; if not, return
move.w d1,y_vel(a0)
+
tst.b (Control_Locked).w ; Are Controls locked?
bne.s return_316522 ; If so, branch, and do not bother with Super code
move.b (Ctrl_1_Press_Logical).w,d0
andi.b #button_A_mask,d0 ; is the A button pressed?
bne.w Knuckles_CheckGoSuper ; if yes, test for turning into Super Knuckles
rts
return_316522:
rts
; ---------------------------------------------------------------------------
Knuckles_UpwardsVelocityCap:
tst.b spindash_flag(a0)
bne.s return_316538
cmp.w #-$FC0,y_vel(a0)
bge.s return_316538
move.w #-$FC0,y_vel(a0)
return_316538:
rts
; ---------------------------------------------------------------------------
Knuckles_CheckGlide:
tst.w (Demo_mode_flag).w ; Don't glide on demos
bne.w return_3165D2
tst.b $42(a0)
bne.w return_3165D2
move.b ($FFFFF603).w,d0
and.b #$70,d0
beq.w return_3165D2
tst.b (Super_Sonic_flag).w
bne.s Knuckles_BeginGlide
cmp.b #7,($FFFFFFB1).w
bcs.s Knuckles_BeginGlide
cmp.w #50,($FFFFFE20).w
bcs.s Knuckles_BeginGlide
tst.b ($FFFFFE1E).w
bne.s Knuckles_CheckGoSuper
Knuckles_BeginGlide:
bclr #2,status(a0)
move.b #$A,y_radius(a0)
move.b #$A,x_radius(a0)
bclr #4,status(a0)
move.b #1,$42(a0)
add.w #$200,y_vel(a0)
bpl.s loc_31659E
move.w #0,y_vel(a0)
loc_31659E:
moveq #0,d1
move.w #$400,d0
move.w d0,inertia(a0)
btst #0,status(a0)
beq.s loc_3165B4
neg.w d0
moveq #-$80,d1
loc_3165B4:
move.w d0,x_vel(a0)
move.b d1,$43(a0)
move.w #0,angle(a0)
move.b #0,($FFFFF7AC).w
bset #1,($FFFFF7AC).w
bsr.w sub_315C7C
return_3165D2:
rts
; ---------------------------------------------------------------------------
Knuckles_CheckGoSuper:
tst.b (Update_HUD_timer).w ; has Knuckles reached the end of the act?
beq.w return_316671 ; if yes, branch
tst.b (Super_Sonic_flag).w ; is Knuckles already Super?
bne.w Knuckles_RevertToNormal ; if yes, branch (This allows for reverting manually)
cmpi.b #7,(Emerald_count).w ; does Knuckles have exactly 7 emeralds?
bne.s return_316671 ; if not, branch
cmpi.w #50,(Ring_count).w ; does Knuckles have at least 50 rings?
blo.s return_316671 ; if not, branch
move.b #1,($FFFFF65F).w
move.b #$F,($FFFFF65E).w
move.b #1,(Super_Sonic_flag).w
move.w #60,($FFFFF670).w
move.b #$81,obj_control(a0)
move.b #$1F,anim(a0)
move.b #$7E,($FFFFD040).w
move.w #$A00,(Sonic_top_speed).w
move.w #$30,(Sonic_acceleration).w
move.w #$100,(Sonic_deceleration).w
btst #6,status(a0) ; Check if underwater, return if not
beq.s +
move.w #$500,(Sonic_top_speed).w
move.w #$18,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
+
move.b #0,invincibility_time(a0)
bset #1,status_secondary(a0)
move.w #$DF,d0
jsr (PlaySound).l
move.w #$97,d0
jmp (PlayMusic).l
; End of function Knuckles_JumpHeight
; ---------------------------------------------------------------------------
return_316671:
rts
; =============== S U B R O U T I N E =======================================
Knuckles_Super:
tst.b (Super_Sonic_flag).w
beq.w return_3166C8
tst.b (Update_HUD_timer).w
beq.s Knuckles_RevertToNormal ; ?
subq.w #1,($FFFFF670).w
bpl.w return_3166C8
move.w #60,($FFFFF670).w
tst.w ($FFFFFE20).w
beq.s Knuckles_RevertToNormal
or.b #1,($FFFFFE1D).w
cmp.w #1,($FFFFFE20).w
beq.s loc_316672
cmp.w #10,($FFFFFE20).w
beq.s loc_316672
cmp.w #100,($FFFFFE20).w
bne.s loc_316678
loc_316672:
or.b #%10000000,(Update_HUD_rings).w
loc_316678:
subq.w #1,(Ring_count).w
bne.s return_3166C8
; originally loc_31667E
Knuckles_RevertToNormal:
move.b #2,(Super_Sonic_palette).w
move.w #40,(Palette_frame).w
move.b #0,(Super_Sonic_flag).w
move.b #1,next_anim(a0)
move.b #1,invincibility_time(a0)
move.w #$600,(Sonic_top_speed).w
move.w #$C,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
btst #6,status(a0)
beq.s return_3166C8
move.w #$300,(Sonic_top_speed).w
move.w #6,(Sonic_acceleration).w
move.w #$40,(Sonic_deceleration).w
return_3166C8:
rts
; End of function Knuckles_Super
; =============== S U B R O U T I N E =======================================
Knuckles_CheckSpindash:
tst.b spindash_flag(a0)
bne.s Knuckles_UpdateSpindash
cmp.b #8,anim(a0)
bne.s return_316718
move.b (Ctrl_1_Press_Logical).w,d0
andi.b #button_B_mask|button_C_mask|button_A_mask,d0
beq.w return_316718
move.b #9,anim(a0)
move.w #$E0,d0
jsr (PlaySound).l
addq.l #4,sp
move.b #1,spindash_flag(a0)
move.b #0,spindash_counter(a0)
cmpi.b #$C,air_left(a0)
bcs.s +
move.b #2,($FFFFD11C).w
+
bsr.w Knuckles_LevelBound
jsr (AnglePos).l
return_316718:
rts
; ---------------------------------------------------------------------------
Knuckles_UpdateSpindash:
move.b (Ctrl_1_Held_Logical).w,d0
btst #button_down,d0
bne.w Knuckles_ChargingSpindash
; unleash the charged spindash and start rolling quickly:
move.b #$E,y_radius(a0)
move.b #7,x_radius(a0)
move.b #2,anim(a0)
addq.w #5,y_pos(a0)
move.b #0,spindash_flag(a0)
moveq #0,d0
move.b spindash_counter(a0),d0
add.w d0,d0
move.w Knuckles_SpindashSpeeds(pc,d0.w),inertia(a0)
tst.b (Super_Sonic_flag).w
beq.s loc_31675C
move.w Knuckles_SpindashSpeedsSuper(pc,d0.w),inertia(a0)
loc_31675C:
move.w inertia(a0),d0
sub.w #$800,d0
add.b d0,d0
and.w #$1F00,d0
neg.w d0
add.w #$2000,d0
move.w d0,($FFFFEED0).w ; Lock camera for a certain number of frames
btst #0,status(a0)
beq.s loc_316780
neg.w inertia(a0)
loc_316780:
bset #2,status(a0)
move.b #0,($FFFFD11C).w
move.w #$BC,d0
jsr (PlaySound).l
move.b angle(a0),d0
jsr (CalcSine).l
muls.w inertia(a0),d1
asr.l #8,d1
move.w d1,x_vel(a0)
muls.w inertia(a0),d0
asr.l #8,d0
move.w d0,y_vel(a0)
bra.s Obj4C_Spindash_ResetScr
; ---------------------------------------------------------------------------
Knuckles_SpindashSpeeds:
dc.w $800 ; 0
dc.w $880 ; 1
dc.w $900 ; 2
dc.w $980 ; 3
dc.w $A00 ; 4
dc.w $A80 ; 5
dc.w $B00 ; 6
dc.w $B80 ; 7
dc.w $C00 ; 8
Knuckles_SpindashSpeedsSuper:
dc.w $B00 ; 0
dc.w $B80 ; 1
dc.w $C00 ; 2
dc.w $C80 ; 3
dc.w $D00 ; 4
dc.w $D80 ; 5
dc.w $E00 ; 6
dc.w $E80 ; 7
dc.w $F00 ; 8
; ---------------------------------------------------------------------------
Knuckles_ChargingSpindash: ; If still charging the dash...
tst.b spindash_counter(a0)
beq.s +
move.b spindash_counter(a0),d0
lsr.b #5,d0
sub.b d0,spindash_counter(a0)
bcc.s +
move.b #0,spindash_counter(a0)
+
move.b (Ctrl_1_Press_Logical).w,d0
andi.b #button_B_mask|button_C_mask|button_A_mask,d0
beq.w Obj4C_Spindash_ResetScr
move.w #$900,anim(a0)
move.w #$E0,d0
jsr (PlaySound).l
addi.b #$1,spindash_counter(a0)
cmpi.b #8,spindash_counter(a0)
bcs.s Obj4C_Spindash_ResetScr
move.b #8,spindash_counter(a0)
bra.s Obj4C_Spindash_ResetScr
move.b #8,spindash_counter(a0)
Obj4C_Spindash_ResetScr:
addq.l #4,sp
cmpi.w #$60,(Camera_Y_pos_bias).w
beq.s loc_316818
bhs.s +
addq.w #4,(Camera_Y_pos_bias).w
+ subq.w #2,(Camera_Y_pos_bias).w
loc_316818:
bsr.w Knuckles_LevelBound
jsr (AnglePos).l
rts
; End of function Knuckles_Spindash
; =============== S U B R O U T I N E =======================================
Knuckles_SlopeResist:
move.b angle(a0),d0
add.b #$60,d0
cmp.b #$C0,d0
bcc.s return_316856
move.b angle(a0),d0
jsr CalcSine
muls.w #$20,d0
asr.l #8,d0
tst.w inertia(a0)
beq.s return_316856
bmi.s loc_316852
tst.w d0
beq.s return_316850
add.w d0,inertia(a0)
return_316850:
rts
; ---------------------------------------------------------------------------
loc_316852:
add.w d0,inertia(a0)
return_316856:
rts
; End of function Knuckles_SlopeResist
; =============== S U B R O U T I N E =======================================
Knuckles_RollRepel:
move.b angle(a0),d0
add.b #$60,d0
cmp.b #$C0,d0
bcc.s return_316892
move.b angle(a0),d0
jsr CalcSine
muls.w #$50,d0
asr.l #8,d0
tst.w inertia(a0)
bmi.s loc_316888
tst.w d0
bpl.s loc_316882
asr.l #2,d0
loc_316882:
add.w d0,inertia(a0)
rts
; ---------------------------------------------------------------------------
loc_316888:
tst.w d0
bmi.s loc_31688E
asr.l #2,d0
loc_31688E:
add.w d0,inertia(a0)
return_316892:
rts
; End of function Knuckles_RollRepel
; =============== S U B R O U T I N E =======================================
Knuckles_SlopeRepel:
nop
tst.b stick_to_convex(a0)
bne.s return_3168CE
tst.b move_lock(a0)
bne.s loc_3168D0
move.b angle(a0),d0
add.b #$20,d0
and.b #$C0,d0
beq.s return_3168CE
move.w inertia(a0),d0
bpl.s loc_3168B8
neg.w d0
loc_3168B8:
cmp.w #$280,d0
bcc.s return_3168CE
clr.w inertia(a0)
bset #1,status(a0)
move.b #$1E,move_lock(a0)
return_3168CE:
rts
; ---------------------------------------------------------------------------
loc_3168D0:
subq.b #1,move_lock(a0)
rts
; End of function Knuckles_SlopeRepel
; =============== S U B R O U T I N E =======================================
Knuckles_JumpAngle:
move.b angle(a0),d0
beq.s Knuckles_JumpFlip
bpl.s loc_3168E6
addq.b #2,d0
bcc.s Knuckles_JumpAngleSet
moveq #0,d0
bra.s Knuckles_JumpAngleSet
; ---------------------------------------------------------------------------
loc_3168E6:
subq.b #2,d0
bcc.s Knuckles_JumpAngleSet
moveq #0,d0
Knuckles_JumpAngleSet:
move.b d0,angle(a0)
Knuckles_JumpFlip:
move.b flip_angle(a0),d0
beq.s return_316934
tst.w inertia(a0)
bmi.s Knuckles_JumpLeftFlip
Knuckles_JumpRightFlip:
move.b flip_speed(a0),d1
add.b d1,d0
bcc.s Knuckles_JumpFlipSet
subq.b #1,flips_remaining(a0)
bcc.s Knuckles_JumpFlipSet
move.b #0,flips_remaining(a0)
moveq #0,d0
bra.s Knuckles_JumpFlipSet
; ---------------------------------------------------------------------------
Knuckles_JumpLeftFlip:
tst.b flip_turned(a0)
bne.s Knuckles_JumpRightFlip
move.b flip_speed(a0),d1
sub.b d1,d0
bcc.s Knuckles_JumpFlipSet
subq.b #1,flips_remaining(a0)
bcc.s Knuckles_JumpFlipSet
move.b #0,flips_remaining(a0)
moveq #0,d0
Knuckles_JumpFlipSet:
move.b d0,flip_angle(a0)
return_316934:
rts
; End of function Knuckles_JumpAngle
; =============== S U B R O U T I N E =======================================
Knuckles_DoLevelCollision2:
move.l #$FFFFD600,($FFFFF796).w
cmp.b #$C,layer(a0)
beq.s loc_31694E
move.l #$FFFFD900,($FFFFF796).w
loc_31694E:
move.b layer_plus(a0),d5
move.w x_vel(a0),d1
move.w y_vel(a0),d2
jsr CalcAngle
sub.b #$20,d0
and.b #$C0,d0
cmp.b #$40,d0
beq.w Knuckles_HitLeftWall2
cmp.b #$80,d0
beq.w Knuckles_HitCeilingAndWalls2
cmp.b #$C0,d0
beq.w Knuckles_HitRightWall2
jsr CheckLeftWallDist
tst.w d1
bpl.s loc_316998
sub.w d1,x_pos(a0)
move.w #0,x_vel(a0)
bset #5,($FFFFF7AC).w
loc_316998:
jsr CheckRightWallDist
tst.w d1
bpl.s loc_3169B0
add.w d1,x_pos(a0)
move.w #0,x_vel(a0)
bset #5,($FFFFF7AC).w
loc_3169B0:
jsr Sonic_CheckFloor
tst.w d1
bpl.s return_3169CC
add.w d1,y_pos(a0)
move.b d3,angle(a0)
move.w #0,y_vel(a0)
bclr #1,($FFFFF7AC).w
return_3169CC:
rts
; ---------------------------------------------------------------------------
Knuckles_HitLeftWall2:
jsr CheckLeftWallDist
tst.w d1
bpl.s Knuckles_HitCeilingAlt
sub.w d1,x_pos(a0)
move.w #0,x_vel(a0)
bset #5,($FFFFF7AC).w
Knuckles_HitCeilingAlt:
jsr CheckCeilingDist
tst.w d1
bpl.s Knuckles_HitFloor
neg.w d1
cmp.w #$14,d1
bcc.s loc_316A08
add.w d1,y_pos(a0)
tst.w y_vel(a0)
bpl.s return_316A06
move.w #0,y_vel(a0)
return_316A06:
rts
; ---------------------------------------------------------------------------
loc_316A08:
jsr CheckRightWallDist
tst.w d1
bpl.s return_316A20
add.w d1,x_pos(a0)
move.w #0,x_vel(a0)
bset #5,($FFFFF7AC).w
return_316A20:
rts
; ---------------------------------------------------------------------------
Knuckles_HitFloor:
tst.w y_vel(a0)
bmi.s return_316A44
jsr Sonic_CheckFloor
tst.w d1
bpl.s return_316A44
add.w d1,y_pos(a0)
move.b d3,angle(a0)
move.w #0,y_vel(a0)
bclr #1,($FFFFF7AC).w
return_316A44:
rts
; ---------------------------------------------------------------------------
Knuckles_HitCeilingAndWalls2:
jsr CheckLeftWallDist
tst.w d1
bpl.s loc_316A5E
sub.w d1,x_pos(a0)
move.w #0,x_vel(a0)
bset #5,($FFFFF7AC).w
loc_316A5E:
jsr CheckRightWallDist
tst.w d1
bpl.s loc_316A76
add.w d1,x_pos(a0)
move.w #0,x_vel(a0)
bset #5,($FFFFF7AC).w
loc_316A76:
jsr CheckCeilingDist
tst.w d1
bpl.s return_316A88
sub.w d1,y_pos(a0)
move.w #0,y_vel(a0)
return_316A88:
rts
; ---------------------------------------------------------------------------
Knuckles_HitRightWall2:
jsr CheckRightWallDist
tst.w d1
bpl.s loc_316AA2
add.w d1,x_pos(a0)
move.w #0,x_vel(a0)
bset #5,($FFFFF7AC).w
loc_316AA2:
jsr CheckCeilingDist
tst.w d1
bpl.s loc_316ABC
sub.w d1,y_pos(a0)
tst.w y_vel(a0)
bpl.s return_316ABA
move.w #0,y_vel(a0)
return_316ABA:
rts
; ---------------------------------------------------------------------------
loc_316ABC:
tst.w y_vel(a0)
bmi.s return_316ADE
jsr Sonic_CheckFloor
tst.w d1
bpl.s return_316ADE
add.w d1,y_pos(a0)
move.b d3,angle(a0)
move.w #0,y_vel(a0)
bclr #1,($FFFFF7AC).w
return_316ADE:
rts
; End of function Knuckles_DoLevelCollision2
; =============== S U B R O U T I N E =======================================
Knuckles_DoLevelCollision:
move.l #$FFFFD600,($FFFFF796).w
cmp.b #$C,layer(a0)
beq.s loc_316AF8
move.l #$FFFFD900,($FFFFF796).w
loc_316AF8:
move.b layer_plus(a0),d5
move.w x_vel(a0),d1
move.w y_vel(a0),d2
jsr CalcAngle
sub.b #$20,d0
and.b #$C0,d0
cmp.b #$40,d0
beq.w Knuckles_HitLeftWall
cmp.b #$80,d0
beq.w Knuckles_HitCeilingAndWalls
cmp.b #$C0,d0
beq.w Knuckles_HitRightWall
jsr CheckLeftWallDist
tst.w d1
bpl.s loc_316B3C
sub.w d1,x_pos(a0)
move.w #0,x_vel(a0)
loc_316B3C:
jsr CheckRightWallDist
tst.w d1
bpl.s loc_316B4E
add.w d1,x_pos(a0)
move.w #0,x_vel(a0)
loc_316B4E:
jsr Sonic_CheckFloor
tst.w d1
bpl.s return_316BC0
move.b y_vel(a0),d2
addq.b #8,d2
neg.b d2
cmp.b d2,d1
bge.s loc_316B66
cmp.b d2,d0
blt.s return_316BC0
loc_316B66:
add.w d1,y_pos(a0)
move.b d3,angle(a0)
bsr.w Knuckles_ResetOnFloor
move.b d3,d0
add.b #$20,d0
and.b #$40,d0
bne.s loc_316B9E
move.b d3,d0
add.b #$10,d0
and.b #$20,d0
beq.s loc_316B90
asr y_vel(a0)
bra.s loc_316BB2
; ---------------------------------------------------------------------------
loc_316B90:
move.w #0,y_vel(a0)
move.w x_vel(a0),inertia(a0)
rts
; ---------------------------------------------------------------------------
loc_316B9E:
move.w #0,x_vel(a0)
cmp.w #$FC0,y_vel(a0)
ble.s loc_316BB2
move.w #$FC0,y_vel(a0)
loc_316BB2:
move.w y_vel(a0),inertia(a0)
tst.b d3
bpl.s return_316BC0
neg.w inertia(a0)
return_316BC0:
rts
; ---------------------------------------------------------------------------
Knuckles_HitLeftWall:
jsr CheckLeftWallDist
tst.w d1
bpl.s Knuckles_HitCeiling
sub.w d1,x_pos(a0)
move.w #0,x_vel(a0)
move.w y_vel(a0),inertia(a0)
rts
; ---------------------------------------------------------------------------
Knuckles_HitCeiling:
jsr CheckCeilingDist
tst.w d1
bpl.s Knuckles_HitFloor_0
sub.w d1,y_pos(a0)
tst.w y_vel(a0)
bpl.s return_316BF4
move.w #0,y_vel(a0)
return_316BF4:
rts
; ---------------------------------------------------------------------------
Knuckles_HitFloor_0:
tst.w y_vel(a0)
bmi.s return_316C1C
jsr Sonic_CheckFloor
tst.w d1
bpl.s return_316C1C
add.w d1,y_pos(a0)
move.b d3,angle(a0)
bsr.w Knuckles_ResetOnFloor
move.w #0,y_vel(a0)
move.w x_vel(a0),inertia(a0)
return_316C1C:
rts
; ---------------------------------------------------------------------------
Knuckles_HitCeilingAndWalls:
jsr CheckLeftWallDist
tst.w d1
bpl.s loc_316C30
sub.w d1,x_pos(a0)
move.w #0,x_vel(a0)
loc_316C30:
jsr CheckRightWallDist
tst.w d1
bpl.s loc_316C42
add.w d1,x_pos(a0)
move.w #0,x_vel(a0)
loc_316C42:
jsr CheckCeilingDist
tst.w d1
bpl.s return_316C78
sub.w d1,y_pos(a0)
move.b d3,d0
add.b #$20,d0
and.b #$40,d0
bne.s loc_316C62
move.w #0,y_vel(a0)
rts
; ---------------------------------------------------------------------------
loc_316C62:
move.b d3,angle(a0)
bsr.w Knuckles_ResetOnFloor
move.w y_vel(a0),inertia(a0)
tst.b d3
bpl.s return_316C78
neg.w inertia(a0)
return_316C78:
rts
; ---------------------------------------------------------------------------
Knuckles_HitRightWall:
jsr CheckRightWallDist
tst.w d1
bpl.s Knuckles_HitCeiling2
add.w d1,x_pos(a0)
move.w #0,x_vel(a0)
move.w y_vel(a0),inertia(a0)
rts
; ---------------------------------------------------------------------------
Knuckles_HitCeiling2:
jsr CheckCeilingDist
tst.w d1
bpl.s Knuckles_HitFloor2
sub.w d1,y_pos(a0)
tst.w y_vel(a0)
bpl.s return_316CAC
move.w #0,y_vel(a0)
return_316CAC:
rts
; ---------------------------------------------------------------------------
Knuckles_HitFloor2:
tst.w y_vel(a0)
bmi.s return_316CD4
jsr Sonic_CheckFloor
tst.w d1
bpl.s return_316CD4
add.w d1,y_pos(a0)
move.b d3,angle(a0)
bsr.w Knuckles_ResetOnFloor
move.w #0,y_vel(a0)
move.w x_vel(a0),inertia(a0)
return_316CD4:
rts
; End of function Knuckles_DoLevelCollision
; =============== S U B R O U T I N E =======================================
Knuckles_ResetOnFloor:
tst.b spindash_flag(a0)
bne.s Knuckles_ResetOnFloor_Part3
move.b #0,anim(a0)
; End of function Knuckles_ResetOnFloor
; =============== S U B R O U T I N E =======================================
Knuckles_ResetOnFloor_Part2:
move.b y_radius(a0),d0
move.b #$13,y_radius(a0)
move.b #9,x_radius(a0)
btst #2,status(a0)
beq.s Knuckles_ResetOnFloor_Part3
bclr #2,status(a0)
move.b #0,anim(a0)
sub.b #$13,d0
ext.w d0
add.w d0,y_pos(a0)
Knuckles_ResetOnFloor_Part3:
bclr #1,status(a0)
bclr #5,status(a0)
bclr #4,status(a0)
move.b #0,jumping(a0)
move.w #0,(Chain_Bonus_counter).w
move.b #0,flip_angle(a0)
move.b #0,flip_turned(a0)
move.b #0,flips_remaining(a0)
move.w #0,(Sonic_Look_delay_counter).w
move.b #0,$42(a0)
cmp.b #$20,anim(a0)
bcc.s loc_316D5C
cmp.b #$14,anim(a0)
bne.s return_316D62
loc_316D5C:
move.b #0,anim(a0)
return_316D62:
rts
; End of function Knuckles_ResetOnFloor_Part2
; =============== S U B R O U T I N E =======================================
Obj4C_Hurt:
; FUNCTION CHUNK AT 00316E14 SIZE 0000001C BYTES
tst.w ($FFFFFFDA).w
beq.s Obj4C_Hurt_Normal
btst #4,($FFFFF605).w
beq.s Obj4C_Hurt_Normal
move.w #1,($FFFFFE08).w
clr.b ($FFFFF7CC).w
rts
; ---------------------------------------------------------------------------
Obj4C_Hurt_Normal:
tst.b routine_secondary(a0)
bmi.w Knuckles_HurtInstantRecover
jsr (ObjectMove).l
addi.w #$30,y_vel(a0)
btst #6,status(a0)
beq.s +
subi.w #$20,y_vel(a0)
+
cmpi.w #-$100,(Camera_Min_Y_pos).w
bne.s +
andi.w #$7FF,y_pos(a0)
+
bsr.w Knuckles_HurtStop
bsr.w Knuckles_LevelBound
bsr.w Knuckles_RecordPos
bsr.w Knuckles_Water
bsr.w Knuckles_Animate
bsr.w LoadKnucklesDynPLC
jmp (DisplaySprite).l
; End of function Obj4C_Hurt
; =============== S U B R O U T I N E =======================================
Knuckles_HurtStop:
move.w ($FFFFEECE).w,d0
add.w #$E0,d0
cmp.w y_pos(a0),d0
blt.w JmpTo3_KillCharacter
bsr.w Knuckles_DoLevelCollision
btst #1,status(a0)
bne.s return_316E0C
moveq #0,d0
move.w d0,y_vel(a0)
move.w d0,x_vel(a0)
move.w d0,inertia(a0)
move.b d0,obj_control(a0)
move.b #0,anim(a0)
subq.b #2,routine(a0)
move.b #$78,invulnerable_time(a0)
move.b #0,spindash_flag(a0)
return_316E0C:
rts
; ---------------------------------------------------------------------------
JmpTo3_KillCharacter:
jmp (KillCharacter).l
; End of function Knuckles_HurtStop
; ---------------------------------------------------------------------------
; START OF FUNCTION CHUNK FOR Obj4C_Hurt
Knuckles_HurtInstantRecover:
subq.b #2,routine(a0)
move.b #0,routine_secondary(a0)
bsr.w Knuckles_RecordPos
bsr.w Knuckles_Animate
bsr.w LoadKnucklesDynPLC
jmp DisplaySprite
; END OF FUNCTION CHUNK FOR Obj4C_Hurt
; =============== S U B R O U T I N E =======================================
Obj4C_Dead:
tst.w ($FFFFFFDA).w
beq.s loc_316E4A
btst #4,($FFFFF605).w
beq.s loc_316E4A
move.w #1,($FFFFFE08).w
clr.b ($FFFFF7CC).w
rts
; ---------------------------------------------------------------------------
loc_316E4A:
bsr.w CheckGameOverKnux
jsr (ObjectMoveAndFall).l
bsr.w Knuckles_RecordPos
bsr.w Knuckles_Animate
bsr.w LoadKnucklesDynPLC
jmp (DisplaySprite).l
; End of function Obj4C_Dead
; =============== S U B R O U T I N E =======================================
CheckGameOverKnux:
move.b #1,($FFFFEEBE).w
move.b #0,spindash_flag(a0)
move.w ($FFFFEECE).w,d0
add.w #$100,d0
cmp.w y_pos(a0),d0
bge.w return_316F64
move.b #8,routine(a0)
move.b #$3C,spindash_counter(a0)
addq.b #1,($FFFFFE1C).w
subq.b #1,($FFFFFE12).w
bne.s Obj4C_ResetLevel
move.b #0,spindash_counter(a0)
move.b #$39,($FFFFB080).w
move.b #$39,($FFFFB0C0).w
move.b #1,($FFFFB0DA).w
move.w a0,($FFFFB0BE).w
clr.b ($FFFFFE1A).w
Obj4C_Finished:
clr.b ($FFFFFE1E).w
clr.b ($FFFFFECA).w
move.b #8,routine(a0)
move.w #$9B,d0
jsr (PlayMusic).l
moveq #3,d0
jmp LoadPLC
; ---------------------------------------------------------------------------
Obj4C_ResetLevel:
tst.b (Time_Over_flag).w
beq.s Obj4C_ResetLevel_Part2
move.b #0,spindash_counter(a0)
move.b #$39,($FFFFB080).w
move.b #$39,($FFFFB0C0).w
move.b #2,($FFFFB09A).w
move.b #3,($FFFFB0DA).w
move.w a0,($FFFFB0BE).w
bra.s Obj4C_Finished
; ---------------------------------------------------------------------------
Obj4C_ResetLevel_Part2:
tst.w (Two_player_mode).w
beq.s return_316F64
move.b #0,(Scroll_lock).w
move.b #$A,routine(a0) ; => Obj4C_Respawning
move.w (Saved_x_pos).w,x_pos(a0)
move.w (Saved_y_pos).w,y_pos(a0)
move.w (Saved_art_tile).w,art_tile(a0)
move.w (Saved_layer).w,layer(a0)
clr.w (Ring_count).w
clr.b (Extra_life_flags).w
move.b #0,obj_control(a0)
move.b #5,anim(a0)
move.w #0,x_vel(a0)
move.w #0,y_vel(a0)
move.w #0,inertia(a0)
move.b #2,status(a0)
move.b #0,move_lock(a0)
move.b #0,spindash_counter(a0)
return_316F64:
rts
; End of function Obj4C_CheckGameOver
; =============== S U B R O U T I N E =======================================
Obj4C_Gone:
tst.b spindash_counter(a0)
beq.s return_316F78
subq.b #1,spindash_counter(a0)
bne.s return_316F78
move.w #1,($FFFFFE02).w
return_316F78:
rts
; End of function Obj4C_Gone
; ---------------------------------------------------------------------------
Obj4C_Respawning:
tst.w ($FFFFEEB0).w
bne.s loc_316F8C
tst.w ($FFFFEEB2).w
bne.s loc_316F8C
move.b #2,routine(a0)
loc_316F8C:
bsr.w Knuckles_Animate
bsr.w LoadKnucklesDynPLC
jmp DisplaySprite
; ---------------------------------------------------------------------------
; Knuckles when he's drowning
; ---------------------------------------------------------------------------
Obj4C_Drowned:
jsr (ObjectMove).l ; Make Knuckles able to move
addi.w #$10,y_vel(a0) ; Apply gravity
bsr.w Knuckles_RecordPos ; Record position
bsr.w Knuckles_Animate ; Animate Knuckles
bsr.w LoadKnucklesDynPLC ; Load Knuckles' DPLCs
jmp (DisplaySprite).l ; And finally, display Knuckles
; ===========================================================================
; ---------------------------------------------------------------------------
; Subroutine to animate Knuckles' sprites
; See also: AnimateSprite
; ---------------------------------------------------------------------------
; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
Knuckles_Animate:
lea (KnucklesAniData).l,a1
moveq #0,d0
move.b anim(a0),d0
cmp.b next_anim(a0),d0
beq.s KAnim_Do
move.b d0,next_anim(a0)
move.b #0,anim_frame(a0)
move.b #0,anim_frame_duration(a0)
bclr #5,status(a0)
KAnim_Do:
add.w d0,d0
add.w (a1,d0.w),a1
move.b (a1),d0
bmi.s KAnim_WalkRun
move.b status(a0),d1
and.b #1,d1
and.b #$FC,render_flags(a0)
or.b d1,render_flags(a0)
subq.b #1,anim_frame_duration(a0)
bpl.s KAnim_Delay
move.b d0,anim_frame_duration(a0)
KAnim_Do2:
moveq #0,d1
move.b anim_frame(a0),d1
move.b 1(a1,d1.w),d0
cmp.b #$FC,d0
bcc.s KAnim_End_FF
KAnim_Next:
move.b d0,mapping_frame(a0)
addq.b #1,anim_frame(a0)
KAnim_Delay:
rts
; ---------------------------------------------------------------------------
KAnim_End_FF:
addq.b #1,d0
bne.s KAnim_End_FE
move.b #0,anim_frame(a0)
move.b 1(a1),d0
bra.s KAnim_Next
; ---------------------------------------------------------------------------
KAnim_End_FE:
addq.b #1,d0
bne.s KAnim_End_FD
move.b 2(a1,d1.w),d0
sub.b d0,anim_frame(a0)
sub.b d0,d1
move.b 1(a1,d1.w),d0
bra.s KAnim_Next
; ---------------------------------------------------------------------------
KAnim_End_FD:
addq.b #1,d0
bne.s KAnim_End
move.b 2(a1,d1.w),anim(a0)
KAnim_End:
rts
; ---------------------------------------------------------------------------
KAnim_WalkRun:
addq.b #1,d0
bne.w KAnim_Roll
moveq #0,d0
move.b flip_angle(a0),d0
bne.w KAnim_Tumble
moveq #0,d1
move.b angle(a0),d0
bmi.s loc_31704E
beq.s loc_31704E
subq.b #1,d0
loc_31704E:
move.b status(a0),d2
and.b #1,d2
bne.s loc_31705A
not.b d0
loc_31705A:
add.b #$10,d0
bpl.s loc_317062
moveq #3,d1
loc_317062:
and.b #$FC,render_flags(a0)
eor.b d1,d2
or.b d2,render_flags(a0)
btst #5,status(a0)
bne.w KAnim_Push
lsr.b #4,d0
and.b #6,d0
move.w inertia(a0),d2
bpl.s loc_317086
neg.w d2
loc_317086:
tst.b status_secondary(a0)
bpl.w loc_317090
add.w d2,d2
loc_317090:
lea (KnuxAni_Run).l,a1
cmp.w #$600,d2
bcc.s loc_3170A4
lea (KnuxAni_Walk).l,a1
add.b d0,d0
loc_3170A4:
add.b d0,d0
move.b d0,d3
moveq #0,d1
move.b anim_frame(a0),d1
move.b 1(a1,d1.w),d0
cmp.b #$FF,d0
bne.s loc_3170C2
move.b #0,anim_frame(a0)
move.b 1(a1),d0
loc_3170C2:
move.b d0,mapping_frame(a0)
add.b d3,mapping_frame(a0)
subq.b #1,anim_frame_duration(a0)
bpl.s return_3170E4
neg.w d2
add.w #$800,d2
bpl.s loc_3170DA
moveq #0,d2
loc_3170DA:
lsr.w #8,d2
move.b d2,anim_frame_duration(a0)
addq.b #1,anim_frame(a0)
return_3170E4:
rts
; ---------------------------------------------------------------------------
KAnim_Tumble:
move.b flip_angle(a0),d0
moveq #0,d1
move.b status(a0),d2
and.b #1,d2
bne.s KAnim_Tumble_Left
and.b #$FC,render_flags(a0)
add.b #$B,d0
divu.w #$16,d0
add.b #$31,d0
move.b d0,mapping_frame(a0)
move.b #0,anim_frame_duration(a0)
rts
; ---------------------------------------------------------------------------
KAnim_Tumble_Left:
and.b #$FC,render_flags(a0)
tst.b flip_turned(a0)
beq.s loc_31712C
or.b #1,render_flags(a0)
add.b #$B,d0
bra.s loc_317138
; ---------------------------------------------------------------------------
loc_31712C:
or.b #3,render_flags(a0)
neg.b d0
add.b #-$71,d0
loc_317138:
divu.w #$16,d0
add.b #$31,d0
move.b d0,mapping_frame(a0)
move.b #0,anim_frame_duration(a0)
rts
; ---------------------------------------------------------------------------
KAnim_Roll:
subq.b #1,anim_frame_duration(a0)
bpl.w KAnim_Delay
addq.b #1,d0
bne.s KAnim_Push
move.w inertia(a0),d2
bpl.s loc_317160
neg.w d2
loc_317160:
lea (KnuxAni_Roll2).l,a1
cmp.w #$600,d2
bcc.s loc_317172
lea (KnuxAni_Roll).l,a1
loc_317172:
neg.w d2
add.w #$400,d2
bpl.s loc_31717C
moveq #0,d2
loc_31717C:
lsr.w #8,d2
move.b d2,anim_frame_duration(a0)
move.b status(a0),d1
and.b #1,d1
and.b #$FC,render_flags(a0)
or.b d1,render_flags(a0)
bra.w KAnim_Do2
; ---------------------------------------------------------------------------
KAnim_Push:
subq.b #1,anim_frame_duration(a0)
bpl.w KAnim_Delay
move.w inertia(a0),d2
bmi.s loc_3171A8
neg.w d2
loc_3171A8:
add.w #$800,d2
bpl.s loc_3171B0
moveq #0,d2
loc_3171B0:
lsr.w #8,d2
move.b d2,anim_frame_duration(a0)
lea (KnuxAni_Push).l,a1
move.b status(a0),d1
and.b #1,d1
and.b #$FC,render_flags(a0)
or.b d1,render_flags(a0)
bra.w KAnim_Do2
; End of function Knuckles_Animate
; ---------------------------------------------------------------------------
KnucklesAniData: offsetTable
KnuxAni_Walk_ptr: offsetTableEntry.w KnuxAni_Walk ; 0 ; 0
KnuxAni_Run_ptr: offsetTableEntry.w KnuxAni_Run ; 1 ; 1
KnuxAni_Roll_ptr: offsetTableEntry.w KnuxAni_Roll ; 2 ; 2
offsetTableEntry.w KnuxAni_Roll2 ; 3 ; 3
offsetTableEntry.w KnuxAni_Push ; 4 ; 4
offsetTableEntry.w KnuxAni_Wait ; 5 ; 5
offsetTableEntry.w KnuxAni_Balance ; 6 ; 6
offsetTableEntry.w KnuxAni_LookUp ; 7 ; 7
offsetTableEntry.w KnuxAni_Duck ; 8 ; 8
offsetTableEntry.w KnuxAni_Spindash ; 9 ; 9
offsetTableEntry.w KnuxAni_Unused ; 10 ; $A
offsetTableEntry.w KnuxAni_Pull ; 11 ; $B
offsetTableEntry.w KnuxAni_Balance2 ; 12 ; $C
offsetTableEntry.w KnuxAni_Stop ; 13 ; $D
offsetTableEntry.w KnuxAni_Float ; 14 ; $E
offsetTableEntry.w KnuxAni_Float2 ; 15 ; $F
offsetTableEntry.w KnuxAni_Spring ; 16 ; $10
offsetTableEntry.w KnuxAni_Hang ; 17
offsetTableEntry.w KnuxAni_Unused_0 ; 18
offsetTableEntry.w KnuxAni_S3EndingPose ; 19
offsetTableEntry.w KnuxAni_WFZHang ; 20
offsetTableEntry.w KnuxAni_Bubble ; 21
offsetTableEntry.w KnuxAni_DeathBW ; 22
offsetTableEntry.w KnuxAni_Drown ; 23
offsetTableEntry.w KnuxAni_Death ; 24
offsetTableEntry.w KnuxAni_OilSlide ; 25
offsetTableEntry.w KnuxAni_Hurt ; 26
offsetTableEntry.w KnuxAni_OilSlide_0 ; 27
offsetTableEntry.w KnuxAni_Blank ; 28
offsetTableEntry.w KnuxAni_Unused_1 ; 29
offsetTableEntry.w KnuxAni_Unused_2 ; 30
offsetTableEntry.w KnuxAni_Transform ; 31
offsetTableEntry.w KnuxAni_Gliding ; 32
offsetTableEntry.w KnuxAni_FallFromGlide ; 33
offsetTableEntry.w KnuxAni_GetUp ; 34
offsetTableEntry.w KnuxAni_HardFall ; 35
offsetTableEntry.w KnuxAni_Badass ; 36
KnuxAni_Walk: dc.b $FF, 7, 8, 1, 2, 3, 4, 5, 6,$FF; 0 ; ...
KnuxAni_Run: dc.b $FF,$21,$22,$23,$24,$FF,$FF,$FF,$FF,$FF; 0 ; ...
KnuxAni_Roll: dc.b $FE,$9A,$96,$9A,$97,$9A,$98,$9A,$99,$FF; 0 ; ...
KnuxAni_Roll2: dc.b $FE,$9A,$96,$9A,$97,$9A,$98,$9A,$99,$FF; 0 ; ...
KnuxAni_Push: dc.b $FD,$CE,$CF,$D0,$D1,$FF,$FF,$FF,$FF,$FF; 0 ; ...
KnuxAni_Wait: dc.b 5,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56; 0 ; ...
dc.b $56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56; 13
dc.b $56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56; 26
dc.b $56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$56,$D2; 39
dc.b $D2,$D2,$D3,$D3,$D3,$D2,$D2,$D2,$D3,$D3,$D3,$D2,$D2; 52
dc.b $D2,$D3,$D3,$D3,$D2,$D2,$D2,$D3,$D3,$D3,$D2,$D2,$D2; 65
dc.b $D3,$D3,$D3,$D2,$D2,$D2,$D3,$D3,$D3,$D2,$D2,$D2,$D3; 78
dc.b $D3,$D3,$D2,$D2,$D2,$D3,$D3,$D3,$D2,$D2,$D2,$D3,$D3; 91
dc.b $D3,$D4,$D4,$D4,$D4,$D4,$D7,$D8,$D9,$DA,$DB,$D8,$D9; 104
dc.b $DA,$DB,$D8,$D9,$DA,$DB,$D8,$D9,$DA,$DB,$D8,$D9,$DA; 117
dc.b $DB,$D8,$D9,$DA,$DB,$D8,$D9,$DA,$DB,$D8,$D9,$DA,$DB; 130
dc.b $DC,$DD,$DC,$DD,$DE,$DE,$D8,$D7,$FF; 143
KnuxAni_Balance: dc.b 3,$9F,$9F,$A0,$A0,$A1,$A1,$A2,$A2,$A3,$A3,$A4,$A4; 0 ; ...
dc.b $A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5; 13
dc.b $A5,$A5,$A6,$A6,$A6,$A7,$A7,$A7,$A8,$A8,$A9,$A9,$AA; 26
dc.b $AA,$FE, 6 ; 39
KnuxAni_LookUp: dc.b 5,$D5,$D6,$FE, 1 ; 0 ; ...
KnuxAni_Duck: dc.b 5,$9B,$9C,$FE, 1 ; 0 ; ...
KnuxAni_Spindash: dc.b 0,$86,$87,$86,$88,$86,$89,$86,$8A,$86,$8B,$FF; 0 ; ...
KnuxAni_Unused: dc.b 9,$BA,$C5,$C6,$C6,$C6,$C6,$C6,$C6,$C7,$C7,$C7,$C7; 0 ; ...
dc.b $C7,$C7,$C7,$C7,$C7,$C7,$C7,$C7,$FD, 0; 13
KnuxAni_Pull: dc.b $F,$8F,$FF ; 0 ; ...
KnuxAni_Balance2: dc.b 3,$A1,$A1,$A2,$A2,$A3,$A3,$A4,$A4,$A5,$A5,$A5,$A5; 0 ; ...
dc.b $A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5,$A5,$A6,$A6; 13
dc.b $A6,$A7,$A7,$A7,$A8,$A8,$A9,$A9,$AA,$AA,$FE; 26
dc.b 6
KnuxAni_Stop: dc.b 3,$9D,$9E,$9F,$A0,$FD, 0 ; 0 ; ...
KnuxAni_Float: dc.b 7,$C0,$FF ; 0 ; ...
KnuxAni_Float2: dc.b 5,$C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7,$C8,$C9,$FF; 0 ; ...
KnuxAni_Spring: dc.b $2F,$8E,$FD, 0 ; 0 ; ...
KnuxAni_Hang: dc.b 1,$AE,$AF,$FF ; 0 ; ...
KnuxAni_Unused_0: dc.b $F,$43,$43,$43,$FE, 1 ; 0 ; ...
KnuxAni_S3EndingPose: dc.b 5,$B1,$B2,$B2,$B2,$B3,$B4,$FE, 1, 7,$B1,$B3,$B3; 0 ; ...
dc.b $B3,$B3,$B3,$B3,$B2,$B3,$B4,$B3,$FE, 4; 13
KnuxAni_WFZHang: dc.b $13,$91,$FF ; 0 ; ...
KnuxAni_Bubble: dc.b $B,$B0,$B0, 3, 4,$FD, 0 ; 0 ; ...
KnuxAni_DeathBW: dc.b $20,$AC,$FF ; 0 ; ...
KnuxAni_Drown: dc.b $20,$AD,$FF ; 0 ; ...
KnuxAni_Death: dc.b $20,$AB,$FF ; 0 ; ...
KnuxAni_OilSlide: dc.b 9,$8C,$FF ; 0 ; ...
KnuxAni_Hurt: dc.b $40,$8D,$FF ; 0 ; ...
KnuxAni_OilSlide_0: dc.b 9,$8C,$FF ; 0 ; ...
KnuxAni_Blank: dc.b $77, 0,$FF ; 0 ; ...
KnuxAni_Unused_1: dc.b $13,$D0,$D1,$FF ; 0 ; ...
KnuxAni_Unused_2: dc.b 3,$CF,$C8,$C9,$CA,$CB,$FE ; 0 ; ...
dc.b 4
KnuxAni_Gliding: dc.b $1F,$C0,$FF ; 0 ; ...
KnuxAni_FallFromGlide: dc.b 7,$CA,$CB,$FE, 1 ; 0 ; ...
KnuxAni_GetUp: dc.b $F,$CD,$FD, 0 ; 0 ; ...
KnuxAni_HardFall: dc.b $F,$9C,$FD, 0 ; 0 ; ...
KnuxAni_Badass: dc.b 5,$D8,$D9,$DA,$DB,$D8,$D9,$DA,$DB,$D8,$D9,$DA,$DB; 0 ; ...
dc.b $D8,$D9,$DA,$DB,$D8,$D9,$DA,$DB,$D8,$D9,$DA,$DB,$D8; 13
dc.b $D9,$DA,$DB,$D8,$D9,$DA,$DB,$DC,$DD,$DC,$DD,$DE,$DE; 26
dc.b $FF ; 39
KnuxAni_Transform: dc.b 2,$EB,$EB,$EC,$ED,$EC,$ED,$EC,$ED,$EC,$ED,$EC,$ED; 0 ; ...
dc.b $FD, 0, 0 ; 13
; =============== S U B R O U T I N E =======================================
LoadKnucklesDynPLC:
moveq #0,d0
move.b mapping_frame(a0),d0
; End of function LoadKnucklesDynPLC
; START OF FUNCTION CHUNK FOR sub_333D66
LoadKnucklesDynPLC_Part2:
cmp.b ($FFFFF766).w,d0
beq.w return_31753E
move.b d0,($FFFFF766).w
lea (SK_PLC_Knuckles).l,a2 ; SK_PLC_Knuckles
add.w d0,d0
add.w (a2,d0.w),a2
move.w (a2)+,d5
subq.w #1,d5
bmi.w return_31753E
move.w #tiles_to_bytes(ArtTile_ArtUnc_Knuckles),d4
; loc_1B86E:
KPLC_ReadEntry:
moveq #0,d1
move.w (a2)+,d1
move.w d1,d3
lsr.w #8,d3
andi.w #$F0,d3
addi.w #$10,d3
andi.w #$FFF,d1
lsl.l #5,d1
addi.l #SK_ArtUnc_Knux,d1
move.w d4,d2
add.w d3,d4
add.w d3,d4
jsr (QueueDMATransfer).l
dbf d5,KPLC_ReadEntry ; repeat for number of entries
return_31753E:
rts
; END OF FUNCTION CHUNK FOR sub_333D66
; =============== S U B R O U T I N E =======================================
; Doesn't exist in S2
sub_3192E6:
move.b x_radius(a0),d0
ext.w d0
sub.w d0,d2
eor.w #$F,d2
lea ($FFFFF768).w,a4
move.w #-$10,a3
move.w #$800,d6
jsr FindFloor
move.b #$80,d2
loc_319306:
bra.w loc_318FE8
; End of function sub_3192E6
; START OF FUNCTION CHUNK FOR CheckRightWallDist
loc_318FE8:
move.b ($FFFFF768).w,d3
btst #0,d3
beq.s return_318FF4
move.b d2,d3
return_318FF4:
rts
; END OF FUNCTION CHUNK FOR CheckRightWallDist
; =============== S U B R O U T I N E =======================================
sub_318FF6:
move.b x_radius(a0),d0
ext.w d0
add.w d0,d2
lea ($FFFFF768).w,a4
move.w #$10,a3
move.w #0,d6
jsr FindFloor
move.b #0,d2
bra.s loc_318FE8
; End of function sub_318FF6
; ---------------------------------------------------------------------------
; This doesn't exist in S2...
; START OF FUNCTION CHUNK FOR sub_315C22
loc_319208:
move.b x_radius(a0),d0
ext.w d0
add.w d0,d3
lea ($FFFFF768).w,a4
move.w #$10,a3
move.w #0,d6
jsr FindWall
move.b #$C0,d2
bra.w loc_318FE8
; END OF FUNCTION CHUNK FOR sub_315C22
; ---------------------------------------------------------------------------
; START OF FUNCTION CHUNK FOR sub_315C22
loc_3193D2:
move.b x_radius(a0),d0
ext.w d0
sub.w d0,d3
eor.w #$F,d3
lea ($FFFFF768).w,a4
move.w #$FFF0,a3
move.w #$400,d6
jsr FindWall
move.b #$40,d2
bra.w loc_318FE8
; END OF FUNCTION CHUNK FOR sub_315C22
Comments