Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Help with a color fade out trick

Reply to topic
Author Message
  • Joined: 15 Feb 2016
  • Posts: 19
Reply with quote
Help with a color fade out trick
Post Posted: Wed Jan 18, 2017 10:47 pm
So here's what I've been trying to hammer out for several weeks now. I thought fading the screen out when moving into a new room, switching the background and fading it back in again would be a pretty neato effect. I've gotten it to fade out just fine, but fading it back in is posing quite a problem.

I find myself trying to juggle registers because I don't have enough working room to handle the color value that I need to compare the current value against.

I'm at my wit's end at this point and just can't see what I'm missing. Why the new colors aren't loaded into the RAM space I have set up for them. I'm pasting my fade out and fade in subroutines here. If anyone could nudge me in the right direction or point out a critical flaw in this system I would greatly appreciate it! Thanks in advance!


.section "Fade Screen" free
FadeScreen:
     ld a , 4                ;Cycling through this routine four times should get us where we need to be
     ld (FadeTimer), a
-:
     ld bc, 32
     ld hl, ActiveSpritePalette ;This is a section in RAM where my screen update routine looks for the palette data
                                ;ActiveBGPalette is located 16 bytes after this so it is one continuous block
_Blue:
     ld a, (hl)
     and    %00110000       ;Mask off the color value bits that we want to manipulate
     jr z, _Green           ;If it's already 00, we can move on to the next value bits
     sbc a, %00010000       ;Otherwise knock it down 1 and put it back
     or     %11001111
     and (hl)
     ld (hl), a
_Green:
     ld a, (hl)
     and    %00001100
     jr z, _Red
     sbc a, %00000100
     or     %11110011
     and (hl)
     ld (hl), a
_Red:
     ld a, (hl)
     and    %00000011
     jr z, +
     sbc a, %00000001
     or     %11111100
     and (hl)
     ld (hl), a
+:
     inc hl
     djnz _Blue              ;32 colors in total

     push bc
     push hl
     ld a, 4                 ;Delay a few frames so we can actually see the fade effect
     ld (FrameTimer), a
     call WaitFrames
     pop hl
     pop bc

     ld a, (FadeTimer)
     dec a
     ld (FadeTimer), a
     cp 0
     jp nz, -
     ret
.ends

.section "Fade exterior" free
FadeInExterior:
     ld a , 4
     ld (FadeTimer), a
-:
     ld ix, 16
     ld bc, ActiveBGPalette
     ld de, ExteriorPalette   ;Palette data in ROM to compare our current colors to

_Blue:
     ld a, (de)
     and    %00110000
     ld (ColorCompare), a

     ld a, (bc)
     and    %00110000
     ld hl, ColorCompare
     cp  (hl)
     jr z, _Red

     push bc
     pop hl
     adc a, %00010000
     or     %11001111
     and (hl)
     ld (hl), a
     push hl
     pop bc
_Red:
     ld a, (de)
     and    %00001100
     ld (ColorCompare), a

     ld a, (bc)
     and    %00110000
     ld hl, ColorCompare
     cp  (hl)
     jr z, _Green

     push bc
     pop hl
     adc a, %00000100
     or     %11110011
     and (hl)
     ld (hl), a
     push hl
     pop bc

_Green:
      ld a, (de)
     and    %00001100
     ld (ColorCompare), a

     ld a, (bc)
     and    %00001100
     ld hl, ColorCompare
     cp  (hl)
     jr z, +

     push bc
     pop hl
     adc a, %00000100
     or     %11110011
     and (hl)
     ld (hl), a
     push hl
     pop bc
+:
     inc bc
     inc de
     dec ix
     jr nz, _Blue

     push de
     push bc
     push ix
     ld a, 4
     ld (FrameTimer), a
     call WaitFrames
     pop ix
     pop bc
     pop de
     
     ld a, (FadeTimer)
     dec a
     ld (FadeTimer), a
     cp 0
     jr nz, -

     ret
.ends
[/code]
  View user's profile Send private message
  • Joined: 26 Dec 2004
  • Posts: 374
  • Location: Japan
Reply with quote
Post Posted: Thu Jan 19, 2017 12:12 am
In your fade out/in code, you're doing OR #%11110011 etc, which will set all colours to white; then you're doing AND (HL) which is also wrong.

How about AND #%11110011, and then OR (HL)?
  View user's profile Send private message Visit poster's website
  • Joined: 15 Feb 2016
  • Posts: 19
Reply with quote
Post Posted: Thu Jan 19, 2017 4:23 am
It's based on something I worked out on paper on my lunch break but I did go over it a dozen times. Let's assume the color byte we are working on is:
%00111010
This is what (hl) is pointing to and we are just interested in the rightmost two bits for now. I have it labeled Red in my code, but it doesn't matter. ANDing it with %00000011 is trivial but now this is in a:
%00000010
We're fading out so knock it down 1 because it isn't black.
%00000001
Now I had to insert just those two bits back into (hl) without messing up the other values in it so we can have a smooth transition. The only way I found that would work was by ORing it with %11111100 which should give me:
%11111101
The weird part is ANDing this with the original byte which, if I'm not insane, yeilds:
%00111001

