How to improve the fade in and fade out progressions in Sonic 1 and 2

Discussion in 'Approved' started by MarkeyJester, Dec 17, 2011.

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

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    The palette fading routines in Sonic 1 and Sonic 2 (and possibly to a degree Sonic 3 & Knuckles) known as "Pal_FadeTo" and "Pal_FadeFrom", aren't 100% true to their name. Here is a screenshot of Sonic 1's title screen 6 frames during fade in:


    [​IMG]


    From a logical point of view, this is incorrect fading, what happens here is it fades the blue parts in first, then fades the green parts in, and then finally fades the red parts in, the same goes for fading out, red first, then green, finally blue.


    Strictly speaking for a the nearest possible perfect fade, all colours need to be fading in and out simultaneously (At the correct timing of course), so for example the colour 06E4 should fade in the pattern of:


    0020 0040 0060 0080 02A0 04C2 06E4


    And fade out in the pattern of:


    04C2 02A0 0080 0060 0040 0020 0000


    To correct for Sonic 1, you'll need to go to the routine "Pal_FadeTo" and replace everything from there down to "; End of function Pal_DecColor" with this:


    (Unfortunately this is going to look more messy than it is until IPB can get the fucking tab spaces fixed properly)



    Pal_FadeTo:
    move.w #$3F,($FFFFF626).w


    Pal_FadeTo2:


    moveq #0,d0


    lea ($FFFFFB00).w,a0


    move.b ($FFFFF626).w,d0


    adda.w d0,a0


    moveq #0,d1


    move.b ($FFFFF627).w,d0


    Pal_ToBlack:


    move.w d1,(a0)+


    dbf d0,Pal_ToBlack ; fill pallet with $000 (black)


    moveq #$0E,d4 ; MJ: prepare maximum colour check


    moveq #$00,d6 ; MJ: clear d6


    loc_1DCE:


    bsr.w RunPLC_RAM


    move.b #$12,($FFFFF62A).w


    bsr.w DelayProgram


    bchg #$00,d6 ; MJ: change delay counter


    beq loc_1DCE ; MJ: if null, delay a frame


    bsr.s Pal_FadeIn


    subq.b #$02,d4 ; MJ: decrease colour check


    bne loc_1DCE ; 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_FadeTo


    ; ---------------------------------------------------------------------------


    ; Pallet fade-in subroutine


    ; ---------------------------------------------------------------------------


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


    Pal_FadeIn: ; XREF: Pal_FadeTo


    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_1DFA:


    bsr.s Pal_AddColor


    dbf d0,loc_1DFA


    cmpi.b #1,($FFFFFE10).w


    bne.s locret_1E24


    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_1E1E:


    bsr.s Pal_AddColor


    dbf d0,loc_1E1E


    locret_1E24:


    rts


    ; End of function Pal_FadeIn


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


    Pal_AddColor: ; XREF: Pal_FadeIn


    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?


    bhi FCI_NoBlue ; MJ: if not, branch


    addi.w #$0200,d3 ; MJ: increase blue


    FCI_NoBlue:


    cmp.b d1,d4 ; MJ: is it time for green to fade?


    bhi FCI_NoGreen ; MJ: if not, branch


    addi.b #$20,d3 ; MJ: increase green


    FCI_NoGreen:


    cmp.b d2,d4 ; MJ: is it time for red to fade?


    bhi FCI_NoRed ; MJ: if not, branch


    addq.b #$02,d3 ; MJ: increase red


    FCI_NoRed:


    move.w d3,(a0)+ ; MJ: save colour


    rts ; MJ: return


    ; End of function Pal_AddColor


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


    Pal_FadeFrom:


    move.w #$3F,($FFFFF626).w


    moveq #$07,d4 ; MJ: set repeat times


    moveq #$00,d6 ; MJ: clear d6


    loc_1E5C:


    bsr.w RunPLC_RAM


    move.b #$12,($FFFFF62A).w


    bsr.w DelayProgram


    bchg #$00,d6 ; MJ: change delay counter


    beq loc_1E5C ; MJ: if null, delay a frame


    bsr.s Pal_FadeOut


    dbf d4,loc_1E5C


    rts


    ; End of function Pal_FadeFrom


    ; ---------------------------------------------------------------------------


    ; Pallet fade-out subroutine


    ; ---------------------------------------------------------------------------


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


    Pal_FadeOut: ; XREF: Pal_FadeFrom


    moveq #0,d0


    lea ($FFFFFB00).w,a0


    move.b ($FFFFF626).w,d0


    adda.w d0,a0


    move.b ($FFFFF627).w,d0


    loc_1E82:


    bsr.s Pal_DecColor


    dbf d0,loc_1E82


    moveq #0,d0


    lea ($FFFFFA80).w,a0


    move.b ($FFFFF626).w,d0


    adda.w d0,a0


    move.b ($FFFFF627).w,d0


    loc_1E98:


    bsr.s Pal_DecColor


    dbf d0,loc_1E98


    rts


    ; End of function Pal_FadeOut


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


    Pal_DecColor: ; XREF: Pal_FadeOut


    move.w (a0),d5 ; MJ: load colour


    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


    beq FCO_NoBlue ; MJ: if blue is finished, branch


    subi.w #$0200,d5 ; MJ: decrease blue


    FCO_NoBlue:


    andi.b #$E0,d2 ; MJ: get only green


    beq FCO_NoGreen ; MJ: if green is finished, branch


    subi.b #$20,d5 ; MJ: decrease green


    FCO_NoGreen:


    andi.b #$0E,d3 ; MJ: get only red


    beq FCO_NoRed ; MJ: if red is finished, branch


    subq.b #$02,d5 ; MJ: decrease red


    FCO_NoRed:


    move.w d5,(a0)+ ; MJ: save new colour


    rts ; MJ: return


    ; End of function Pal_DecColor



    This will result in proper fading:


    [​IMG]


    The same for Sonic 2:



    Pal_FadeTo:
    move.w #$3F,($FFFFF626).w


    moveq #0,d0


    lea (Normal_palette).w,a0


    move.b ($FFFFF626).w,d0


    adda.w d0,a0


    moveq #0,d1


    move.b ($FFFFF627).w,d0


    ; loc_23DE:


    Pal_ToBlack:


    move.w d1,(a0)+


    dbf d0,Pal_ToBlack ; fill palette with $000 (black)


    moveq #$0E,d4 ; MJ: prepare maximum colour check


    moveq #$00,d6 ; MJ: clear d6


    - bsr.w RunPLC_RAM


    move.b #$12,(Delay_Time).w


    bsr.w DelayProgram


    bchg #$00,d6 ; MJ: change delay counter


    beq - ; MJ: if null, delay a frame


    bsr.s Pal_FadeIn


    subq.b #$02,d4 ; MJ: decrease colour check


    bne - ; MJ: if it has not reached null, branch


    move.b #$12,(Delay_Time).w ; MJ: wait for V-blank again (so colours transfer)


    bra DelayProgram ; MJ: ''


    ; End of function Pal_FadeTo


    ; ---------------------------------------------------------------------------


    ; Palette fade-in subroutine


    ; ---------------------------------------------------------------------------


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


    ; sub_23FE:


    Pal_FadeIn:


    moveq #0,d0


    lea (Normal_palette).w,a0


    lea (Second_palette).w,a1


    move.b ($FFFFF626).w,d0


    adda.w d0,a0


    adda.w d0,a1


    move.b ($FFFFF627).w,d0


    - bsr.s Pal_AddColor


    dbf d0,-


    tst.b (Water_flag).w


    beq.s return_243C


    moveq #0,d0


    lea (Underwater_palette).w,a0


    lea (Underwater_palette_2).w,a1


    move.b ($FFFFF626).w,d0


    adda.w d0,a0


    adda.w d0,a1


    move.b ($FFFFF627).w,d0


    - bsr.s Pal_AddColor


    dbf d0,-


    return_243C:


    rts


    ; End of function Pal_FadeIn


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


    ; sub_243E:


    Pal_AddColor:


    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?


    bhi FCI_NoBlue ; MJ: if not, branch


    addi.w #$0200,d3 ; MJ: increase blue


    FCI_NoBlue:


    cmp.b d1,d4 ; MJ: is it time for green to fade?


    bhi FCI_NoGreen ; MJ: if not, branch


    addi.b #$20,d3 ; MJ: increase green


    FCI_NoGreen:


    cmp.b d2,d4 ; MJ: is it time for red to fade?


    bhi FCI_NoRed ; MJ: if not, branch


    addq.b #$02,d3 ; MJ: increase red


    FCI_NoRed:


    move.w d3,(a0)+ ; MJ: save colour


    rts ; MJ: return


    ; End of function Pal_AddColor


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


    ; sub_246A:


    Pal_FadeFrom:


    move.w #$3F,($FFFFF626).w


    moveq #$07,d4 ; MJ: set repeat times


    moveq #$00,d6 ; MJ: clear d6


    - bsr.w RunPLC_RAM


    move.b #$12,(Delay_Time).w


    bsr.w DelayProgram


    bchg #$00,d6 ; MJ: change delay counter


    beq - ; MJ: if null, delay a frame


    bsr.s Pal_FadeOut


    dbf d4,-


    rts


    ; End of function Pal_FadeFrom


    ; ---------------------------------------------------------------------------


    ; Palette fade-out subroutine


    ; ---------------------------------------------------------------------------


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


    ; sub_248A:


    Pal_FadeOut:


    moveq #0,d0


    lea (Normal_palette).w,a0


    move.b ($FFFFF626).w,d0


    adda.w d0,a0


    move.b ($FFFFF627).w,d0


    - bsr.s Pal_DecColor


    dbf d0,-


    moveq #0,d0


    lea (Underwater_palette).w,a0


    move.b ($FFFFF626).w,d0


    adda.w d0,a0


    move.b ($FFFFF627).w,d0


    - bsr.s Pal_DecColor


    dbf d0,-


    rts


    ; End of function Pal_FadeOut


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


    ; sub_24B8:


    Pal_DecColor:


    move.w (a0),d5 ; MJ: load colour


    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


    beq FCO_NoBlue ; MJ: if blue is finished, branch


    subi.w #$0200,d5 ; MJ: decrease blue


    FCO_NoBlue:


    andi.b #$E0,d2 ; MJ: get only green


    beq FCO_NoGreen ; MJ: if green is finished, branch


    subi.b #$20,d5 ; MJ: decrease green


    FCO_NoGreen:


    andi.b #$0E,d3 ; MJ: get only red


    beq FCO_NoRed ; MJ: if red is finished, branch


    subq.b #$02,d5 ; MJ: decrease red


    FCO_NoRed:


    move.w d5,(a0)+ ; MJ: save new colour


    rts ; MJ: return


    ; End of function Pal_DecColor



    Sonic 2 has a specialised object to deal with title screen fading, so a correction is needed there too, At:



    loc_13302:
    addq.b #2,routine(a0)


    moveq #0,d0


    move.b subtype(a0),d0


    lea (PaletteChangerDataIndex).l,a1


    adda.w (a1,d0.w),a1


    move.l (a1)+,objoff_3A(a0)


    movea.l (a1)+,a2


    move.b (a1)+,d0


    move.w d0,objoff_34(a0)


    lea (Second_palette).w,a3


    adda.w d0,a3


    move.b (a1)+,d0


    move.w d0,objoff_36(a0)



    Place this instruction directly at the end:



    move.b #$0E,objoff_33(a0) ; MJ: set fade counter



    At:



    NewRoutine:
    subq.b #1,objoff_30(a0)


    bpl.s return_1337A


    move.b objoff_31(a0),objoff_30(a0)


    subq.b #1,objoff_32(a0)


    bmi.w DeleteObject



    Place these instructions directly underneath (Just above "movea.l objoff_3A(a0),a2"):




    moveq #$00,d4 ; MJ: clear d4


    move.b objoff_33(a0),d4 ; MJ: load fade counter


    subq.b #$02,objoff_33(a0) ; MJ: decrease fade counter



    And finally:



    off_1338C: C9PalInfo Pal_AddColor, Pal_1342C, $60, $F,2,$15



    Replace the $15 on the end with $07, this will correct the palette fading in and out for Sonic 2:


    [​IMG]


    Left old, right new, here are some roms with the code in action:


    Sonic 1 Fade


    Sonic 2 Fade
     
    Last edited by a moderator: Dec 18, 2011
  2. Psycho RFG

    Psycho RFG Well-Known Member Member

    Joined:
    Feb 22, 2011
    Messages:
    234
    Nice! Good work MarkeyJester. Now the palettes fit perfecly when using fades. The white starting as blue was too weird sometimes. Thanks for this fix.
     
  3. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    loc_1332E:
    move.w (a2)+,(a3)+


    dbf d0,loc_1332E


    move.b (a1)+,d0


    move.b d0,objoff_30(a0)


    move.b d0,objoff_31(a0)


    move.b (a1)+,objoff_32(a0)


    rts


    ; ===========================================================================


    ; unused/dead code ; a0=object


    subq.b #1,objoff_30(a0)


    bpl.s return_1337A


    move.b objoff_31(a0),objoff_30(a0)


    subq.b #1,objoff_32(a0)


    bmi.w DeleteObject


    movea.l objoff_3A(a0),a2


    movea.l a0,a3


    move.w objoff_36(a0),d0


    move.w objoff_34(a0),d1


    lea (Normal_palette).w,a0


    adda.w d1,a0


    lea (Second_palette).w,a1


    adda.w d1,a1



    So that code isn't really dead then? =P Also, I applied your new fading technique and it's nice and it works from going from one level to another, but the title menu has gone wrong now, any reason?


    [​IMG]


    EDIT: Although, when the stars twinkle just before the art work loads, if you press start, it all loads up instantly and then it's viewable. If I don't press start and let the artwork fade in, I get the above result.
     
    Last edited by a moderator: Dec 18, 2011
  4. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,429
    Location:
    Northern Germany
    Man, we should really get these ASM tags to work again. But until that is done, it'd be a better idea to use [code] tags, so it'd be great if you could edit your post again (as annoying as it may seem).


    As for the actual content, this is one of these "Never noticed it before you mentioned it" kind of things. This comes from the fact that I always found the fade transition fine as it was, but taking a closer look really shows me that I was wrong. This looks cleaner and more accurate, the way it should've always been.


    However, it did give me a weird feeling. I noticed that I've seen this before. So, is it just me or did you use this feature in your own projects for years now, but never had time to actually make a guide for it? Because when I downloaded the Sonic 1 example, I immediately thought "Yep, this is done by MarkeyJester".
     
  5. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    As a matter of fact, no, it isn't, it was just overlooked by a table that was disassembled when it shouldn't have been:





    Code:
    	move.w	loc_132FE(pc,d0.w),d1
    
    	jmp	loc_132FE(pc,d1.w)
    
    ; ===========================================================================
    
    
    
    loc_132FE:
    
    	ori.b	#$46,d4


    That ori.b #$46,d4 is infact two words of pointer data being 0004 and 0046, these are the routines address minus the table start address:





    Code:
    	move.w	loc_132FE(pc,d0.w),d1
    
    	jmp	loc_132FE(pc,d1.w)
    
    ; ===========================================================================
    
    
    
    loc_132FE:
    
    	dc.w	loc_13302-loc_132FE
    
    	dc.w	NewRoutine-loc_132FE
    
    
    
    loc_13302:


    Where "NewRoutine" points to that "unused" routine you've noted. As for what's gone wrong on your end, it's beyond me, if you don't have this code then it simply won't run correctly:





    Code:
    ; ===========================================================================
    
    ; ----------------------------------------------------------------------------
    
    ; Object C9 - "Palette changing handler" from title screen
    
    ; ----------------------------------------------------------------------------
    
    ; Sprite_132F0:
    
    ObjC9:
    
    	moveq	#0,d0
    
    	move.b	routine(a0),d0
    
    	move.w	loc_132FE(pc,d0.w),d1
    
    	jmp	loc_132FE(pc,d1.w)
    
    ; ===========================================================================
    
    
    
    loc_132FE:
    
    	dc.w	loc_13302-loc_132FE
    
    	dc.w	NewRoutine-loc_132FE
    
    
    
    loc_13302:
    
    	addq.b	#2,routine(a0)
    
    	moveq	#0,d0
    
    	move.b	subtype(a0),d0
    
    	lea	(PaletteChangerDataIndex).l,a1
    
    	adda.w	(a1,d0.w),a1
    
    	move.l	(a1)+,objoff_3A(a0)
    
    	movea.l	(a1)+,a2
    
    	move.b	(a1)+,d0
    
    	move.w	d0,objoff_34(a0)
    
    	lea	(Second_palette).w,a3
    
    	adda.w	d0,a3
    
    	move.b	(a1)+,d0
    
    	move.w	d0,objoff_36(a0)
    
    		move.b	#$0E,objoff_33(a0)			; MJ: set fade counter
    
    
    
    loc_1332E:
    
    	move.w	(a2)+,(a3)+
    
    	dbf	d0,loc_1332E
    
    	move.b	(a1)+,d0
    
    	move.b	d0,objoff_30(a0)
    
    	move.b	d0,objoff_31(a0)
    
    	move.b	(a1)+,objoff_32(a0)
    
    	rts
    
    ; ===========================================================================
    
    	; unused/dead code ; a0=object
    
    
    
    NewRoutine:
    
    	subq.b	#1,objoff_30(a0)
    
    	bpl.s	return_1337A
    
    	move.b	objoff_31(a0),objoff_30(a0)
    
    	subq.b	#1,objoff_32(a0)
    
    	bmi.w	DeleteObject
    
    		moveq	#$00,d4					; MJ: clear d4
    
    		move.b	objoff_33(a0),d4			; MJ: load fade counter
    
    		subq.b	#$02,objoff_33(a0)			; MJ: decrease fade counter
    
    	movea.l	objoff_3A(a0),a2				; load routine to run
    
    	movea.l	a0,a3						; store current object
    
    	move.w	objoff_36(a0),d0				; load length
    
    	move.w	objoff_34(a0),d1				; load loadtooffset
    
    	lea	(Normal_palette).w,a0
    
    	adda.w	d1,a0
    
    	lea	(Second_palette).w,a1
    
    	adda.w	d1,a1
    
    
    
    -	jsr	(a2)	; dynamic call! to Pal_AddColor, loc_1344C, or loc_1348A, assuming the PaletteChangerData pointers haven't been changed
    
    	dbf	d0,-
    
    	movea.l	a3,a0
    
    
    
    return_1337A:
    
    	rts
    
    	
    
    ; ===========================================================================
    
    ; off_1337C:
    
    PaletteChangerDataIndex:
    
    	dc.w off_1338C - PaletteChangerDataIndex; 0
    
    	dc.w off_13398 - PaletteChangerDataIndex; 1
    
    	dc.w off_133A4 - PaletteChangerDataIndex; 2
    
    	dc.w off_133B0 - PaletteChangerDataIndex; 3
    
    	dc.w off_133BC - PaletteChangerDataIndex; 4
    
    	dc.w off_133C8 - PaletteChangerDataIndex; 5
    
    	dc.w off_133D4 - PaletteChangerDataIndex; 6
    
    	dc.w off_133E0 - PaletteChangerDataIndex; 7
    
    
    
    C9PalInfo macro codeptr,dataptr,loadtoOffset,length,fadeinTime,fadeinAmount
    
    	dc.l codeptr, dataptr
    
    	dc.b loadtoOffset, length, fadeinTime, fadeinAmount
    
    	endm
    
    
    
    off_1338C:	C9PalInfo Pal_AddColor, Pal_1342C, $60, $F,2,$07 ; MJ: 15 to 7
    
    off_13398:	C9PalInfo	loc_1344C, Pal_1340C, $40, $F,4,7
    
    off_133A4:	C9PalInfo	loc_1344C,  Pal_AD1E,   0, $F,8,7
    
    off_133B0:	C9PalInfo	loc_1348A,  Pal_AD1E,   0, $F,8,7
    
    off_133BC:	C9PalInfo	loc_1344C,  Pal_AC7E,   0,$1F,4,7
    
    off_133C8:	C9PalInfo	loc_1344C,  Pal_ACDE, $40,$1F,4,7
    
    off_133D4:	C9PalInfo	loc_1344C,  Pal_AD3E,   0, $F,4,7
    
    off_133E0:	C9PalInfo	loc_1344C,  Pal_AC9E,   0,$1F,4,7
    
    
    
    Pal_133EC:	BINCLUDE "art/palettes/Title Sonic.bin"
    
    Pal_1340C:	BINCLUDE "art/palettes/Title Background.bin"
    
    Pal_1342C:	BINCLUDE "art/palettes/Title Emblem.bin"
    
    
    
    ; ===========================================================================

    I haven't actually applied it to any hacks before, but I did note about it a few years ago, but that was in a private channel, so chances are you've never seen any hack associated with me to do with palette fading
     
    Last edited by a moderator: Dec 18, 2011
  6. OrdosAlpha

    OrdosAlpha RIGHT! Naebody move! Root Admin

    Joined:
    Aug 5, 2007
    Messages:
    1,793
    Location:
    Glasgow, Scotland
    For two decades the fading in and fading out routines have irritated me. Now I can finally correct it.
     
    Last edited by a moderator: Dec 18, 2011
  7. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    Nice work, and very well commented as usual :)


    Well, I tested it, and don't like it much. It's technically perfect, but it looks kind of depressing to me for some reason. It probably isn't colourful enough.


    I modified a few bits here and there to turn it into a secondary fading routine though, I'll probably use it in a few cases (death or pale/greyish levels for example).


    I think I'll experiment a little with it, for example increasing the blue for one frame, then the blue and the green, and finally all colours. I'll report if the results are... worth reporting xD
     
  8. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    This was the probem. As you can see when I quoted to you that dead (yet undead) code, there was no label pointing to it and right above it is an 'rts', so it was truley being "unused". Adding the new code you quoted above and then adding the "NewRouine" label next to the "dead" code, it now works perfectly. Cheers, mate =)
     
  9. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    I experimented a little with this, as said above, and have this version where the blue loads 1 frame before the green, and the green one frame before the red.


    Screenshot (not from the original s1, but little was modified)


    [​IMG]


    This is only for the first part, and you may have to remove the "Neutral_" from the labels. It goes from "Pal_ToBlack" to "; End of function Pal_AddColor"





    Pal_Neutral_ToBlack:


    move.w d1,(a0)+


    dbf d0,Pal_Neutral_ToBlack ; fill pallet with $000 (black)


    moveq #$12,d4 ; MJ: prepare maximum colour check ($E) ; SI: maximum is not enough, MOOOAAAR


    moveq #$00,d6 ; MJ: clear d6


    @loop:


    bsr.w RunPLC_RAM


    move.b #$12,($FFFFF62A).w


    bsr.w DelayProgram


    bchg #$00,d6 ; MJ: change delay counter


    beq @loop ; MJ: if null, delay a frame


    bsr.s Pal_Neutral_FadeIn


    subq.b #$02,d4 ; MJ: decrease colour check


    cmpi.b #4,d4


    bne @loop ; MJ: if it has not reached null, branch


    @loop2:


    move.b #$12,($FFFFF62A).w ; MJ: wait for V-blank again (so colours transfer)


    bsr.w DelayProgram ; MJ: ''


    bchg #$00,d6 ; MJ: change delay counter


    beq @loop2 ; MJ: if null, delay a frame


    bsr Pal_Neutral_FadeInGR ; SI: add more green and red


    @loop3:


    move.b #$12,($FFFFF62A).w ; MJ: wait for V-blank again (so colours transfer)


    bsr.w DelayProgram ; MJ: ''


    bchg #$00,d6 ; MJ: change delay counter


    beq @loop3 ; MJ: if null, delay a frame


    bsr Pal_Neutral_FadeInR ; SI: add more red


    move.b #$12,($FFFFF62A).w ; MJ: wait for V-blank again (so colours transfer)


    bra DelayProgram ; MJ: ''


    Pal_Neutral_FadeIn: ; XREF: Pal_Neutral_FadeTo


    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


    @loop:


    bsr.s Pal_Neutral_AddColor


    dbf d0,@loop


    cmpi.b #1,($FFFFFE10).w


    bne.s @skip


    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


    @loop2:


    bsr.s Pal_Neutral_AddColor


    dbf d0,@loop2


    @skip:


    rts


    ; End of function Pal_Neutral_FadeIn


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


    Pal_Neutral_AddColor: ; XREF: Pal_Neutral_FadeIn


    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


    addi.b #4,d5 ; SI: this is blue magic


    cmp.b d5,d4 ; MJ: is it time for blue to fade?


    bhi @FCI_NoBlue ; MJ: if not, branch


    addi.w #$0200,d3 ; MJ: increase blue


    @FCI_NoBlue:


    addi.b #2,d1 ; SI: this is green magic


    cmp.b d1,d4 ; MJ: is it time for green to fade?


    bhi @FCI_NoGreen ; MJ: if not, branch


    addi.b #$20,d3 ; MJ: increase green


    @FCI_NoGreen:


    cmp.b d2,d4 ; MJ: is it time for red to fade?


    bhi @FCI_NoRed ; MJ: if not, branch


    addq.b #$02,d3 ; MJ: increase red


    @FCI_NoRed:


    move.w d3,(a0)+ ; MJ: save colour


    rts ; MJ: return


    Pal_Neutral_FadeInGR: ; XREF: Pal_Neutral_FadeTo


    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


    @loop:


    bsr.s Pal_Neutral_AddColorGR


    dbf d0,@loop


    cmpi.b #1,($FFFFFE10).w


    bne.s @skip


    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


    @loop2:


    bsr.s Pal_Neutral_AddColorGR


    dbf d0,@loop2


    @skip:


    rts


    Pal_Neutral_AddColorGR: ; XREF: Pal_Neutral_FadeIn


    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


    addi.b #2,d1 ; SI: don't ask, it works


    cmp.b d1,d4 ; MJ: is it time for green to fade?


    bhi @FCI_NoGreen ; MJ: if not, branch


    addi.b #$20,d3 ; MJ: increase green


    @FCI_NoGreen:


    cmp.b d2,d4 ; MJ: is it time for red to fade?


    bhi @FCI_NoRed ; MJ: if not, branch


    addq.b #$02,d3 ; MJ: increase red


    @FCI_NoRed:


    move.w d3,(a0)+ ; MJ: save colour


    rts ; MJ: return


    Pal_Neutral_FadeInR: ; XREF: Pal_Neutral_FadeTo


    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


    @loop:


    bsr.s Pal_Neutral_AddColorR


    dbf d0,@loop


    cmpi.b #1,($FFFFFE10).w


    bne.s @skip


    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


    @loop2:


    bsr.s Pal_Neutral_AddColorR


    dbf d0,@loop2


    @skip:


    rts


    Pal_Neutral_AddColorR: ; XREF: Pal_Neutral_FadeIn


    move.w (a1)+,d1 ; MJ: load green and red


    move.b d1,d2 ; MJ: load red


    andi.b #$0E,d2 ; MJ: get only red


    move.w (a0),d3 ; MJ: load current colour in buffer


    addi.b #2,d2 ; SI: no questions please.


    cmp.b d2,d4 ; MJ: is it time for red to fade?


    bhi @FCI_NoRed ; MJ: if not, branch


    addq.b #$02,d3 ; MJ: increase red


    @FCI_NoRed:


    move.w d3,(a0)+ ; MJ: save colour


    rts ; MJ: return



    The changes are a little dirty, but it works. I did it for experimental purpose, there are probably better ways to do it.
     
    Last edited by a moderator: Dec 19, 2011
  10. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    A bug has appeared in the Sonic 2 Fade-in routine, although this only seems to happen on the Title screen.


    [​IMG]


    (Don't worry, the selection menu is gone because I took it out myself)


    When the title screen is in the middle of fading in, if you press start to go straight to the point, the palette goes wrong (or doesn't seem to finish loading). I tried the ROM you supplied us, MJ, and the bug exists in that too, so I know it's not any of my work interfering.


    [​IMG]


    (The ROM you supplied in your first post)


    Any solutions?
     
  11. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Gah, there is always something now isn't there, go to:



    loc_135D6:
    move.l (a1)+,(a2)+


    dbf d6,loc_135D6


    tst.b objoff_30(a0)


    bne.s return_135E8


    moveq #$19+$80,d0 ; title music


    bsr.w JmpTo4_PlayMusic



    And insert the instruction:



    sf.b (Object_RAM+($100+$32)).w ; set fade counter to 00 (finish)



    Just after the dbf instruction, this will set the palette fading object's fade counter to 0 and set the object to delete itself.
     
  12. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    I'm sorry =(


    It's fixed, cheers =P
     
  13. Irixion

    Irixion Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    670
    Location:
    Ontario, Canada
    This sir, is the best thing on the planet. I love you. I really do. This has bugged me for I don't even know, and to see a fix, it makes me squirm with excitement.
     
  14. Irixion

    Irixion Well-Known Member Member

    Joined:
    Aug 11, 2007
    Messages:
    670
    Location:
    Ontario, Canada
    Sorry for the double post--but this works for the SVN disassembly as well, few changes though:


    DelayProgram: is WaitForVint:


    Delay_Time: is Vint_routine:


    loc_13302: is ObjC9_Init:


    NewRoutine: is ObjC9_Main:


    The rest is the same. Make sure you do the very last step as it can bork things up if you forget! Thanks again Markey! :eek:
     
Thread Status:
Not open for further replies.