PCEngineFans.com - The PC Engine and TurboGrafx-16 Community Forum
Tech and Homebrew => Turbo/PCE Game/Tool Development => Topic started by: Bonknuts on January 21, 2014, 10:54:33 AM
-
I figured I'd post this. I've written a few in the past, but I needed something more efficient and faster. Plus, I like the fade 'in' part much better than my older method.
;....................................................................
;
FadePal:
lda <D3
asl a
asl a
asl a
sta <D4
asl a
asl a
asl a
sta <D5
cla
rol a
sta <D5+1
_int_Fade0:
clx
.loop
lda PalBlock,x
and #$07
sec
sbc <D3
bpl .BlueOVF
cla
.BlueOVF
sta WorkBlock,x
lda PalBlock,x
and #$38
sec
sbc <D4
bpl .RedOVF
cla
.RedOVF
ora WorkBlock,x
sta WorkBlock,x
lda PalBlock,x
and #$c0
sec
sbc <D5
tay
lda PalBlock+1,x
and #$01 ;needed because reading pal data from VCE leaves garbage in the top unused bits
sbc <D5+1
bpl .GreenOVF
cla
cly
.GreenOVF
sta WorkBlock+1,x
tya
ora WorkBlock,x
sta WorkBlock,x
inx
inx
bne .loop
_int_Fade1:
.loop
lda PalBlock+256,x
and #$07
sec
sbc <D3
bpl .BlueOVF
cla
.BlueOVF
sta WorkBlock+256,x
lda PalBlock+256,x
and #$38
sec
sbc <D4
bpl .RedOVF
cla
.RedOVF
ora WorkBlock+256,x
sta WorkBlock+256,x
lda PalBlock+256,x
and #$c0
sec
sbc <D5
tay
lda PalBlock+256+1,x
and #$01
sbc <D5+1
bpl .GreenOVF
cla
cly
.GreenOVF
sta WorkBlock+256+1,x
tya
ora WorkBlock+256,x
sta WorkBlock+256,x
inx
inx
bne .loop
rts
;endsub
The call argument is D3, and two blocks of memory are whatever you define in local ram. D3 is a value from 00 to 07. It's modified for D4 and D5, so they can subtract those specific R/G elements without shifting them. I use two blocks of memory; both are 512 bytes long. Because I need to fade the existing BG palette, which might be made up of dynamic subpalettes at any point in time - I read all of CRAM from the VCE into "PalBlock" segment of ram. "WorkBlock" is the temporary palette buffer that the changes are saved to, to be uploaded to the VCE CRAM.
Here's the code to read CRAM into the block/array(local ram).
;....................................................................
;
UpdateWorkPal:
stz $402
stz $403
tia WorkBlock,$404,$200
rts
;endsub
Not many docs mention that you can actually read from VCE CRAM, but you can. IIRC, though, there's no guarantee that the upper unused bits will be cleared. Normally not a problem, especially if you upload with those bits set, but when altering the color value as such as the above code - make sure you AND/mask off those bits. The above fade routine does that, so no worries.
Reading and writing to the VCE (any of the VCE regs) will stall the VCE and show distortion on active display. It's best to call the VCE CRAM read routine from vblank to avoid this. You only need to call it once; one and done (the VCE CRAM read routine).
The above routines only fade/adjust the BG 256 colors. You'd have to modify it for sprite 256 colors. If you want to fade to black or fade up from black, you'll need another routine that modifies D3 and calls the FadePal routine each time.
-
And if you want smoother fading, you could always do it the way many Genesis games do... fade R+G down one level, then fade Blue afterward, then repeat... You get 16 steps that way and it looks kinda nice too.
-
Ouuu :3 That sounds like a good idea. I'm gonna try that out. Thanks for the tip :D
-
You can also use directly a dec of 1 for B, sub of 8 for R and a sub 64 for G to avoid multiple asl ..
With that, a simple OR (G,R,B) rebuild the 9 bit color .
-
Ouuu :3 That sounds like a good idea. I'm gonna try that out. Thanks for the tip :D
Strictly speaking, the way they do it is far more complex... I just checked out Sonic and the Red gets faded out first, then Blue (but slowly), then Green (more quickly?)
Someone wanna disassemble that?
-
Ouuu :3 That sounds like a good idea. I'm gonna try that out. Thanks for the tip :D
Strictly speaking, the way they do it is far more complex... I just checked out Sonic and the Red gets faded out first, then Blue (but slowly), then Green (more quickly?)
Someone wanna disassemble that?
Interesting! I'm going to have to experiment with various fade in/out methods now. You've piqued my interest. :)
-
Ouuu :3 That sounds like a good idea. I'm gonna try that out. Thanks for the tip :D
Strictly speaking, the way they do it is far more complex... I just checked out Sonic and the Red gets faded out first, then Blue (but slowly), then Green (more quickly?)
Someone wanna disassemble that?
I was just looking at Sonic 1 fade out, and it is quite complex. It seems to be weighted. The sky, which is almost pure blue, gets faded down to black pretty quickly - but the water which is a lighter blue, doesn't have much taken off in the Blue element. The sky was a 5, and received -5. But on the same frame, the water was 7 for Blue and only received -2 decrement. So it definitely seems weighted. I wonder if they're just converting the RGB to another color space and applying the fading, then converting back.