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