Advertisement
Guest User

Tails in sonic 1 porting code

a guest
Sep 22nd, 2013
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
XML 52.00 KB | None | 0 0
  1. ; ===========================================================================
  2. ; ---------------------------------------------------------------------------
  3. ; Object 02 - Tails
  4. ; ---------------------------------------------------------------------------
  5.  
  6. Obj02:
  7. ; ---------------------------------------------------------------------------
  8. ; Subroutine to record Tails' previous positions for invincibility stars
  9. ; ---------------------------------------------------------------------------
  10.  
  11. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  12.  
  13. ; loc_1BF38:
  14. Tails_RecordPos:
  15.     move.w  (Tails_Pos_Record_Index).w,d0
  16.     lea (Tails_Pos_Record_Buf).w,a1
  17.     lea (a1,d0.w),a1
  18.     move.w  x_pos(a0),(a1)+
  19.     move.w  y_pos(a0),(a1)+
  20.     addq.b  #4,(Tails_Pos_Record_Index+1).w
  21.  
  22.     rts
  23. ; End of subroutine Tails_RecordPos
  24.  
  25. ; ---------------------------------------------------------------------------
  26. ; Subroutine for Tails when he's underwater
  27. ; ---------------------------------------------------------------------------
  28.  
  29. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  30.  
  31. ; loc_1BF52:
  32. Tails_Water:
  33.     tst.b   (Water_flag).w  ; does level have water?
  34.     bne.s   Obj02_InWater   ; if yes, branch
  35.  
  36. return_1BF58:
  37.     rts
  38. ; ---------------------------------------------------------------------------
  39. ; loc_1BF5A:
  40. Obj02_InWater:
  41.     move.w  (Water_Level_1).w,d0
  42.     cmp.w   y_pos(a0),d0    ; is Sonic above the water?
  43.     bge.s   Obj02_OutWater  ; if yes, branch
  44.  
  45.     bset    #6,status(a0)   ; set underwater flag
  46.     bne.s   return_1BF58    ; if already underwater, branch
  47.  
  48.     movea.l a0,a1
  49.     bsr.w   ResumeMusic
  50.     move.b  #$A,(Object_RAM+$20C0).w ; load Obj0A (tail's breathing bubbles) at $FFFFD0C0
  51.     move.b  #$81,(Object_RAM+$20C0+subtype).w
  52.     move.l  a0,(Object_RAM+$20C0+$3C).w ; set its parent to be this (obj0A uses $3C instead of $3E for some reason)
  53.     move.w  #$300,(Tails_top_speed).w
  54.     move.w  #6,(Tails_acceleration).w
  55.     move.w  #$40,(Tails_deceleration).w
  56.     asr x_vel(a0)
  57.     asr y_vel(a0)
  58.     asr y_vel(a0)
  59.     beq.s   return_1BF58
  60.     move.w  #$100,(Tails_Dust+anim).w   ; splash animation
  61.     move.w  #$2A+$80,d0 ; splash sound
  62.     jmp (PlaySound).l
  63. ; ---------------------------------------------------------------------------
  64. ; loc_1BFB2:
  65. Obj02_OutWater:
  66.     bclr    #6,status(a0)   ; unset underwater flag
  67.     beq.s   return_1BF58    ; if already above water, branch
  68.  
  69.     movea.l a0,a1
  70.     bsr.w   ResumeMusic
  71.     move.w  #$600,(Tails_top_speed).w
  72.     move.w  #$C,(Tails_acceleration).w
  73.     move.w  #$80,(Tails_deceleration).w
  74.  
  75.     cmpi.b  #4,routine(a0)  ; is Tails falling back from getting hurt?
  76.     beq.s   +       ; if yes, branch
  77.     asl y_vel(a0)
  78. +
  79.     tst.w   y_vel(a0)
  80.     beq.w   return_1BF58
  81.     move.w  #$100,(Tails_Dust+anim).w   ; splash animation
  82.     movea.l a0,a1
  83.     bsr.w   ResumeMusic
  84.     cmpi.w  #-$1000,y_vel(a0)
  85.     bgt.s   +
  86.     move.w  #-$1000,y_vel(a0)   ; limit upward y velocity exiting the water
  87. +
  88.     move.w  #$2A+$80,d0 ; splash sound
  89.     jmp (PlaySound).l
  90. ; End of subroutine Tails_Water
  91.  
  92. ; ===========================================================================
  93. ; ---------------------------------------------------------------------------
  94. ; Modes for controlling Tails
  95. ; ---------------------------------------------------------------------------
  96.  
  97. Obj02_MdNormal:
  98.     bsr.w   Tails_Spindash
  99.     bsr.w   Tails_Jump
  100.     bsr.w   Tails_SlopeResist
  101.     bsr.w   Tails_Move
  102.     bsr.w   Tails_Roll
  103.     bsr.w   Tails_LevelBound
  104.     jsr ObjectMove
  105.     bsr.w   AnglePos
  106.     bsr.w   Tails_SlopeRepel
  107.     rts
  108. ; End of subroutine Obj02_MdNormal
  109. ============================================================================
  110.  
  111. Obj02_MdJump:
  112.     bsr.w   Tails_JumpHeight
  113.     bsr.w   Tails_ChgJumpDir
  114.     bsr.w   Tails_LevelBound
  115.     jsr ObjectMoveAndFall
  116.     btst    #6,status(a0)   ; is Tails underwater?
  117.     beq.s   +       ; if not, branch
  118.     subi.w  #$28,y_vel(a0)  ; reduce gravity by $28 ($38-$28=$10)
  119. +
  120.     bsr.w   Tails_JumpAngle
  121.     bsr.w   Tails_DoLevelCollision
  122.     rts
  123. ; End of subroutine Obj02_MdJump
  124.  
  125. ; ---------------------------------------------------------------------------
  126. ; Subroutine to make Tails walk/run
  127. ; ---------------------------------------------------------------------------
  128.  
  129. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  130.  
  131. ; loc_1C0AC:
  132. Tails_Move:
  133.     move.w  (Tails_top_speed).w,d6
  134.     move.w  (Tails_acceleration).w,d5
  135.     move.w  (Tails_deceleration).w,d4
  136.     tst.b   status_secondary(a0)
  137.     bmi.w   Obj02_Traction
  138.     tst.w   move_lock(a0)
  139.     bne.w   Obj02_ResetScr
  140.     btst    #2,(Ctrl_2_Held_Logical).w  ; is left being pressed?
  141.     beq.s   Obj02_NotLeft           ; if not, branch
  142.     bsr.w   Tails_MoveLeft
  143. ; loc_1C0D4:
  144. Obj02_NotLeft:
  145.     btst    #3,(Ctrl_2_Held_Logical).w  ; is right being pressed?
  146.     beq.s   Obj02_NotRight          ; if not, branch
  147.     bsr.w   Tails_MoveRight
  148. ; loc_1C0E0:
  149. Obj02_NotRight:
  150.     move.b  angle(a0),d0
  151.     addi.b  #$20,d0
  152.     andi.b  #$C0,d0     ; is Tails on a slope?
  153.     bne.w   Obj02_ResetScr  ; if yes, branch
  154.     tst.w   inertia(a0) ; is Tails moving?
  155.     bne.w   Obj02_ResetScr  ; if yes, branch
  156.     bclr    #5,status(a0)
  157.     move.b  #5,anim(a0) ; use "standing" animation
  158.     btst    #3,status(a0)
  159.     beq.s   Tails_Balance
  160.     moveq   #0,d0
  161.     move.b  interact(a0),d0
  162.     lsl.w   #6,d0
  163.     lea (MainCharacter).w,a1 ; a1=character
  164.     lea (a1,d0.w),a1 ; a1=object
  165.     tst.b   status(a1)
  166.     bmi.s   Tails_Lookup
  167.     moveq   #0,d1
  168.     move.b  width_pixels(a1),d1
  169.     move.w  d1,d2
  170.     add.w   d2,d2
  171.     subq.w  #4,d2
  172.     add.w   x_pos(a0),d1
  173.     sub.w   x_pos(a1),d1
  174.     cmpi.w  #4,d1
  175.     blt.s   Tails_BalanceOnObjLeft
  176.     cmp.w   d2,d1
  177.     bge.s   Tails_BalanceOnObjRight
  178.     bra.s   Tails_Lookup
  179. ; ---------------------------------------------------------------------------
  180. ; balancing checks for Tails
  181. ; loc_1C142:
  182. Tails_Balance:
  183.     jsr (ChkFloorEdge).l
  184.     cmpi.w  #$C,d1
  185.     blt.s   Tails_Lookup
  186.     cmpi.b  #3,next_tilt(a0)
  187.     bne.s   Tails_BalanceLeft
  188. ; loc_1C156:
  189. Tails_BalanceOnObjRight:
  190.     bclr    #0,status(a0)
  191.     bra.s   Tails_BalanceDone
  192. ; ---------------------------------------------------------------------------
  193. ; loc_1C15E:
  194. Tails_BalanceLeft:
  195.     cmpi.b  #3,tilt(a0)
  196.     bne.s   Tails_Lookup
  197. ; loc_1C166:
  198. Tails_BalanceOnObjLeft:
  199.     bset    #0,status(a0)
  200. ; loc_1C16C:
  201. Tails_BalanceDone:
  202.     move.b  #6,anim(a0)
  203.     bra.s   Obj02_ResetScr
  204. ; ---------------------------------------------------------------------------
  205. ; loc_1C174:
  206. Tails_Lookup:
  207.     btst    #0,(Ctrl_2_Held_Logical).w  ; is up being pressed?
  208.     beq.s   Tails_Duck          ; if not, branch
  209.     move.b  #7,anim(a0)         ; use "looking up" animation
  210.     addq.w  #1,(Tails_Look_delay_counter).w
  211.     cmpi.w  #$78,(Tails_Look_delay_counter).w
  212.     bcs.s   Obj02_ResetScr_Part2
  213.     move.w  #$78,(Tails_Look_delay_counter).w
  214.     cmpi.w  #$C8,(Camera_Y_pos_bias_2P).w
  215.     beq.s   Obj02_UpdateSpeedOnGround
  216.     addq.w  #2,(Camera_Y_pos_bias_2P).w
  217.     bra.s   Obj02_UpdateSpeedOnGround
  218. ; ---------------------------------------------------------------------------
  219. ; loc_1C1A2:
  220. Tails_Duck:
  221.     btst    #1,(Ctrl_2_Held_Logical).w  ; is down being pressed?
  222.     beq.s   Obj02_ResetScr          ; if not, branch
  223.     move.b  #8,anim(a0)         ; use "ducking" animation
  224.     addq.w  #1,(Tails_Look_delay_counter).w
  225.     cmpi.w  #$78,(Tails_Look_delay_counter).w
  226.     bcs.s   Obj02_ResetScr_Part2
  227.     move.w  #$78,(Tails_Look_delay_counter).w
  228.     cmpi.w  #8,(Camera_Y_pos_bias_2P).w
  229.     beq.s   Obj02_UpdateSpeedOnGround
  230.     subq.w  #2,(Camera_Y_pos_bias_2P).w
  231.     bra.s   Obj02_UpdateSpeedOnGround
  232.  
  233. ; ===========================================================================
  234. ; moves the screen back to its normal position after looking up or down
  235. ; loc_1C1D0:
  236. Obj02_ResetScr:
  237.     move.w  #0,(Tails_Look_delay_counter).w
  238. ; loc_1C1D6:
  239. Obj02_ResetScr_Part2:
  240.     cmpi.w  #$60,(Camera_Y_pos_bias_2P).w   ; is screen in its default position?
  241.     beq.s   Obj02_UpdateSpeedOnGround   ; if yes, branch.
  242.     bcc.s   +               ; depending on the sign of the difference,
  243.     addq.w  #4,(Camera_Y_pos_bias_2P).w ; either add 2
  244. +   subq.w  #2,(Camera_Y_pos_bias_2P).w ; or subtract 2
  245.  
  246. ; ---------------------------------------------------------------------------
  247. ; updates Tails' speed on the ground
  248. ; ---------------------------------------------------------------------------
  249. ; loc_1C1E8:
  250. Obj02_UpdateSpeedOnGround:
  251.     move.b  (Ctrl_2_Held_Logical).w,d0
  252.     andi.b  #$C,d0      ; is left/right pressed?
  253.     bne.s   Obj02_Traction  ; if yes, branch
  254.     move.w  inertia(a0),d0
  255.     beq.s   Obj02_Traction
  256.     bmi.s   Obj02_SettleLeft
  257.  
  258. ; slow down when facing right and not pressing a direction
  259. ; Obj02_SettleRight:
  260.     sub.w   d5,d0
  261.     bcc.s   +
  262.     move.w  #0,d0
  263. +
  264.     move.w  d0,inertia(a0)
  265.     bra.s   Obj02_Traction
  266. ; ---------------------------------------------------------------------------
  267. ; slow down when facing left and not pressing a direction
  268. ; loc_1C208:
  269. Obj02_SettleLeft:
  270.     add.w   d5,d0
  271.     bcc.s   +
  272.     move.w  #0,d0
  273. +
  274.     move.w  d0,inertia(a0)
  275.  
  276. ; increase or decrease speed on the ground
  277. ; loc_1C214:
  278. Obj02_Traction:
  279.     move.b  angle(a0),d0
  280.     jsr (CalcSine).l
  281.     muls.w  inertia(a0),d1
  282.     asr.l   #8,d1
  283.     move.w  d1,x_vel(a0)
  284.     muls.w  inertia(a0),d0
  285.     asr.l   #8,d0
  286.     move.w  d0,y_vel(a0)
  287.  
  288. ; stops Tails from running through walls that meet the ground
  289. ; loc_1C232:
  290. Obj02_CheckWallsOnGround:
  291.     move.b  angle(a0),d0
  292.     addi.b  #$40,d0
  293.     bmi.s   return_1C2A2
  294.     move.b  #$40,d1
  295.     tst.w   inertia(a0)
  296.     beq.s   return_1C2A2
  297.     bmi.s   +
  298.     neg.w   d1
  299. +
  300.     move.b  angle(a0),d0
  301.     add.b   d1,d0
  302.     move.w  d0,-(sp)
  303.     bsr.w   CalcRoomInFront
  304.     move.w  (sp)+,d0
  305.     tst.w   d1
  306.     bpl.s   return_1C2A2
  307.     asl.w   #8,d1
  308.     addi.b  #$20,d0
  309.     andi.b  #$C0,d0
  310.     beq.s   loc_1C29E
  311.     cmpi.b  #$40,d0
  312.     beq.s   loc_1C28C
  313.     cmpi.b  #$80,d0
  314.     beq.s   loc_1C286
  315.     add.w   d1,x_vel(a0)
  316.     bset    #5,status(a0)
  317.     move.w  #0,inertia(a0)
  318.     rts
  319. ; ---------------------------------------------------------------------------
  320.  
  321. loc_1C286:
  322.     sub.w   d1,y_vel(a0)
  323.     rts
  324. ; ---------------------------------------------------------------------------
  325.  
  326. loc_1C28C:
  327.     sub.w   d1,x_vel(a0)
  328.     bset    #5,status(a0)
  329.     move.w  #0,inertia(a0)
  330.     rts
  331. ; ---------------------------------------------------------------------------
  332. loc_1C29E:
  333.     add.w   d1,y_vel(a0)
  334.  
  335. return_1C2A2:
  336.     rts
  337. ; End of subroutine Tails_Move
  338.  
  339.  
  340. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  341.  
  342. ; loc_1C2A4:
  343. Tails_MoveLeft:
  344.     move.w  inertia(a0),d0
  345.     beq.s   +
  346.     bpl.s   Tails_TurnLeft  ; if Tails is already moving to the right, branch
  347. +
  348.     bset    #0,status(a0)
  349.     bne.s   +
  350.     bclr    #5,status(a0)
  351.     move.b  #1,next_anim(a0)
  352. +
  353.     sub.w   d5,d0   ; add acceleration to the left
  354.     move.w  d6,d1
  355.     neg.w   d1
  356.     cmp.w   d1,d0   ; compare new speed with top speed
  357.     bgt.s   +   ; if new speed is less than the maximum, branch
  358.     add.w   d5,d0   ; remove this frame's acceleration change
  359.     cmp.w   d1,d0   ; compare speed with top speed
  360.     ble.s   +   ; if speed was already greater than the maximum, branch
  361.     move.w  d1,d0   ; limit speed on ground going left
  362. +
  363.     move.w  d0,inertia(a0)
  364.     move.b  #0,anim(a0) ; use walking animation
  365.     rts
  366. ; ---------------------------------------------------------------------------
  367. ; loc_1C2DE:
  368. Tails_TurnLeft:
  369.     sub.w   d4,d0
  370.     bcc.s   +
  371.     move.w  #-$80,d0
  372. +
  373.     move.w  d0,inertia(a0)
  374.     move.b  angle(a0),d0
  375.     addi.b  #$20,d0
  376.     andi.b  #$C0,d0
  377.     bne.s   return_1C328
  378.     cmpi.w  #$400,d0
  379.     blt.s   return_1C328
  380.     move.b  #$D,anim(a0)    ; use "stopping" animation
  381.     bclr    #0,status(a0)
  382.     move.w  #$A4,d0
  383.     jsr (PlaySound).l
  384.     cmpi.b  #$C,air_left(a0)
  385.     bcs.s   return_1C328    ; if he's drowning, branch to not make dust
  386.     move.b  #6,(Tails_Dust+routine).w
  387.     move.b  #$15,(Tails_Dust+mapping_frame).w
  388.  
  389. return_1C328:
  390.     rts
  391. ; End of subroutine Tails_MoveLeft
  392.  
  393.  
  394. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  395.  
  396. ; loc_1C32A:
  397. Tails_MoveRight:
  398.     move.w  inertia(a0),d0
  399.     bmi.s   Tails_TurnRight
  400.     bclr    #0,status(a0)
  401.     beq.s   +
  402.     bclr    #5,status(a0)
  403.     move.b  #1,next_anim(a0)
  404. +
  405.     add.w   d5,d0   ; add acceleration to the right
  406.     cmp.w   d6,d0   ; compare new speed with top speed
  407.     blt.s   +   ; if new speed is less than the maximum, branch
  408.     sub.w   d5,d0   ; remove this frame's acceleration change
  409.     cmp.w   d6,d0   ; compare speed with top speed
  410.     bge.s   +   ; if speed was already greater than the maximum, branch
  411.     move.w  d6,d0   ; limit speed on ground going right
  412. +
  413.     move.w  d0,inertia(a0)
  414.     move.b  #0,anim(a0) ; use walking animation
  415.     rts
  416. ; ---------------------------------------------------------------------------
  417. ; loc_1C35E:
  418. Tails_TurnRight:
  419.     add.w   d4,d0
  420.     bcc.s   +
  421.     move.w  #$80,d0
  422. +
  423.     move.w  d0,inertia(a0)
  424.     move.b  angle(a0),d0
  425.     addi.b  #$20,d0
  426.     andi.b  #$C0,d0
  427.     bne.s   return_1C3A8
  428.     cmpi.w  #-$400,d0
  429.     bgt.s   return_1C3A8
  430.     move.b  #$D,anim(a0)    ; use "stopping" animation
  431.     bset    #0,status(a0)
  432.     move.w  #$24+$80,d0 ; use "stopping" sound
  433.     jsr (PlaySound).l
  434.     cmpi.b  #$C,air_left(a0)
  435.     bcs.s   return_1C3A8    ; if he's drowning, branch to not make dust
  436.     move.b  #6,(Tails_Dust+routine).w
  437.     move.b  #$15,(Tails_Dust+mapping_frame).w
  438.  
  439. return_1C3A8:
  440.     rts
  441. ; End of subroutine Tails_MoveRight
  442.  
  443. ; ---------------------------------------------------------------------------
  444. ; Subroutine to change Tails' speed as he rolls
  445. ; ---------------------------------------------------------------------------
  446.  
  447. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  448.  
  449. ; loc_1C3AA:
  450. Tails_RollSpeed:
  451.     move.w  (Tails_top_speed).w,d6
  452.     asl.w   #1,d6
  453.     move.w  (Tails_acceleration).w,d5
  454.     asr.w   #1,d5   ; natural roll deceleration = 1/2 normal acceleration
  455.     move.w  (Tails_deceleration).w,d4
  456.     asr.w   #2,d4   ; controlled roll deceleration...
  457.             ; interestingly, Tails is much worse at this than Sonic when underwater
  458.     tst.b   status_secondary(a0)
  459.     bmi.w   Obj02_Roll_ResetScr
  460.     tst.w   move_lock(a0)
  461.     bne.s   Tails_ApplyRollSpeed
  462.     btst    #2,(Ctrl_2_Held_Logical).w  ; is left being pressed?
  463.     beq.s   +               ; if not, branch
  464.     bsr.w   Tails_RollLeft
  465. +
  466.     btst    #3,(Ctrl_2_Held_Logical).w  ; is right being pressed?
  467.     beq.s   Tails_ApplyRollSpeed        ; if not, branch
  468.     bsr.w   Tails_RollRight
  469.  
  470. ; loc_1C3E2:
  471. Tails_ApplyRollSpeed:
  472.     move.w  inertia(a0),d0
  473.     beq.s   Tails_CheckRollStop
  474.     bmi.s   Tails_ApplyRollSpeedLeft
  475.  
  476. ; Tails_ApplyRollSpeedRight:
  477.     sub.w   d5,d0
  478.     bcc.s   +
  479.     move.w  #0,d0
  480. +
  481.     move.w  d0,inertia(a0)
  482.     bra.s   Tails_CheckRollStop
  483. ; ---------------------------------------------------------------------------
  484. ; loc_1C3F8:
  485. Tails_ApplyRollSpeedLeft:
  486.     add.w   d5,d0
  487.     bcc.s   +
  488.     move.w  #0,d0
  489. +
  490.     move.w  d0,inertia(a0)
  491.  
  492. ; loc_1C404
  493. Tails_CheckRollStop:
  494.     tst.w   inertia(a0)
  495.     bne.s   Obj02_Roll_ResetScr
  496.     tst.b   spindash_flag(a0)  ; note: the spindash flag has a different meaning when Tails is already rolling -- it's used to mean he's not allowed to stop rolling
  497.     bne.s   Tails_KeepRolling
  498.     bclr    #2,status(a0)
  499.     move.b  #$F,y_radius(a0) ; sets standing height to only slightly higher than rolling height, unlike Sonic
  500.     move.b  #9,x_radius(a0)
  501.     move.b  #5,anim(a0)
  502.     subq.w  #1,y_pos(a0)
  503.     bra.s   Obj02_Roll_ResetScr
  504.  
  505. ; ---------------------------------------------------------------------------
  506. ; magically gives Tails an extra push if he's going to stop rolling where it's not allowed
  507. ; (such as in an S-curve in HTZ or a stopper chamber in CNZ)
  508. ; loc_1C42E:
  509. Tails_KeepRolling:
  510.     move.w  #$400,inertia(a0)
  511.     btst    #0,status(a0)
  512.     beq.s   Obj02_Roll_ResetScr
  513.     neg.w   inertia(a0)
  514.  
  515. ; resets the screen to normal while rolling, like Obj02_ResetScr
  516. ; loc_1C440:
  517. Obj02_Roll_ResetScr:
  518.     cmpi.w  #$60,(Camera_Y_pos_bias_2P).w   ; is screen in its default position?
  519.     beq.s   Tails_SetRollSpeed      ; if yes, branch
  520.     bcc.s   +               ; depending on the sign of the difference,
  521.     addq.w  #4,(Camera_Y_pos_bias_2P).w ; either add 2
  522. +   subq.w  #2,(Camera_Y_pos_bias_2P).w ; or subtract 2
  523.  
  524. ; loc_1C452:
  525. Tails_SetRollSpeed:
  526.     move.b  angle(a0),d0
  527.     jsr (CalcSine).l
  528.     muls.w  inertia(a0),d0
  529.     asr.l   #8,d0
  530.     move.w  d0,y_vel(a0)    ; set y velocity based on $14 and angle
  531.     muls.w  inertia(a0),d1
  532.     asr.l   #8,d1
  533.     cmpi.w  #$1000,d1
  534.     ble.s   +
  535.     move.w  #$1000,d1   ; limit Tails' speed rolling right
  536. +
  537.     cmpi.w  #-$1000,d1
  538.     bge.s   +
  539.     move.w  #-$1000,d1  ; limit Tails' speed rolling left
  540. +
  541.     move.w  d1,x_vel(a0)    ; set x velocity based on $14 and angle
  542.     bra.w   Obj02_CheckWallsOnGround
  543. ; End of function Tails_RollSpeed
  544.  
  545.  
  546. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  547.  
  548.  
  549. ; loc_1C488:
  550. Tails_RollLeft:
  551.     move.w  inertia(a0),d0
  552.     beq.s   +
  553.     bpl.s   Tails_BrakeRollingRight
  554. +
  555.     bset    #0,status(a0)
  556.     move.b  #2,anim(a0) ; use "rolling" animation
  557.     rts
  558. ; ---------------------------------------------------------------------------
  559. ; loc_1C49E:
  560. Tails_BrakeRollingRight:
  561.     sub.w   d4,d0   ; reduce rightward rolling speed
  562.     bcc.s   +
  563.     move.w  #-$80,d0
  564. +
  565.     move.w  d0,inertia(a0)
  566.     rts
  567. ; End of function Tails_RollLeft
  568.  
  569.  
  570. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  571.  
  572.  
  573. ; loc_1C4AC:
  574. Tails_RollRight:
  575.     move.w  inertia(a0),d0
  576.     bmi.s   Tails_BrakeRollingLeft
  577.     bclr    #0,status(a0)
  578.     move.b  #2,anim(a0) ; use "rolling" animation
  579.     rts
  580. ; ---------------------------------------------------------------------------
  581. ; loc_1C4C0:
  582. Tails_BrakeRollingLeft:
  583.     add.w   d4,d0       ; reduce leftward rolling speed
  584.     bcc.s   +
  585.     move.w  #$80,d0
  586. +
  587.     move.w  d0,inertia(a0)
  588.     rts
  589. ; End of subroutine Tails_RollRight
  590.  
  591.  
  592. ; ---------------------------------------------------------------------------
  593. ; Subroutine for moving Tails left or right when he's in the air
  594. ; ---------------------------------------------------------------------------
  595.  
  596. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  597.  
  598. ; loc_1C4CE:
  599. Tails_ChgJumpDir:
  600.     move.w  (Tails_top_speed).w,d6
  601.     move.w  (Tails_acceleration).w,d5
  602.     asl.w   #1,d5
  603.     btst    #4,status(a0)       ; did Tails jump from rolling?
  604.     bne.s   Obj02_Jump_ResetScr ; if yes, branch to skip midair control
  605.     move.w  x_vel(a0),d0
  606.     btst    #2,(Ctrl_2_Held_Logical).w
  607.     beq.s   +   ; if not holding left, branch
  608.  
  609.     bset    #0,status(a0)
  610.     sub.w   d5,d0   ; add acceleration to the left
  611.     move.w  d6,d1
  612.     neg.w   d1
  613.     cmp.w   d1,d0   ; compare new speed with top speed
  614.     bgt.s   +   ; if new speed is less than the maximum, branch
  615.     move.w  d1,d0   ; limit speed in air going left, even if Tails was already going faster (speed limit/cap)
  616. +
  617.     btst    #3,(Ctrl_2_Held_Logical).w
  618.     beq.s   +   ; if not holding right, branch
  619.  
  620.     bclr    #0,status(a0)
  621.     add.w   d5,d0   ; accelerate right in the air
  622.     cmp.w   d6,d0   ; compare new speed with top speed
  623.     blt.s   +   ; if new speed is less than the maximum, branch
  624.     move.w  d6,d0   ; limit speed in air going right, even if Tails was already going faster (speed limit/cap)
  625. ; Obj02_JumpMove:
  626. +   move.w  d0,x_vel(a0)
  627.  
  628. ; loc_1C518: Obj02_ResetScr2:
  629. Obj02_Jump_ResetScr:
  630.     cmpi.w  #$60,(Camera_Y_pos_bias_2P).w   ; is screen in its default position?
  631.     beq.s   Tails_JumpPeakDecelerate            ; if yes, branch
  632.     bcc.s   +               ; depending on the sign of the difference,
  633.     addq.w  #4,(Camera_Y_pos_bias_2P).w ; either add 2
  634. +   subq.w  #2,(Camera_Y_pos_bias_2P).w ; or subtract 2
  635.  
  636. ; loc_1C52A:
  637. Tails_JumpPeakDecelerate:
  638.     cmpi.w  #-$400,y_vel(a0)    ; is Tails moving faster than -$400 upwards?
  639.     bcs.s   return_1C558        ; if yes, return
  640.     move.w  x_vel(a0),d0
  641.     move.w  d0,d1
  642.     asr.w   #5,d1       ; d1 = x_velocity / 32
  643.     beq.s   return_1C558    ; return if d1 is 0
  644.     bmi.s   Tails_JumpPeakDecelerateLeft
  645.  
  646. ; Tails_JumpPeakDecelerateRight:
  647.     sub.w   d1,d0   ; reduce x velocity by d1
  648.     bcc.s   +
  649.     move.w  #0,d0
  650. +
  651.     move.w  d0,x_vel(a0)
  652.     rts
  653. ; ---------------------------------------------------------------------------
  654. ; loc_1C54C:
  655. Tails_JumpPeakDecelerateLeft:
  656.     sub.w   d1,d0   ; reduce x velocity by d1
  657.     bcs.s   +
  658.     move.w  #0,d0
  659. +
  660.     move.w  d0,x_vel(a0)
  661.  
  662. return_1C558:
  663.     rts
  664. ; End of subroutine Tails_ChgJumpDir
  665. ; ===========================================================================
  666.  
  667. ; ---------------------------------------------------------------------------
  668. ; Subroutine to prevent Tails from leaving the boundaries of a level
  669. ; ---------------------------------------------------------------------------
  670.  
  671. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  672.  
  673. ; loc_1C55A:
  674. Tails_LevelBound:
  675.     move.l  x_pos(a0),d1
  676.     move.w  x_vel(a0),d0
  677.     ext.l   d0
  678.     asl.l   #8,d0
  679.     add.l   d0,d1
  680.     swap    d1
  681.     move.w  (Tails_Min_X_pos).w,d0
  682.     addi.w  #$10,d0
  683.     cmp.w   d1,d0           ; has Tails touched the left boundary?
  684.     bhi.s   Tails_Boundary_Sides    ; if yes, branch
  685.     move.w  (Tails_Max_X_pos).w,d0
  686.     addi.w  #$128,d0
  687.     tst.b   (Current_Boss_ID).w
  688.     bne.s   +
  689.     addi.w  #$40,d0
  690. +
  691.     cmp.w   d1,d0           ; has Tails touched the right boundary?
  692.     bls.s   Tails_Boundary_Sides    ; if yes, branch
  693.  
  694. ; loc_1C58C:
  695. Tails_Boundary_CheckBottom:
  696.     move.w  (Tails_Max_Y_pos).w,d0
  697.     addi.w  #$E0,d0
  698.     cmp.w   y_pos(a0),d0        ; has Tails touched the bottom boundary?
  699.     blt.s   Tails_Boundary_Bottom   ; if yes, branch
  700.     rts
  701. ; ---------------------------------------------------------------------------
  702. Tails_Boundary_Bottom: ;;
  703.     bra.w   JmpTo2_KillCharacter
  704. ; ===========================================================================
  705.  
  706. ; loc_1C5A0:
  707. Tails_Boundary_Sides:
  708.     move.w  d0,x_pos(a0)
  709.     move.w  #0,2+x_pos(a0) ; subpixel x
  710.     move.w  #0,x_vel(a0)
  711.     move.w  #0,inertia(a0)
  712.     bra.s   Tails_Boundary_CheckBottom
  713. ; ===========================================================================
  714.  
  715. ; ---------------------------------------------------------------------------
  716. ; Subroutine allowing Tails to start rolling when he's moving
  717. ; ---------------------------------------------------------------------------
  718.  
  719. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  720.  
  721. ; loc_1C5B8:
  722. Tails_Roll:
  723.     tst.b   status_secondary(a0)
  724.     bmi.s   Obj02_NoRoll
  725.     move.w  inertia(a0),d0
  726.     bpl.s   +
  727.     neg.w   d0
  728. +
  729.     cmpi.w  #$80,d0     ; is Tails moving at $80 speed or faster?
  730.     bcs.s   Obj02_NoRoll    ; if not, branch
  731.     move.b  (Ctrl_2_Held_Logical).w,d0
  732.     andi.b  #$C,d0      ; is left/right being pressed?
  733.     bne.s   Obj02_NoRoll    ; if yes, branch
  734.     btst    #1,(Ctrl_2_Held_Logical).w  ; is down being pressed?
  735.     bne.s   Obj02_ChkRoll           ; if yes, branch
  736. ; return_1C5DE:
  737. Obj02_NoRoll:
  738.     rts
  739.  
  740. ; ---------------------------------------------------------------------------
  741. ; loc_1C5E0:
  742. Obj02_ChkRoll:
  743.     btst    #2,status(a0)   ; is Tails already rolling?
  744.     beq.s   Obj02_DoRoll    ; if not, branch
  745.     rts
  746.  
  747. ; ---------------------------------------------------------------------------
  748. ; loc_1C5EA:
  749. Obj02_DoRoll:
  750.     bset    #2,status(a0)
  751.     move.b  #$E,y_radius(a0)
  752.     move.b  #7,x_radius(a0)
  753.     move.b  #2,anim(a0) ; use "rolling" animation
  754.     addq.w  #1,y_pos(a0)
  755.     move.w  #$BE,d0
  756.     jsr (PlaySound).l   ; play rolling sound
  757.     tst.w   inertia(a0)
  758.     bne.s   return_1C61C
  759.     move.w  #$200,inertia(a0)
  760.  
  761. return_1C61C:
  762.     rts
  763. ; End of function Tails_Roll
  764.  
  765.  
  766. ; ---------------------------------------------------------------------------
  767. ; Subroutine allowing Tails to jump
  768. ; ---------------------------------------------------------------------------
  769.  
  770. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  771.  
  772. ; loc_1C61E:
  773. Tails_Jump:
  774.     move.b  (Ctrl_2_Press_Logical).w,d0
  775.     andi.b  #$70,d0     ; is A, B or C pressed?
  776.     beq.w   return_1C6C2    ; if not, return
  777.     moveq   #0,d0
  778.     move.b  angle(a0),d0
  779.     addi.b  #$80,d0
  780.     bsr.w   CalcRoomOverHead
  781.     cmpi.w  #6,d1       ; does Tails have enough room to jump?
  782.     blt.w   return_1C6C2    ; if not, branch
  783.     move.w  #$680,d2
  784.     btst    #6,status(a0)   ; Test if underwater
  785.     beq.s   +
  786.     move.w  #$380,d2    ; set lower jump speed if underwater
  787. +
  788.     moveq   #0,d0
  789.     move.b  angle(a0),d0
  790.     subi.b  #$40,d0
  791.     jsr (CalcSine).l
  792.     muls.w  d2,d1
  793.     asr.l   #8,d1
  794.     add.w   d1,x_vel(a0)    ; make Tails jump (in X... this adds nothing on level ground)
  795.     muls.w  d2,d0
  796.     asr.l   #8,d0
  797.     add.w   d0,y_vel(a0)    ; make Tails jump (in Y)
  798.     bset    #1,status(a0)
  799.     bclr    #5,status(a0)
  800.     addq.l  #4,sp
  801.     move.b  #1,jumping(a0)
  802.     clr.b   stick_to_convex(a0)
  803.     move.w  #$A0,d0
  804.     jsr (PlaySound).l   ; play jumping sound
  805.     move.b  #$F,y_radius(a0)
  806.     move.b  #9,x_radius(a0)
  807.     btst    #2,status(a0)
  808.     bne.s   Tails_RollJump
  809.     move.b  #$E,y_radius(a0)
  810.     move.b  #7,x_radius(a0)
  811.     move.b  #2,anim(a0) ; use "jumping" animation
  812.     bset    #2,status(a0)
  813.     addq.w  #1,y_pos(a0)
  814.  
  815. return_1C6C2:
  816.     rts
  817. ; ---------------------------------------------------------------------------
  818. ; loc_1C6C4:
  819. Tails_RollJump:
  820.     bset    #4,status(a0) ; set the rolling+jumping flag
  821.     rts
  822. ; End of function Tails_Jump
  823.  
  824.  
  825. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  826.  
  827. ; ===========================================================================
  828. ; loc_1C6CC:
  829. Tails_JumpHeight:
  830.     tst.b   jumping(a0) ; is Tails jumping?
  831.     beq.s   Tails_UpVelCap  ; if not, branch
  832.  
  833.     move.w  #-$400,d1
  834.     btst    #6,status(a0)   ; is Tails underwater?
  835.     beq.s   +       ; if not, branch
  836.     move.w  #-$200,d1
  837. +
  838.     cmp.w   y_vel(a0),d1    ; is Tails going up faster than d1?
  839.     ble.s   +       ; if not, branch
  840.     move.b  (Ctrl_2_Held_Logical).w,d0
  841.     andi.b  #$70,d0     ; is a jump button pressed?
  842.     bne.s   +       ; if yes, branch
  843.     move.w  d1,y_vel(a0)    ; immediately reduce Tails's upward speed to d1
  844. +
  845.     rts
  846. ; ---------------------------------------------------------------------------
  847. ; loc_1C6F8:
  848. Tails_UpVelCap:
  849.     tst.b   spindash_flag(a0)   ; is Tails charging a spindash or in a rolling-only area?
  850.     bne.s   return_1C70C        ; if yes, return
  851.     cmpi.w  #-$FC0,y_vel(a0)    ; is Tails moving up really fast?
  852.     bge.s   return_1C70C        ; if not, return
  853.     move.w  #-$FC0,y_vel(a0)    ; cap upward speed
  854.  
  855. return_1C70C:
  856.     rts
  857. ; End of subroutine Tails_JumpHeight
  858.  
  859. ; ---------------------------------------------------------------------------
  860. ; Subrouting to update an already-charging spindash
  861. ; ---------------------------------------------------------------------------
  862.  
  863. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  864.  
  865.  
  866. Tails_SpinDash:
  867.         tst.b   $39(a0)         ; already Spin Dashing?
  868.         bne.s   loc2_1AC8E      ; if set, branch
  869.         cmpi.b  #8,$1C(a0)      ; is anim duck
  870.         bne.s   locret2_1AC8C       ; if not, return
  871.         move.b  ($FFFFF603).w,d0    ; read controller
  872.         andi.b  #$70,d0         ; pressing A/B/C ?
  873.         beq.w   locret2_1AC8C       ; if not, return
  874.         move.b  #$1F,$1C(a0)        ; set Spin Dash anim (9 in s2)
  875.         move.w  #$D1,d0         ; spin sound ($E0 in s2)
  876.         jsr (PlaySound_Special).l   ; play spin sound
  877.         addq.l  #4,sp           ; increment stack ptr
  878.         move.b  #1,$39(a0)      ; set Spin Dash flag
  879.         move.w  #0,$3A(a0)      ; set charge count to 0
  880.         cmpi.b  #$C,$28(a0)     ; ??? oxygen remaining?
  881.         move.b  #2,($FFFFD1DC).w    ; Set the Spin Dash dust animation to $2.
  882.                         ; the smoke/dust object
  883. loc2_1AC84:
  884.         bsr.w   Tails_LevelBound
  885.         bsr.w   Tails_AnglePos
  886.  
  887. locret2_1AC8C:
  888.         rts
  889. ; ---------------------------------------------------------------------------
  890.  
  891. loc2_1AC8E:
  892.                 move.b  #$1F,$1C(a0)
  893.         move.b  ($FFFFF602).w,d0    ; read controller
  894.         btst    #1,d0           ; check down button
  895.         bne.w   loc2_1AD30      ; if set, branch
  896.         move.b  #$E,$16(a0)     ; $16(a0) is height/2
  897.         move.b  #7,$17(a0)      ; $17(a0) is width/2
  898.         move.b  #2,$1C(a0)      ; set animation to roll
  899.         addq.w  #5,$C(a0)       ; $C(a0) is Y coordinate
  900.         move.b  #0,$39(a0)      ; clear Spin Dash flag
  901.         moveq   #0,d0
  902.         move.b  $3A(a0),d0      ; copy charge count
  903.         add.w   d0,d0           ; double it
  904.         move.w  Dash_Speeds(pc,d0.w),$14(a0) ; get normal speed
  905.         move.w  $14(a0),d0      ; get inertia
  906.         subi.w  #$800,d0        ; subtract $800
  907.         add.w   d0,d0           ; double it
  908.         andi.w  #$1F00,d0       ; mask it against $1F00
  909.         neg.w   d0          ; negate it
  910.         addi.w  #$2000,d0       ; add $2000
  911.         move.w  d0,($FFFFEED0).w    ; move to $EED0
  912.         btst    #0,$22(a0)      ; is sonic facing right?
  913.         beq.s   loc2_1ACF4      ; if not, branch
  914.         neg.w   $14(a0)         ; negate inertia
  915.  
  916. loc2_1ACF4:
  917.         bset    #2,$22(a0)      ; set unused (in s1) flag
  918.         move.b  #0,($FFFFD1DC).w    ; clear Spin Dash dust animation.
  919.         move.w  #$BC,d0         ; spin release sound
  920.         jsr (PlaySound_Special).l   ; play it!
  921.         bra.s   loc2_1AD78
  922. ; ===========================================================================
  923. Dash_Speeds:
  924.         dc.w  $800      ; 0
  925.         dc.w  $880      ; 1
  926.         dc.w  $900      ; 2
  927.         dc.w  $980      ; 3
  928.         dc.w  $A00      ; 4
  929.         dc.w  $A80      ; 5
  930.         dc.w  $B00      ; 6
  931.         dc.w  $B80      ; 7
  932.         dc.w  $C00      ; 8
  933. ; ===========================================================================
  934.  
  935. loc2_1AD30:             ; If still charging the dash...
  936.         tst.w   $3A(a0)     ; check charge count
  937.         beq.s   loc2_1AD48  ; if zero, branch
  938.         move.w  $3A(a0),d0  ; otherwise put it in d0
  939.         lsr.w   #5,d0       ; shift right 5 (divide it by 32)
  940.         sub.w   d0,$3A(a0)  ; subtract from charge count
  941.         bcc.s   loc2_1AD48  ; ??? branch if carry clear
  942.         move.w  #0,$3A(a0)  ; set charge count to 0
  943.  
  944. loc2_1AD48:
  945.         move.b  ($FFFFF603).w,d0    ; read controller
  946.         andi.b  #$70,d0         ; pressing A/B/C?
  947.         beq.w   loc2_1AD78      ; if not, branch
  948.         move.w  #$1F00,$1C(a0)      ; reset spdsh animation
  949.         move.w  #$D1,d0         ; was $E0 in sonic 2
  950.         jsr (PlaySound_Special).l   ; play charge sound
  951.         addi.w  #$200,$3A(a0)       ; increase charge count
  952.         cmpi.w  #$800,$3A(a0)       ; check if it's maxed
  953.         bcs.s   loc2_1AD78      ; if not, then branch
  954.         move.w  #$800,$3A(a0)       ; reset it to max
  955.  
  956. loc2_1AD78:
  957.         addq.l  #4,sp           ; increase stack ptr
  958.         cmpi.w  #$60,($FFFFF73E).w
  959.         beq.s   loc2_1AD8C
  960.         bcc.s   loc2_1AD88
  961.         addq.w  #4,($FFFFF73E).w
  962.  
  963. loc2_1AD88:
  964.         subq.w  #2,($FFFFF73E).w
  965.  
  966. loc2_1AD8C:
  967.         bsr.w   Tails_LevelBound
  968.         bsr.w   Tails_AnglePos
  969.         ;move.w #$60,($FFFFF73E).w  ; reset looking up/down
  970.         rts
  971. ; End of subroutine Tails_SpinDash
  972.  
  973. ; ---------------------------------------------------------------------------
  974. ; Subroutine to slow Tails walking up a slope
  975. ; ---------------------------------------------------------------------------
  976.  
  977. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  978.  
  979. ; loc_1C846:
  980. Tails_SlopeResist:
  981.     move.b  angle(a0),d0
  982.     addi.b  #$60,d0
  983.     cmpi.b  #$C0,d0
  984.     bcc.s   return_1C87A
  985.     move.b  angle(a0),d0
  986.     jsr (CalcSine).l
  987.     muls.w  #$20,d0
  988.     asr.l   #8,d0
  989.     tst.w   inertia(a0)
  990.     beq.s   return_1C87A
  991.     bmi.s   loc_1C876
  992.     tst.w   d0
  993.     beq.s   +
  994.     add.w   d0,inertia(a0)  ; change Tails' $14
  995. +
  996.     rts
  997. ; ---------------------------------------------------------------------------
  998.  
  999. loc_1C876:
  1000.     add.w   d0,inertia(a0)
  1001.  
  1002. return_1C87A:
  1003.     rts
  1004. ; End of subroutine Tails_SlopeResist
  1005.  
  1006. ; ---------------------------------------------------------------------------
  1007. ; Subroutine to push Tails down a slope while he's rolling
  1008. ; ---------------------------------------------------------------------------
  1009.  
  1010. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  1011.  
  1012. ; loc_1C87C:
  1013. Tails_RollRepel:
  1014.     move.b  angle(a0),d0
  1015.     addi.b  #$60,d0
  1016.     cmpi.b  #-$40,d0
  1017.     bcc.s   return_1C8B6
  1018.     move.b  angle(a0),d0
  1019.     jsr (CalcSine).l
  1020.     muls.w  #$50,d0
  1021.     asr.l   #8,d0
  1022.     tst.w   inertia(a0)
  1023.     bmi.s   loc_1C8AC
  1024.     tst.w   d0
  1025.     bpl.s   loc_1C8A6
  1026.     asr.l   #2,d0
  1027.  
  1028. loc_1C8A6:
  1029.     add.w   d0,inertia(a0)
  1030.     rts
  1031. ; ===========================================================================
  1032.  
  1033. loc_1C8AC:
  1034.     tst.w   d0
  1035.     bmi.s   loc_1C8B2
  1036.     asr.l   #2,d0
  1037.  
  1038. loc_1C8B2:
  1039.     add.w   d0,inertia(a0)
  1040.  
  1041. return_1C8B6:
  1042.     rts
  1043. ; End of function Tails_RollRepel
  1044.  
  1045. ; ---------------------------------------------------------------------------
  1046. ; Subroutine to push Tails down a slope
  1047. ; ---------------------------------------------------------------------------
  1048.  
  1049. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  1050.  
  1051. ; loc_1C8B8:
  1052. Tails_SlopeRepel:
  1053.     nop
  1054.     tst.b   stick_to_convex(a0)
  1055.     bne.s   return_1C8F2
  1056.     tst.w   move_lock(a0)
  1057.     bne.s   loc_1C8F4
  1058.     move.b  angle(a0),d0
  1059.     addi.b  #$20,d0
  1060.     andi.b  #$C0,d0
  1061.     beq.s   return_1C8F2
  1062.     move.w  inertia(a0),d0
  1063.     bpl.s   loc_1C8DC
  1064.     neg.w   d0
  1065.  
  1066. loc_1C8DC:
  1067.     cmpi.w  #$280,d0
  1068.     bcc.s   return_1C8F2
  1069.     clr.w   inertia(a0)
  1070.     bset    #1,status(a0)
  1071.     move.w  #$1E,move_lock(a0)
  1072.  
  1073. return_1C8F2:
  1074.     rts
  1075. ; ===========================================================================
  1076.  
  1077. loc_1C8F4:
  1078.     subq.w  #1,move_lock(a0)
  1079.     rts
  1080. ; End of function Tails_SlopeRepel
  1081.  
  1082. ; ---------------------------------------------------------------------------
  1083. ; Subroutine to return Tails' angle to 0 as he jumps
  1084. ; ---------------------------------------------------------------------------
  1085.  
  1086. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  1087.  
  1088. ; loc_1C8FA:
  1089. Tails_JumpAngle:
  1090.     move.b  angle(a0),d0    ; get Tails' angle
  1091.     beq.s   Tails_JumpFlip  ; if already 0, branch
  1092.     bpl.s   loc_1C90A   ; if higher than 0, branch
  1093.  
  1094.     addq.b  #2,d0       ; increase angle
  1095.     bcc.s   BranchTo_Tails_JumpAngleSet
  1096.     moveq   #0,d0
  1097.  
  1098. BranchTo_Tails_JumpAngleSet
  1099.     bra.s   Tails_JumpAngleSet
  1100. ; ===========================================================================
  1101.  
  1102. loc_1C90A:
  1103.     subq.b  #2,d0       ; decrease angle
  1104.     bcc.s   Tails_JumpAngleSet
  1105.     moveq   #0,d0
  1106.  
  1107. ; loc_1C910:
  1108. Tails_JumpAngleSet:
  1109.     move.b  d0,angle(a0)
  1110. ; End of function Tails_JumpAngle
  1111.     ; continue straight to Tails_JumpFlip
  1112.  
  1113. ; ---------------------------------------------------------------------------
  1114. ; Updates Tails' secondary angle if he's tumbling
  1115. ; ---------------------------------------------------------------------------
  1116.  
  1117. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  1118.  
  1119. ; loc_1C914:
  1120. Tails_JumpFlip:
  1121.     move.b  flip_angle(a0),d0
  1122.     beq.s   return_1C958
  1123.     tst.w   inertia(a0)
  1124.     bmi.s   Tails_JumpLeftFlip
  1125. ; loc_1C920:
  1126. Tails_JumpRightFlip:
  1127.     move.b  flip_speed(a0),d1
  1128.     add.b   d1,d0
  1129.     bcc.s   BranchTo_Tails_JumpFlipSet
  1130.     subq.b  #1,flips_remaining(a0)
  1131.     bcc.s   BranchTo_Tails_JumpFlipSet
  1132.     move.b  #0,flips_remaining(a0)
  1133.     moveq   #0,d0
  1134.  
  1135. BranchTo_Tails_JumpFlipSet
  1136.     bra.s   Tails_JumpFlipSet
  1137. ; ===========================================================================
  1138. ; loc_1C938:
  1139. Tails_JumpLeftFlip:
  1140.     tst.b   flip_turned(a0)
  1141.     bne.s   Tails_JumpRightFlip
  1142.     move.b  flip_speed(a0),d1
  1143.     sub.b   d1,d0
  1144.     bcc.s   Tails_JumpFlipSet
  1145.     subq.b  #1,flips_remaining(a0)
  1146.     bcc.s   Tails_JumpFlipSet
  1147.     move.b  #0,flips_remaining(a0)
  1148.     moveq   #0,d0
  1149. ; loc_1C954:
  1150. Tails_JumpFlipSet:
  1151.     move.b  d0,flip_angle(a0)
  1152.  
  1153. return_1C958:
  1154.     rts
  1155. ; End of function Tails_JumpFlip
  1156.  
  1157. ; ---------------------------------------------------------------------------
  1158. ; Subroutine for Tails to interact with the floor and walls when he's in the air
  1159. ; ---------------------------------------------------------------------------
  1160.  
  1161. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  1162.  
  1163. ; loc_1C95A: Tails_Floor:
  1164. Tails_DoLevelCollision:
  1165.     move.l  #Primary_Collision,(Collision_addr).w
  1166.     cmpi.b  #$C,layer(a0)
  1167.     beq.s   +
  1168.     move.l  #Secondary_Collision,(Collision_addr).w
  1169. +
  1170.     move.b  layer_plus(a0),d5
  1171.     move.w  x_vel(a0),d1
  1172.     move.w  y_vel(a0),d2
  1173.     jsr (CalcAngle).l
  1174.     subi.b  #$20,d0
  1175.     andi.b  #$C0,d0
  1176.     cmpi.b  #$40,d0
  1177.     beq.w   Tails_HitLeftWall
  1178.     cmpi.b  #$80,d0
  1179.     beq.w   Tails_HitCeilingAndWalls
  1180.     cmpi.b  #-$40,d0
  1181.     beq.w   Tails_HitRightWall
  1182.     bsr.w   CheckLeftWallDist
  1183.     tst.w   d1
  1184.     bpl.s   +
  1185.     sub.w   d1,x_pos(a0)
  1186.     move.w  #0,x_vel(a0)    ; stop Tails since he hit a wall
  1187. +
  1188.     bsr.w   CheckRightWallDist
  1189.     tst.w   d1
  1190.     bpl.s   +
  1191.     add.w   d1,x_pos(a0)
  1192.     move.w  #0,x_vel(a0)    ; stop Tails since he hit a wall
  1193. +
  1194.     bsr.w   Sonic_CheckFloor
  1195.     tst.w   d1
  1196.     bpl.s   return_1CA3A
  1197.     move.b  y_vel(a0),d2
  1198.     addq.b  #8,d2
  1199.     neg.b   d2
  1200.     cmp.b   d2,d1
  1201.     bge.s   +
  1202.     cmp.b   d2,d0
  1203.     blt.s   return_1CA3A
  1204. +
  1205.     add.w   d1,y_pos(a0)
  1206.     move.b  d3,angle(a0)
  1207.     bsr.w   Tails_ResetOnFloor
  1208.     move.b  d3,d0
  1209.     addi.b  #$20,d0
  1210.     andi.b  #$40,d0
  1211.     bne.s   loc_1CA18
  1212.     move.b  d3,d0
  1213.     addi.b  #$10,d0
  1214.     andi.b  #$20,d0
  1215.     beq.s   loc_1CA0A
  1216.     asr y_vel(a0)
  1217.     bra.s   loc_1CA2C
  1218. ; ===========================================================================
  1219.  
  1220. loc_1CA0A:
  1221.     move.w  #0,y_vel(a0)
  1222.     move.w  x_vel(a0),inertia(a0)
  1223.     rts
  1224. ; ===========================================================================
  1225.  
  1226. loc_1CA18:
  1227.     move.w  #0,x_vel(a0)    ; stop Tails since he hit a wall
  1228.     cmpi.w  #$FC0,y_vel(a0)
  1229.     ble.s   loc_1CA2C
  1230.     move.w  #$FC0,y_vel(a0)
  1231.  
  1232. loc_1CA2C:
  1233.     move.w  y_vel(a0),inertia(a0)
  1234.     tst.b   d3
  1235.     bpl.s   return_1CA3A
  1236.     neg.w   inertia(a0)
  1237.  
  1238. return_1CA3A:
  1239.     rts
  1240. ; ===========================================================================
  1241. ; loc_1CA3C:
  1242. Tails_HitLeftWall:
  1243.     bsr.w   CheckLeftWallDist
  1244.     tst.w   d1
  1245.     bpl.s   Tails_HitCeiling ; branch if distance is positive (not inside wall)
  1246.     sub.w   d1,x_pos(a0)
  1247.     move.w  #0,x_vel(a0)    ; stop Tails since he hit a wall
  1248.     move.w  y_vel(a0),inertia(a0)
  1249.     rts
  1250. ; ===========================================================================
  1251. ; loc_1CA56:
  1252. Tails_HitCeiling:
  1253.     bsr.w   CheckCeilingDist
  1254.     tst.w   d1
  1255.     bpl.s   Tails_HitFloor  ; branch if distance is positive (not inside ceiling)
  1256.     sub.w   d1,y_pos(a0)
  1257.     tst.w   y_vel(a0)
  1258.     bpl.s   return_1CA6E
  1259.     move.w  #0,y_vel(a0)    ; stop Tails in y since he hit a ceiling
  1260.  
  1261. return_1CA6E:
  1262.     rts
  1263. ; ===========================================================================
  1264. ; loc_1CA70:
  1265. Tails_HitFloor:
  1266.     tst.w   y_vel(a0)
  1267.     bmi.s   return_1CA96
  1268.     bsr.w   Sonic_CheckFloor
  1269.     tst.w   d1
  1270.     bpl.s   return_1CA96
  1271.     add.w   d1,y_pos(a0)
  1272.     move.b  d3,angle(a0)
  1273.     bsr.w   Tails_ResetOnFloor
  1274.     move.w  #0,y_vel(a0)
  1275.     move.w  x_vel(a0),inertia(a0)
  1276.  
  1277. return_1CA96:
  1278.     rts
  1279. ; ===========================================================================
  1280. ; loc_1CA98:
  1281. Tails_HitCeilingAndWalls:
  1282.     bsr.w   CheckLeftWallDist
  1283.     tst.w   d1
  1284.     bpl.s   +
  1285.     sub.w   d1,x_pos(a0)
  1286.     move.w  #0,x_vel(a0)    ; stop Tails since he hit a wall
  1287. +
  1288.     bsr.w   CheckRightWallDist
  1289.     tst.w   d1
  1290.     bpl.s   +
  1291.     add.w   d1,x_pos(a0)
  1292.     move.w  #0,x_vel(a0)    ; stop Tails since he hit a wall
  1293. +
  1294.     bsr.w   CheckCeilingDist
  1295.     tst.w   d1
  1296.     bpl.s   return_1CAF2
  1297.     sub.w   d1,y_pos(a0)
  1298.     move.b  d3,d0
  1299.     addi.b  #$20,d0
  1300.     andi.b  #$40,d0
  1301.     bne.s   loc_1CADC
  1302.     move.w  #0,y_vel(a0)    ; stop Tails in y since he hit a ceiling
  1303.     rts
  1304. ; ===========================================================================
  1305.  
  1306. loc_1CADC:
  1307.     move.b  d3,angle(a0)
  1308.     bsr.w   Tails_ResetOnFloor
  1309.     move.w  y_vel(a0),inertia(a0)
  1310.     tst.b   d3
  1311.     bpl.s   return_1CAF2
  1312.     neg.w   inertia(a0)
  1313.  
  1314. return_1CAF2:
  1315.     rts
  1316. ; ===========================================================================
  1317. ; loc_1CAF4:
  1318. Tails_HitRightWall:
  1319.     bsr.w   CheckRightWallDist
  1320.     tst.w   d1
  1321.     bpl.s   Tails_HitCeiling2
  1322.     add.w   d1,x_pos(a0)
  1323.     move.w  #0,x_vel(a0)    ; stop Tails since he hit a wall
  1324.     move.w  y_vel(a0),inertia(a0)
  1325.     rts
  1326. ; ===========================================================================
  1327. ; identical to Tails_HitCeiling...
  1328. ; loc_1CB0E:
  1329. Tails_HitCeiling2:
  1330.     bsr.w   CheckCeilingDist
  1331.     tst.w   d1
  1332.     bpl.s   Tails_HitFloor2
  1333.     sub.w   d1,y_pos(a0)
  1334.     tst.w   y_vel(a0)
  1335.     bpl.s   return_1CB26
  1336.     move.w  #0,y_vel(a0)    ; stop Tails in y since he hit a ceiling
  1337.  
  1338. return_1CB26:
  1339.     rts
  1340. ; ===========================================================================
  1341. ; identical to Tails_HitFloor...
  1342. ; loc_1CB28:
  1343. Tails_HitFloor2:
  1344.     tst.w   y_vel(a0)
  1345.     bmi.s   return_1CB4E
  1346.     bsr.w   Sonic_CheckFloor
  1347.     tst.w   d1
  1348.     bpl.s   return_1CB4E
  1349.     add.w   d1,y_pos(a0)
  1350.     move.b  d3,angle(a0)
  1351.     bsr.w   Tails_ResetOnFloor
  1352.     move.w  #0,y_vel(a0)
  1353.     move.w  x_vel(a0),inertia(a0)
  1354.  
  1355. return_1CB4E:
  1356.     rts
  1357. ; End of function Tails_DoLevelCollision
  1358.  
  1359.  
  1360.  
  1361. ; ---------------------------------------------------------------------------
  1362. ; Subroutine to reset Tails' mode when he lands on the floor
  1363. ; ---------------------------------------------------------------------------
  1364.  
  1365. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  1366.  
  1367. ; loc_1CB50:
  1368. Tails_ResetOnFloor:
  1369.     tst.b   spindash_flag(a0)
  1370.     bne.s   Tails_ResetOnFloor_Part3
  1371.     move.b  #0,anim(a0)
  1372. ; loc_1CB5C:
  1373. Tails_ResetOnFloor_Part2:
  1374.     btst    #2,status(a0)
  1375.     beq.s   Tails_ResetOnFloor_Part3
  1376.     bclr    #2,status(a0)
  1377.     move.b  #$F,y_radius(a0) ; this slightly increases Tails' collision height to standing
  1378.     move.b  #9,x_radius(a0)
  1379.     move.b  #0,anim(a0) ; use running/walking/standing animation
  1380.     subq.w  #1,y_pos(a0)    ; move Tails up 1 pixel so the increased height doesn't push him slightly into the ground
  1381. ; loc_1CB80:
  1382. Tails_ResetOnFloor_Part3:
  1383.     bclr    #1,status(a0)
  1384.     bclr    #5,status(a0)
  1385.     bclr    #4,status(a0)
  1386.     move.b  #0,jumping(a0)
  1387.     move.w  #0,(Chain_Bonus_counter).w
  1388.     move.b  #0,flip_angle(a0)
  1389.     move.b  #0,flip_turned(a0)
  1390.     move.b  #0,flips_remaining(a0)
  1391.     move.w  #0,(Tails_Look_delay_counter).w
  1392.     cmpi.b  #$14,anim(a0)
  1393.     bne.s   return_1CBC4
  1394.     move.b  #0,anim(a0)
  1395.  
  1396. return_1CBC4:
  1397.     rts
  1398. ; End of subroutine Tails_ResetOnFloor
  1399.  
  1400. ; ===========================================================================
  1401. ; ---------------------------------------------------------------------------
  1402. ; Tails when he gets hurt
  1403. ; ---------------------------------------------------------------------------
  1404. ; loc_1CBC6:
  1405. Obj02_Hurt:
  1406.     jsr ObjectMove
  1407.     addi.w  #$30,y_vel(a0)
  1408.     btst    #6,status(a0)
  1409.     beq.s   +
  1410.     subi.w  #$20,y_vel(a0)
  1411. +
  1412.     cmpi.w  #-$100,(Camera_Min_Y_pos).w
  1413.     bne.s   +
  1414.     andi.w  #$7FF,y_pos(a0)
  1415. +
  1416.     bsr.w   Tails_HurtStop
  1417.     bsr.w   Tails_LevelBound
  1418.     bsr.w   Tails_RecordPos
  1419.     bsr.w   Tails_Animate
  1420.     bsr.w   LoadTailsDynPLC
  1421.     jmp DisplaySprite
  1422. ; ===========================================================================
  1423. ; loc_1CC08:
  1424. Tails_HurtStop:
  1425.     move.w  (Tails_Max_Y_pos).w,d0
  1426.     addi.w  #$E0,d0
  1427.     cmp.w   y_pos(a0),d0
  1428.     blt.w   JmpTo2_KillCharacter
  1429.     bsr.w   Tails_DoLevelCollision
  1430.     btst    #1,status(a0)
  1431.     bne.s   return_1CC4E
  1432.     moveq   #0,d0
  1433.     move.w  d0,y_vel(a0)
  1434.     move.w  d0,x_vel(a0)
  1435.     move.w  d0,inertia(a0)
  1436.     move.b  d0,obj_control(a0)
  1437.     move.b  #0,anim(a0)
  1438.     move.b  #2,routine(a0)  ; => Obj02_Control
  1439.     move.w  #$78,invulnerable_time(a0)
  1440.     move.b  #0,spindash_flag(a0)
  1441.  
  1442. return_1CC4E:
  1443.     rts
  1444. ; ===========================================================================
  1445.  
  1446. ; ---------------------------------------------------------------------------
  1447. ; Tails when he dies
  1448. ; .
  1449. ; ---------------------------------------------------------------------------
  1450.  
  1451. ; loc_1CC50:
  1452. Obj02_Dead:
  1453.     bsr.w   Obj02_CheckGameOver
  1454.     jsr ObjectMoveAndFall
  1455.     bsr.w   Tails_RecordPos
  1456.     bsr.w   Tails_Animate
  1457.     bsr.w   LoadTailsDynPLC
  1458.     jmp DisplaySprite
  1459.  
  1460. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  1461.  
  1462. ; loc_1CC6C:
  1463. Obj02_CheckGameOver:
  1464.     cmpi.w  #2,(Player_mode).w  ; is it a Tails Alone game?
  1465.     beq.w   CheckGameOver       ; if yes, branch... goodness, code reuse
  1466.     move.b  #1,($FFFFEEBF).w
  1467.     move.b  #0,spindash_flag(a0)
  1468.     move.w  (Tails_Max_Y_pos).w,d0
  1469.     addi.w  #$100,d0
  1470.     cmp.w   y_pos(a0),d0
  1471.     bge.w   return_1CD8E
  1472.     move.b  #2,routine(a0)
  1473.     tst.w   (Two_player_mode).w
  1474.     bne.s   Obj02_CheckGameOver_2Pmode
  1475.     bra.w   TailsCPU_Despawn
  1476. ; ---------------------------------------------------------------------------
  1477. ; loc_1CCA2:
  1478. Obj02_CheckGameOver_2Pmode:
  1479.     addq.b  #1,(Update_HUD_lives_2P).w
  1480.     subq.b  #1,(Life_count_2P).w
  1481.     bne.s   Obj02_ResetLevel
  1482.     move.w  #0,spindash_counter(a0)
  1483.     move.b  #$39,(Object_RAM+$80).w ; load Obj39
  1484.     move.b  #$39,(Object_RAM+$C0).w ; load Obj39
  1485.     move.b  #1,(Object_RAM+$C0+mapping_frame).w
  1486.     move.w  a0,(Object_RAM+$80+parent).w
  1487.     clr.b   (Time_Over_flag_2P).w
  1488. ; loc_1CCCC:
  1489. Obj02_Finished:
  1490.     clr.b   (Update_HUD_timer).w
  1491.     clr.b   (Update_HUD_timer_2P).w
  1492.     move.b  #8,routine(a0)
  1493.     move.w  #$9B,d0
  1494.     jsr (PlayMusic).l
  1495.     moveq   #3,d0
  1496.     jmp (LoadPLC).l
  1497. ; End of function Obj02_CheckGameOver
  1498.  
  1499. ; ===========================================================================
  1500. ; ---------------------------------------------------------------------------
  1501. ; Tails when the level is restarted
  1502. ; ---------------------------------------------------------------------------
  1503. ; loc_1CCEC:
  1504. Obj02_ResetLevel:
  1505.     tst.b   (Time_Over_flag).w
  1506.     beq.s   Obj02_ResetLevel_Part2
  1507.     tst.b   (Time_Over_flag_2P).w
  1508.     beq.s   Obj02_ResetLevel_Part3
  1509.     move.w  #0,spindash_counter(a0)
  1510.     clr.b   (Update_HUD_timer).w
  1511.     clr.b   (Update_HUD_timer_2P).w
  1512.     move.b  #8,routine(a0)
  1513.     rts
  1514. ; ---------------------------------------------------------------------------
  1515. Obj02_ResetLevel_Part2:
  1516.     tst.b   (Time_Over_flag_2P).w
  1517.     beq.s   Obj02_ResetLevel_Part3
  1518.     move.w  #0,spindash_counter(a0)
  1519.     move.b  #$39,(Object_RAM+$80).w ; load Obj39
  1520.     move.b  #$39,(Object_RAM+$C0).w ; load Obj39
  1521.     move.b  #2,(Object_RAM+$80+mapping_frame).w
  1522.     move.b  #3,(Object_RAM+$C0+mapping_frame).w
  1523.     move.w  a0,(Object_RAM+$80+parent).w
  1524.     bra.s   Obj02_Finished
  1525. ; ---------------------------------------------------------------------------
  1526. Obj02_ResetLevel_Part3:
  1527.     move.b  #0,($FFFFEEBF).w
  1528.     move.b  #$A,routine(a0) ; => Obj02_Respawning
  1529.     move.w  (Saved_x_pos_2P).w,x_pos(a0)
  1530.     move.w  (Saved_y_pos_2P).w,y_pos(a0)
  1531.     move.w  (Saved_art_tile_2P).w,art_tile(a0)
  1532.     move.w  (Saved_layer_2P).w,layer(a0)
  1533.     clr.w   (Ring_count_2P).w
  1534.     clr.b   (Extra_life_flags_2P).w
  1535.     move.b  #0,obj_control(a0)
  1536.     move.b  #5,anim(a0)
  1537.     move.w  #0,x_vel(a0)
  1538.     move.w  #0,y_vel(a0)
  1539.     move.w  #0,inertia(a0)
  1540.     move.b  #2,status(a0)
  1541.     move.w  #0,move_lock(a0)
  1542.  
  1543. return_1CD8E:
  1544.     rts
  1545. ; ===========================================================================
  1546. ; ---------------------------------------------------------------------------
  1547. ; Tails when he's offscreen and waiting for the level to restart
  1548. ; ---------------------------------------------------------------------------
  1549. ; loc_1CD90:
  1550. Obj02_Gone:
  1551.     tst.w   spindash_counter(a0)
  1552.     beq.s   +
  1553.     subq.w  #1,spindash_counter(a0)
  1554.     bne.s   +
  1555.     move.w  #1,(Level_Inactive_flag).w
  1556. +
  1557.     rts
  1558. ; ===========================================================================
  1559. ; ---------------------------------------------------------------------------
  1560. ; Tails when he's waiting for the camera to scroll back to where he respawned
  1561. ; ---------------------------------------------------------------------------
  1562. ; loc_1CDA4:
  1563. Obj02_Respawning:
  1564.     tst.w   ($FFFFEEB8).w
  1565.     bne.s   +
  1566.     tst.w   ($FFFFEEBA).w
  1567.     bne.s   +
  1568.     move.b  #2,routine(a0)
  1569. +
  1570.     bsr.w   Tails_Animate
  1571.     bsr.w   LoadTailsDynPLC
  1572.     jmp DisplaySprite
  1573. ; ===========================================================================
  1574.  
  1575. ; ---------------------------------------------------------------------------
  1576. ; Subroutine to animate Tails' sprites
  1577. ; See also: AnimateSprite and Sonic_Animate
  1578. ; ---------------------------------------------------------------------------
  1579.  
  1580. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  1581.  
  1582. ; loc_1CDC4:
  1583. Tails_Animate:
  1584.     lea (TailsAniData).l,a1
  1585. ; loc_1CDCA:
  1586. Tails_Animate_Part2:
  1587.     moveq   #0,d0
  1588.     move.b  anim(a0),d0
  1589.     cmp.b   next_anim(a0),d0    ; has animation changed?
  1590.     beq.s   TAnim_Do        ; if not, branch
  1591.     move.b  d0,next_anim(a0)    ; set to next animation
  1592.     move.b  #0,anim_frame(a0)   ; reset animation frame
  1593.     move.b  #0,anim_frame_duration(a0)  ; reset frame duration
  1594.     bclr    #5,status(a0)
  1595. ; loc_1CDEC:
  1596. TAnim_Do:
  1597.     add.w   d0,d0
  1598.     adda.w  (a1,d0.w),a1    ; calculate address of appropriate animation script
  1599.     move.b  (a1),d0
  1600.     bmi.s   TAnim_WalkRunZoom   ; if animation is walk/run/roll/jump, branch
  1601.     move.b  status(a0),d1
  1602.     andi.b  #1,d1
  1603.     andi.b  #$FC,render_flags(a0)
  1604.     or.b    d1,render_flags(a0)
  1605.     subq.b  #1,anim_frame_duration(a0)  ; subtract 1 from frame duration
  1606.     bpl.s   TAnim_Delay         ; if time remains, branch
  1607.     move.b  d0,anim_frame_duration(a0)  ; load frame duration
  1608. ; loc_1CE12:
  1609. TAnim_Do2:
  1610.     moveq   #0,d1
  1611.     move.b  anim_frame(a0),d1   ; load current frame number
  1612.     move.b  1(a1,d1.w),d0       ; read sprite number from script
  1613.     cmpi.b  #$F0,d0
  1614.     bcc.s   TAnim_End_FF        ; if animation is complete, branch
  1615. ; loc_1CE22:
  1616. TAnim_Next:
  1617.     move.b  d0,mapping_frame(a0)
  1618.     addq.b  #1,anim_frame(a0)
  1619. ; return_1CE2A:
  1620. TAnim_Delay:
  1621.     rts
  1622. ; ===========================================================================
  1623. ; loc_1CE2C:
  1624. TAnim_End_FF:
  1625.     addq.b  #1,d0           ; is the end flag = $FF ?
  1626.     bne.s   TAnim_End_FE        ; if not, branch
  1627.     move.b  #0,anim_frame(a0)   ; restart the animation
  1628.     move.b  1(a1),d0            ; read sprite number
  1629.     bra.s   TAnim_Next
  1630. ; ===========================================================================
  1631. ; loc_1CE3C:
  1632. TAnim_End_FE:
  1633.     addq.b  #1,d0           ; is the end flag = $FE ?
  1634.     bne.s   TAnim_End_FD        ; if not, branch
  1635.     move.b  2(a1,d1.w),d0       ; read the next byte in the script
  1636.     sub.b   d0,anim_frame(a0)   ; jump back d0 bytes in the script
  1637.     sub.b   d0,d1
  1638.     move.b  1(a1,d1.w),d0       ; read sprite number
  1639.     bra.s   TAnim_Next
  1640. ; ===========================================================================
  1641. ; loc_1CE50:
  1642. TAnim_End_FD:
  1643.     addq.b  #1,d0           ; is the end flag = $FD ?
  1644.     bne.s   TAnim_End       ; if not, branch
  1645.     move.b  2(a1,d1.w),anim(a0) ; read next byte, run that animation
  1646. ; return_1CE5A:
  1647. TAnim_End:
  1648.     rts
  1649. ; ===========================================================================
  1650. ; loc_1CE5C:
  1651. TAnim_WalkRunZoom: ; a0=character
  1652.     ; note: for some reason SAnim_WalkRun doesn't need to do this here...
  1653.     subq.b  #1,anim_frame_duration(a0)  ; subtract 1 from Tails' frame duration
  1654.     bpl.s   TAnim_Delay         ; if time remains, branch
  1655.  
  1656.     addq.b  #1,d0       ; is the end flag = $FF ?
  1657.     bne.w   TAnim_Roll  ; if not, branch
  1658.     moveq   #0,d0       ; is animation walking/running?
  1659.     move.b  flip_angle(a0),d0   ; if not, branch
  1660.     bne.w   loc_1CF08
  1661.     moveq   #0,d1
  1662.     move.b  angle(a0),d0    ; get Tails' angle
  1663.     bmi.s   +
  1664.     beq.s   +
  1665.     subq.b  #1,d0
  1666. +
  1667.     move.b  status(a0),d2
  1668.     andi.b  #1,d2       ; is Tails mirrored horizontally?
  1669.     bne.s   +       ; if yes, branch
  1670.     not.b   d0      ; reverse angle
  1671. +
  1672.     addi.b  #$10,d0     ; add $10 to angle
  1673.     bpl.s   +       ; if angle is $0-$7F, branch
  1674.     moveq   #3,d1
  1675. +
  1676.     andi.b  #$FC,render_flags(a0)
  1677.     eor.b   d1,d2
  1678.     or.b    d2,render_flags(a0)
  1679.     btst    #5,status(a0)
  1680.     bne.w   loc_1CFB2
  1681.     lsr.b   #4,d0       ; divide angle by 16
  1682.     andi.b  #6,d0       ; make it 0, 2, 4 or 6
  1683.     move.w  inertia(a0),d2  ; get Tails' "speed" for animation purposes
  1684.     bpl.s   +
  1685.     neg.w   d2
  1686. +
  1687.     tst.b   status_secondary(a0)
  1688.     bpl.w   +
  1689.     add.w   d2,d2
  1690. +
  1691.     move.b  d0,d3
  1692.     add.b   d3,d3
  1693.     add.b   d3,d3
  1694.     lea (TailsAni_Walk).l,a1
  1695.  
  1696.     cmpi.w  #$600,d2        ; is Tails going pretty fast?
  1697.     bcs.s   TAnim_SpeedSelected ; if not, branch
  1698.     lea (TailsAni_Run).l,a1
  1699.     move.b  d0,d1
  1700.     lsr.b   #1,d1
  1701.     add.b   d1,d0
  1702.     add.b   d0,d0
  1703.     move.b  d0,d3
  1704.  
  1705.     cmpi.w  #$700,d2        ; is Tails going really fast?
  1706.     bcs.s   TAnim_SpeedSelected ; if not, branch
  1707.     lea (TailsAni_HaulAss).l,a1
  1708.  
  1709. ; loc_1CEEE:
  1710. TAnim_SpeedSelected:
  1711.     neg.w   d2
  1712.     addi.w  #$800,d2
  1713.     bpl.s   +
  1714.     moveq   #0,d2
  1715. +
  1716.     lsr.w   #8,d2
  1717.     move.b  d2,anim_frame_duration(a0)
  1718.     bsr.w   TAnim_Do2
  1719.     add.b   d3,mapping_frame(a0)
  1720.     rts
  1721. ; ===========================================================================
  1722.  
  1723. loc_1CF08:
  1724.     move.b  flip_angle(a0),d0
  1725.     moveq   #0,d1
  1726.     move.b  status(a0),d2
  1727.     andi.b  #1,d2
  1728.     bne.s   loc_1CF36
  1729.     andi.b  #$FC,render_flags(a0)
  1730.     addi.b  #$B,d0
  1731.     divu.w  #$16,d0
  1732.     addi.b  #$75,d0
  1733.     move.b  d0,mapping_frame(a0)
  1734.     move.b  #0,anim_frame_duration(a0)
  1735.     rts
  1736. ; ===========================================================================
  1737.  
  1738. loc_1CF36:
  1739.     andi.b  #$FC,render_flags(a0)
  1740.     tst.b   flip_turned(a0)
  1741.     beq.s   loc_1CF4E
  1742.     ori.b   #1,render_flags(a0)
  1743.     addi.b  #$B,d0
  1744.     bra.s   loc_1CF5A
  1745. ; ===========================================================================
  1746.  
  1747. loc_1CF4E:
  1748.     ori.b   #3,render_flags(a0)
  1749.     neg.b   d0
  1750.     addi.b  #-$71,d0
  1751.  
  1752. loc_1CF5A:
  1753.     divu.w  #$16,d0
  1754.     addi.b  #$75,d0
  1755.     move.b  d0,mapping_frame(a0)
  1756.     move.b  #0,anim_frame_duration(a0)
  1757.     rts
  1758.  
  1759. ; ===========================================================================
  1760. ; loc_1CF6E:
  1761. TAnim_Roll:
  1762.     addq.b  #1,d0       ; is the end flag = $FE ?
  1763.     bne.s   TAnim_Push  ; if not, branch
  1764.     move.w  inertia(a0),d2
  1765.     bpl.s   +
  1766.     neg.w   d2
  1767. +
  1768.     lea (TailsAni_Roll2).l,a1
  1769.     cmpi.w  #$600,d2
  1770.     bcc.s   +
  1771.     lea (TailsAni_Roll).l,a1
  1772. +
  1773.     neg.w   d2
  1774.     addi.w  #$400,d2
  1775.     bpl.s   +
  1776.     moveq   #0,d2
  1777. +
  1778.     lsr.w   #8,d2
  1779.     move.b  d2,anim_frame_duration(a0)
  1780.     move.b  status(a0),d1
  1781.     andi.b  #1,d1
  1782.     andi.b  #$FC,render_flags(a0)
  1783.     or.b    d1,render_flags(a0)
  1784.     bra.w   TAnim_Do2
  1785. ; ===========================================================================
  1786.  
  1787. loc_1CFB2:
  1788.     move.w  inertia(a0),d2
  1789.     bmi.s   +
  1790.     neg.w   d2
  1791. +
  1792.     addi.w  #$800,d2
  1793.     bpl.s   +
  1794.     moveq   #0,d2
  1795. +
  1796.     lsr.w   #6,d2
  1797.     move.b  d2,anim_frame_duration(a0)
  1798.     lea (TailsAni_Push).l,a1
  1799.     move.b  status(a0),d1
  1800.     andi.b  #1,d1
  1801.     andi.b  #$FC,render_flags(a0)
  1802.     or.b    d1,render_flags(a0)
  1803.     bra.w   TAnim_Do2
  1804.  
  1805. ; ===========================================================================
  1806. ; loc_1CFE4:
  1807. TAnim_Push:
  1808.     move.w  x_vel(a2),d1
  1809.     move.w  y_vel(a2),d2
  1810.     jsr (CalcAngle).l
  1811.     moveq   #0,d1
  1812.     move.b  status(a0),d2
  1813.     andi.b  #1,d2
  1814.     bne.s   loc_1D002
  1815.     not.b   d0
  1816.     bra.s   loc_1D006
  1817. ; ===========================================================================
  1818.  
  1819. loc_1D002:
  1820.     addi.b  #$80,d0
  1821.  
  1822. loc_1D006:
  1823.     addi.b  #$10,d0
  1824.     bpl.s   +
  1825.     moveq   #3,d1
  1826. +
  1827.     andi.b  #$FC,render_flags(a0)
  1828.     eor.b   d1,d2
  1829.     or.b    d2,render_flags(a0)
  1830.     lsr.b   #3,d0
  1831.     andi.b  #$C,d0
  1832.     move.b  d0,d3
  1833.     lea (Obj05Ani_Directional).l,a1
  1834.     move.b  #3,anim_frame_duration(a0)
  1835.     bsr.w   TAnim_Do2
  1836.     add.b   d3,mapping_frame(a0)
  1837.     rts
  1838. ; End of function Tails_Animate
  1839. ; ===========================================================================
  1840. TailsAniData:
  1841.         include "_anim\Tails.asm"
  1842.  
  1843. ; ---------------------------------------------------------------------------
  1844. ; Tails' Tails pattern loading subroutine
  1845. ; ---------------------------------------------------------------------------
  1846.  
  1847. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  1848.  
  1849. ; loc_1D184:
  1850. LoadTailsTailsDynPLC:
  1851.     moveq   #0,d0
  1852.     move.b  mapping_frame(a0),d0
  1853.     cmp.b   ($FFFFF7DF).w,d0
  1854.     beq.s   return_1D1FE
  1855.     move.b  d0,($FFFFF7DF).w
  1856.     lea (MapRUnc_Tails).l,a2
  1857.     add.w   d0,d0
  1858.     adda.w  (a2,d0.w),a2
  1859.     move.w  (a2)+,d5
  1860.     subq.w  #1,d5
  1861.     bmi.s   return_1D1FE
  1862.     move.w  #-$A00,d4
  1863.     bra.s   TPLC_ReadEntry
  1864.  
  1865. ; ---------------------------------------------------------------------------
  1866. ; Tails pattern loading subroutine
  1867. ; ---------------------------------------------------------------------------
  1868.  
  1869. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  1870.  
  1871. ; loc_1D1AC:
  1872. LoadTailsDynPLC:
  1873.     moveq   #0,d0
  1874.     move.b  mapping_frame(a0),d0    ; load frame number
  1875. ; loc_1D1B2:
  1876. LoadTailsDynPLC_Part2:
  1877.     cmp.b   ($FFFFF7DE).w,d0
  1878.     beq.s   return_1D1FE
  1879.     move.b  d0,($FFFFF7DE).w
  1880.     lea (MapRUnc_Tails).l,a2
  1881.     add.w   d0,d0
  1882.     adda.w  (a2,d0.w),a2
  1883.     move.w  (a2)+,d5
  1884.     subq.w  #1,d5
  1885.     bmi.s   return_1D1FE
  1886.     move.w  #-$C00,d4
  1887. ; loc_1D1D2:
  1888. TPLC_ReadEntry:
  1889.     moveq   #0,d1
  1890.     move.w  (a2)+,d1
  1891.     move.w  d1,d3
  1892.     lsr.w   #8,d3
  1893.     andi.w  #$F0,d3
  1894.     addi.w  #$10,d3
  1895.     andi.w  #$FFF,d1
  1896.     lsl.l   #5,d1
  1897.     addi.l  #ArtUnc_Tails,d1
  1898.     move.w  d4,d2
  1899.     add.w   d3,d4
  1900.     add.w   d3,d4
  1901.     jsr (QueueDMATransfer).l
  1902.     dbf d5,TPLC_ReadEntry   ; repeat for number of entries
  1903.  
  1904. return_1D1FE:
  1905.     rts
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement