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 NUM_BIG_LIGHTS 3
32 #define BIG_LIGHT_WIDTH 256
33 #define BIG_LIGHT_HEIGHT BIG_LIGHT_WIDTH
35 static unsigned long startingTime;
37 static unsigned char *heightmap;
38 static unsigned short *lightmap;
39 static int *bumpOffset;
41 static unsigned short *bigLight[NUM_BIG_LIGHTS];
42 static struct point bigLightPoint[NUM_BIG_LIGHTS];
44 struct screen *bump_screen(void)
51 int i, j, x, y, c, r, g, b;
53 const int numBlurs = 3;
54 const int lightRadius = BIG_LIGHT_WIDTH / 2;
56 const int bigLightSize = BIG_LIGHT_WIDTH * BIG_LIGHT_HEIGHT;
57 const int fb_size = fb_width * fb_height;
59 // Just some parameters to temporary test the colors of 3 lights
60 // if every light uses it's own channel bits, it's better
61 const float rgbMul[9] = { 1.0f, 0.0f, 0.0f,
66 heightmap = malloc(sizeof(*heightmap) * fb_size);
67 lightmap = malloc(sizeof(*lightmap) * fb_size);
68 bumpOffset = malloc(sizeof(*bumpOffset) * fb_size);
70 for (i = 0; i < NUM_BIG_LIGHTS; i++)
71 bigLight[i] = malloc(sizeof(*bigLight[i]) * bigLightSize);
73 memset(lightmap, 0, sizeof(*lightmap) * fb_size);
74 memset(bumpOffset, 0, sizeof(*bumpOffset) * fb_size);
77 for (i = 0; i < fb_size; i++)
78 heightmap[i] = rand() & 255;
81 for (j = 0; j < numBlurs; j++)
82 for (i = 0; i < fb_size; i++)
83 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;
85 // Inclination precalculation
87 for (y = 0; y < fb_height; y++)
89 for (x = 0; x < fb_width; x++)
91 const float offsetPower = 2.0f;
94 dx = i < fb_size - 1 ? (int)((heightmap[i] - heightmap[i + 1]) * offsetPower) : 0;
95 dy = i < fb_size - fb_width ? (int)((heightmap[i] - heightmap[i + fb_width]) * offsetPower) : 0;
99 if (xp > fb_width - 1) xp = fb_width - 1;
103 if (yp > fb_height - 1) yp = fb_height - 1;
105 bumpOffset[i++] = yp * fb_width + xp;
109 // Generate three lights
111 for (y = 0; y < BIG_LIGHT_HEIGHT; y++)
113 int yc = y - (BIG_LIGHT_HEIGHT / 2);
114 for (x = 0; x < BIG_LIGHT_WIDTH; x++)
116 int xc = x - (BIG_LIGHT_WIDTH / 2);
117 float d = (float)sqrt(xc * xc + yc * yc);
118 float invDist = ((float)lightRadius - (float)sqrt(xc * xc + yc * yc)) / (float)lightRadius;
119 if (invDist < 0.0f) invDist = 0.0f;
121 c = (int)(invDist * 63);
126 for (j = 0; j < NUM_BIG_LIGHTS; j++)
128 bigLight[j][i] = ((int)(r * rgbMul[j * 3]) << 11) | ((int)(g * rgbMul[j * 3 + 1]) << 5) | (int)(b * rgbMul[j * 3 + 2]);
137 static void destroy(void)
141 static void start(long trans_time)
143 startingTime = time_msec;
146 static void stop(long trans_time)
150 static void eraseArea(struct point *p, int width, int height)
157 int x1 = p->x + width;
158 int y1 = p->y + height;
162 if (x1 > fb_width) x1 = fb_width;
163 if (y1 > fb_height) y1 = fb_height;
167 dst = lightmap + y0 * fb_width + x0;
169 for (y = y0; y < y1; y++)
171 for (x = x0; x < x1; x++)
175 dst += fb_width - dx;
180 static void renderLight(struct point *p, int width, int height, unsigned short *light)
183 unsigned short *src, *dst;
187 int x1 = p->x + width;
188 int y1 = p->y + height;
205 if (x1 > fb_width) x1 = fb_width;
206 if (y1 > fb_height) y1 = fb_height;
210 dst = lightmap + y0 * fb_width + x0;
211 src = light + yl * width + xl;
213 for (y = y0; y < y1; y++)
215 for (x = x0; x < x1; x++)
219 dst += fb_width - dx;
224 static void eraseLights()
227 for (i = 0; i < NUM_BIG_LIGHTS; i++)
228 eraseArea(&bigLightPoint[i], BIG_LIGHT_WIDTH, BIG_LIGHT_HEIGHT);
231 static void renderLights()
234 for (i = 0; i < NUM_BIG_LIGHTS; i++)
235 renderLight(&bigLightPoint[i], BIG_LIGHT_WIDTH, BIG_LIGHT_HEIGHT, bigLight[i]);
238 static void animateLights()
241 float dt = (float)(time_msec - startingTime) / 1000.0f;
243 center.x = (fb_width >> 1) - (BIG_LIGHT_WIDTH / 2);
244 center.y = (fb_height >> 1) - (BIG_LIGHT_HEIGHT / 2);
246 bigLightPoint[0].x = center.x + sin(1.2f * dt) * 144.0f;
247 bigLightPoint[0].y = center.y + sin(0.8f * dt) * 148.0f;
249 bigLightPoint[1].x = center.x + sin(1.5f * dt) * 156.0f;
250 bigLightPoint[1].y = center.y + sin(1.1f * dt) * 92.0f;
252 bigLightPoint[2].x = center.x + sin(2.0f * dt) * 112.0f;
253 bigLightPoint[2].y = center.y + sin(1.3f * dt) * 136.0f;
256 static void renderBump(unsigned short *vram)
259 for (i = 0; i < fb_width * fb_height; i++)
261 unsigned short c = lightmap[bumpOffset[i]];
266 static void draw(void)
271 renderBump((unsigned short*)vmem_back);
273 drawFps((unsigned short*)vmem_back);