[Sonic 1] Removing the Speed Cap

Discussion in 'Tutorials Archive' started by PsychoSk8r, Sep 8, 2007.

Thread Status:
Not open for further replies.
  1. PsychoSk8r

    PsychoSk8r HighKnights Member

    Joined:
    Aug 9, 2007
    Messages:
    271
    Location:
    Birmingham, UK
    This guide was written by Tweaker & Puto.


    None of this guide was written by myself

    Tweaker's Post

    To remove the speed cap requires taking a look at Sonic 2's version of Sonic_MoveLeft, and Sonic_MoveRight. First off, we should take a look at Sonic_MoveLeft (for example), and look at it's code.



    Code:
    Sonic_MoveLeft:		   &#59; XREF: Sonic_Move
    
    		move.w	$14(a0),d0
    
    		beq.s	loc_13086
    
    		bpl.s	loc_130B2
    
    
    
    loc_13086:
    
    		bset	#0,$22(a0)
    
    		bne.s	loc_1309A
    
    		bclr	#5,$22(a0)
    
    		move.b	#1,$1D(a0)
    
    
    
    loc_1309A:
    
    		sub.w	d5,d0
    
    		move.w	d6,d1
    
    		neg.w	d1
    
    		cmp.w	d1,d0
    
    		bgt.s	loc_130A6
    
    		move.w	d1,d0
    
    
    
    loc_130A6:
    
    		move.w	d0,$14(a0)
    
    		move.b	#0,$1C(a0); use walking animation
    
    		rts
    This is the section we're looking for. Now, let's look up one of the lines in here until we find a matching pattern in S2.



    Code:
    loc_1C2A4:		   &#59; CODE XREF: h+515C p
    
    		move.w	$14(a0),d0
    
    		beq.s	loc_1C2AC
    
    		bpl.s	loc_1C2DE
    
    
    
    loc_1C2AC:		   &#59; CODE XREF: h+5334 j
    
    		bset	#0,$22(a0)
    
    		bne.s	loc_1C2C0
    
    		bclr	#5,$22(a0)
    
    		move.b	#1,$1D(a0)
    
    
    
    loc_1C2C0:		   &#59; CODE XREF: h+533E j
    
    		sub.w	d5,d0
    
    		move.w	d6,d1
    
    		neg.w	d1
    
    		cmp.w	d1,d0
    
    		bgt.s	loc_1C2D2
    
    		add.w	d5,d0
    
    		cmp.w	d1,d0
    
    		ble.s	loc_1C2D2
    
    		move.w	d1,d0
    
    
    
    loc_1C2D2:		   &#59; CODE XREF: h+5354 j h+535A j
    
    		move.w	d0,$14(a0)
    
    		move.b	#0,$1C(a0)
    
    		rts
    Success! Now, let's compare the differences here. You'll notice S2's routine has 3 extra lines in it:



    Code:
    		add.w	d5,d0
    
    		cmp.w	d1,d0
    
    		ble.s	loc_1C2D2
    So, what we want to do is add this code to Sonic 1's routine. Take these 3 lines and modify them to work with S1. You should end up with this:



    Code:
    Sonic_MoveLeft:		   &#59; XREF: Sonic_Move
    
    		move.w	$14(a0),d0
    
    		beq.s	loc_13086
    
    		bpl.s	loc_130B2
    
    
    
    loc_13086:
    
    		bset	#0,$22(a0)
    
    		bne.s	loc_1309A
    
    		bclr	#5,$22(a0)
    
    		move.b	#1,$1D(a0)
    
    
    
    loc_1309A:
    
    		sub.w	d5,d0
    
    		move.w	d6,d1
    
    		neg.w	d1
    
    		cmp.w	d1,d0
    
    		bgt.s	loc_130A6
    
    		add.w	d5,d0
    
    		cmp.w	d1,d0
    
    		ble.s	loc_130A6
    
    		move.w	d1,d0
    
    
    
    loc_130A6:
    
    		move.w	d0,$14(a0)
    
    		move.b	#0,$1C(a0); use walking animation
    
    		rts
    Now, we have to do the same for Sonic_MoveRight. Once again, let's find the S2 equivalent of the routine using Sonic 1's routine.



    Sonic 1's:



    Code:
    Sonic_MoveRight:	   &#59; XREF: Sonic_Move
    
    		move.w	$14(a0),d0
    
    		bmi.s	loc_13118
    
    		bclr	#0,$22(a0)
    
    		beq.s	loc_13104
    
    		bclr	#5,$22(a0)
    
    		move.b	#1,$1D(a0)
    
    
    
    loc_13104:
    
    		add.w	d5,d0
    
    		cmp.w	d6,d0
    
    		blt.s	loc_1310C
    
    		move.w	d6,d0
    
    
    
    loc_1310C:
    
    		move.w	d0,$14(a0)
    
    		move.b	#0,$1C(a0); use walking animation
    
    		rts
    And, with the same amount of backsearching, we can find Sonic 2's, which is the following:



    Code:
    loc_1C32A:		   &#59; CODE XREF: h+5168 p
    
    		move.w	$14(a0),d0
    
    		bmi.s	loc_1C35E
    
    		bclr	#0,$22(a0)
    
    		beq.s	loc_1C344
    
    		bclr	#5,$22(a0)
    
    		move.b	#1,$1D(a0)
    
    
    
    loc_1C344:		   &#59; CODE XREF: h+53C2 j
    
    		add.w	d5,d0
    
    		cmp.w	d6,d0
    
    		blt.s	loc_1C352
    
    		sub.w	d5,d0
    
    		cmp.w	d6,d0
    
    		bge.s	loc_1C352
    
    		move.w	d6,d0
    
    
    
    loc_1C352:		   &#59; CODE XREF: h+53D4 j h+53DA j
    
    		move.w	d0,$14(a0)
    
    		move.b	#0,$1C(a0)
    
    		rts
    Now, once again, you'll notice the difference between the two routines is the following lines:



    Code:
    		sub.w	d5,d0
    
    		cmp.w	d6,d0
    
    		bge.s	loc_1C352
    So, once again, let's apply these changes to work with S1, providing our final, result routine for S1:



    Code:
    Sonic_MoveRight:	   &#59; XREF: Sonic_Move
    
    		move.w	$14(a0),d0
    
    		bmi.s	loc_13118
    
    		bclr	#0,$22(a0)
    
    		beq.s	loc_13104
    
    		bclr	#5,$22(a0)
    
    		move.b	#1,$1D(a0)
    
    
    
    loc_13104:
    
    		add.w	d5,d0
    
    		cmp.w	d6,d0
    
    		blt.s	loc_1310C
    
    		sub.w	d5,d0
    
    		cmp.w	d6,d0
    
    		bge.s	loc_1310C
    
    		move.w	d6,d0
    
    
    
    loc_1310C:
    
    		move.w	d0,$14(a0)
    
    		move.b	#0,$1C(a0); use walking animation
    
    		rts


    And that should be it! Build your new ROM, and the infamous speed cap should be gone!

    Puto's Continuation

    That still keeps the cap in mid-air. So let's adapt that to fix the speed cap in mid-air too.



    Here's the original code:





    Code:
    Sonic_ChgJumpDir:		&#59; XREF: Obj01_MdJump; Obj01_MdJump2
    
    	move.w	($FFFFF760).w,d6	
    
    	move.w	($FFFFF762).w,d5	
    
    	asl.w	#1,d5	
    
    	btst	#4,$22(a0)	
    
    	bne.s Obj01_ResetScr2	
    
    	move.w	$10(a0),d0	
    
    	btst	#2,($FFFFF602).w&#59; is left being pressed?	
    
    	beq.s loc_13278&#59; if not, branch	
    
    	bset	#0,$22(a0)	
    
    	sub.w	d5,d0	
    
    	move.w	d6,d1	
    
    	neg.w	d1	
    
    	cmp.w	d1,d0	
    
    	bgt.s	loc_13278	
    
    	move.w	d1,d0loc_13278:	
    
    	btst	#3,($FFFFF602).w&#59; is right being pressed?	
    
    	beq.s   Obj01_JumpMove&#59; if not, branch	
    
    	bclr	#0,$22(a0)	
    
    	add.w	d5,d0	
    
    	cmp.w	d6,d0	
    
    	blt.s	Obj01_JumpMove	
    
    	move.w	d6,d0


    As you can see, it works exactly the same way as the MoveLeft/Right routines. So let's apply the same fix. After bgt.s loc_13278, add the following lines:



    Code:
    	add.w d5,d0
    
    	cmp.w d1,d0
    
    	ble.s loc_13278


    And do a similar thing after blt.s Obj01_JumpMove:



    Code:
    	sub.w d5,d0
    
    	cmp.w d6,d0
    
    	bge.s Obj01_JumpMove
    Final result:





    Code:
    Sonic_ChgJumpDir:		&#59; CODE XREF: ROM:00012E40 p ...		move.w	($FFFFF760).w,d6		move.w	($FFFFF762).w,d5
    
    	asl.w	#1,d5
    
    	btst	#4,$22(a0)	
    
    	bne.s	Obj01_ResetScr2	
    
    	move.w	$10(a0),d0	
    
    	btst	#2,($FFFFF602).w&#59; is left being pressed?	
    
    	beq.s	loc_13278&#59; if not, branch	
    
    	bset	#0,$22(a0)	
    
    	sub.w	d5,d0	
    
    	move.w	d6,d1	
    
    	neg.w	d1	
    
    	cmp.w	d1,d0	
    
    	bgt.s	loc_13278	
    
    	add.w	d5,d0
    
    				cmp.w	d1,d0 
    
    				ble.s	 loc_13278	
    
    	move.w	d1,d0
    
    
    
    loc_13278:	&#59; CODE XREF: Sonic_ChgJumpDir+1C j ...	
    
    	btst	#3,($FFFFF602).w&#59; is right being pressed?	
    
    	beq.s	Obj01_JumpMove&#59; if not, branch	
    
    	bclr	#0,$22(a0)	
    
    	add.w	d5,d0	
    
    	cmp.w	d6,d0	
    
    	blt.s	Obj01_JumpMove
    
    				sub.w	d5,d0  
    
    				cmp.w	d6,d0
    
    				bge.s	Obj01_JumpMove 
    
    				move.w	d6,d0
     
  2. shobiz

    shobiz Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    198
    Location:
    Karachi, Pakistan
    Not that it matters at all, but the Sonic 2 subroutines Tweaker refers to are Tails' moving routines, not Sonic's. They're exactly the same though.
     
  3. Tweaker

    Tweaker OI! MIRON! Member

    Joined:
    Aug 10, 2007
    Messages:
    324
    Well, I suppose proper labels would have helped avoid that confusion. XD
     
  4. PsychoSk8r

    PsychoSk8r HighKnights Member

    Joined:
    Aug 9, 2007
    Messages:
    271
    Location:
    Birmingham, UK
    Also, thank you Tweaker, and Puto for a kick-ass guide. Worked Perfectly =P


    Now i can continue with my ART. i've spent 3 days flat on ASM.
     
Thread Status:
Not open for further replies.