Improve the Fade to White Routines in Sonic 1

Discussion in 'Tutorials Archive' started by ProjectFM, Aug 21, 2015.

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

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    Ever since I found Markey Jester's tutorial on improving fade in and fade out progression, it always bothered me the that there wasn't a tutorial for improving the fade to and from white used for Sonic 1's special stage so today, I fixed that. Originally, the fade to white would look like this:[​IMG]

    To fix it, replace the beginning of Pal_MakeWhite to the end of Pal_AddColor2 with this: (Made to work with Hivebrain's 2005 Sonic 1 disassembly)

    ; ---------------------------------------------------------------------------
    ; Subroutine to fill the pallet with white (special stage)
    ; ---------------------------------------------------------------------------

    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||


    Pal_MakeWhite: ; XREF: SpecialStage
    move.w #$3F,($FFFFF626).w
    moveq #0,d0
    lea ($FFFFFB00).w,a0
    move.b ($FFFFF626).w,d0
    adda.w d0,a0
    move.w #$EEE,d1
    move.b ($FFFFF627).w,d0

    PalWhite_Loop:
    move.w d1,(a0)+
    dbf d0,PalWhite_Loop ; fill pallet with $000 (black)
    moveq #$0E,d4 ; MJ: prepare maximum colour check
    moveq #$00,d6 ; MJ: clear d6

    loc_1EF4:
    bsr.w RunPLC_RAM
    move.b #$12,($FFFFF62A).w
    bsr.w DelayProgram
    bchg #$00,d6 ; MJ: change delay counter
    beq loc_1EF4 ; MJ: if null, delay a frame
    bsr.s Pal_WhiteToBlack
    subq.b #$02,d4 ; MJ: decrease colour check
    bne loc_1EF4 ; MJ: if it has not reached null, branch
    move.b #$12,($FFFFF62A).w ; MJ: wait for V-blank again (so colours transfer)
    bra DelayProgram ; MJ: ''
    ; End of function Pal_MakeWhite


    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||


    Pal_WhiteToBlack: ; XREF: Pal_MakeWhite
    moveq #0,d0
    lea ($FFFFFB00).w,a0
    lea ($FFFFFB80).w,a1
    move.b ($FFFFF626).w,d0
    adda.w d0,a0
    adda.w d0,a1
    move.b ($FFFFF627).w,d0

    loc_1F20:
    bsr.s Pal_DecColor2
    dbf d0,loc_1F20
    cmpi.b #1,($FFFFFE10).w
    bne.s locret_1F4A
    moveq #0,d0
    lea ($FFFFFA80).w,a0
    lea ($FFFFFA00).w,a1
    move.b ($FFFFF626).w,d0
    adda.w d0,a0
    adda.w d0,a1
    move.b ($FFFFF627).w,d0

    loc_1F44:
    bsr.s Pal_DecColor2
    dbf d0,loc_1F44

    locret_1F4A:
    rts
    ; End of function Pal_WhiteToBlack


    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||


    Pal_DecColor2: ; XREF: Pal_WhiteToBlack
    move.b (a1),d5 ; MJ: load blue
    move.w (a1)+,d1 ; MJ: load green and red
    move.b d1,d2 ; MJ: load red
    lsr.b #$04,d1 ; MJ: get only green
    andi.b #$0E,d2 ; MJ: get only red
    move.w (a0),d3 ; MJ: load current colour in buffer
    cmp.b d5,d4 ; MJ: is it time for blue to fade?
    bcs FCI2_NoBlue ; MJ: if not, branch
    subi.w #$0200,d3 ; MJ: dencrease blue

    FCI2_NoBlue:
    cmp.b d1,d4 ; MJ: is it time for green to fade?
    bcs FCI2_NoGreen ; MJ: if not, branch
    subi.b #$20,d3 ; MJ: dencrease green

    FCI2_NoGreen:
    cmp.b d2,d4 ; MJ: is it time for red to fade?
    bcs FCI2_NoRed ; MJ: if not, branch
    subq.b #$02,d3 ; MJ: dencrease red

    FCI2_NoRed:
    move.w d3,(a0)+ ; MJ: save colour
    rts ; MJ: return
    ; End of function Pal_DecColor2

    ; ---------------------------------------------------------------------------
    ; Subroutine to make a white flash when you enter a special stage
    ; ---------------------------------------------------------------------------

    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||


    Pal_MakeFlash: ; XREF: SpecialStage
    move.w #$3F,($FFFFF626).w
    moveq #$07,d4 ; MJ: set repeat times
    moveq #$00,d6 ; MJ: clear d6

    loc_1F86:
    bsr.w RunPLC_RAM
    move.b #$12,($FFFFF62A).w
    bsr.w DelayProgram
    bchg #$00,d6 ; MJ: change delay counter
    beq loc_1F86 ; MJ: if null, delay a frame
    bsr.s Pal_ToWhite
    dbf d4,loc_1F86
    rts
    ; End of function Pal_MakeFlash


    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||


    Pal_ToWhite: ; XREF: Pal_MakeFlash
    moveq #0,d0
    lea ($FFFFFB00).w,a0
    move.b ($FFFFF626).w,d0
    adda.w d0,a0
    move.b ($FFFFF627).w,d0

    loc_1FAC:
    bsr.s Pal_AddColor2
    dbf d0,loc_1FAC

    moveq #0,d0
    lea ($FFFFFA80).w,a0
    move.b ($FFFFF626).w,d0
    adda.w d0,a0
    move.b ($FFFFF627).w,d0

    loc_1FC2:
    bsr.s Pal_AddColor2
    dbf d0,loc_1FC2
    rts
    ; End of function Pal_ToWhite


    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||


    Pal_AddColor2: ; XREF: Pal_ToWhite
    move.w (a0),d5 ; MJ: load colour
    cmpi.w #$EEE,d5
    beq.s FCO2_NoRed
    move.w d5,d1 ; MJ: copy to d1
    move.b d1,d2 ; MJ: load green and red
    move.b d1,d3 ; MJ: load red
    andi.w #$0E00,d1 ; MJ: get only blue
    cmpi.w #$0E00,d1
    beq FCO2_NoBlue ; MJ: if blue is finished, branch
    addi.w #$0200,d5 ; MJ: increase blue

    FCO2_NoBlue:
    andi.w #$00E0,d2 ; MJ: get only green (needs to be word)
    cmpi.w #$00E0,d2
    beq FCO2_NoGreen ; MJ: if green is finished, branch
    addi.b #$20,d5 ; MJ: increase green

    FCO2_NoGreen:
    andi.b #$0E,d3 ; MJ: get only red
    cmpi.b #$0E,d3
    beq FCO2_NoRed ; MJ: if red is finished, branch
    addq.b #$02,d5 ; MJ: increase red

    FCO2_NoRed:
    move.w d5,(a0)+ ; MJ: save new colour
    rts ; MJ: return
    ; End of function Pal_AddColor2
    Now it should look like this:

    [​IMG]

    Credit goes to Markey Jester for the original code this is based off of.
     
    MarkeyJester likes this.
  2. TheStoneBanana

    TheStoneBanana banana Member

    Joined:
    Nov 27, 2013
    Messages:
    602
    Location:
    The Milky Way Galaxy
    Though, for whatever reason, I prefer the yellower flash, this looks very nice as well. Good work!
     
  3. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,429
    Location:
    Northern Germany
    Yeah, same here. The yellow flash kinda adds that particular feel to it when entering a special stage. Still nice work!
     
  4. FохConED

    FохConED Join to Digital Resistance! Member

    Joined:
    Dec 13, 2014
    Messages:
    206
    Location:
    Konakovo
    Not bad tutorial. I already use it!
     
Thread Status:
Not open for further replies.