How to Port Super Sonic from Sonic 2 to Sonic 1

Discussion in 'Tutorials Archive' started by warr1or2, Mar 12, 2015.

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

    warr1or2 I AM CLG Member

    Joined:
    Apr 7, 2008
    Messages:
    417
    Location:
    Town Creek, AL
    This is My first tutorial, I made this tutorial while doing so myself.

    Tools needed
    A Sonic 1 Disassembly (I'll be working from Address music, but it's basicly a modded Sonic 1 2005 Disassembly)
    A Sonic 2 Disassembly (I'll be using Xenowhirl)
    SonMapEd

    In SonMapEd, Change the game format to Sonic 2 & Load From Sonic 2 the Art, Map & DPLC.
    Switch the Game Format to Sonic 1 & save the Uncompressed Art, Mappings & DPLC to your

    Sonic 1 Disassembly.
    Open Sonic1.asm & s2.asm.
    In Sonic1.asm go to Map_Sonic: & chage the three to load

    Code:
    ; ---------------------------------------------------------------------------
    ; Sprite mappings - Sonic
    ; ---------------------------------------------------------------------------
    Map_Sonic:
    include "Sonic/map.asm" ;(Example)
    
    ; ---------------------------------------------------------------------------
    ; Uncompressed graphics loading array for Sonic
    ; ---------------------------------------------------------------------------
    SonicDynPLC:
    include "Sonic/DPLC.asm" ;(Example)
    
    ; ---------------------------------------------------------------------------
    ; Uncompressed graphics - Sonic
    ; ---------------------------------------------------------------------------
    Art_Sonic: incbin SonicTiles.bin ; (Example)
    even
    
    If you save & Build now, Sonic will act weird.
    so in S2.asm Copy & Paste ALL macros to a new file called Macro.asm in your Sonic 1 Disassembly.
    Replace (Ctrl+H in notepad) ALL ramaddr with nothing & do the same to ( and ) & Include "macro.asm" at the beginning.
    If you save & Build now you'll get 4 errors. go to them & comment them out. Save & build again & this time you should get no errors.
    in s2.asm, copy all Sonic_Animate down to SuperSonicAniData's Even & Overwrite Sonic 1's Sonic_Animate & SonicAniData.
    You'll get the first set of error, concerning spacings within the anidata's like "Sonani_run Sonicanidata" Just remove the spacings.
    the second set of errors, Sonic 1 can't handle + routines.Change them.. The entire Sonic_Animate should look something like this
    Code:
    
    Sonic_Animate:
    lea (SonicAniData).l,a1 ; Load SonicAniData to a1
    tst.b (Super_Sonic_flag).w ; Is Sonic Normal?
    beq.s Loc1 ; if so, branch
    lea (SuperSonicAniData).l,a1 ; Load SuperSonicAniData to a1
    Loc1:
    moveq #0,d0 ; Clear d0
    move.b anim(a0),d0 ; move animations to d0
    cmp.b next_anim(a0),d0 ; has animation changed?
    beq.s SAnim_Do ; if not, branch
    move.b d0,next_anim(a0) ; set to next animation
    move.b #0,anim_frame(a0) ; reset animation frame
    move.b #0,anim_frame_duration(a0) ; reset frame duration
    bclr #5,status(a0)
    ; loc_1B384:
    SAnim_Do:
    add.w d0,d0
    adda.w (a1,d0.w),a1 ; calculate address of appropriate animation script
    move.b (a1),d0 ;
    bmi.s SAnim_WalkRun ; if animation is walk/run/roll/jump, branch
    move.b status(a0),d1 ; move status to d1
    andi.b #1,d1 ; is status at bit 1,
    andi.b #$FC,render_flags(a0) & render flags at FC?
    or.b d1,render_flags(a0)
    subq.b #1,anim_frame_duration(a0) ; subtract 1 from frame duration
    bpl.s SAnim_Delay ; if time remains, branch
    move.b d0,anim_frame_duration(a0) ; load frame duration
    ; loc_1B3AA:
    SAnim_Do2:
    moveq #0,d1 ; clear d1
    move.b anim_frame(a0),d1 ; load current frame number
    move.b 1(a1,d1.w),d0 ; read sprite number from script
    cmpi.b #$F0,d0 ; is Sprite Number F0?
    bcc.s SAnim_End_FF ; if animation is complete, branch
    ; loc_1B3BA:
    SAnim_Next:
    move.b d0,mapping_frame(a0) ; load sprite number
    addq.b #1,anim_frame(a0) ; go to next frame
    ; return_1B3C2:
    SAnim_Delay:
    rts
    ; ===========================================================================
    ; loc_1B3C4:
    SAnim_End_FF:
    addq.b #1,d0 ; is the end flag = $FF ?
    bne.s SAnim_End_FE ; if not, branch
    move.b #0,anim_frame(a0) ; restart the animation
    move.b 1(a1),d0 ; read sprite number
    bra.s SAnim_Next ; continue
    ; ===========================================================================
    ; loc_1B3D4:
    SAnim_End_FE:
    addq.b #1,d0 ; is the end flag = $FE ?
    bne.s SAnim_End_FD ; if not, branch
    move.b 2(a1,d1.w),d0 ; read the next byte in the script
    sub.b d0,anim_frame(a0) ; jump back d0 bytes in the script
    sub.b d0,d1
    move.b 1(a1,d1.w),d0 ; read sprite number
    bra.s SAnim_Next ; continue
    ; ===========================================================================
    ; loc_1B3E8:
    SAnim_End_FD:
    addq.b #1,d0 ; is the end flag = $FD ?
    bne.s SAnim_End ; if not, branch
    move.b 2(a1,d1.w),anim(a0) ; read next byte, run that animation
    ; return_1B3F2:
    SAnim_End:
    rts
    ; ===========================================================================
    ; loc_1B3F4:
    SAnim_WalkRun:
    addq.b #1,d0 ; is the start flag = $FF ?
    bne.w SAnim_Roll ; if not, branch
    moveq #0,d0 ; is animation walking/running?
    move.b flip_angle(a0),d0 ; if not, branch
    bne.w SAnim_Tumble
    moveq #0,d1 ; clear d1
    move.b angle(a0),d0 ; get Sonic's angle
    bmi.s Loc2
    beq.s Loc2
    subq.b #1,d0 ;  subtract 1 from angle
    Loc2:
    move.b status(a0),d2 ; move status to d2
    andi.b #1,d2 ; is Sonic mirrored horizontally?
    bne.s Loc3 ; if yes, branch
    not.b d0 ; reverse angle
    Loc3:
    addi.b #$10,d0 ; add $10 to angle
    bpl.s Loc4 ; if angle is $0-$7F, branch
    moveq #3,d1 ; move 3 to d1
    Loc4:
    andi.b #$FC,render_flags(a0) ; is render flags at FC?
    eor.b d1,d2
    or.b d2,render_flags(a0)
    btst #5,status(a0); is status at 5?
    bne.w SAnim_Push ; if not, branch
    lsr.b #4,d0 ; divide angle by 16
    andi.b #6,d0 ; angle must be 0, 2, 4 or 6
    move.w inertia(a0),d2 ; get Sonic's "speed" for animation purposes
    bpl.s Loc5 ; Branch if plus
    neg.w d2
    Loc5:
    tst.b status_secondary(a0) ; secondary status check
    bpl.w Loc6 ; branch if greater than 0
    add.w d2,d2
    Loc6:
    tst.b (Super_Sonic_flag).w ; Is Sonic Normal?
    bne.s SAnim_Super ; If not, branch
    lea (SonAni_Run).l,a1 ; use running animation
    cmpi.w #$600,d2 ; is Sonic at running speed?
    bcc.s Loc7 ; use running animation
    lea (SonAni_Walk).l,a1 ; if yes, branch
    add.b d0,d0
    Loc7:
    add.b d0,d0
    move.b d0,d3
    moveq #0,d1 ; clear d1
    move.b anim_frame(a0),d1 ; move animation frame to d1
    move.b 1(a1,d1.w),d0
    cmpi.b #-1,d0
    bne.s Loc8
    move.b #0,anim_frame(a0) ; clear animation frame
    move.b 1(a1),d0
    Loc8:
    move.b d0,mapping_frame(a0);
    add.b d3,mapping_frame(a0)
    subq.b #1,anim_frame_duration(a0) ; subtract 1 from the animation frame
    bpl.s return_1B4AC ; Branch
    neg.w d2
    addi.w #$800,d2
    bpl.s Loc9
    moveq #0,d2 ; clear d2
    Loc9:
    lsr.w #8,d2
    move.b d2,anim_frame_duration(a0) ; modify frame duration
    addq.b #1,anim_frame(a0) ; modify frame number
    
    return_1B4AC:
    rts
    ; ===========================================================================
    ; loc_1B4AE:
    SAnim_Super:
    lea (SupSonAni_Run).l,a1 ; use fast animation
    cmpi.w #$800,d2 ; is Sonic moving fast?
    bcc.s SAnim_SuperRun ; if yes, branch
    lea (SupSonAni_Walk).l,a1 ; use slower animation
    add.b d0,d0
    add.b d0,d0
    bra.s SAnim_SuperWalk ; continue
    ; ---------------------------------------------------------------------------
    ; loc_1B4C6:
    SAnim_SuperRun:
    lsr.b #1,d0
    ; loc_1B4C8:
    SAnim_SuperWalk:
    move.b d0,d3
    moveq #0,d1 ; clear d1
    move.b anim_frame(a0),d1 ; muve animation frame to d1
    move.b 1(a1,d1.w),d0
    cmpi.b #-1,d0
    bne.s Loc10
    move.b #0,anim_frame(a0) ; clear animation frame
    move.b 1(a1),d0
    Loc10:
    move.b d0,mapping_frame(a0)
    add.b d3,mapping_frame(a0)
    move.b ($FFFFFE05).w,d1 ; move address to d1
    andi.b #3,d1 ; is it set to 3?
    bne.s Loc11 ; if not, branch
    cmpi.b #-$4B,mapping_frame(a0)
    bcc.s Loc11
    addi.b #$20,mapping_frame(a0) ; add $20 to mapping frame
    Loc11:
    subq.b #1,anim_frame_duration(a0) ; subtract 1 from frame duration
    bpl.s return_1B51E ; branch if plus
    neg.w d2
    addi.w #$800,d2
    bpl.s Loc12 ; branch if plus
    moveq #0,d2 ; clear d2
    Loc12:
    lsr.w #8,d2
    move.b d2,anim_frame_duration(a0)
    addq.b #1,anim_frame(a0) ; add 1 to animation frame
    
    return_1B51E:
    rts
    ; ===========================================================================
    ; loc_1B520:
    SAnim_Tumble:
    move.b flip_angle(a0),d0 ; move flip angle to d0
    moveq #0,d1 ; clear d1
    move.b status(a0),d2 ; move status to d2
    andi.b #1,d2 ; is status set to 2?
    bne.s SAnim_Tumble_Left ; if not, branch
    
    andi.b #$FC,render_flags(a0) ; are render flags at FC?
    addi.b #$B,d0 ; add B to flip angle
    divu.w #$16,d0 ; divide $16
    addi.b #$5F,d0 ; add 5F
    move.b d0,mapping_frame(a0) ; Set mapping frame to total
    move.b #0,anim_frame_duration(a0) ; clear frame duration
    rts
    ; ===========================================================================
    ; loc_1B54E:
    SAnim_Tumble_Left:
    andi.b #$FC,render_flags(a0) ; Render flags set at FC?
    tst.b flip_turned(a0) ; & Flip Turned to 0?
    beq.s loc_1B566 ; if so, branch
    ori.b #1,render_flags(a0)
    addi.b #$B,d0 ; add B to Flip Angle
    bra.s loc_1B572 ; & coninue
    ; ===========================================================================
    
    loc_1B566:
    ori.b #3,render_flags(a0)
    neg.b d0
    addi.b #$8F,d0
    
    loc_1B572:
    divu.w #$16,d0
    addi.b #$5F,d0
    move.b d0,mapping_frame(a0)
    move.b #0,anim_frame_duration(a0) ; Clear Frame duration
    rts
    ; ===========================================================================
    ; loc_1B586:
    SAnim_Roll:
    subq.b #1,anim_frame_duration(a0) ; subtract 1 from frame duration
    bpl.w SAnim_Delay ; if time remains, branch
    addq.b #1,d0 ; is the start flag = $FE ?
    bne.s SAnim_Push ; if not, branch
    move.w inertia(a0),d2 ; move inertia to d2
    bpl.s Loc13 ; Branch if plus
    neg.w d2
    Loc13:
    lea (SonAni_Roll2).l,a1 ; load Roll2 to a1
    cmpi.w #$600,d2 ; speed at $600?
    bcc.s Loc14 ; branch
    lea (SonAni_Roll).l,a1 ; load Roll
    Loc14:
    neg.w d2
    addi.w #$400,d2 ; speed at $400?
    bpl.s Loc15 ; Branch if more
    moveq #0,d2 ; clear d2
    Loc15:
    lsr.w #8,d2
    move.b d2,anim_frame_duration(a0)
    move.b status(a0),d1 ; move status to d1
    andi.b #1,d1 ; is it set to 1?
    andi.b #$FC,render_flags(a0) ; & the render flags at FC?
    or.b d1,render_flags(a0)
    bra.w SAnim_Do2 ; continue
    ; ===========================================================================
    
    SAnim_Push:
    subq.b #1,anim_frame_duration(a0) ; subtract 1 from frame duration
    bpl.w SAnim_Delay ; if time remains, branch
    move.w inertia(a0),d2 ; Move inertia to d2
    bmi.s Loc16 ; branch
    neg.w d2
    Loc16:
    addi.w #$800,d2
    bpl.s Loc17
    moveq #0,d2 ; clear d2
    Loc17:
    lsr.w #6,d2
    move.b d2,anim_frame_duration(a0)
    lea (SonAni_Push).l,a1 ; Load Push animation
    tst.b (Super_Sonic_flag).w ; Is Sonic normal?
    beq.s Loc18 ; If so, branch
    lea (SupSonAni_Push).l,a1 ; Load Super Push animation
    Loc18:
    move.b status(a0),d1 ; move status to d1
    andi.b #1,d1
    andi.b #$FC,render_flags(a0)
    or.b d1,render_flags(a0)
    bra.w SAnim_Do2
    ; ===========================================================================
    
    ; ---------------------------------------------------------------------------
    ; Animation script - Sonic
    ; ---------------------------------------------------------------------------
    ; off_1B618:
    SonicAniData:
    dc.w SonAni_Walk-SonicAniData ; 0
    dc.w SonAni_Run-SonicAniData ; 1
    dc.w SonAni_Roll-SonicAniData ; 2
    dc.w SonAni_Roll2-SonicAniData ; 3
    dc.w SonAni_Push-SonicAniData ; 4
    dc.w SonAni_Wait-SonicAniData ; 5
    dc.w SonAni_Balance-SonicAniData ; 6
    dc.w SonAni_LookUp-SonicAniData ; 7
    dc.w SonAni_Duck-SonicAniData ; 8
    dc.w SonAni_Spindash-SonicAniData ; 9
    dc.w SonAni_Blink-SonicAniData ; 10 ; $A
    dc.w SonAni_GetUp-SonicAniData ; 11 ; $B
    dc.w SonAni_Balance2-SonicAniData ; 12 ; $C
    dc.w SonAni_Stop-SonicAniData ; 13 ; $D
    dc.w SonAni_Float-SonicAniData ; 14 ; $E
    dc.w SonAni_Float2-SonicAniData ; 15 ; $F
    dc.w SonAni_Spring-SonicAniData ; 16 ; $10
    dc.w SonAni_Hang-SonicAniData ; 17 ; $11
    dc.w SonAni_Dash2-SonicAniData ; 18 ; $12
    dc.w SonAni_Dash3-SonicAniData ; 19 ; $13
    dc.w SonAni_Hang2-SonicAniData ; 20 ; $14
    dc.w SonAni_Bubble-SonicAniData ; 21 ; $15
    dc.w SonAni_DeathBW-SonicAniData ; 22 ; $16
    dc.w SonAni_Drown-SonicAniData ; 23 ; $17
    dc.w SonAni_Death-SonicAniData ; 24 ; $18
    dc.w SonAni_Hurt-SonicAniData ; 25 ; $19
    dc.w SonAni_Hurt-SonicAniData ; 26 ; $1A
    dc.w SonAni_Slide-SonicAniData ; 27 ; $1B
    dc.w SonAni_Blank-SonicAniData ; 28 ; $1C
    dc.w SonAni_Balance3-SonicAniData ; 29 ; $1D
    dc.w SonAni_Balance4-SonicAniData ; 30 ; $1E
    dc.w SupSonAni_Transform-SonicAniData ; 31 ; $1F
    dc.w SonAni_Lying-SonicAniData ; 32 ; $20
    dc.w SonAni_LieDown-SonicAniData ; 33 ; $21
    SonAni_Walk: dc.b $FF, $F,$10,$11,$12,$13,$14, $D, $E,$FF
    SonAni_Run: dc.b $FF,$2D,$2E,$2F,$30,$FF,$FF,$FF,$FF,$FF
    SonAni_Roll: dc.b $FE,$3D,$41,$3E,$41,$3F,$41,$40,$41,$FF
    SonAni_Roll2: dc.b $FE,$3D,$41,$3E,$41,$3F,$41,$40,$41,$FF
    SonAni_Push: dc.b $FD,$48,$49,$4A,$4B,$FF,$FF,$FF,$FF,$FF
    SonAni_Wait:
    dc.b 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
    dc.b 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2
    dc.b 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 5
    dc.b 5, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 6, 6, 6
    dc.b 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 5, 5, 5, 4, 4, 4
    dc.b 5, 5, 5, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 6
    dc.b 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 5, 5, 5, 4
    dc.b 4, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 5
    dc.b 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 5, 5
    dc.b 5, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 4, 4, 4
    dc.b 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 8, 8
    dc.b 8, 9, 9, 9,$FE, 6
    SonAni_Balance: dc.b 9,$CC,$CD,$CE,$CD,$FF
    SonAni_LookUp: dc.b 5, $B, $C,$FE, 1
    SonAni_Duck: dc.b 5,$4C,$4D,$FE, 1
    SonAni_Spindash:dc.b 0,$42,$43,$42,$44,$42,$45,$42,$46,$42,$47,$FF
    SonAni_Blink: dc.b 1, 2,$FD, 0
    SonAni_GetUp: dc.b 3, $A,$FD, 0
    SonAni_Balance2:dc.b 3,$C8,$C9,$CA,$CB,$FF
    SonAni_Stop: dc.b 5,$D2,$D3,$D4,$D5,$FD, 0 ; halt/skidding animation
    SonAni_Float: dc.b 7,$54,$59,$FF
    SonAni_Float2: dc.b 7,$54,$55,$56,$57,$58,$FF
    SonAni_Spring: dc.b $2F,$5B,$FD, 0
    SonAni_Hang: dc.b 1,$50,$51,$FF
    SonAni_Dash2: dc.b $F,$43,$43,$43,$FE, 1
    SonAni_Dash3: dc.b $F,$43,$44,$FE, 1
    SonAni_Hang2: dc.b $13,$6B,$6C,$FF
    SonAni_Bubble: dc.b $B,$5A,$5A,$11,$12,$FD, 0 ; breathe
    SonAni_DeathBW: dc.b $20,$5E,$FF
    SonAni_Drown: dc.b $20,$5D,$FF
    SonAni_Death: dc.b $20,$5C,$FF
    SonAni_Hurt: dc.b $40,$4E,$FF
    SonAni_Slide: dc.b 9,$4E,$4F,$FF
    SonAni_Blank: dc.b $77, 0,$FD, 0
    SonAni_Balance3:dc.b $13,$D0,$D1,$FF
    SonAni_Balance4:dc.b 3,$CF,$C8,$C9,$CA,$CB,$FE, 4
    SonAni_Lying: dc.b 9, 8, 9,$FF
    SonAni_LieDown: dc.b 3, 7,$FD, 0
    even
    ; ---------------------------------------------------------------------------
    ; Animation script-Super Sonic
    ; (many of these point to the data above this)
    ; ---------------------------------------------------------------------------
    SuperSonicAniData:
    dc.w SupSonAni_Walk-SuperSonicAniData ; 0
    dc.w SupSonAni_Run-SuperSonicAniData ; 1
    dc.w SonAni_Roll-SuperSonicAniData ; 2
    dc.w SonAni_Roll2-SuperSonicAniData ; 3
    dc.w SupSonAni_Push-SuperSonicAniData ; 4
    dc.w SupSonAni_Stand-SuperSonicAniData ; 5
    dc.w SupSonAni_Balance-SuperSonicAniData ; 6
    dc.w SonAni_LookUp-SuperSonicAniData ; 7
    dc.w SupSonAni_Duck-SuperSonicAniData ; 8
    dc.w SonAni_Spindash-SuperSonicAniData ; 9
    dc.w SonAni_Blink-SuperSonicAniData ; 10 ; $A
    dc.w SonAni_GetUp-SuperSonicAniData ; 11 ; $B
    dc.w SonAni_Balance2-SuperSonicAniData ; 12 ; $C
    dc.w SonAni_Stop-SuperSonicAniData ; 13 ; $D
    dc.w SonAni_Float-SuperSonicAniData ; 14 ; $E
    dc.w SonAni_Float2-SuperSonicAniData ; 15 ; $F
    dc.w SonAni_Spring-SuperSonicAniData ; 16 ; $10
    dc.w SonAni_Hang-SuperSonicAniData ; 17 ; $11
    dc.w SonAni_Dash2-SuperSonicAniData ; 18 ; $12
    dc.w SonAni_Dash3-SuperSonicAniData ; 19 ; $13
    dc.w SonAni_Hang2-SuperSonicAniData ; 20 ; $14
    dc.w SonAni_Bubble-SuperSonicAniData ; 21 ; $15
    dc.w SonAni_DeathBW-SuperSonicAniData ; 22 ; $16
    dc.w SonAni_Drown-SuperSonicAniData ; 23 ; $17
    dc.w SonAni_Death-SuperSonicAniData ; 24 ; $18
    dc.w SonAni_Hurt-SuperSonicAniData ; 25 ; $19
    dc.w SonAni_Hurt-SuperSonicAniData ; 26 ; $1A
    dc.w SonAni_Slide-SuperSonicAniData ; 27 ; $1B
    dc.w SonAni_Blank-SuperSonicAniData ; 28 ; $1C
    dc.w SonAni_Balance3-SuperSonicAniData ; 29 ; $1D
    dc.w SonAni_Balance4-SuperSonicAniData ; 30 ; $1E
    dc.w SupSonAni_Transform-SuperSonicAniData ; 31 ; $1F
    
    SupSonAni_Walk: dc.b $FF,$77,$78,$79,$7A,$7B,$7C,$75,$76,$FF
    SupSonAni_Run: dc.b $FF,$B5,$B9,$FF,$FF,$FF,$FF,$FF,$FF,$FF
    SupSonAni_Push: dc.b $FD,$BD,$BE,$BF,$C0,$FF,$FF,$FF,$FF,$FF
    SupSonAni_Stand: dc.b 7,$72,$73,$74,$73,$FF
    SupSonAni_Balance: dc.b 9,$C2,$C3,$C4,$C3,$C5,$C6,$C7,$C6,$FF
    SupSonAni_Duck: dc.b 5,$C1,$FF
    SupSonAni_Transform: dc.b
    
    2,$6D,$6D,$6E,$6E,$6F,$70,$71,$70,$71,$70,$71,$70,$71,$FD, 0
    even
    
    Build & something seems off.
    Now port the DMAqueue which the tutorial can be found here
    http://info.sonicretro.org/SCHG_How-to:Add_Spin_Dash_to_Sonic_1/Part_3
    & also Extend sonic's art limit found here
    http://info.sonicretro.org/SCHG_How-to:Extend_the_Sonic_1_sprite_mappings_and_art_limit
    only change the loc_D700 & Anim_Run.
    So far everything seems right. Now to get to Poting Super Sonic.
    At sonic_JumpHeight, go to locret_134C2 & add this

    Code:
    tst.b $12(a0) ; is Sonic exactly at the height of his jump?
    beq.s Sonic_CheckGoSuper ; if yes, test for turning into Super Sonic
    
    before the rts.
    In s2.asm, find & copy the Sonic_CheckGoSuper all the way down to End of subroutine Sonic_Super. Paste it in sonic1.asm below ; End of function Sonic_JumpHeight & convert code to Sonic 1. After fixes should look like this (some code is commented out)
    Code:
    
    Sonic_CheckGoSuper:
    tst.b (Update_HUD_timer).w ; Has the timer stopped?
    beq.s return_1ABA4 ; if yes, branch
    tst.b (Super_Sonic_flag).w ; is Sonic already Super?
    bne.s return_1ABA4 ; if yes, branch
    ;cmpi.b #7,(Emerald_count).w ; does Sonic have exactly 7 emeralds?
    ;bne.s return_1ABA4 ; if not, branch
    cmpi.w #50,(Ring_count).w ; does Sonic have at least 50 rings?
    bcs.s return_1ABA4 ; if not, branch
    
    move.b #1,(Super_Sonic_palette).w ; set Super Sonic Pallet
    move.b #$F,(Palette_frame_count).w ; and the Pallet frame count
    move.b #1,(Super_Sonic_flag).w ; and Make Sonic Super
    move.b #$81,obj_control(a0)
    move.b #$1F,anim(a0) ; use transformation animation
    ;move.b #$7E,(Object_RAM+$2040).w ; Commented out, THIS MOVES THE HUD AWAY
    move.w #$A00,(Sonic_top_speed).w ; Change top speed
    move.w #$30,(Sonic_acceleration).w ; change acceleration
    move.w #$100,(Sonic_deceleration).w ; change deceleration
    move.w #0,invincibility_time(a0) ; no timer for invincibility (hmmmm...)
    bset #1,status_secondary(a0) ; make Sonic invincible
    ;move.w #$5F+$80,d0
    ;jsr (PlaySound).l ; Play transformation sound effect.
    ;move.w #$16+$80,d0
    ;jmp (PlayMusic).l ; load the Super Sonic song and return
    
    ; ---------------------------------------------------------------------------
    return_1ABA4:
    rts
    ; End of subroutine Sonic_CheckGoSuper
    
    ; ---------------------------------------------------------------------------
    ; Subroutine doing the extra logic for Super Sonic
    ; ---------------------------------------------------------------------------
    
    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
    
    ; loc_1ABA6:
    Sonic_Super:
    tst.b (Super_Sonic_flag).w ; Ignore all this code if not Super Sonic
    beq.w return_1AC3C
    tst.b (Update_HUD_timer).w ; ???
    beq.s Sonic_RevertToNormal ; ?
    subq.w #1,(Super_Sonic_frame_count).w ; subtract 1 from Super Sonic Frame Count
    bpl.w return_1AC3C ; branch if plus
    move.w #60,(Super_Sonic_frame_count).w ; Reset frame counter to 60
    tst.w (Ring_count).w ; Does Sonic have rings?
    beq.s Sonic_RevertToNormal ; if not, branch
    ori.b #1,(Update_HUD_rings).w ; Update the rings HUD
    cmpi.w #1,(Ring_count).w ; Does Sonic have at least 1 ring?
    beq.s loc20 ; if so, branch
    cmpi.w #10,(Ring_count).w ; 10 rings?
    beq.s loc20 ; if so, branch
    cmpi.w #100,(Ring_count).w ; 100 rings?
    bne.s loc21 ; if not, branch
    loc20:
    ori.b #$80,(Update_HUD_rings).w
    loc21:
    subq.w #1,(Ring_count).w ; Subtract 1 from ring count
    bne.s return_1AC3C
    ; loc_1ABF2:
    Sonic_RevertToNormal:
    move.b #2,(Super_Sonic_palette).w ; Remove rotating palette
    move.w #$28,($FFFFF65C).w ; Unknown
    move.b #0,(Super_Sonic_flag).w ; Revert Sonic back to normal
    move.b #1,next_anim(a0) ; Change animation back to normal ?
    move.w #1,invincibility_time(a0) ; Remove invincibility
    move.w #$600,(Sonic_top_speed).w ; Revert Speeds
    move.w #$C,(Sonic_acceleration).w ; ^^^
    move.w #$80,(Sonic_deceleration).w ; ^^^
    btst #6,status(a0) ; Check if underwater, return if not
    beq.s return_1AC3C
    move.w #$300,(Sonic_top_speed).w ; Revert if underwater
    move.w #6,(Sonic_acceleration).w ; ^^^
    move.w #$40,(Sonic_deceleration).w ; ^^^
    
    return_1AC3C:
    rts
    ; End of subroutine Sonic_Super
    
    However you're not invincible.
    Change the

    Code:
    bset #1,status_secondary(a0) ; make Sonic invincible
    
    to
    Code:
    move.b #1,($FFFFFE2D).w ; make Sonic invincible
    
    Now he goes invincible, but no rotating pallet, but he retains his super form through the stage.
    Also he still runs at super speed.
    Go to Obj0D_Spin & add
    Code:
    Clr (Super_Sonic_Flag).w ; Revert Sonic to Normal
    move.w #$300,(Sonic_top_speed).w ; Revert speeds
    move.w #6,(Sonic_acceleration).w ; ^^^
    move.w #$40,(Sonic_deceleration).w ; ^^^
    
    below the label, & Also Below the KillSonic Label, but grab an invincibility monitor & let it run out. you can get hurt now.
    go to Obj2E_ChkInvinc & add
    Code:
    cmpi.b #1,(Super_Sonic_Flag).w ; Prevent Sonic from getting (invincibility, shoes) if Super
    beq Obj2E_NoMusic
    
    below
    Code:
    bne.s Obj2E_ChkRings
    
    & also in chkshoes below
    Code:
    bne.s Obj2E_ChkShield
    
    Now that is fixed & you have a Super Sonic.
    If you want your own music & sound, just change

    Code:
    ;move.w #$5F+$80,d0
    ;jsr (PlaySound).l ; Play transformation sound effect.
    ;move.w #$16+$80,d0
    ;jmp (PlayMusic).l ; load the Super Sonic song and return
    
    To a sound & music you prefer, or if you like, to this
    Code:
    move.l #SoundC3,d0
    jsr PlaySound ; Play transformation sound effect.
    move.l #Music87,d0
    jmp PlayMusic ; load the Super Sonic song and return
    
    To add PalletCycle, go to palcycle_Load & add after the label
    Code:
    bsr.w Palcycle_SuperSonic
    
    below the palcycle's .bin files, copy from s2.asm Palcycle_SuperSonic paste to to sonic 1.asm
    Code:
    PalCycle_SuperSonic:
    move.b (Super_Sonic_palette).w,d0
    beq.s return_2186
    bmi.w loc_21E6
    subq.b #1,d0
    bne.s loc_2188
    subq.b #1,(Palette_frame_count).w
    bpl.s return_2186
    move.b #3,(Palette_frame_count).w
    lea (Pal_2246).l,a0
    move.w ($FFFFF65C).w,d0
    addq.w #8,($FFFFF65C).w
    cmpi.w #$30,($FFFFF65C).w
    bcs.s +
    move.b #-1,(Super_Sonic_palette).w
    move.b #0,(MainCharacter+obj_control).w
    + lea (Normal_palette+4).w,a1
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)
    
    return_2186:
    rts
    ; ===========================================================================
    
    loc_2188:
    subq.b #1,(Palette_frame_count).w
    bpl.s return_2186
    move.b #3,(Palette_frame_count).w
    lea (Pal_2246).l,a0
    move.w ($FFFFF65C).w,d0
    subq.w #8,($FFFFF65C).w
    bcc.s loc_21B0
    move.b #0,($FFFFF65C).w
    move.b #0,(Super_Sonic_palette).w
    loc_21B0:
    lea (Normal_palette+4).w,a1
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)
    lea (Pal_22C6).l,a0
    cmpi.b #$D,(Current_Zone).w
    beq.s +
    cmpi.b #$F,(Current_Zone).w
    bne.s return_2186
    lea (Pal_2346).l,a0
    + lea (Underwater_palette+4).w,a1
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)
    rts
    ; ===========================================================================
    
    loc_21E6:
    subq.b #1,(Palette_frame_count).w
    bpl.s return_2186
    move.b #7,(Palette_frame_count).w
    lea (Pal_2246).l,a0
    move.w ($FFFFF65C).w,d0
    addq.w #8,($FFFFF65C).w
    cmpi.w #$78,($FFFFF65C).w
    bcs.s +
    move.w #$30,($FFFFF65C).w
    + lea (Normal_palette+4).w,a1
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)
    lea (Pal_22C6).l,a0
    cmpi.b #$D,(Current_Zone).w
    beq.s +
    cmpi.b #$F,(Current_Zone).w
    bne.w return_2186
    lea (Pal_2346).l,a0
    + lea (Underwater_palette+4).w,a1
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)
    rts
    ; End of function PalCycle_SuperSonic
    
    ; ===========================================================================
    ;----------------------------------------------------------------------------
    ;Palette for transformation to Super Sonic
    ;----------------------------------------------------------------------------
    Pal_2246: BINCLUDE "art/palettes/Super Sonic transformation.bin"
    ;----------------------------------------------------------------------------
    ;Palette for transformation to Super Sonic while underwater in CPZ
    ;----------------------------------------------------------------------------
    Pal_22C6: BINCLUDE "art/palettes/CPZWater SS transformation.bin"
    ;----------------------------------------------------------------------------
    ;Palette for transformation to Super Sonic while underwater in ARZ
    ;----------------------------------------------------------------------------
    Pal_2346: BINCLUDE "art/palettes/ARZWater SS transformation.bin"
    
    just convert it to Sonic 1, also change binclude to incbin, change underwater pallets to load in LZ & SBZ3 instead. after changes should look something like this
    Code:
    PalCycle_SuperSonic:
    move.b (Super_Sonic_palette).w,d0 ; move Super Sonic Pallet to d0
    beq.s return_2186
    bmi.w loc_21E6
    subq.b #1,d0 ; Subtract 1 from Super Sonic Pallet
    bne.s loc_2188
    subq.b #1,(Palette_frame_count).w ; Subtract 1 from Pallet frame count
    bpl.s return_2186 ; branch if plus
    move.b #3,(Palette_frame_count).w ; set Pallet frame count to 3
    lea (Pal_2246).l,a0 ; Load Pallet
    move.w ($FFFFF65C).w,d0 ; Move ??? to d0
    addq.w #8,($FFFFF65C).w add 8 to ???
    cmpi.w #$30,($FFFFF65C).w ; is ??? set to $30
    bcs.s Loc30 ; Branch
    move.b #-1,(Super_Sonic_palette).w
    move.b #0,(MainCharacter+obj_control).w
    Loc30: lea (Normal_palette+4).w,a1 Load Normal Pallet
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)
    
    return_2186:
    rts
    ; ===========================================================================
    
    loc_2188:
    subq.b #1,(Palette_frame_count).w ; Subtract 1 from Pallet frame count
    bpl.s return_2186 ; branch if plus
    move.b #3,(Palette_frame_count).w ; set Pallet Frame count to 3
    lea (Pal_2246).l,a0 ; load pallet
    move.w ($FFFFF65C).w,d0 ; move ??? to d0
    subq.w #8,($FFFFF65C).w ; subtract 8 to ???
    bcc.s loc_21B0 ; branch
    move.b #0,($FFFFF65C).w ; clear it
    move.b #0,(Super_Sonic_palette).w ; Clear Super Sonic Pallet
    loc_21B0:
    lea (Normal_palette+4).w,a1 ; Load Normal Pallet
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)
    lea (Pal_22C6).l,a0 ; Load Pallet
    cmpi.b #$01,(Current_Zone).w ; Is current zone (Labyrinth)?
    beq.s Loc31 ; If so, Branch
    cmpi.b #$F,(Current_Zone).w ; Is Current zone (& Act Scrap Brain Zone 3) ?
    bne.s return_2186 ;if not, branch
    lea (Pal_2346).l,a0 ; load pallet
    Loc31: lea (Underwater_palette+4).w,a1 ; load underwater pallet
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)
    rts
    ; ===========================================================================
    
    loc_21E6:
    subq.b #1,(Palette_frame_count).w ; Subtract 1 from Pallet frame count
    bpl.s return_2186 ; branch if plus
    move.b #7,(Palette_frame_count).w ; set to 7 instead
    lea (Pal_2246).l,a0 ; load pallet
    move.w ($FFFFF65C).w,d0 ; move ??? to d0
    addq.w #8,($FFFFF65C).w ; add 8 to it
    cmpi.w #$78,($FFFFF65C).w ; Is it set to $78?
    bcs.s Loc32 ; branch
    move.w #$30,($FFFFF65C).w ; set it to $30
    Loc32: lea (Normal_palette+4).w,a1 ; load Normal pallet
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)
    lea (Pal_22C6).l,a0 ; Load pallet
    cmpi.b #$01,(Current_Zone).w ; Is The zone (Labyrinth)?
    beq.s Loc33 ; if so, branch
    cmpi.b #$F,(Current_Zone).w ; Is zone (& act Scrap Brain Zone 3)?
    bne.w return_2186 ; if not, branch
    lea (Pal_2346).l,a0 ; load pallet
    Loc33: lea (Underwater_palette+4).w,a1 ; load Underwater pallet
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)
    rts
    ; End of function PalCycle_SuperSonic
    
    Pal_2246: incbin "SST.bin" ; Super Sonic's Pallet
    Pal_22C6: incbin "LZT.bin" ; Underwater in Labyrinth Zone
    ;----------------------------------------------------------------------------
    ;Palette for transformation to Super Sonic while underwater in ARZ
    ;----------------------------------------------------------------------------
    Pal_2346: incbin "SBZT.bin" ; Underwater In Scrap Brain Zone 3 (Labyrinth Zone 4?)
    
    & be sure to take the needed files & rename them if necessary.

    EDIT: Some comments added, & I need to find out what $FFFFF65C Does. You need to port the DMAQueue for Sonic's art to load correctly, or at the shoes will load Points art over it.
    Edit 2: I figured out what caused the HUD to move away so added note and more comments. Also I thought I added code tags when I did this, fixed
     
    Last edited: Dec 6, 2017
  2. DanielHall

    DanielHall Well-Known Member Member

    Joined:
    Jan 18, 2010
    Messages:
    860
    Location:
    North Wales
    Cool, would appreciate some comments on the code myself, though. At the moment, it's literally a C/P guide, with very little annotation on what exactly any of the instructions do. There's nothing to learn from this if all someone's going to do is just come and paste it in. For instance, two model examples:
     


    Code:
    move.w #$28,($FFFFF65C).w ; Unknown
    





    addq.w #8,($FFFFF65C).w
    cmpi.w #$30,($FFFFF65C).w
    bcs.s +
    move.b #-1,(Super_Sonic_palette).w
    move.b #0,(MainCharacter+obj_control).w
    + lea (Normal_palette+4).w,a1
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0.w),(a1)



    Would a new hacker understand what any of these things do? Your guide would also raises questions such as: "Why would I need to port the DMA queue?" / "Why would I need to extend the animation limit?" etc. These are questions your guide should be answering so it doesn't become a complete C/P guide for something that would have been a notable accomplishment around 5 years ago. There was a similar guide on here while back, and was removed for a similar reason, but it's your guide and choice as to whether you want to explain a little more detail or not.
     
    Last edited by a moderator: Mar 12, 2015
  3. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    I agree with the lack of commentation issue, but it isn't nearly copy and paste. I had to add new equates from scratch, as the actual equate setup he mentioned doesn't seem to work right. I had to both look up what the equates should be and find unused ram for the new ones; add that to the fact that the formatting is a bit off, and it's anything but copy/paste. Also, I'd like to point out that you can skip the first part of the guide if you don't want your old sonic art getting overwritten by S2s'; it works, but lacks custom animations, which I find not to be of issue.
     
  4. warr1or2

    warr1or2 I AM CLG Member

    Joined:
    Apr 7, 2008
    Messages:
    417
    Location:
    Town Creek, AL
    I'll see what I can do.

    EDIT1: some comments added
     
    Last edited by a moderator: Mar 12, 2015
  5. Devon

    Devon I'm a loser, baby, so why don't you kill me? Member

    Joined:
    Aug 26, 2013
    Messages:
    1,376
    Location:
    your mom
    Cool guide and all, but now everyone is going to have Super Sonic in Sonic 1, and now it isn't very special (for a lack of a better word) anymore.
     
  6. Clownacy

    Clownacy Retired Staff lolololo Member

    Joined:
    Aug 15, 2014
    Messages:
    1,020
    That's why things are so complicated when it comes to guides. There are so many things I could easily make good educational guides out of, like porting Super Sonic's code to Tails, and making "Super Tails", but I've reasoned with myself to only write guides on engine modifications, not gameplay.


    It's the same reason I've given up my noob-pursuit of making all guides on Retro's wiki target both the Xeno/Hivebrain and Git disasm: learning. The way I see it, no documentation will ever amount to a little tough love. It was me being left in the dark that made me move on from the mindless C/P nonsense, and actually learn 68k ASM. You know that saying: "Give a man a fish"?
     
  7. warr1or2

    warr1or2 I AM CLG Member

    Joined:
    Apr 7, 2008
    Messages:
    417
    Location:
    Town Creek, AL
    Yea, but at least this may teach one Sonic 2 to Sonic 1 Conversion from using +, ++, -, -- to Loc1, Loc2, Loc3.

    (at least I'm getting better with porting)

    I'm trying to get to that as best I can. That way I can add more to it to tell what does what.
     
    Last edited by a moderator: Mar 13, 2015
Thread Status:
Not open for further replies.