Please feel free to correct me, but fading out and injecting the new value into the color byte seems to work this way. To be fair, I haven't spent much time working it out the other way around so it may very well be advantageous if it does work!


In the end, I just hand picked color values, stuck them in ROM in a data table and loaded each one individually every few frames when fading back in. Good practices be damned.
  View user's profile Send private message
  • Joined: 14 Oct 2008
  • Posts: 511
Reply with quote
Post Posted: Thu Jan 19, 2017 4:53 am
OR makes the resulting bit 1 if the corresponding bit is 1 in either of the values. In the comparison X OR Y, effectively all 1 bits in Y will always be turned to Y.


00010011
11001001
--------
11011011 - Result is a 1 when there is a 1 in either value


X AND Y


00010011
11001001
--------
00000001 - Result is a 1 only when there is a 1 in both values.


And for completion, X XOR/EOR Y (exclusive-or)


00010011
11001001
--------
11011010 - Result is a 1 when there is a 1 in either but not both values
  View user's profile Send private message
  • Joined: 15 Feb 2016
  • Posts: 19
Reply with quote
Post Posted: Thu Jan 19, 2017 6:39 am
I do understand how logic gates work (I've got drawers FULL of 7400 series chips) But can you see what I was trying to do with these color bytes? Fade out works well enough but it falls apart when I introduce more registers and a comparison value.

As I've said thougg, I just hacked something together for now that works very smoothly. It's at the expense of a few extra bytes of ROM but it's all the same to the player and frankly I'm tired of thinking about it!
  View user's profile Send private message
  • Site Admin
  • Joined: 08 Jul 2001
  • Posts: 8651
  • Location: Paris, France
Reply with quote
Post Posted: Thu Jan 19, 2017 9:24 am
Quote
In the end, I just hand picked color values, stuck them in ROM in a data table and loaded each one individually every few frames when fading back in. Good practices be damned.


What you could do instead of storing faded values for your actual palette, is to just create a fading table, which for each of the 64 possible colors gives you 0..3 variations, then the fading out is just a lookup in this table and you can keep your palettes flexible.

Another idea is that you might experiment with increasing the 0..3 range to a larger range and decrement each components at a different step during the fade, which might create the illusion of a smoother (if weirder?) fade. I'm not sure if many games do that but I guess some would.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14744
  • Location: London
Reply with quote
Post Posted: Thu Jan 19, 2017 1:54 pm
Many games fade one channel at a time to make it take more frames, Phantasy Star does it fairly slowly if you want an example.
  View user's profile Send private message Visit poster's website
  • Joined: 26 Dec 2004
  • Posts: 374
  • Location: Japan
Reply with quote
Post Posted: Thu Jan 19, 2017 2:06 pm
Here's one that I had prepared earlier:

Psychic World on the Sega Master System had a pretty smooth and nice-looking fade in & out routine, so I wanted to find out how it did it. Turns out it was a very simple 3-step process: for fade-outs, ramp down the red channel to zero, then do the same with green and blue sequentially. Almost a bit too primitive, but it actually looks good in-game.

The SMS has only 3 shades of each colour channel so a fade would have only a total of 4 steps if all 3 channels were simply faded out at the same time. Doing it sequentially gives 10 steps total.



The eye is sensitive to the different channels of colour differently, and so Sega/Hertz exploit that, not to mention fading through 4 or 8 (on the Gen/MD) levels only will look too abrupt and might look like it's "shaking" to some viewers.
FD64BC39-E0D2-41EC-A9C5-695230748388.gif (373.03 KB)
Attachment fairy
FD64BC39-E0D2-41EC-A9C5-695230748388.gif

  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Jan 19, 2017 3:33 pm
so it all boils down to
3x: if col>0x0F then col-=0x10
3x: if col>0x03 then col-=0x04
3x: if col>0x00 then col-=0x01
  View user's profile Send private message Visit poster's website
  • Joined: 15 Feb 2016
  • Posts: 19
Reply with quote
Post Posted: Thu Jan 19, 2017 7:28 pm
Bock wrote
Quote
In the end, I just hand picked color values, stuck them in ROM in a data table and loaded each one individually every few frames when fading back in. Good practices be damned.


What you could do instead of storing faded values for your actual palette, is to just create a fading table, which for each of the 64 possible colors gives you 0..3 variations, then the fading out is just a lookup in this table and you can keep your palettes flexible.


A fade table isn't a bad idea and I'll play around with that when I have more time.

The little noir style proof of concept game I'm working on has a limited palette and fades nicely enough when all channels are reduced at once. If I find this is unsatisfactory when I make more colorful games I'll keep the rest in mind. Thanks!
[/quote]
  View user's profile Send private message
Reply to topic



Back to the top of this page

Back to SMS Power!