rev |
line source |
nuclear@1
|
1 #include <stdio.h>
|
nuclear@1
|
2 #include <stdlib.h>
|
nuclear@1
|
3 #include <string.h>
|
nuclear@7
|
4 #include <signal.h>
|
nuclear@14
|
5 #include <errno.h>
|
nuclear@17
|
6 #include <float.h>
|
nuclear@14
|
7 #include <direct.h>
|
nuclear@1
|
8 #include "inttypes.h"
|
nuclear@1
|
9 #include "gfx.h"
|
nuclear@1
|
10 #include "keyb.h"
|
nuclear@1
|
11 #include "mouse.h"
|
nuclear@1
|
12 #include "logger.h"
|
nuclear@6
|
13 #include "scene.h"
|
nuclear@9
|
14 #include "rayzor.h"
|
nuclear@9
|
15 #include "screen.h"
|
nuclear@9
|
16 #include "modeller.h"
|
nuclear@9
|
17 #include "renderer.h"
|
nuclear@9
|
18 #include "scrman.h"
|
nuclear@10
|
19 #include "timer.h"
|
nuclear@10
|
20
|
nuclear@10
|
21 #ifdef __DOS__
|
nuclear@10
|
22 #undef USE_ASM_SWAPBUF
|
nuclear@10
|
23 #endif
|
nuclear@10
|
24
|
nuclear@10
|
25 #ifdef USE_ASM_SWAPBUF
|
nuclear@10
|
26 // defined in swapbuf.asm
|
nuclear@10
|
27 extern "C" void swap_buffers_asm(void *dest, void *src, int xsz, int ysz, int bpp);
|
nuclear@10
|
28 #endif
|
nuclear@1
|
29
|
nuclear@6
|
30 static bool init();
|
nuclear@6
|
31 static void cleanup();
|
nuclear@1
|
32 static void display();
|
nuclear@1
|
33 static void swap_buffers();
|
nuclear@9
|
34 static void draw_cursor(uint32_t *buf, int mx, int my);
|
nuclear@14
|
35 static void screenshot();
|
nuclear@1
|
36 static void handle_keyboard();
|
nuclear@1
|
37 static void handle_mouse();
|
nuclear@1
|
38 static bool parse_args(int argc, char **argv);
|
nuclear@7
|
39 static void sig(int s);
|
nuclear@1
|
40
|
nuclear@9
|
41 uint32_t *fb_pixels;
|
nuclear@9
|
42 int fb_width = 640;
|
nuclear@9
|
43 int fb_height = 480;
|
nuclear@9
|
44 int fb_bpp = 32;
|
nuclear@9
|
45 Scene *scene;
|
nuclear@9
|
46
|
nuclear@6
|
47 static bool novideo;
|
nuclear@9
|
48 static void *fb;
|
nuclear@1
|
49 static int rbits, gbits, bbits;
|
nuclear@1
|
50 static int rshift, gshift, bshift;
|
nuclear@1
|
51 static unsigned int rmask, gmask, bmask;
|
nuclear@1
|
52
|
nuclear@10
|
53 static bool use_asm_swap = true;
|
nuclear@7
|
54 static bool use_mouse;
|
nuclear@9
|
55 static int mouse_x, mouse_y;
|
nuclear@1
|
56 static bool quit;
|
nuclear@14
|
57 static bool cap_shot;
|
nuclear@1
|
58
|
nuclear@1
|
59 int main(int argc, char **argv)
|
nuclear@1
|
60 {
|
nuclear@10
|
61 unsigned long start_msec, msec;
|
nuclear@10
|
62 unsigned long nframes = 0;
|
nuclear@10
|
63
|
nuclear@1
|
64 if(!parse_args(argc, argv)) {
|
nuclear@1
|
65 return 1;
|
nuclear@1
|
66 }
|
nuclear@6
|
67 if(!init()) {
|
nuclear@1
|
68 return 1;
|
nuclear@1
|
69 }
|
nuclear@1
|
70
|
nuclear@10
|
71 start_msec = get_msec();
|
nuclear@10
|
72
|
nuclear@1
|
73 // main loop
|
nuclear@1
|
74 for(;;) {
|
nuclear@1
|
75 handle_keyboard();
|
nuclear@1
|
76 handle_mouse();
|
nuclear@1
|
77 if(quit) break;
|
nuclear@1
|
78
|
nuclear@1
|
79 display();
|
nuclear@10
|
80 ++nframes;
|
nuclear@6
|
81
|
nuclear@6
|
82 if(novideo) break;
|
nuclear@1
|
83 }
|
nuclear@1
|
84
|
nuclear@10
|
85 msec = get_msec() - start_msec;
|
nuclear@10
|
86
|
nuclear@6
|
87 cleanup();
|
nuclear@10
|
88
|
nuclear@10
|
89 printf("Average framerate: %g\n", (float)nframes / ((float)msec / 1000.0f));
|
nuclear@1
|
90 printf("Thank you for using Rayzor!\n");
|
nuclear@1
|
91 return 0;
|
nuclear@1
|
92 }
|
nuclear@1
|
93
|
nuclear@9
|
94 void quit_app()
|
nuclear@9
|
95 {
|
nuclear@9
|
96 quit = true;
|
nuclear@9
|
97 }
|
nuclear@9
|
98
|
nuclear@6
|
99 static bool init()
|
nuclear@6
|
100 {
|
nuclear@7
|
101 signal(SIGINT, sig);
|
nuclear@7
|
102 signal(SIGSEGV, sig);
|
nuclear@7
|
103 signal(SIGILL, sig);
|
nuclear@7
|
104 signal(SIGFPE, sig);
|
nuclear@7
|
105
|
nuclear@18
|
106 #ifdef __WATCOM__
|
nuclear@17
|
107 // mask all fpe except invalid op
|
nuclear@17
|
108 _control87(~_EM_INVALID, _MCW_EM);
|
nuclear@18
|
109 #endif
|
nuclear@17
|
110
|
nuclear@10
|
111 init_timer(128);
|
nuclear@10
|
112
|
nuclear@6
|
113 if(!novideo) {
|
nuclear@6
|
114 if(kb_init(32) == -1) {
|
nuclear@6
|
115 fprintf(stderr, "failed to initialize keyboard driver\n");
|
nuclear@6
|
116 return false;
|
nuclear@6
|
117 }
|
nuclear@6
|
118
|
nuclear@9
|
119 if(!(fb = set_video_mode(fb_width, fb_height, fb_bpp))) {
|
nuclear@6
|
120 set_text_mode();
|
nuclear@9
|
121 fprintf(stderr, "failed to set video mode: %dx%d %dbpp\n", fb_width, fb_height, fb_bpp);
|
nuclear@6
|
122 return false;
|
nuclear@6
|
123 }
|
nuclear@9
|
124 fb_bpp = get_color_depth();
|
nuclear@6
|
125 get_color_bits(&rbits, &gbits, &bbits);
|
nuclear@6
|
126 get_color_shift(&rshift, &gshift, &bshift);
|
nuclear@6
|
127 get_color_mask(&rmask, &gmask, &bmask);
|
nuclear@6
|
128
|
nuclear@10
|
129 printlog("video resolution: %dx%d\n", fb_width, fb_height);
|
nuclear@9
|
130 printlog("bpp: %d (%d %d %d)\n", fb_bpp, rbits, gbits, bbits);
|
nuclear@6
|
131 printlog("shift: %d %d %d\n", rshift, gshift, bshift);
|
nuclear@6
|
132 printlog("mask: %x %x %x\n", rmask, gmask, bmask);
|
nuclear@7
|
133
|
nuclear@7
|
134 if(have_mouse()) {
|
nuclear@7
|
135 use_mouse = true;
|
nuclear@9
|
136 set_mouse_limits(0, 0, fb_width - 1, fb_height - 1);
|
nuclear@7
|
137 }
|
nuclear@6
|
138 } else {
|
nuclear@6
|
139 logger_output(stdout);
|
nuclear@6
|
140 printlog("novideo (debug) mode\n");
|
nuclear@10
|
141 fb_bpp = 24;
|
nuclear@6
|
142 rbits = gbits = bbits = 8;
|
nuclear@6
|
143 }
|
nuclear@6
|
144
|
nuclear@9
|
145 fb_pixels = new uint32_t[fb_width * fb_height * 4];
|
nuclear@9
|
146 if(!fb_pixels) {
|
nuclear@6
|
147 return false;
|
nuclear@6
|
148 }
|
nuclear@6
|
149
|
nuclear@9
|
150 scene = new Scene;
|
nuclear@6
|
151
|
nuclear@6
|
152 Sphere *sph = new Sphere;
|
nuclear@17
|
153 sph->mtl.diffuse = Vector3(1.0, 0.3, 0.1);
|
nuclear@17
|
154 sph->mtl.roughness = 0.4;
|
nuclear@12
|
155 scene->add(sph);
|
nuclear@12
|
156
|
nuclear@12
|
157 Box *box = new Box;
|
nuclear@17
|
158 box->mtl.diffuse = Vector3(0.1, 0.4, 1.0);
|
nuclear@19
|
159 box->mtl.specular = Vector3(0.3, 0.6, 1.0);
|
nuclear@19
|
160 box->mtl.roughness = 0.2;
|
nuclear@19
|
161 box->mtl.reflect = 0.8;
|
nuclear@17
|
162 box->set_position(Vector3(0, -1.1, 0));
|
nuclear@17
|
163 box->set_scaling(Vector3(4, 0.1, 4));
|
nuclear@12
|
164 scene->add(box);
|
nuclear@17
|
165
|
nuclear@17
|
166 Light *lt = new Light;
|
nuclear@17
|
167 lt->set_intensity(0.8);
|
nuclear@17
|
168 lt->set_position(Vector3(-10, 10, 10));
|
nuclear@17
|
169 scene->add(lt);
|
nuclear@6
|
170
|
nuclear@9
|
171 Modeller *modeller = new Modeller;
|
nuclear@9
|
172 if(!modeller->init()) {
|
nuclear@9
|
173 return false;
|
nuclear@9
|
174 }
|
nuclear@9
|
175 add_screen(modeller);
|
nuclear@9
|
176
|
nuclear@9
|
177 Renderer *renderer = new Renderer;
|
nuclear@9
|
178 if(!renderer->init()) {
|
nuclear@9
|
179 return false;
|
nuclear@9
|
180 }
|
nuclear@9
|
181 add_screen(renderer);
|
nuclear@9
|
182
|
nuclear@9
|
183 activate_screen(modeller); // start the modeller screen
|
nuclear@6
|
184 return true;
|
nuclear@6
|
185 }
|
nuclear@6
|
186
|
nuclear@6
|
187 static void cleanup()
|
nuclear@6
|
188 {
|
nuclear@9
|
189 delete scene;
|
nuclear@9
|
190 delete [] fb_pixels;
|
nuclear@6
|
191
|
nuclear@9
|
192 destroy_screens();
|
nuclear@6
|
193
|
nuclear@6
|
194 if(!novideo) {
|
nuclear@6
|
195 set_text_mode();
|
nuclear@6
|
196 kb_shutdown();
|
nuclear@6
|
197 }
|
nuclear@6
|
198 }
|
nuclear@6
|
199
|
nuclear@1
|
200 static void display()
|
nuclear@1
|
201 {
|
nuclear@9
|
202 Screen *scr = active_screen();
|
nuclear@9
|
203 if(scr) {
|
nuclear@9
|
204 scr->update();
|
nuclear@9
|
205 scr->draw();
|
nuclear@9
|
206 }
|
nuclear@6
|
207
|
nuclear@7
|
208 // draw the mouse cursor
|
nuclear@7
|
209 if(use_mouse) {
|
nuclear@9
|
210 draw_cursor(fb_pixels, mouse_x, mouse_y);
|
nuclear@7
|
211 }
|
nuclear@7
|
212
|
nuclear@14
|
213 if(cap_shot) {
|
nuclear@14
|
214 screenshot();
|
nuclear@14
|
215 cap_shot = false;
|
nuclear@14
|
216 }
|
nuclear@14
|
217
|
nuclear@6
|
218 if(!novideo) {
|
nuclear@10
|
219 wait_vsync();
|
nuclear@10
|
220 #ifdef USE_ASM_SWAPBUF
|
nuclear@10
|
221 swap_buffers_asm(fb, fb_pixels, fb_width, fb_height, fb_bpp);
|
nuclear@10
|
222 #else
|
nuclear@6
|
223 swap_buffers();
|
nuclear@10
|
224 #endif
|
nuclear@1
|
225 }
|
nuclear@1
|
226 }
|
nuclear@1
|
227
|
nuclear@1
|
228 #define PACK_RGB(r, g, b) \
|
nuclear@1
|
229 ((((r) << rshift) & rmask) | \
|
nuclear@1
|
230 (((g) << gshift) & gmask) | \
|
nuclear@1
|
231 (((b) << bshift) & bmask))
|
nuclear@1
|
232
|
nuclear@11
|
233 #define UNPACK_RED(c) (((c) >> 16) & 0xff)
|
nuclear@9
|
234 #define UNPACK_GREEN(c) (((c) >> 8) & 0xff)
|
nuclear@11
|
235 #define UNPACK_BLUE(c) ((c) & 0xff)
|
nuclear@9
|
236
|
nuclear@1
|
237 static void swap_buffers()
|
nuclear@1
|
238 {
|
nuclear@9
|
239 uint32_t *src = fb_pixels;
|
nuclear@9
|
240 int num_pixels = fb_width * fb_height;
|
nuclear@1
|
241
|
nuclear@9
|
242 switch(fb_bpp) {
|
nuclear@1
|
243 case 32:
|
nuclear@9
|
244 memcpy(fb, fb_pixels, num_pixels * 4);
|
nuclear@1
|
245 break;
|
nuclear@1
|
246
|
nuclear@1
|
247 case 24:
|
nuclear@9
|
248 {
|
nuclear@9
|
249 unsigned char *dest = (unsigned char*)fb;
|
nuclear@10
|
250 for(int i=0; i<num_pixels-1; i++) {
|
nuclear@10
|
251 *((uint32_t*)dest) = *src++;
|
nuclear@10
|
252 dest += 3;
|
nuclear@9
|
253 }
|
nuclear@10
|
254 *dest++ = UNPACK_RED(*src);
|
nuclear@10
|
255 *dest++ = UNPACK_GREEN(*src);
|
nuclear@10
|
256 *dest++ = UNPACK_BLUE(*src);
|
nuclear@9
|
257 }
|
nuclear@1
|
258 break;
|
nuclear@1
|
259
|
nuclear@1
|
260 case 16:
|
nuclear@1
|
261 {
|
nuclear@1
|
262 uint16_t *dest = (uint16_t*)fb;
|
nuclear@1
|
263 for(int i=0; i<num_pixels; i++) {
|
nuclear@9
|
264 uint32_t c = *src++;
|
nuclear@9
|
265 unsigned char r = UNPACK_RED(c);
|
nuclear@9
|
266 unsigned char g = UNPACK_GREEN(c);
|
nuclear@9
|
267 unsigned char b = UNPACK_BLUE(c);
|
nuclear@9
|
268
|
nuclear@11
|
269 *dest++ = (((r) << 8) & 0xf800) |
|
nuclear@11
|
270 (((g) << 3) & 0x7e0) |
|
nuclear@11
|
271 (((b) >> 3) & 0x1f);
|
nuclear@1
|
272 }
|
nuclear@1
|
273 }
|
nuclear@1
|
274 break;
|
nuclear@1
|
275
|
nuclear@1
|
276 default:
|
nuclear@1
|
277 break;
|
nuclear@1
|
278 }
|
nuclear@1
|
279 }
|
nuclear@1
|
280
|
nuclear@9
|
281 static void draw_cursor(uint32_t *buf, int mx, int my)
|
nuclear@7
|
282 {
|
nuclear@9
|
283 uint32_t *cptr = buf + my * fb_width + mx;
|
nuclear@7
|
284 int i, cw[2] = {4, 4}, ch[2] = {4, 4};
|
nuclear@7
|
285
|
nuclear@7
|
286 if(mx < cw[0]) cw[0] = mx;
|
nuclear@7
|
287 if(my < ch[0]) ch[0] = my;
|
nuclear@9
|
288 if(fb_width - mx < cw[1]) cw[1] = fb_width - mx - 1;
|
nuclear@9
|
289 if(fb_height - my < ch[1]) ch[1] = fb_height - my - 1;
|
nuclear@7
|
290
|
nuclear@7
|
291 for(i=1; i<cw[0]; i++) {
|
nuclear@9
|
292 int idx = -i;
|
nuclear@9
|
293 cptr[idx] = 0xffffff;
|
nuclear@7
|
294 }
|
nuclear@7
|
295 for(i=1; i<cw[1]; i++) {
|
nuclear@9
|
296 int idx = i;
|
nuclear@9
|
297 cptr[idx] = 0xffffff;
|
nuclear@7
|
298 }
|
nuclear@7
|
299 for(i=1; i<ch[0]; i++) {
|
nuclear@9
|
300 int idx = -i * fb_width;
|
nuclear@9
|
301 cptr[idx] = 0xffffff;
|
nuclear@7
|
302 }
|
nuclear@7
|
303 for(i=1; i<ch[1]; i++) {
|
nuclear@9
|
304 int idx = i * fb_width;
|
nuclear@9
|
305 cptr[idx] = 0xffffff;
|
nuclear@7
|
306 }
|
nuclear@7
|
307 }
|
nuclear@7
|
308
|
nuclear@14
|
309 #define PPM_COMMENT "screenshot saved by the rayzor modeller/renderer"
|
nuclear@14
|
310 static void screenshot()
|
nuclear@14
|
311 {
|
nuclear@14
|
312 static int shotidx = -1;
|
nuclear@14
|
313 FILE *fp;
|
nuclear@14
|
314 char fname[PATH_MAX];
|
nuclear@14
|
315
|
nuclear@14
|
316 if(shotidx == -1) {
|
nuclear@14
|
317 DIR *dir;
|
nuclear@14
|
318 struct dirent *dent;
|
nuclear@14
|
319
|
nuclear@14
|
320 shotidx = 0;
|
nuclear@14
|
321 if((dir = opendir("."))) {
|
nuclear@14
|
322 while((dent = readdir(dir))) {
|
nuclear@14
|
323 int i, num;
|
nuclear@14
|
324 for(i=0; dent->d_name[i]; i++) {
|
nuclear@14
|
325 fname[i] = tolower(dent->d_name[i]);
|
nuclear@14
|
326 }
|
nuclear@14
|
327 fname[i] = 0;
|
nuclear@14
|
328
|
nuclear@14
|
329 if(sscanf(fname, "shot%d.ppm", &num) == 1 && num > shotidx) {
|
nuclear@14
|
330 shotidx = num;
|
nuclear@14
|
331 }
|
nuclear@14
|
332 }
|
nuclear@14
|
333 closedir(dir);
|
nuclear@14
|
334 }
|
nuclear@14
|
335 }
|
nuclear@14
|
336
|
nuclear@14
|
337 sprintf(fname, "shot%04d.ppm", ++shotidx);
|
nuclear@14
|
338 if(!(fp = fopen(fname, "wb"))) {
|
nuclear@14
|
339 printlog("failed to save screenshot %s: %s\n", fname, strerror(errno));
|
nuclear@14
|
340 return;
|
nuclear@14
|
341 }
|
nuclear@14
|
342
|
nuclear@17
|
343 fprintf(fp, "P6\n# " PPM_COMMENT "\n%d %d\n255\n", fb_width, fb_height);
|
nuclear@14
|
344 for(int i=0; i<fb_width * fb_height; i++) {
|
nuclear@14
|
345 uint32_t c = fb_pixels[i];
|
nuclear@14
|
346 fputc(UNPACK_RED(c), fp);
|
nuclear@14
|
347 fputc(UNPACK_GREEN(c), fp);
|
nuclear@14
|
348 fputc(UNPACK_BLUE(c), fp);
|
nuclear@14
|
349 }
|
nuclear@14
|
350
|
nuclear@14
|
351 fclose(fp);
|
nuclear@14
|
352 }
|
nuclear@14
|
353
|
nuclear@1
|
354 static void handle_keyboard()
|
nuclear@1
|
355 {
|
nuclear@5
|
356 int key;
|
nuclear@9
|
357 Screen *scr = active_screen();
|
nuclear@1
|
358
|
nuclear@6
|
359 if(novideo) return;
|
nuclear@6
|
360
|
nuclear@5
|
361 while((key = kb_getkey()) != -1) {
|
nuclear@10
|
362 switch(key) {
|
nuclear@10
|
363 case '`':
|
nuclear@10
|
364 use_asm_swap = !use_asm_swap;
|
nuclear@10
|
365 break;
|
nuclear@10
|
366
|
nuclear@12
|
367 case 'q':
|
nuclear@12
|
368 case 'x':
|
nuclear@12
|
369 if(kb_isdown(KB_ALT)) {
|
nuclear@12
|
370 quit_app();
|
nuclear@12
|
371 }
|
nuclear@12
|
372 break;
|
nuclear@12
|
373
|
nuclear@14
|
374 case KB_F12:
|
nuclear@14
|
375 cap_shot = true;
|
nuclear@14
|
376 break;
|
nuclear@14
|
377
|
nuclear@10
|
378 default:
|
nuclear@10
|
379 break;
|
nuclear@10
|
380 }
|
nuclear@9
|
381 scr->handle_keyboard(key, true); // TODO also generate release events...
|
nuclear@1
|
382 }
|
nuclear@1
|
383 }
|
nuclear@1
|
384
|
nuclear@1
|
385 static void handle_mouse()
|
nuclear@1
|
386 {
|
nuclear@9
|
387 static int prev_mx, prev_my, prev_bnmask, bndiff;
|
nuclear@9
|
388 int mx, my, bnmask;
|
nuclear@9
|
389 Screen *scr = active_screen();
|
nuclear@7
|
390
|
nuclear@7
|
391 if(!use_mouse || novideo) return;
|
nuclear@7
|
392
|
nuclear@7
|
393 bnmask = read_mouse(&mx, &my);
|
nuclear@9
|
394 if(scr && (bndiff = bnmask ^ prev_bnmask)) {
|
nuclear@9
|
395 for(int i=0; i<8; i++) {
|
nuclear@9
|
396 int bit = 1 << i;
|
nuclear@9
|
397 if(bndiff & bit) {
|
nuclear@9
|
398 scr->handle_mbutton(i, bnmask & bit, mx, my);
|
nuclear@9
|
399 }
|
nuclear@9
|
400 }
|
nuclear@7
|
401 }
|
nuclear@9
|
402 prev_bnmask = bnmask;
|
nuclear@9
|
403
|
nuclear@9
|
404 if(scr && (mx != prev_mx || my != prev_my)) {
|
nuclear@9
|
405 scr->handle_mmotion(mx, my);
|
nuclear@7
|
406 }
|
nuclear@9
|
407 prev_mx = mx;
|
nuclear@9
|
408 prev_my = my;
|
nuclear@10
|
409
|
nuclear@10
|
410 mouse_x = mx;
|
nuclear@10
|
411 mouse_y = my;
|
nuclear@7
|
412 }
|
nuclear@7
|
413
|
nuclear@1
|
414
|
nuclear@1
|
415 static struct {
|
nuclear@1
|
416 int opt;
|
nuclear@1
|
417 const char *lopt;
|
nuclear@1
|
418 const char *desc;
|
nuclear@1
|
419 } options[] = {
|
nuclear@1
|
420 {'s', "size", "resolution <xres>x<yres>[:bpp]"},
|
nuclear@6
|
421 {'n', "novid", "don't switch video mode (for debugging)"},
|
nuclear@1
|
422 {'h', "help", "print usage information and exit"},
|
nuclear@1
|
423 {-1, 0, 0}
|
nuclear@1
|
424 };
|
nuclear@1
|
425
|
nuclear@1
|
426 static void print_usage(const char *argv0)
|
nuclear@1
|
427 {
|
nuclear@1
|
428 printf("%s usage\n", argv0);
|
nuclear@1
|
429 for(int i=0; options[i].opt != -1; i++) {
|
nuclear@1
|
430 printf(" -%c, -%s: %s\n", options[i].opt, options[i].lopt, options[i].desc);
|
nuclear@1
|
431 }
|
nuclear@1
|
432 exit(0);
|
nuclear@1
|
433 }
|
nuclear@1
|
434
|
nuclear@1
|
435 static bool parse_args(int argc, char **argv)
|
nuclear@1
|
436 {
|
nuclear@1
|
437 for(int i=1; i<argc; i++) {
|
nuclear@1
|
438 if(argv[i][0] == '-') {
|
nuclear@1
|
439 int opt = -1;
|
nuclear@1
|
440
|
nuclear@1
|
441 for(int j=0; options[j].opt != -1; j++) {
|
nuclear@1
|
442 if(argv[i][2] == 0) {
|
nuclear@1
|
443 if(argv[i][1] == options[j].opt) {
|
nuclear@1
|
444 opt = options[j].opt;
|
nuclear@1
|
445 break;
|
nuclear@1
|
446 }
|
nuclear@1
|
447 } else {
|
nuclear@1
|
448 if(strcmp(argv[i] + 1, options[j].lopt) == 0) {
|
nuclear@1
|
449 opt = options[j].opt;
|
nuclear@1
|
450 break;
|
nuclear@1
|
451 }
|
nuclear@1
|
452 }
|
nuclear@1
|
453 }
|
nuclear@1
|
454
|
nuclear@1
|
455 switch(opt) {
|
nuclear@1
|
456 case 's':
|
nuclear@9
|
457 if(sscanf(argv[++i], "%dx%d:%d", &fb_width, &fb_height, &fb_bpp) < 2) {
|
nuclear@1
|
458 fprintf(stderr, "%s must be followed by a resolution: WxH\n", argv[i - 1]);
|
nuclear@1
|
459 return false;
|
nuclear@1
|
460 }
|
nuclear@1
|
461 break;
|
nuclear@1
|
462
|
nuclear@6
|
463 case 'n':
|
nuclear@6
|
464 novideo = true;
|
nuclear@6
|
465 break;
|
nuclear@6
|
466
|
nuclear@1
|
467 case 'h':
|
nuclear@1
|
468 print_usage(argv[0]); // doesn't return
|
nuclear@1
|
469 break;
|
nuclear@1
|
470
|
nuclear@1
|
471 default:
|
nuclear@1
|
472 fprintf(stderr, "unknown option: %s\n", argv[i]);
|
nuclear@1
|
473 return false;
|
nuclear@1
|
474 }
|
nuclear@1
|
475 } else {
|
nuclear@1
|
476 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
|
nuclear@1
|
477 return false;
|
nuclear@1
|
478 }
|
nuclear@1
|
479 }
|
nuclear@1
|
480 return true;
|
nuclear@1
|
481 }
|
nuclear@7
|
482
|
nuclear@7
|
483 static void sig(int s)
|
nuclear@7
|
484 {
|
nuclear@7
|
485 cleanup();
|
nuclear@7
|
486 fprintf(stderr, "signal caught: %d\n", s);
|
nuclear@17
|
487
|
nuclear@18
|
488 #ifdef __WATCOM__
|
nuclear@17
|
489 if(s == SIGFPE) {
|
nuclear@17
|
490 unsigned int st = _status87();
|
nuclear@17
|
491 fprintf(stderr, "fpu status: %x\n", st);
|
nuclear@17
|
492 }
|
nuclear@18
|
493 #endif
|
nuclear@17
|
494
|
nuclear@9
|
495 exit(1);
|
nuclear@7
|
496 }
|