Jump to content

  •  

Photo

Palette line fading help


  • This topic is locked This topic is locked
23 replies to this topic

#1 redhotsonic

redhotsonic

    Also known as RHS

  • Staff
  • 1591 posts
  • Gender:Male
  • Location:United Kingdom

Posted 27 March 2012 - 09:18 AM

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
  • 0

#2 MarkeyJester

MarkeyJester

    A word in your shell-like, pal

  • Pro User
  • 1335 posts
  • Gender:Male

Posted 27 March 2012 - 09:46 AM

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:

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.
  • 0

#3 redhotsonic

redhotsonic

    Also known as RHS

  • Staff
  • 1591 posts
  • Gender:Male
  • Location:United Kingdom

Posted 27 March 2012 - 07:19 PM

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:
Posted Image



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


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


Here's some ASM work to show:

Spoiler

Edited by redhotsonic, 27 March 2012 - 07:46 PM.

  • 0

#4 MarkeyJester

MarkeyJester

    A word in your shell-like, pal

  • Pro User
  • 1335 posts
  • Gender:Male

Posted 27 March 2012 - 07:25 PM

$403F


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).
  • 0

#5 redhotsonic

redhotsonic

    Also known as RHS

  • Staff
  • 1591 posts
  • Gender:Male
  • Location:United Kingdom

Posted 27 March 2012 - 07:41 PM

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 =/

Edited by redhotsonic, 27 March 2012 - 07:42 PM.

  • 0

#6 MarkeyJester

MarkeyJester

    A word in your shell-like, pal

  • Pro User
  • 1335 posts
  • Gender:Male

Posted 27 March 2012 - 07:42 PM

Have you...

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.


?
  • 0

#7 redhotsonic

redhotsonic

    Also known as RHS

  • Staff
  • 1591 posts
  • Gender:Male
  • Location:United Kingdom

Posted 27 March 2012 - 07:50 PM

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.
  • 0

#8 MarkeyJester

MarkeyJester

    A word in your shell-like, pal

  • Pro User
  • 1335 posts
  • Gender:Male

Posted 27 March 2012 - 08:12 PM

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
  • 0

#9 redhotsonic

redhotsonic

    Also known as RHS

  • Staff
  • 1591 posts
  • Gender:Male
  • Location:United Kingdom

Posted 27 March 2012 - 08:38 PM

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

Edited by redhotsonic, 27 March 2012 - 08:41 PM.

  • 0

#10 MarkeyJester

MarkeyJester

    A word in your shell-like, pal

  • Pro User
  • 1335 posts
  • Gender:Male

Posted 27 March 2012 - 08:42 PM

There's your problem, right there, Pal_FadeFrom uses a0, but you've got it used for your object, try this:

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.
  • 0

#11 redhotsonic

redhotsonic

    Also known as RHS

  • Staff
  • 1591 posts
  • Gender:Male
  • Location:United Kingdom

Posted 27 March 2012 - 08:56 PM

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:
Posted Image


After fade-out:
Posted Image


I hit the monitor, and it fades in:
Posted Image


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

  • 0

#12 MarkeyJester

MarkeyJester

    A word in your shell-like, pal

  • Pro User
  • 1335 posts
  • Gender:Male

Posted 27 March 2012 - 09:34 PM

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

Not sure entirely, but one thing is certain:

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:

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.
  • 0

#13 redhotsonic

redhotsonic

    Also known as RHS

  • Staff
  • 1591 posts
  • Gender:Male
  • Location:United Kingdom

Posted 27 March 2012 - 09:56 PM

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.


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

  • 0

#14 MarkeyJester

MarkeyJester

    A word in your shell-like, pal

  • Pro User
  • 1335 posts
  • Gender:Male

Posted 27 March 2012 - 09:58 PM

Well, have you given it a try?
  • 0

#15 redhotsonic

redhotsonic

    Also known as RHS

  • Staff
  • 1591 posts
  • Gender:Male
  • Location:United Kingdom

Posted 27 March 2012 - 10:14 PM

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 ...)
  • 0

#16 MarkeyJester

MarkeyJester

    A word in your shell-like, pal

  • Pro User
  • 1335 posts
  • Gender:Male

Posted 27 March 2012 - 10:39 PM

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.
  • 0

#17 redhotsonic

redhotsonic

    Also known as RHS

  • Staff
  • 1591 posts
  • Gender:Male
  • Location:United Kingdom

Posted 27 March 2012 - 10:55 PM

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

Edited by redhotsonic, 27 March 2012 - 10:56 PM.

  • 0

#18 redhotsonic

redhotsonic

    Also known as RHS

  • Staff
  • 1591 posts
  • Gender:Male
  • Location:United Kingdom

Posted 28 March 2012 - 10:18 PM

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.


Posted Image

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.

Posted Image

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.

Posted Image




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.
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users