1 // Bump effect (not moving yet of course, I have many ideas on this to commit before it's ready)
12 static int init(void);
13 static void destroy(void);
14 static void start(long trans_time);
15 static void stop(long trans_time);
16 static void draw(void);
18 static struct screen scr = {
31 #define LIGHT_WIDTH 128
32 #define LIGHT_HEIGHT LIGHT_WIDTH
34 static unsigned long startingTime;
36 static unsigned char *heightmap;
37 static unsigned short *lightmap;
38 static int *bumpOffset;
40 static unsigned short *lightR;
41 static unsigned short *lightG;
42 static unsigned short *lightB;
43 static struct point pointR, pointG, pointB;
45 //#define FUNKY_COLORS
48 struct screen *bump_screen(void)
55 int i, j, x, y, c, r, g, b;
57 const int numBlurs = 3;
58 const int lightRadius = LIGHT_WIDTH / 2;
60 const int lightSize = LIGHT_WIDTH * LIGHT_HEIGHT;
61 const int fb_size = fb_width * fb_height;
63 // Just some parameters to temporary test the colors of 3 lights
65 // I see some artifacts if I mix channels, not sure if ORing is fine
66 const float r0 = 1.0f, g0 = 0.6f, b0 = 0.0f;
67 const float r1 = 0.5f, g1 = 1.0f, b1 = 0.2f;
68 const float r2 = 0.6f, g2 = 0.4f, b2 = 1.0f;
70 // if every light uses it's own channel bits, it's better
71 const float r0 = 1.0f, g0 = 0.0f, b0 = 0.0f;
72 const float r1 = 0.0f, g1 = 1.0f, b1 = 0.0f;
73 const float r2 = 0.0f, g2 = 0.0f, b2 = 1.0f;
78 heightmap = malloc(sizeof(*heightmap) * fb_size);
79 lightmap = malloc(sizeof(*lightmap) * fb_size);
80 bumpOffset = malloc(sizeof(*bumpOffset) * fb_size);
82 lightR = malloc(sizeof(*lightR) * lightSize);
83 lightG = malloc(sizeof(*lightG) * lightSize);
84 lightB = malloc(sizeof(*lightB) * lightSize);
86 memset(lightmap, 0, sizeof(*lightmap) * fb_size);
87 memset(bumpOffset, 0, sizeof(*bumpOffset) * fb_size);
90 for (i = 0; i < fb_size; i++)
91 heightmap[i] = rand() & 255;
94 for (j = 0; j < numBlurs; j++)
95 for (i = 0; i < fb_size; i++)
96 heightmap[i] = (heightmap[abs((i - 1) % fb_size)] + heightmap[abs((i + 1) % fb_size)] + heightmap[abs((i - fb_width) % fb_size)] + heightmap[abs((i + fb_width) % fb_size)]) >> 2;
98 // Inclination precalculation
100 for (y = 0; y < fb_height; y++)
102 for (x = 0; x < fb_width; x++)
104 const float offsetPower = 2.0f;
107 dx = (int)((heightmap[i] - heightmap[i + 1]) * offsetPower);
108 dy = (int)((heightmap[i] - heightmap[i + fb_width]) * offsetPower);
112 if (xp > fb_width - 1) xp = fb_width - 1;
116 if (yp > fb_height - 1) yp = fb_height - 1;
118 bumpOffset[i++] = yp * fb_width + xp;
122 // Generate three lights
124 for (y = 0; y < LIGHT_HEIGHT; y++)
126 int yc = y - (LIGHT_HEIGHT / 2);
127 for (x = 0; x < LIGHT_WIDTH; x++)
129 int xc = x - (LIGHT_WIDTH / 2);
130 float d = (float)sqrt(xc * xc + yc * yc);
131 float invDist = ((float)lightRadius - (float)sqrt(xc * xc + yc * yc)) / (float)lightRadius;
132 if (invDist < 0.0f) invDist = 0.0f;
134 c = (int)(invDist * 63);
139 lightR[i] = ((int)(r * r0) << 11) | ((int)(g * g0) << 5) | (int)(b * b0);
140 lightG[i] = ((int)(r * r1) << 11) | ((int)(g * g1) << 5) | (int)(b * b1);
141 lightB[i] = ((int)(r * r2) << 11) | ((int)(g * g2) << 5) | (int)(b * b2);
149 static void destroy(void)
153 static void start(long trans_time)
155 startingTime = time_msec;
158 static void stop(long trans_time)
163 static void renderLight(struct point *p, unsigned short *light)
165 // Check for boundaries is missing atm, will add soon
167 unsigned short *dst = (unsigned short*)lightmap + p->y * fb_width + p->x;
168 for (y = 0; y < LIGHT_HEIGHT; y++)
170 for (x = 0; x < LIGHT_WIDTH; x++)
174 dst += fb_width - LIGHT_WIDTH;
179 static void renderLights()
181 memset(lightmap, 0, fb_width * fb_height * sizeof(*lightmap));
182 // I will later delete only the regions of lights to speed up
184 renderLight(&pointR, lightR);
185 renderLight(&pointG, lightG);
186 renderLight(&pointB, lightB);
189 static void animateLights()
192 float dt = (float)(time_msec - startingTime) / 1000.0f;
194 center.x = (fb_width >> 1) - (LIGHT_WIDTH / 2);
195 center.y = (fb_height >> 1) - (LIGHT_HEIGHT / 2);
197 pointR.x = center.x + sin(1.2f * dt) * 64.0f;
198 pointR.y = center.y + sin(0.8f * dt) * 48.0f;
200 pointG.x = center.x + sin(1.5f * dt) * 56.0f;
201 pointG.y = center.y + sin(1.1f * dt) * 42.0f;
203 pointB.x = center.x + sin(2.0f * dt) * 80.0f;
204 pointB.y = center.y + sin(1.3f * dt) * 46.0f;
207 static void renderBump(unsigned short *vram)
210 for (i = 0; i < fb_width * fb_height; i++)
212 unsigned short c = lightmap[bumpOffset[i]];
217 static void draw(void)
221 renderBump((unsigned short*)vmem_back);
223 drawFps((unsigned short*)vmem_back);