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