as you might have noticed I work on a pacman-like game. Player-Tiles collision and Player-Ghosts collision detection is working already. Now 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 divides 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 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 being faded with the correct colors) there are flashing pixels all around the screen while fading. I assume, this comes from the rather slow floating point arithmetics in C.
Later I changed the routine to use integer values and moved the waiting for the vertical retrace period 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?
Simon
Here is the code:
Code: Select all
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
start_palette is disabled for testing */
void fade_palette(uint8_t palnumin, RGBQUAD *start_palette, RGBQUAD *target_palette, uint16_t frames) {
uint8_t palnum,i,numColors;
uint16_t j;
numColors=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<numColors;i++) {
stepsR[i]=(target_palette[i].rgbRed<<8)/frames; //*256/frames
stepsG[i]=(target_palette[i].rgbGreen<<8)/frames;
stepsB[i]=(target_palette[i].rgbBlue<<8)/frames;
palR[i]=0; // ignore starting color and fade from black to target
palG[i]=0;
palB[i]=0;
}
for(j=0;j<frames;j++) { // iterate n*frames
for (i=0;i<numColors;i++) { // in every iteration calculate all (16) RGB tripples (full palette)
palR[i]+=stepsR[i];
palG[i]+=stepsG[i];
palB[i]+=stepsB[i];
R[i]=(BYTE)(palR[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)); // palette number
for (i=0;i<numColors;i++) {
asm volatile ("move.b %0, 0x3de002"::"m" (R[i])); // red
asm volatile ("move.b %0, 0x3de002"::"m" (G[i])); // green
asm volatile ("move.b %0, 0x3de002"::"m" (B[i])); // blue
}
}
}