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