V9990 palette fading

Page 1/2
| 2

By Bogogil

Master (135)

Bogogil's picture

28-09-2012, 10:20

Hi,

as you might have noticed I work on a pacman-like game for my computer. Player-Tiles collision and Player-Ghosts collision detection is working already. I want to fade-in and -out different screens. Like fading-out title screen, fading-in playfield and so on. First I came with a routine which first devides the deltas of target colors to start colors by the count of wanted steps. Assume start color is 0,0,0 (RGB black) and target color is 150,100,50 and I want to fade in 10 steps. So the deltas would be 150/10=15, 100/10=10, 50/10=5: 15,10,5. I did this for all 16 palette colors for the tilemap as well as for the 16 sprite palette colors.
In the second step the routine iterates the wanted count of steps and increases every color triple by its delta in every iteration. The 16 triples are written to the VDP palette and then it waits for the vertical retrace before it continues with the next iteration.
Although this almost works (the palette is beeing faded with the correct colors) there are disturbance around the screen. Flashing pixels all around. I assume, this comes from the rather slow floating point arithmetics in C.
I changed the routine to use integer values and wait for the vertical retrace right before writing the calculated palette, but the flashing pixel are still there - although in the bottom border only.
I wonder if the VR-status bit is set when the bottom boarder is reached.

Any ideas?

Here is the code (sorry, the forum crunches my source-code. Bug?):
[code]
void wait_retrace() {
while ((READ_VDP(0x0a) & 64) != 0x00);
while ((READ_VDP(0x0a) & 64) == 0x00);
}

/* Fades in n frames from start_palette to target_palette */
void fade_palette(uint8_t palnumin, RGBQUAD *start_palette, RGBQUAD *target_palette, uint16_t frames) {
uint8_t palnum,i,numColours;
uint16_t j;
numColours=16;
int16_t stepsR[16];
int16_t stepsG[16];
int16_t stepsB[16];
int16_t palR[16];
int16_t palG[16];
int16_t palB[16];
BYTE R[16],G[16],B[16];
palnum=(uint8_t)(palnumin<<6);
for (i=0;i>8); // divide by 256
G[i]=(BYTE)(palG[i]>>8);
B[i]=(BYTE)(palB[i]>>8);
}
wait_retrace(); // wait for the vertical non-display
asm volatile ("move.b #14, 0x3de008"); // Register 14 (Palette pointer)
asm volatile ("move.b %0, 0x3de006"::"m" (palnum)); // rot
for (i=0;i

Login or register to post comments

By Bogogil

Master (135)

Bogogil's picture

28-09-2012, 17:36

Well, I moved the wait_retrace() call before calculating the next 16 RGB values within the fading loop. Now there are no "flashing pixel" when fading. I really assume, the VDP actually sets it's "vertical retrace display" bit before it really happens. Maybe it is a bug, maybe I am wrong or maybe it is by intention to give a slower CPU more time.
Now I have to work around rounding errors. But that's another topic...

Bogo

By Manuel

Ascended (17496)

Manuel's picture

28-09-2012, 21:10

Isn't there some V9990 hardware flaw when changing palette registers?

By Bogogil

Master (135)

Bogogil's picture

28-09-2012, 22:07

I am not sure. It could be. Do others have the same experience with the V9990?
I would expect the VDP would use its WAIT pin to delay palette writes when needed. Then one could update palette data any time. But obviously it doesn't. Well, it works any time (values are written correct), but with these annoying "sparkles".

With fading two palettes (tiles and sprites) the timing issues are back again. But the new function makes use of structs instead of simple arrays. I don't know how this is optimized by the compiler. Last but not least I could interleave fading of both palettes. Even frames for tile colors, odd frames for sprite colors.

By Manuel

Ascended (17496)

Manuel's picture

28-09-2012, 22:32

I think Koen van Hartingsveldt told me about it a few times. You see some stray pixels when changing palette or something.

By Algorythms

Champion (287)

Algorythms's picture

29-09-2012, 00:12

You need to time it so the changes to the palette are done when the sync is below visible area. I believe that did the trick when I was playing with the gfx9000.

By msd

Paragon (1412)

msd's picture

29-09-2012, 08:40

Algorythms is right. you really only can change the palette without side effects when the vdp is not using the palette data. So also during the backdrop color you will see the noise. You only have some time to change it during vertical retrace.

By snout

Ascended (15184)

snout's picture

29-09-2012, 08:52

So, theoretically, a palette split on a GFX9000 is not possible without these artefacts?

By Bogogil

Master (135)

Bogogil's picture

29-09-2012, 09:04

Thank you for the confirmation of my assumption. Now I have achieved a pretty smooth fading-in and -out. Smile
I tried interleaving both palettes as this afforded minimal changes. What I do now is:

  1. Wait for retrace
  2. Loop over all 16 tile palette colors and calculate next values
  3. Loop again over these colors, but write the values to the VDP
  4. Wait for retrace again
  5. Loop over all 16 sprite palette colors and calculate next values
  6. Loop again over these colors, but write the values to the VDP

This is the fading loop which iterates 16 times right now giving a nice fading. Smile

By GhostwriterP

Hero (556)

GhostwriterP's picture

29-09-2012, 10:10

Well snout, in P1 you also have the option to select one palette set out of four Wink . Changing that halfway works fine... trick does not work for sprites though.

By PingPong

Prophet (3623)

PingPong's picture

30-09-2012, 12:39

snout wrote:

So, theoretically, a palette split on a GFX9000 is not possible without these artefacts?

this is a great limitation. i also suspect that more others things on v9990 cannot be changed on the fly like on the old v99x8 chip.

Page 1/2
| 2