b2a03e00e43a5e276b0ad879f5ddb4b7db05158d
[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 "music.h"
12 #include "cfgopt.h"
13 #include "tinyfps.h"
14 #include "util.h"
15
16 int fb_width = 320;
17 int fb_height = 240;
18 int fb_bpp = 16;
19 uint16_t *fb_pixels, *vmem_back, *vmem_front;
20 unsigned long time_msec;
21 int mouse_x, mouse_y;
22 unsigned int mouse_bmask;
23
24 float sball_matrix[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
25
26 static unsigned long nframes;
27
28 int demo_init(int argc, char **argv)
29 {
30         struct screen *scr;
31         char *env;
32
33         if(load_config("demo.cfg") == -1) {
34                 return -1;
35         }
36         if((env = getenv("START_SCR"))) {
37                 opt.start_scr = env;
38         }
39         if(parse_args(argc, argv) == -1) {
40                 return -1;
41         }
42
43         initFpsFonts();
44
45         if(g3d_init() == -1) {
46                 return -1;
47         }
48         g3d_framebuffer(fb_width, fb_height, fb_pixels);
49
50         if(opt.music) {
51                 if(music_open("data/test.mod") == -1) {
52                         return -1;
53                 }
54         }
55
56         if(scr_init() == -1) {
57                 return -1;
58         }
59         if(opt.start_scr) {
60                 scr = scr_lookup(opt.start_scr);
61         } else {
62                 scr = scr_screen(0);
63         }
64
65         if(!scr || scr_change(scr, 4000) == -1) {
66                 fprintf(stderr, "screen %s not found\n", opt.start_scr ? opt.start_scr : "0");
67                 return -1;
68         }
69
70         /* clear the framebuffer at least once */
71         memset(fb_pixels, 0, fb_width * fb_height * fb_bpp / CHAR_BIT);
72
73         if(opt.music) {
74                 music_play();
75         }
76         return 0;
77 }
78
79 void demo_cleanup(void)
80 {
81         if(opt.music) {
82                 music_close();
83         }
84         scr_shutdown();
85         g3d_destroy();
86
87         if(time_msec) {
88                 float fps = (float)nframes / ((float)time_msec / 1000.0f);
89                 printf("average framerate: %.1f\n", fps);
90         }
91 }
92
93 void demo_draw(void)
94 {
95         if(opt.music) {
96                 music_update();
97         }
98         scr_update();
99         scr_draw();
100
101         ++nframes;
102 }
103
104 static void change_screen(int idx)
105 {
106         printf("change screen %d\n", idx);
107         scr_change(scr_screen(idx), 4000);
108 }
109
110 #define CBUF_SIZE       64
111 #define CBUF_MASK       (CBUF_SIZE - 1)
112 void demo_keyboard(int key, int press)
113 {
114         static char cbuf[CBUF_SIZE];
115         static int rd, wr;
116         char inp[CBUF_SIZE + 1], *dptr;
117         int i, nscr;
118
119         if(press) {
120                 switch(key) {
121                 case 27:
122                         demo_quit();
123                         break;
124
125                 case 127:
126                         debug_break();
127                         break;
128
129                 case '\n':
130                 case '\r':
131                         dptr = inp;
132                         while(rd != wr) {
133                                 *dptr++ = cbuf[rd];
134                                 rd = (rd + 1) & CBUF_MASK;
135                         }
136                         *dptr = 0;
137                         if(inp[0]) {
138                                 printf("trying to match: %s\n", inp);
139                                 nscr = scr_num_screens();
140                                 for(i=0; i<nscr; i++) {
141                                         if(strstr(scr_screen(i)->name, inp)) {
142                                                 change_screen(i);
143                                                 break;
144                                         }
145                                 }
146                         }
147                         break;
148
149                 default:
150                         if(key >= '1' && key <= '9' && key <= '1' + scr_num_screens()) {
151                                 change_screen(key - '1');
152                         } else if(key == '0' && scr_num_screens() >= 10) {
153                                 change_screen(9);
154                         }
155
156                         if(key < 256 && isprint(key)) {
157                                 cbuf[wr] = key;
158                                 wr = (wr + 1) & CBUF_MASK;
159                                 if(wr == rd) { /* overflow */
160                                         rd = (rd + 1) & CBUF_MASK;
161                                 }
162                         }
163                         break;
164                 }
165         }
166 }
167
168
169 void mouse_orbit_update(float *theta, float *phi, float *dist)
170 {
171         static int prev_mx, prev_my;
172         static unsigned int prev_bmask;
173
174         if(mouse_bmask) {
175                 if((mouse_bmask ^ prev_bmask) == 0) {
176                         int dx = mouse_x - prev_mx;
177                         int dy = mouse_y - prev_my;
178
179                         if(dx || dy) {
180                                 if(mouse_bmask & 1) {
181                                         float p = *phi;
182                                         *theta += dx * 1.0;
183                                         p += dy * 1.0;
184
185                                         if(p < -90) p = -90;
186                                         if(p > 90) p = 90;
187                                         *phi = p;
188                                 }
189                                 if(mouse_bmask & 4) {
190                                         *dist += dy * 0.5;
191
192                                         if(*dist < 0) *dist = 0;
193                                 }
194                         }
195                 }
196         }
197         prev_mx = mouse_x;
198         prev_my = mouse_y;
199         prev_bmask = mouse_bmask;
200 }