0de90ed1d1a00ffcacdb6f6a797f41969b854122
[dosdemo] / src / dos / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "demo.h"
5 #include "keyb.h"
6 #include "timer.h"
7 #include "gfx.h"
8 #include "logger.h"
9 #include "cdpmi.h"
10 #include "audio.h"
11 #include "sball.h"
12 #include "vmath.h"
13
14 static int handle_sball_event(sball_event *ev);
15 static void recalc_sball_matrix(float *xform);
16
17 static int quit;
18
19 int force_snd_config;
20
21 static int use_sball;
22 static vec3_t pos = {0, 0, 0};
23 static quat_t rot = {0, 0, 0, 1};
24
25
26 int main(int argc, char **argv)
27 {
28         int i;
29         int vmidx, status = 0;
30
31         for(i=1; i<argc; i++) {
32                 if(strcmp(argv[i], "-setup") == 0) {
33                         force_snd_config = 1;
34                 }
35         }
36
37 #ifdef __DJGPP__
38         __djgpp_nearptr_enable();
39 #endif
40
41         init_logger("demo.log");
42
43         /* au_init needs to be called early, before init_timer, and also before
44          * we enter graphics mode, to use the midas configuration tool if necessary
45          */
46         if(au_init() == -1) {
47                 return 1;
48         }
49
50         init_timer(100);
51         kb_init(32);
52
53         if(init_video() == -1) {
54                 return 1;
55         }
56
57         if((vmidx = match_video_mode(640, 480, 16)) == -1) {
58                 return 1;
59         }
60         if(!(vmem = set_video_mode(vmidx, 1))) {
61                 return 1;
62         }
63
64         if(opt.mouse) {
65                 if((opt.mouse = have_mouse())) {
66                         printf("initializing mouse input\n");
67                         set_mouse_limits(0, 0, FB_WIDTH - 1, FB_HEIGHT - 1);
68                         set_mouse(FB_WIDTH / 2, FB_HEIGHT / 2);
69                 }
70         }
71
72         if(init(argc, argv) == -1) {
73                 status = -1;
74                 goto break_evloop;
75         }
76
77         if(opt.sball && sball_init() == 0) {
78                 use_sball = 1;
79         }
80
81         reset_timer();
82
83         for(;;) {
84                 int key;
85                 while((key = kb_getkey()) != -1) {
86                         demo_key(key, 1);
87                         if(quit) goto break_evloop;
88                 }
89
90                 if(opt.mouse) {
91                         mouse_bmask = read_mouse(&mouse_x, &mouse_y);
92                 }
93                 if(use_sball && sball_pending()) {
94                         sball_event ev;
95                         while(sball_getevent(&ev)) {
96                                 handle_sball_event(&ev);
97                         }
98                         recalc_sball_matrix(sball_matrix);
99                 }
100
101                 time_msec = get_msec();
102                 draw();
103         }
104
105 break_evloop:
106         cleanup();
107         set_text_mode();
108         cleanup_video();
109         kb_shutdown();
110         au_shutdown();
111         if(use_sball) {
112                 sball_shutdown();
113         }
114         return status;
115 }
116
117 void demo_quit(void)
118 {
119         quit = 1;
120 }
121
122 #define TX(ev)  ((ev)->motion.motion[0])
123 #define TY(ev)  ((ev)->motion.motion[1])
124 #define TZ(ev)  ((ev)->motion.motion[2])
125 #define RX(ev)  ((ev)->motion.motion[3])
126 #define RY(ev)  ((ev)->motion.motion[4])
127 #define RZ(ev)  ((ev)->motion.motion[5])
128
129 static int handle_sball_event(sball_event *ev)
130 {
131         switch(ev->type) {
132         case SBALL_EV_MOTION:
133                 if(RX(ev) | RY(ev) | RZ(ev)) {
134                         float rx = (float)RX(ev);
135                         float ry = (float)RY(ev);
136                         float rz = (float)RZ(ev);
137                         float axis_len = sqrt(rx * rx + ry * ry + rz * rz);
138                         if(axis_len > 0.0) {
139                                 rot = quat_rotate(rot, axis_len * 0.001, -rx / axis_len,
140                                                 -ry / axis_len, -rz / axis_len);
141                         }
142                 }
143
144                 pos.x += TX(ev) * 0.001;
145                 pos.y += TY(ev) * 0.001;
146                 pos.z += TZ(ev) * 0.001;
147                 break;
148
149         case SBALL_EV_BUTTON:
150                 if(ev->button.pressed) {
151                         pos = v3_cons(0, 0, 0);
152                         rot = quat_cons(1, 0, 0, 0);
153                 }
154                 break;
155         }
156
157         return 0;
158 }
159
160 void recalc_sball_matrix(float *xform)
161 {
162         quat_to_mat(xform, rot);
163         xform[12] = pos.x;
164         xform[13] = pos.y;
165         xform[14] = pos.z;
166 }