removed clang-format and clang_complete files from the repo
[dosdemo] / src / scr / minifx.c
1 #include "demo.h"
2 #include "imago2.h"
3 #include "screen.h"
4 #include <assert.h>
5 #include <math.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include "rlebmap.h"
11
12 /* APPROX. 170 FPS Minimum */
13
14 static int init(void);
15 static void destroy(void);
16 static void start(long trans_time);
17 static void stop(long trans_time);
18 static void draw(void);
19
20 static void updatePropeller(float t, RleBitmap *rle);
21
22 static unsigned short *backBuffer;
23
24 static unsigned char miniFXBuffer[1024];
25
26 static long lastFrameTime = 0;
27
28 static struct screen scr = {"minifx", init, destroy, start, 0, draw};
29
30 struct screen *minifx_screen(void) {
31         return &scr;
32 }
33
34 static int init(void) {
35         /* Allocate back buffer */
36         backBuffer = calloc(FB_WIDTH * FB_HEIGHT, sizeof(unsigned short));
37
38         return 0;
39 }
40
41 static void destroy(void) {
42         free(backBuffer);
43         backBuffer = 0;
44 }
45
46 static void start(long trans_time) { lastFrameTime = time_msec; }
47
48 static void draw(void) {
49         long lastFrameDuration;
50         int i, stride;
51         RleBitmap *rle;
52         int clearColor;
53         unsigned short clearColor16;
54
55         lastFrameDuration = (time_msec - lastFrameTime) / 1000.0f;
56         lastFrameTime = time_msec;
57
58         clearColor = 0x888888;
59         clearColor16 = ((clearColor << 8) & 0xF800)     /* R */
60                            | ((clearColor >> 5) & 0x07E0)   /* G */
61                            | ((clearColor >> 19) & 0x001F); /* B */
62
63         for (i=0; i<FB_WIDTH * FB_HEIGHT; i++) {
64                 backBuffer[i] = clearColor16;
65         }
66
67         /* For now create / destroy in each frame. We will manage these later */
68         rle = rleCreate(32, 32);
69
70         updatePropeller(time_msec / 1000.0f, rle);
71         stride = FB_WIDTH;
72         /*
73         rleBlit(rle, backBuffer, FB_WIDTH, FB_HEIGHT, stride,
74                         100, 100);
75         */
76
77         rleBlitScale(rle, backBuffer, FB_WIDTH, FB_HEIGHT, stride, 50,
78                   50, 3.0, 3.0);
79
80         rleDestroy(rle);
81
82         /* Blit effect to framebuffer */
83         memcpy(fb_pixels, backBuffer, FB_WIDTH * FB_HEIGHT * sizeof(unsigned short));
84         swap_buffers(0);
85 }
86
87
88 #define PROPELLER_CIRCLE_RADIUS 18
89 #define PROPELLER_CIRCLE_RADIUS_SQ (PROPELLER_CIRCLE_RADIUS * PROPELLER_CIRCLE_RADIUS)
90
91 static struct {
92         int circleX[3];
93         int circleY[3];
94 } propellerState;
95
96 static void updatePropeller(float t, RleBitmap *rle) {
97
98         int i, j;
99         int cx, cy, count = 0;
100         unsigned char *dst;
101         float x = 0.0f;
102         float y = 18.0f;
103         float nx, ny;
104         float cost, sint;
105         static float sin120 = 0.86602540378f;
106         static float cos120 = -0.5f;
107
108         t *= 0.1; /* Slow-mo to see what happens */
109
110         /* Rotate */
111         sint = sin(t);
112         cost = cos(t);
113         nx = x * cost - y * sint;
114         ny = y * cost + x * sint;
115         x = nx;
116         y = ny;
117         propellerState.circleX[0] = (int)(x + 0.5f) + 16;
118         propellerState.circleY[0] = (int)(y + 0.5f) + 16;
119
120         /* Rotate by 120 degrees, for the second circle */
121         nx = x * cos120 - y * sin120;
122         ny = y * cos120 + x * sin120;
123         x = nx;
124         y = ny;
125         propellerState.circleX[1] = (int)(x + 0.5f) + 16;
126         propellerState.circleY[1] = (int)(y + 0.5f) + 16;
127
128         /* 3rd circle */
129         nx = x * cos120 - y * sin120;
130         ny = y * cos120 + x * sin120;
131         x = nx;
132         y = ny;
133         propellerState.circleX[2] = (int)(x + 0.5f) + 16;
134         propellerState.circleY[2] = (int)(y + 0.5f) + 16;
135
136         /* Write effect to the mini fx buffer*/
137         dst = miniFXBuffer;
138         for (j = 0; j < 32; j++) {
139                 for (i = 0; i < 32; i++) {
140                         count = 0;
141
142                         /* First circle */
143                         cx = propellerState.circleX[0] - i;
144                         cy = propellerState.circleY[0] - j;
145                         if (cx * cx + cy * cy < PROPELLER_CIRCLE_RADIUS_SQ)
146                                 count++;
147
148                         /* 2nd circle */
149                         cx = propellerState.circleX[1] - i;
150                         cy = propellerState.circleY[1] - j;
151                         if (cx * cx + cy * cy < PROPELLER_CIRCLE_RADIUS_SQ)
152                                 count++;
153
154                         /* 3rd circle */
155                         cx = propellerState.circleX[2] - i;
156                         cy = propellerState.circleY[2] - j;
157                         if (cx * cx + cy * cy < PROPELLER_CIRCLE_RADIUS_SQ)
158                                 count++;
159
160                         *dst++ = count >= 2;
161                 }
162         }
163
164         /* Then, encode to rle */
165         rleEncode(rle, miniFXBuffer, 32, 32);
166
167         /* Distribute the produced streaks so that they don't produce garbage when interpolated */
168         rleDistributeStreaks(rle);
169 }