Palette line fading help

Discussion in 'Discussion and Q&A Archive' started by redhotsonic, Mar 27, 2012.

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

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Hello; just a quick question. In my hack, I want a certain palette to fade to black (palette line 2 and 3, so both them lines go black whilst palette line 0 and 1 remain intact).


    It seems like I can't pull it off. I tried jumping to subroutines: Pal_FadeTo, Pal_ToBlack, and Pal_FadeOut. The closest I got to is that it starts to fade, then the game locks up.


    Any advice would be appreciated


    Cheers


    redhotsonic
     
  2. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Sonic 1 has a specialised system for this using RAM address $00FFF626 and $00FFF627, you set the starting palette add address to $00FFF626 and you set the number of colours in total (minus 1) to $00FFF627. An example:



    Code:
    move.w	#$203F,($FFFFF626).w

    The 20 is added to the buffer $00FFFB00, that makes it $00FFFB20, and it'll process 30 colours from that point.


    This system does still exist in Sonic 2, however, due to Sonic 2 never calling the function, IDA didn't pick up on it when it disassembled the game.


    Goto "Pal_FadeTo:" and insert a new lable just after "move.w #$3F,($FFFFF626).w" and call the lable "Pal_FadeTo2:", the same with "Pal_FadeFrom:" insert a new lable after "move.w #$3F,($FFFFF626).w" and call it "Pal_FadeFrom2:". Then, when you want it to fade your specific lines, move the starting buffer add address and the number of colours to $00FFF626 and $00FFF627, and call "Pal_FadeFrom2:". You MIGHT want to make sure that $00FFF626 and $00FFF627 are set back to 00 and 3F when the fading is finished, I've had Sonic 1 get a bit funny on me about it before.


    I'll leave you to figure out what specific values you'll need to move to $00FFF626 and $00FFF627.
     
    Last edited by a moderator: Mar 27, 2012
  3. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    I'm guessing it works out like this:


    P-Line0 = $0


    P-Line1 = $20


    P-Line2 = $40


    P-Line3 = $60


    And $3F uses all the colours on that line?


    Well, I insterted the new labels and then did this:



    move.w #$603F,($FFFFF626).w
    jsr Pal_FadeFrom2



    I put this in the bit when Sonic respawns after he dies (in my hack, the camera scrolls back to the beginning rather than restarting the level; similar on how 2 player works).


    As soon as Sonic respawns, all the colours changes to random colours, but it does change in a fading effect, then the game freezes. One thing I didn't do is reset ($FFFFF626).w, because I wasn't sure where I put it. Do I put clr.w ($FFFFF626).w after it JSR'd?


    Before:


    [​IMG]


    Level after death and respawned (it has frozen so can't do anything from here)


    [​IMG]


    It should fade the background black (so no background).


    Here's some ASM work to show:

    ; ---------------------------------------------------------------------------
    ; Sonic when he's waiting for the camera to scroll back to where he respawned


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


    ; loc_1B330: Obj_01_Sub_A:


    Obj01_Respawning:


    move.b #5,anim(a0) ; Set Sonic's animation to stand


    bclr #2,status_secondary(a0)


    jsr (PlayMusic).l


    move.l (Saved_Timer).w,(Timer).w


    move.w (Saved_Water_Level).w,(Water_Level_2).w


    move.w (Saved_Water_Level).w,(Water_Level_3).w


    tst.w ($FFFFEEB0).w


    bne.s +


    tst.w ($FFFFEEB2).w ; Has camera reached to begining/checkpoint?


    bne.s + ; If not, branch, and keep scrolling til Sonic is on screen


    move.b #2,routine(a0) ; =&--#62; Obj01_Control


    move.b (Saved_Dynamic_Resize_Routine).w,(Dynamic_Resize_Routine).w


    move.b (Saved_Dynamic_Resize_Sec_Routine).w,(Dynamic_Resize_Sec_Routine).w


    clr.b (ARZBGresetwhendead).w


    move.w (Saved_Camera_Max_Y_pos).w,(Camera_Max_Y_pos).w


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


    jsr Pal_FadeTo2





    ; sub_23C6:
    Pal_FadeTo:


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


    Pal_FadeTo2:


    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





    ; sub_246A:
    Pal_FadeFrom:


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


    Pal_FadeFrom2:


    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
     
    Last edited by a moderator: Mar 27, 2012
  4. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Warning.


    3F + 1 = 40 X 2 = 80 - 1 = 7F


    FFFB40 + 7F = FFBBF (the palette buffer stops at FFB7F)


    Each line has 10 hex colours, you're starting on the second line, and want to process two lines which is 20 colours, yet you've told it to process 3F (40 colours).
     
  5. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Ah, I see. I forgot about the minus 1


    I tried this



    move.w #$600F,($FFFFF626).w
    jsr Pal_FadeFrom2



    And according to the debugger, palette line 4 is now fade to black. It works, but once it's faded black, the game still freezes =/
     
    Last edited by a moderator: Mar 27, 2012
  6. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Have you...

    ?
     
  7. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Yes, unless I put it in the wrong place or cleared it wrongly?



    move.w #$600F,($FFFFF626).w
    jsr Pal_FadeFrom2


    clr.w ($FFFFF626).w



    Then I realised you said make sure F627 was $3F, so I tried:



    move.w #$600F,($FFFFF626).w
    jsr Pal_FadeFrom2


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



    But same problem persists.
     
  8. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    There must be something after the fading which is causing the crash, I've just given it a try myself, and the result is well... perfect really (no crashing):


    ROM
     
  9. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Possibly, here is where I have applied it to:



    ; ---------------------------------------------------------------------------
    ; Sonic when he's waiting for the camera to scroll back to where he respawned


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


    ; loc_1B330: Obj_01_Sub_A:


    Obj01_Respawning:


    move.b #5,anim(a0) ; Set Sonic's animation to stand


    bclr #2,status_secondary(a0)


    jsr (PlayMusic).l


    move.l (Saved_Timer).w,(Timer).w


    move.w (Saved_Water_Level).w,(Water_Level_2).w


    move.w (Saved_Water_Level).w,(Water_Level_3).w


    tst.w ($FFFFEEB0).w


    bne.s +


    tst.w ($FFFFEEB2).w ; Has camera reached to begining/checkpoint?


    bne.s + ; If not, branch, and keep scrolling til Sonic is on screen


    move.b #2,routine(a0) ; =&--#62; Obj01_Control


    move.b (Saved_Dynamic_Resize_Routine).w,(Dynamic_Resize_Routine).w


    move.b (Saved_Dynamic_Resize_Sec_Routine).w,(Dynamic_Resize_Sec_Routine).w


    clr.b (ARZBGresetwhendead).w


    move.w (Saved_Camera_Max_Y_pos).w,(Camera_Max_Y_pos).w


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


    jsr Pal_FadeFrom2


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


    clr.b ($FFFFF710).w ; clear rings, so they can respawn again


    ; Start of deletion of all objects except Sonic/Knux and Tails/Knux


    lea ($FFFFB400).w,a1


    moveq #0,d0


    move.w #$87F,d1


    -


    move.l d0,(a1)+


    dbf d1,- ; clear object RAM


    ; End of deletion of all objects except Sonic/Knux and Tails/Knux


    clr.b (Obj_placement_routine).w ; Clear object placement routine, so it automatically starts again, spawning most objects


    move.b #5,(Tails_Tails).w ; load Obj05 (Tails' Tails) at $FFFFD000


    lea (Sidekick).w,a1 ; a1=character


    move.w a1,(Tails_Tails+parent).w ; makes Tails magically grow his tails again


    move.b #8,(Sonic_Dust).w ; load Obj08 Sonic's spindash dust/splash object at $FFFFD100


    move.b #8,(Tails_Dust).w ; load Obj08 Tails' spindash dust/splash object at $FFFFD140


    +


    bsr.w Sonic_Animate


    bsr.w LoadSonicDynPLC


    bra.w DisplaySprite



    Maybe the deletetion of objects is causing it? Let me try moving the commands for the fading somewhere else...


    EDIT: No, I just applied it when you get an extra life monitor, the bg goes black, then it freezes. I must of gone wrong here somewhere:



    ; sub_23C6:
    Pal_FadeTo:


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


    Pal_FadeTo2:


    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





    ; sub_246A:
    Pal_FadeFrom:


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


    Pal_FadeFrom2:


    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
     
    Last edited by a moderator: Mar 27, 2012
  10. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    There's your problem, right there, Pal_FadeFrom uses a0, but you've got it used for your object, try this:



    Code:
    	movem.l	d7/a0,-(sp)
    
    	move.w  #$600F,($FFFFF626).w
    
    	jsr	Pal_FadeFrom2
    
    	move.w  #$003F,($FFFFF626).w
    
    	movem.l	(sp)+,d7/a0

    Be very careful about using routines that normally aren't used in an object's routine.
     
    Last edited by a moderator: Mar 27, 2012
  11. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Okay, that's worked great, it now fades correctly. Just need to make it fade back in now. I've got it to fade to black when you die, then when you get a shield, it comes back again, but it doesn't quite work.


    Before fade out:


    [​IMG]


    After fade-out:


    [​IMG]


    I hit the monitor, and it fades in:


    [​IMG]


    At least it doesn't freeze this time and you can continue to play the game.



    shield_monitor:
    moveq #$4D,d0


    jsr (LoadPLC).l


    bclr #3,status_secondary(a1)


    addq.w #1,(a2)


    bset #0,status_secondary(a1)


    move.w #$AF,d0


    jsr (PlayMusic).l


    move.b #$38,(Object_RAM+$2180).w ; load Obj38 (shield) at $FFFFD180


    move.w a1,(Object_RAM+$2180+parent).w


    movem.l d7/a0,-(sp)


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


    jsr Pal_FadeTo2


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


    movem.l (sp)+,d7/a0


    rts
     
  12. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Not sure entirely, but one thing is certain:



    Code:
    	bclr	#3,status_secondary(a1)
    
    	addq.w	#1,(a2)
    
    	bset	#0,status_secondary(a1)


    a1 and a2 are being used, so add them to the movem instructions to store them:





    Code:
    		movem.l d7/a0-a2,-(sp)
    
    		move.w  #$600F,($FFFFF626).w
    
    		jsr	 Pal_FadeTo2
    
    		move.w  #$003F,($FFFFF626).w
    
    		movem.l (sp)+,d7/a0-a2

    EDIT: oh and don't forget, you'll need to reload the palette data before you can fade it in, because the fade out routine clears the buffer.
     
    Last edited by a moderator: Mar 27, 2012
  13. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    That explains it. Well, as it's palette line 2 I've faded out, I will need to load that palette again. So I would so this:



    movem.l d7/a0-a2,-(sp)
    lea ($FFFFFB50).w,a0


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


    jsr Pal_FadeTo2


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


    movem.l (sp)+,d7/a0-a2



    But $FFFFFB50 has been changed (because some of the colours have gone to 00, seeming as we have faded it out). So, before the fade out, will I need to make a copy of $FFFFFB50 to say, $FFFFF5C0, then try this?:



    movem.l d7/a0-a2,-(sp)
    lea ($FFFFF5C0).w,a0


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


    jsr Pal_FadeTo2


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


    movem.l (sp)+,d7/a0-a2
     
  14. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Well, have you given it a try?
     
  15. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    I can't seem to copy it. I'm not sure how to do that to $20 bytes =P


    I tried



    lea ($FFFFFB50).w,a3
    movea.w a3,($FFFFF5C0).w



    But this only seems to move FB50 to F5C0 (So FFFFF5C0 is now = FB 50 00 00 00 00 00 00 ...)
     
  16. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    move.w (a3) is probably what you were after.


    I do not wish to sound rude, so forgive me, but I feel that if you cannot do something as simple as loading a palette without the aid of forum help, then perhaps it's best I help no further. If I keep providing the answers for you, then you won't learn anything =$


    Perhap you should look into reading a 68k assembly manual/tutorial.
     
    Last edited by a moderator: Mar 27, 2012
  17. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    There's nothing to forgive for. It's not rude.


    I looked into the ASM on how the palette is loaded, and I know how to copy bytes, words, longwords, but not $20s. I thought loading the palette into a3 them moving a3 to another ram address will copy it, but obviously not.


    It's late and I have a headache, so I will give this another shot tomorrow and will see it then. Might be able to concentrate more then =P
     
    Last edited by a moderator: Mar 27, 2012
  18. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Right, my headache has gone, so I have given this a few tries today. No matter what I tried, I couldn't get to copy. I also tried your little tip:



    lea ($FFFFFB50).w,a3
    movea.w (a3),($FFFFF5C0).w



    The only way I could get it to copy, was to look at the palette line's address, and move the same bytes to the new RAM address.



    move.l #$02420EEE,($FFFFF5C0).w
    move.l #$0ACA0622,($FFFFF5C4).w


    move.l #$084400C4,($FFFFF5C8).w


    move.l #$00820060,($FFFFF5CC).w



    So, anyway, $FFFFF5C0 is ready.


    [​IMG]


    Here is the background. When you die, it does this code:



    movem.l d7/a0,-(sp)
    move.w #$5601,($FFFFF626).w


    jsr Pal_FadeFrom2


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


    movem.l (sp)+,d7/a0



    This fades it to black and it works.


    [​IMG]


    Now, there's a shield monitor to the side. The shield monitor has this code:



    shield_monitor:
    moveq #$4D,d0


    jsr (LoadPLC).l


    bclr #3,status_secondary(a1)


    addq.w #1,(a2)


    bset #0,status_secondary(a1)


    move.w #$AF,d0


    jsr (PlayMusic).l


    move.b #$38,(Object_RAM+$2180).w ; load Obj38 (shield) at $FFFFD180


    move.w a1,(Object_RAM+$2180+parent).w


    move.l #$02420EEE,($FFFFF5C0).w


    move.l #$0ACA0622,($FFFFF5C4).w


    move.l #$084400C4,($FFFFF5C8).w


    move.l #$00820060,($FFFFF5CC).w


    movem.l d7/a0-a2,-(sp)


    lea ($FFFFF5C0).w,a0


    move.w #$5601,($FFFFF626).w


    jsr Pal_FadeTo2


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


    movem.l (sp)+,d7/a0-a2


    rts



    The palettes fades in with no freezing, still with the wrong colours, but at least it only fucks up the ones the faded black in the first place, whereas before, it was messing it all up.


    [​IMG]


    Also, I would like to apologise for last night. I was knackered and had a banging headache. I did not want it to make you think that I was just asking all the questions and not trying to figure out for myself. I only know some asm commands. But you doing this, it does make me learn funnily enough. Your command you said earlier "movem.l d7/a0,-(sp)", I didn't have a clue what it meant. But I've learnt now (correct me if wrong), that it holds a0 for a little while so I can move something else to a0, then I can I can use "movem.l (sp)+,d7/a0" to move the original a0 back.


    This will be very useful for me now. In my HPZ boss, I've used a lot of a0, a1, a2, a3, blah blah blah, because I didn't know I can withdraw a0 and then move it back. I may implement it and optimise my HPZ boss.
     
  19. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Indeed that's what it's for, it also does d7 too, d7/a0, you can back up all registers if you really wanted by using d0-a6, you just need to remember to restore them later (or at least increase the stack).

    What you don't know here is how it works, so allow me to elaborate:



    Code:
    	lea	($FFFFFB40).w,a3		; a3 = $FFFFFB40
    
    	lea	($FFFFFBC0).w,a4		; a4 = $FFFFFBC0


    Now, if you were to:





    Code:
    	move.l	a3,a4


    This will move what's in a3 into a4, if a3 = $FFFFFB40, then after that instruction, a4 will also = $FFFFFB40, that will move the "address" accross, not what's AT the address, now... if you were to:





    Code:
    	move.l	(a3),(a4)


    This will move the data AT address a3 to the addres AT a4, so it's basically the same as:





    Code:
    	move.l	($FFFFFB40).w,($FFFFFBC0).w


    Now, by adding the "increment" symbol "+", you can increase the address of the registers:





    Code:
    	move.l	(a3)+,(a4)+

    So:

    1. The data from address $FFFFFB40 - $FFFFFB43 will be copied to $FFFFFBC0 - $FFFFFBC3.
    2. a3 will increment by 4, and a4 will increment by 4, a3 is now $FFFFFB44 and a4 is now $FFFFFBC4.

    By using address registers and the incrementation, you can change the address of the "lea", and the rest of the (a?)+ will follow suit.
     
    Last edited by a moderator: Mar 29, 2012
  20. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    Right, let me see if I get this right.


    move.l (a3)+,(a4)+


    This command will copy the longword from a3 to a4. Then afterwards, both a3 and a4 will increment by a longword. So if I did this:



    lea ($FFFFFB50).w,a3
    lea ($FFFFF5C0).w,a4


    move.l (a3)+,(a4)+


    move.l (a3)+,(a4)+


    move.l (a3)+,(a4)+


    move.l (a3)+,(a4)+



    Would this copy the palette line?


    I'm on my phone as gf has laptop so couldn't test it and I'm off to bed =P


    As for d7, I got told years ago to never use it. Can't remember why, but whenever I have tried using it, the game normally ends up freezing, so I always use d0-d6
     
    Last edited by a moderator: Mar 29, 2012
Thread Status:
Not open for further replies.