deepstone
view src/test.c @ 24:ad6b185723cd
foo
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 21 Sep 2013 20:18:28 +0300 |
parents | 777be77b6432 |
children | 5ff8ce78059a |
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <signal.h>
5 #include <conio.h>
6 #include "wvga.h"
7 #include "mingl.h"
8 #include "timer.h"
9 #include "mouse.h"
10 #include "palman.h"
11 #include "texture.h"
13 static int init(void);
14 static void shutdown(void);
15 static void redraw(void);
16 static void draw_cursor(unsigned char *fb, int xsz, int ysz, int mx, int my, int cidx);
17 static int keyb(char key);
18 static void mouse_button(int bn, int x, int y);
19 static void mouse_motion(int x, int y);
20 static void sighandler(int s);
21 static int parse_args(int argc, char **argv);
22 static void print_perf(void);
24 static unsigned char *fbuf;
26 static struct texture *tex;
27 static char *texfile;
29 static int white_base, red_base, green_base, blue_base;
30 static int grad_range;
32 static int use_vsync = 1;
33 static int under_windows = 0;
34 static unsigned long num_frm;
36 enum { CUBE, SPHERE, TORUS, NUM_PRIMS };
37 static int prim = SPHERE;
38 static int auto_rotate = 1;
39 static float cam_theta, cam_phi, cam_zoom = 4.0;
41 static int mx, my;
43 int main(int argc, char **argv)
44 {
45 int mbn, prev_mx = -1, prev_my = -1, prev_mbn = 0;
47 if(parse_args(argc, argv) == -1) {
48 return 1;
49 }
51 if(init() == -1) {
52 return 1;
53 }
55 reset_timer();
57 for(;;) {
58 if(kbhit()) {
59 if(keyb(getch()) == 0) {
60 break;
61 }
62 }
64 mbn = read_mouse(&mx, &my);
65 if(mbn != prev_mbn) {
66 mouse_button(mbn, mx, my);
67 prev_mbn = mbn;
68 }
69 if(mx != prev_mx || my != prev_my) {
70 if(mbn) {
71 mouse_motion(mx, my);
72 }
73 prev_mx = mx;
74 prev_my = my;
75 }
77 redraw();
78 }
80 shutdown();
81 print_perf();
82 return 0;
83 }
85 static int init(void)
86 {
87 int i;
88 struct palm_color *pal;
90 init_timer(under_windows ? 0 : 100);
92 set_video_mode(0x13);
94 signal(SIGINT, sighandler);
95 signal(SIGSEGV, sighandler);
96 signal(SIGFPE, sighandler);
97 signal(SIGILL, sighandler);
98 signal(SIGABRT, sighandler);
100 have_mouse();
103 if(mgl_init(320, 200) == -1) {
104 fprintf(stderr, "mgl init failed\n");
105 return -1;
106 }
107 fbuf = mgl_framebuffer();
110 if(!texfile) {
111 palm_add_color(255, 255, 255);
112 palm_add_color(255, 0, 0);
113 palm_add_color(0, 255, 0);
114 palm_add_color(0, 0, 255);
115 palm_build();
117 white_base = palm_color_base(255, 255, 255);
118 red_base = palm_color_base(255, 0, 0);
119 green_base = palm_color_base(0, 255, 0);
120 blue_base = palm_color_base(0, 0, 255);
122 tex = tex_gen_checker(64, 64, 3, 3, red_base, blue_base);
123 } else {
124 if(!(tex = load_texture(texfile))) {
125 return -1;
126 }
128 palm_build();
129 get_texture_pixels(tex);
131 mgl_enable(MGL_TEXTURE_2D);
132 }
134 grad_range = palm_color_range();
136 pal = palm_palette();
137 for(i=0; i<palm_palette_size(); i++) {
138 set_pal_entry(i, pal[i].r, pal[i].g, pal[i].b);
139 }
141 mgl_enable(MGL_CULL_FACE);
142 mgl_enable(MGL_DEPTH_TEST);
143 mgl_enable(MGL_SMOOTH);
144 mgl_color_range(grad_range - 1); /* gradient range */
146 mgl_enable(MGL_LIGHTING);
147 mgl_light_intensity(0, 1.0);
148 mgl_light_position(0, -0.5, 0.5, 1, 0);
150 mgl_matrix_mode(MGL_PROJECTION);
151 mgl_load_identity();
152 mgl_perspective(45.0, 320.0 / 200.0, 0.5, 100.0);
154 mgl_teximage(tex->width, tex->height, tex->pixels);
156 return 0;
157 }
159 static void shutdown(void)
160 {
161 mgl_free();
162 set_video_mode(3);
163 }
165 static void redraw(void)
166 {
167 float angle = get_msec() / 10.0;
168 mgl_clear(0);
169 mgl_clear_depth();
171 mgl_matrix_mode(MGL_MODELVIEW);
172 mgl_load_identity();
173 mgl_translate(0, 0, -cam_zoom);
174 if(auto_rotate) {
175 mgl_rotate(angle * 0.5, 1, 0, 0);
176 mgl_rotate(angle, 0, 0, 1);
177 } else {
178 mgl_rotate(cam_phi, 1, 0, 0);
179 mgl_rotate(cam_theta, 0, 1, 0);
180 }
182 switch(prim) {
183 case TORUS:
184 mgl_index(green_base);
185 mgl_torus(1.0, 0.25, 16, 8);
186 break;
187 case SPHERE:
188 mgl_index(blue_base);
189 mgl_sphere(1.0, 16, 8);
190 break;
191 case CUBE:
192 mgl_index(red_base);
193 mgl_cube(1.0);
194 }
196 if(!auto_rotate) {
197 draw_cursor(fbuf, 320, 200, mx, my, white_base + grad_range - 1);
198 }
200 copy_frame(fbuf);
201 if(use_vsync) {
202 wait_vsync();
203 }
204 num_frm++;
205 }
207 static void draw_cursor(unsigned char *fb, int xsz, int ysz, int mx, int my, int cidx)
208 {
209 static char img[] =
210 "oo........"
211 "oxo......."
212 "oxxo......"
213 "oxxxo....."
214 "oxxxxo...."
215 "oxxxxxo..."
216 "oxxxxxxo.."
217 "oxxxxxxxo."
218 "oxxxxxxxxo"
219 "oxxxxxoooo"
220 "oxxoxxo..."
221 "oxo.oxxo.."
222 "oo..oxxo.."
223 ".....oxxo."
224 ".....oxxo."
225 "......oo..";
226 int i, j, w = 10, h = 16;
228 if(mx < 0 || my < 0) {
229 return;
230 }
231 if(mx + w >= xsz) {
232 w = xsz - mx;
233 }
234 if(my + h >= ysz) {
235 h = ysz - my;
236 }
238 fb += my * xsz + mx;
239 for(i=0; i<h; i++) {
240 for(j=0; j<w; j++) {
241 char c = img[(i << 3) + (i << 1) + j];
242 if(c != '.') {
243 fb[j] = c == 'x' ? 0 : cidx;
244 }
245 }
246 fb += xsz;
247 }
248 }
250 static int keyb(char key)
251 {
252 switch(key) {
253 case 'q':
254 case 27:
255 return 0;
257 case 's':
258 if(mgl_isenabled(MGL_SMOOTH)) {
259 mgl_disable(MGL_SMOOTH);
260 } else {
261 mgl_enable(MGL_SMOOTH);
262 }
263 break;
265 case 't':
266 if(mgl_isenabled(MGL_TEXTURE_2D)) {
267 mgl_disable(MGL_TEXTURE_2D);
268 } else {
269 mgl_enable(MGL_TEXTURE_2D);
270 }
271 break;
273 case ' ':
274 auto_rotate = !auto_rotate;
275 break;
277 case 'p':
278 prim = (prim + 1) % NUM_PRIMS;
279 break;
281 default:
282 break;
283 }
284 return 1;
285 }
287 static int bnstate;
288 static int prev_x, prev_y;
290 static void mouse_button(int bn, int x, int y)
291 {
292 bnstate = bn;
293 prev_x = x;
294 prev_y = y;
295 }
297 static void mouse_motion(int x, int y)
298 {
299 int dx, dy;
301 dx = x - prev_x;
302 dy = y - prev_y;
303 prev_x = x;
304 prev_y = y;
306 if(bnstate & MOUSE_LEFT) {
307 cam_theta += dx;
308 cam_phi += dy;
310 if(cam_phi > 90) cam_phi = 90;
311 if(cam_phi < -90) cam_phi = -90;
312 }
313 if(bnstate & MOUSE_RIGHT) {
314 cam_zoom += dy * 0.1;
315 if(cam_zoom < 0.0) {
316 cam_zoom = 0.0;
317 }
318 }
319 }
321 static void sighandler(int s)
322 {
323 set_video_mode(3);
325 switch(s) {
326 case SIGABRT:
327 fprintf(stderr, "abort\n");
328 break;
330 case SIGILL:
331 fprintf(stderr, "illegal operation\n");
332 break;
334 case SIGSEGV:
335 fprintf(stderr, "segmentation fault\n");
336 break;
338 case SIGINT:
339 fprintf(stderr, "interrupted\n");
340 break;
342 case SIGFPE:
343 fprintf(stderr, "floating point exception\n");
344 break;
346 default:
347 fprintf(stderr, "unexpected signal\n");
348 }
350 exit(1);
351 }
353 static int parse_args(int argc, char **argv)
354 {
355 int i;
357 for(i=1; i<argc; i++) {
358 if(argv[i][0] == '-') {
359 if(argv[i][2] != 0) {
360 goto invalid;
361 }
362 switch(argv[i][1]) {
363 case 'a':
364 auto_rotate = !auto_rotate;
365 break;
367 case 't':
368 texfile = argv[++i];
369 break;
371 case 'v':
372 use_vsync = !use_vsync;
373 break;
375 case 'p':
376 if(strcmp(argv[++i], "cube") == 0) {
377 prim = CUBE;
378 } else if(strcmp(argv[i], "sphere") == 0) {
379 prim = SPHERE;
380 } else if(strcmp(argv[i], "torus") == 0) {
381 prim = TORUS;
382 } else {
383 goto invalid;
384 }
385 break;
387 case 'w':
388 under_windows = 1;
389 break;
391 case 'h':
392 printf("Usage %s [options]\n", argv[0]);
393 printf("options:\n");
394 printf(" -p select one of (cube|sphere|torus)\n");
395 printf(" -v use vsync\n");
396 printf(" -w run under windows\n");
397 printf(" -h print usage information and exit\n");
398 exit(0);
400 default:
401 goto invalid;
402 }
403 } else {
404 goto invalid;
405 }
406 }
408 return 0;
410 invalid:
411 fprintf(stderr, "invalid argument: %s\n", argv[i]);
412 return -1;
413 }
416 static void print_perf(void)
417 {
418 unsigned long msec, avg_frame_time;
419 float sec, fps;
421 msec = get_msec();
422 if(!num_frm || msec < 1000) {
423 printf("leaving so soon? (%lu ms)\n", msec);
424 return;
425 }
427 sec = msec / 1000.0f;
428 fps = (float)num_frm / sec;
429 avg_frame_time = msec / num_frm;
431 printf("%lu frames in %.2f seconds\n", num_frm, sec);
432 printf(" avg. frame time: %lu ms\n", avg_frame_time);
433 printf(" avg. framerate: %.2f fps\n", fps);
434 }