removed clang-format and clang_complete files from the repo
[dosdemo] / src / demo.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include <ctype.h>
6 #include <errno.h>
7 #include <limits.h>
8 #include "demo.h"
9 #include "screen.h"
10 #include "3dgfx.h"
11 #include "audio.h"
12 #include "cfgopt.h"
13 #include "console.h"
14 #include "tinyfps.h"
15 #include "util.h"
16
17 #define MOUSE_TIMEOUT   1200
18
19 #define GUARD_XPAD      0
20 #define GUARD_YPAD      32
21
22 int fb_width, fb_height, fb_bpp, fb_scan_size;
23 float fb_aspect;
24 long fb_size, fb_buf_size;
25 uint16_t *fb_pixels, *vmem;
26 uint16_t *fb_buf;
27
28 unsigned long time_msec;
29 int mouse_x, mouse_y;
30 unsigned int mouse_bmask;
31
32 static struct au_module *mod;
33
34 float sball_matrix[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
35
36 static unsigned long last_mouse_move;
37 static int prev_mx, prev_my, mouse_dx, mouse_dy;
38 static unsigned int bmask_diff, prev_bmask;
39
40 static unsigned long nframes;
41 static int con_active;
42
43 extern uint16_t loading_pixels[];       /* data.asm */
44
45 int demo_init(int argc, char **argv)
46 {
47         if(demo_init1(argc, argv) == -1) {
48                 return -1;
49         }
50         if(demo_init2() == -1) {
51                 return -1;
52         }
53         return 0;
54 }
55
56 static struct screen *scr;
57
58 int demo_init1(int argc, char **argv)
59 {
60         char *env;
61
62         if(load_config("demo.cfg") == -1) {
63                 return -1;
64         }
65         if((env = getenv("START_SCR"))) {
66                 opt.start_scr = env;
67         }
68         if(parse_args(argc, argv) == -1) {
69                 return -1;
70         }
71         return 0;
72 }
73
74 int demo_init2(void)
75 {
76         /* reuse the loading image as our back buffer.
77          * adjust fb_pixels to leave 4 pixels guard band top/bottom. We have enough
78          * space since the loading image is 8 pixels taller.
79          */
80         fb_pixels = loading_pixels + 320 * 4;
81
82         con_init();
83         initFpsFonts();
84
85         if(g3d_init() == -1) {
86                 return -1;
87         }
88         g3d_framebuffer(FB_WIDTH, FB_HEIGHT, fb_pixels);
89
90         if(opt.music) {
91                 if(!(mod = au_load_module("data/test.mod"))) {
92                         return -1;
93                 }
94         }
95
96         if(scr_init() == -1) {
97                 return -1;
98         }
99         if(opt.start_scr) {
100                 scr = scr_lookup(opt.start_scr);
101         } else {
102                 scr = scr_screen(0);
103         }
104
105         if(!scr || scr_change(scr, 4000) == -1) {
106                 fprintf(stderr, "screen %s not found\n", opt.start_scr ? opt.start_scr : "0");
107                 return -1;
108         }
109
110         /* clear the framebuffer at least once */
111         memset(fb_pixels, 0, FB_WIDTH * FB_HEIGHT * FB_BPP / CHAR_BIT);
112
113         if(opt.music) {
114                 au_play_module(mod);
115         }
116         return 0;
117 }
118
119 void demo_cleanup(void)
120 {
121         if(opt.music) {
122                 au_free_module(mod);
123         }
124         scr_shutdown();
125         g3d_destroy();
126
127         if(time_msec) {
128                 float fps = (float)nframes / ((float)time_msec / 1000.0f);
129                 printf("average framerate: %.1f\n", fps);
130         }
131 }
132
133 int demo_resizefb(int width, int height, int bpp)
134 {
135         int newsz, new_scansz;
136
137         if(!width || !height || !bpp) {
138                 free(fb_buf);
139                 fb_buf = fb_pixels = 0;
140                 fb_size = fb_buf_size = fb_scan_size = 0;
141                 fb_width = fb_height = fb_bpp = 0;
142                 return 0;
143         }
144
145         new_scansz = ((width + GUARD_XPAD * 2) * bpp + 7) / 8;
146         newsz = (height + GUARD_YPAD * 2) * new_scansz;
147
148         if(!fb_buf || newsz > fb_buf_size) {
149                 void *tmp = malloc(newsz);
150                 if(!tmp) return -1;
151
152                 free(fb_buf);
153                 fb_buf = tmp;
154                 fb_buf_size = newsz;
155         }
156
157         fb_scan_size = new_scansz;
158         fb_pixels = (uint16_t*)((char*)fb_buf + GUARD_YPAD * fb_scan_size + (GUARD_XPAD * bpp + 7) / 8);
159         fb_width = width;
160         fb_height = height;
161         fb_bpp = bpp;
162         fb_size = fb_scan_size * fb_height;
163
164         fb_aspect = (float)fb_width / (float)fb_height;
165
166         return 0;
167 }
168
169
170 void demo_draw(void)
171 {
172         if(opt.mouse) {
173                 mouse_dx = mouse_x - prev_mx;
174                 mouse_dy = mouse_y - prev_my;
175                 prev_mx = mouse_x;
176                 prev_my = mouse_y;
177                 bmask_diff = mouse_bmask ^ prev_bmask;
178                 prev_bmask = mouse_bmask;
179                 if(mouse_dx | mouse_dy) {
180                         last_mouse_move = time_msec;
181                 }
182         }
183
184         if(opt.music) {
185                 au_update();
186         }
187         scr_update();
188         scr_draw();
189
190         ++nframes;
191 }
192
193 /* called by swap_buffers just before the actual swap */
194 void demo_post_draw(void *pixels)
195 {
196         char buf[32];
197         if(opt.dbginfo) {
198                 drawFps(pixels);
199                 if(dbg_curscr_name) {
200                         cs_dputs(pixels, dbg_curscr_name_pos, 240 - 16, dbg_curscr_name);
201                 }
202         }
203
204         if(con_active) {
205                 con_draw(pixels);
206         }
207
208         if(opt.mouse && time_msec - last_mouse_move < MOUSE_TIMEOUT) {
209                 cs_mouseptr(pixels, mouse_x, mouse_y);
210         }
211 }
212
213 void cs_puts_font(cs_font_func csfont, int sz, void *fb, int x, int y, const char *str)
214 {
215         while(*str) {
216                 int c = *str++;
217
218                 if(c > ' ' && c < 128) {
219                         csfont(fb, x, y, c - ' ');
220                 }
221                 x += sz;
222         }
223 }
224
225 void change_screen(int idx)
226 {
227         printf("change screen %d\n", idx);
228         scr_change(scr_screen(idx), 4000);
229 }
230
231 void demo_keyboard(int key, int press)
232 {
233         int nscr;
234
235         if(press) {
236                 switch(key) {
237                 case 27:
238                         if(con_active) {
239                                 con_stop();
240                                 con_active = 0;
241                         } else {
242                                 demo_quit();
243                         }
244                         return;
245
246                 case 127:
247                         debug_break();
248                         return;
249
250                 case '`':
251                         con_active = !con_active;
252                         if(con_active) {
253                                 con_start();
254                         } else {
255                                 con_stop();
256                         }
257                         return;
258
259                 case '/':
260                         if(!con_active) {
261                                 con_start();
262                                 con_active = con_input('/');
263                                 return;
264                         }
265
266                 default:
267                         if(con_active) {
268                                 con_active = con_input(key);
269                                 return;
270                         }
271
272                         if(key >= '1' && key <= '9' && key <= '1' + scr_num_screens()) {
273                                 change_screen(key - '1');
274                                 return;
275                         } else if(key == '0' && scr_num_screens() >= 10) {
276                                 change_screen(9);
277                                 return;
278                         }
279                 }
280
281                 scr_keypress(key);
282         }
283 }
284
285
286 void mouse_orbit_update(float *theta, float *phi, float *dist)
287 {
288         if(mouse_bmask) {
289                 if(bmask_diff == 0) {
290
291                         if(mouse_dx | mouse_dy) {
292                                 if(mouse_bmask & MOUSE_BN_LEFT) {
293                                         float p = *phi;
294                                         *theta += mouse_dx * 1.0;
295                                         p += mouse_dy * 1.0;
296
297                                         if(p < -90) p = -90;
298                                         if(p > 90) p = 90;
299                                         *phi = p;
300                                 }
301                                 if(mouse_bmask & MOUSE_BN_RIGHT) {
302                                         *dist += mouse_dy * 0.5;
303
304                                         if(*dist < 0) *dist = 0;
305                                 }
306                         }
307                 }
308         }
309 }