writing a mesh abstraction
[vrtris] / src / game.c
1 #include <assert.h>
2 #include <goatvr.h>
3 #include <cgmath/cgmath.h>
4 #include "opengl.h"
5 #include "game.h"
6 #include "screen.h"
7 #include "osd.h"
8 #include "opt.h"
9
10 #define DEFSCR  "game"
11
12 static void calc_framerate(void);
13 static void print_framerate(void);
14
15 static float view_matrix[16], proj_matrix[16];
16 static int should_swap;
17 static unsigned long framerate;
18
19 int game_init(int argc, char **argv)
20 {
21         if(init_opengl() == -1) {
22                 return -1;
23         }
24
25         if(init_options(argc, argv, "vrtris.conf") == -1) {
26                 return -1;
27         }
28
29         if(init_screens() == -1) {
30                 return -1;
31         }
32
33         if(opt.flags & OPT_VR) {
34                 if(goatvr_init() == -1) {
35                         return -1;
36                 }
37                 goatvr_set_origin_mode(GOATVR_HEAD);
38
39                 goatvr_startvr();
40                 should_swap = goatvr_should_swap();
41         }
42
43         return 0;
44 }
45
46 void game_cleanup()
47 {
48         if(opt.flags & OPT_VR) {
49                 goatvr_shutdown();
50         }
51         cleanup_screens();
52 }
53
54 static void update(float dt)
55 {
56         int num_vr_sticks;
57
58         if((num_vr_sticks = goatvr_num_sticks()) > 0) {
59                 float p[2];
60                 goatvr_stick_pos(0, p);
61                 /* TODO */
62         }
63
64         screen->update(dt);
65 }
66
67 void game_display(void)
68 {
69         static long prev_msec;
70         int i;
71         float dt = (float)(time_msec - prev_msec) / 1000.0f;
72         prev_msec = time_msec;
73
74         update(dt);
75
76         if(opt.flags & OPT_VR) {
77                 goatvr_draw_start();
78                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
79
80                 for(i=0; i<2; i++) {
81                         /* for each eye */
82                         goatvr_draw_eye(i);
83
84                         cgm_mcopy(proj_matrix, goatvr_projection_matrix(i, 0.5, 500.0));
85                         glMatrixMode(GL_PROJECTION);
86                         glLoadMatrixf(proj_matrix);
87
88                         cgm_mcopy(view_matrix, goatvr_view_matrix(i));
89                         glMatrixMode(GL_MODELVIEW);
90                         glLoadMatrixf(view_matrix);
91
92                         screen->draw();
93                         print_framerate();
94                         draw_osd();
95                 }
96
97                 goatvr_draw_done();
98
99                 if(should_swap) {
100                         game_swap_buffers();
101                 }
102
103         } else {
104                 /* non-VR mode */
105                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
106
107                 cgm_mperspective(proj_matrix, cgm_deg_to_rad(50.0), win_aspect, 0.5, 500.0);
108                 glMatrixMode(GL_PROJECTION);
109                 glLoadMatrixf(proj_matrix);
110
111                 cgm_midentity(view_matrix);
112                 glMatrixMode(GL_MODELVIEW);
113                 glLoadMatrixf(view_matrix);
114
115                 screen->draw();
116                 print_framerate();
117                 draw_osd();
118
119                 game_swap_buffers();
120         }
121
122         assert(glGetError() == GL_NO_ERROR);
123
124         calc_framerate();
125 }
126
127 void game_reshape(int x, int y)
128 {
129         glViewport(0, 0, x, y);
130         goatvr_set_fb_size(x, y, 1.0f);
131
132         reshape_screens(x, y);
133 }
134
135 void game_keyboard(int key, int pressed)
136 {
137         unsigned int mod = game_get_modifiers();
138
139         if(pressed) {
140                 switch(key) {
141                 case 27:
142                         game_quit();
143                         return;
144
145                 case '\n':
146                 case '\r':
147                         if(mod & MOD_ALT) {
148                                 game_toggle_fullscreen();
149                                 return;
150                         }
151                         break;
152
153                 default:
154                         break;
155                 }
156         }
157
158         screen->keyboard(key, pressed);
159 }
160
161 void game_mouse_button(int bn, int pressed, int x, int y)
162 {
163         screen->mouse(bn, pressed, x, y);
164 }
165
166 void game_mouse_motion(int x, int y)
167 {
168         screen->motion(x, y);
169 }
170
171 void game_mouse_wheel(int dir)
172 {
173         screen->wheel(dir);
174 }
175
176
177 void game_gamepad_axis(int axis, float val)
178 {
179 }
180
181 void game_gamepad_button(int bn, int pressed)
182 {
183 }
184
185 static void calc_framerate(void)
186 {
187         static unsigned long nframes;
188         static long prev_upd;
189
190         long elapsed = time_msec - prev_upd;
191         if(elapsed >= 1000) {
192                 framerate = nframes * 10000 / elapsed;
193                 nframes = 1;
194                 prev_upd = time_msec;
195         } else {
196                 ++nframes;
197         }
198 }
199
200 static void print_framerate(void)
201 {
202         print_text(9 * win_width / 10, 20, 1, 1, 0, "fps: %d.%d", framerate / 10, framerate % 10);
203 }