Bump effect added. This is unfinished, nothing to see here yet, just commiting initia...
[dosdemo] / src / bump.c
1 // Bump effect (not moving yet of course, I have many ideas on this to commit before it's ready)
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <math.h>
6
7 #include "demo.h"
8 #include "screen.h"
9 #include "tinyfps.h"
10
11 static int init(void);
12 static void destroy(void);
13 static void start(long trans_time);
14 static void stop(long trans_time);
15 static void draw(void);
16
17 static struct screen scr = {
18         "bump",
19         init,
20         destroy,
21         start,
22         stop,
23         draw
24 };
25
26 static unsigned long startingTime;
27
28 static unsigned char *heightmap;
29 static unsigned short *lightmap;
30 static int *bumpOffset;
31
32 struct screen *bump_screen(void)
33 {
34         return &scr;
35 }
36
37 static int init(void)
38 {
39         const int numBlurs = 3;
40         int i, j, x, y;
41         int fb_size = fb_width * fb_height;
42
43         initFpsFonts();
44
45         heightmap = malloc(sizeof(*heightmap) * fb_size);
46         lightmap = malloc(sizeof(*lightmap) * fb_size);
47         bumpOffset = malloc(sizeof(*bumpOffset) * fb_size);
48
49         memset(lightmap, 0, fb_size);
50         memset(bumpOffset, 0, fb_size);
51
52         // Create random junk
53         for (i = 0; i < fb_size; i++)
54                 heightmap[i] = rand() & 255;
55
56         // Blur to smooth
57         for (j = 0; j < numBlurs; j++)
58                 for (i = 0; i < fb_size; i++)
59                         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;
60
61         // Inclination precalculation
62         i = 0;
63         for (y = 0; y < fb_height; y++)
64         {
65                 for (x = 0; x < fb_width; x++)
66                 {
67                         const float offsetPower = 2.0f;
68                         int dx, dy, xp, yp;
69
70                         dx = (int)((heightmap[i] - heightmap[i + 1]) * offsetPower);
71                         dy = (int)((heightmap[i] - heightmap[i + fb_width]) * offsetPower);
72
73                         xp = x + dx;
74                         if (xp < 0) xp = 0;
75                         if (xp > fb_width - 1) xp = fb_width - 1;
76
77                         yp = y + dy;
78                         if (yp < 0) yp = 0;
79                         if (yp > fb_height - 1) yp = fb_height - 1;
80
81                         bumpOffset[i++] = yp * fb_width + xp;
82                 }
83         }
84
85         // Lightmap test (this will be replaced by code in the main loop later on, the idea is you can render moving lights and other light geometry or sprites in light buffer and the bumpOffset will catch them)
86         i = 0;
87         for (y = 0; y < fb_height; y++)
88         {
89                 int yc = y - (fb_height >> 1);
90                 for (x = 0; x < fb_width; x++)
91                 {
92                         int xc = x - (fb_width >> 1);
93                         int c = (int)sqrt(xc * xc + yc * yc) << 1;
94                         int r;
95                         if (c > 255) c = 255;
96                         r = 255 - c;
97                         lightmap[i++] = ((r >> 4) << 11) | ((r >> 3) << 5) | (r >> 3);
98                 }
99         }
100
101         return 0;
102 }
103
104 static void destroy(void)
105 {
106 }
107
108 static void start(long trans_time)
109 {
110         startingTime = time_msec;
111 }
112
113 static void stop(long trans_time)
114 {
115 }
116
117 static void draw(void)
118 {
119         int i;
120         unsigned short *vram = (unsigned short*)fb_pixels;
121         for (i = 0; i < fb_width * fb_height; i++)
122         {
123                 unsigned short c = lightmap[bumpOffset[i]];
124                 *vram++ = c;
125         }
126
127         drawFps((unsigned short*)fb_pixels);
128
129         swap_buffers(0);
130 }