Thunder... thunder... THUNDER SCREEN! HOOOOOOOOOOOOO
[dosdemo] / thunder.c
1 /* thunder. c */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <math.h>
6 #include <assert.h>
7 #include "imago2.h"
8 #include "demo.h"
9 #include "screen.h"
10
11 /* Render blur in half x half dimenstions. Add one pixel padding in all 
12  * directions (2 pixels horizontally, 2 pixels vertically).
13  */
14 #define BLUR_BUFFER_WIDTH (320/2 + 2)
15 #define BLUR_BUFFER_HEIGHT (240/2 + 2)
16 #define BLUR_BUFFER_SIZE (BLUR_BUFFER_WIDTH * BLUR_BUFFER_HEIGHT)
17 static unsigned char *blurBuffer, *blurBuffer2;
18
19 /* TODO: Load palette from file */
20 static unsigned short palette[256];
21
22 void clearBlurBuffer();
23 void drawPatternOnBlurBuffer();
24 void applyBlur();
25 void blitEffect();
26
27 static int init(void);
28 static void destroy(void);
29 static void start(long trans_time);
30 static void stop(long trans_time);
31 static void draw(void);
32
33 static unsigned int lastFrameTime = 0;
34 static float lastFrameDuration = 0.0f;
35 static struct screen scr = {
36         "thunder",
37         init,
38         destroy,
39         start,
40         0,
41         draw
42 };
43
44 struct screen *thunder_screen(void)
45 {
46         return &scr;
47 }
48
49 static int init(void)
50 {
51         int i = 0;
52
53         blurBuffer = malloc(BLUR_BUFFER_SIZE);
54         blurBuffer2 = malloc(BLUR_BUFFER_SIZE);
55
56         clearBlurBuffer();
57
58         /* For now, map to blue */
59         for (i = 0; i < 256; i++) {
60                 palette[i] = i >> 3;
61         }
62
63         return 0;
64 }
65
66 static void destroy(void)
67 {
68         free(blurBuffer);
69         blurBuffer = 0;
70         
71         free(blurBuffer2);
72         blurBuffer2 = 0;
73 }
74
75 static void start(long trans_time)
76 {
77         lastFrameTime = time_msec;
78 }
79
80
81 static void draw(void)
82 {
83
84         lastFrameDuration = (time_msec - lastFrameTime) / 1000.0f;
85         lastFrameTime = time_msec;
86         
87         drawPatternOnBlurBuffer();
88         applyBlur();
89         blitEffect();
90
91         swap_buffers(0);
92 }
93
94 void clearBlurBuffer() {
95         /* Clear the whole buffer (including its padding ) */
96         memset(blurBuffer, 0, BLUR_BUFFER_SIZE);
97         memset(blurBuffer2, 0, BLUR_BUFFER_SIZE);
98 }
99
100 void drawPatternOnBlurBuffer() {
101         int i, j;
102         unsigned char *dst = blurBuffer + BLUR_BUFFER_WIDTH + 1;
103         int starty, stopy, startx, stopx;
104
105         starty = rand() % 60;
106         stopy = starty + rand() % 60;
107         startx = rand() % 80;
108         stopx = startx + rand() % 80;
109
110         if (rand() % 2) return;
111
112         for (j = starty; j < stopy; j++) {
113                 for (i = startx; i < stopx; i++) {
114                         dst[i + j * BLUR_BUFFER_WIDTH] = 255;
115                 }
116         }
117 }
118
119 void applyBlur() {
120         int i, j;
121         unsigned char *tmp;
122         unsigned char *src = blurBuffer + BLUR_BUFFER_WIDTH + 1;
123         unsigned char *dst = blurBuffer2 + BLUR_BUFFER_WIDTH + 1;
124
125         for (j = 0; j < 120; j++) {
126                 for (i = 0; i < 160; i++) {
127                         *dst = (*(src - 1) + *(src + 1) + *(src - BLUR_BUFFER_WIDTH) + *(src + BLUR_BUFFER_WIDTH)) >> 2;
128                         dst++;
129                         src++;
130                 }
131                 /* Just skip the padding since we went through the scanline in the inner loop (except from the padding) */
132                 src += 2;
133                 dst += 2;
134         }
135
136         /* Swap blur buffers */
137         tmp = blurBuffer;
138         blurBuffer = blurBuffer2;
139         blurBuffer2 = tmp;
140 }
141
142 void blitEffect() {
143         unsigned int *dst1 = (unsigned int*) vmem_back;
144         unsigned int *dst2 = dst1 + 160; /* We're writing two pixels at once */
145         unsigned char *src1 = blurBuffer + BLUR_BUFFER_WIDTH + 1;
146         unsigned char *src2 = src1 + BLUR_BUFFER_WIDTH;
147         unsigned char tl, tr, bl, br;
148         int i, j;
149
150         for (j = 0; j < 120; j++) {
151                 for (i = 0; i < 160; i++) {
152                         tl = *src1;
153                         tr = (*src1 + *(src1 + 1)) >> 1;
154                         bl = (*src1 + *src2) >> 1;
155                         br = tr + ((*src2 + *(src2 + 1)) >> 1) >> 1;
156
157                         /* Pack 2 pixels in each 32 bit word */
158                         *dst1 = (palette[tr] << 16) | palette[tl];
159                         *dst2 = (palette[br] << 16) | palette[bl];
160
161                         dst1++;
162                         src1++;
163                         dst2++;
164                         src2++;
165                 }
166                 /* Again, skip padding */
167                 src1 += 2;
168                 src2 += 2;
169
170                 /* For now, skip a scanline */
171                 dst1 += 160;
172                 dst2 += 160;
173         }
174
175 }
176
177
178
179
180