dungeon_crawler

view prototype/src/main.cc @ 47:d52711f2b9a1

started writting audio code
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 16 Sep 2012 08:16:50 +0300
parents f3030df27110
children aa9e28670ae2
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <unistd.h>
5 #include "opengl.h"
6 #include "psys/psys.h"
7 #include "level.h"
8 #include "texman.h"
9 #include "camera.h"
10 #include "datapath.h"
11 #include "tileset.h"
12 #include "renderer.h"
13 #include "renderer_deferred.h"
14 #include "cmdcon.h"
15 #include "cfg.h"
16 #include "timer.h"
17 #include "audio.h"
19 bool init(int xsz, int ysz);
20 void cleanup();
21 void idle();
22 void disp();
23 void draw();
24 void view_matrix(int eye);
25 void proj_matrix(int eye);
26 void update(unsigned long msec);
27 void reshape(int x, int y);
28 void keyb(unsigned char key, int x, int y);
29 void key_release(unsigned char key, int x, int y);
30 void keyb_con(unsigned char key, int x, int y);
31 void mouse(int bn, int state, int x, int y);
32 void motion(int x, int y);
33 unsigned int load_psys_tex(const char *fname, void *cls);
35 static TileSet *tileset;
36 static Level *level;
38 static FpsCamera cam;
39 static bool keystate[256];
41 static float stereo_focus_dist = 0.25;
42 static float stereo_eye_sep = stereo_focus_dist / 30.0;
44 static bool show_con;
46 int main(int argc, char **argv)
47 {
48 glutInit(&argc, argv);
50 if(!cfg.parse_args(argc, argv)) {
51 return 1;
52 }
54 glutInitWindowSize(cfg.width, cfg.height);
55 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (cfg.stereo ? GLUT_STEREO : 0));
56 glutCreateWindow("dungeon crawler prototype");
58 glutIdleFunc(idle);
59 glutDisplayFunc(disp);
60 glutReshapeFunc(reshape);
61 glutKeyboardFunc(keyb);
62 glutKeyboardUpFunc(key_release);
63 glutMouseFunc(mouse);
64 glutMotionFunc(motion);
66 glewInit();
68 if(!init(cfg.width, cfg.height)) {
69 return 1;
70 }
71 atexit(cleanup);
73 glutMainLoop();
74 }
76 bool init(int xsz, int ysz)
77 {
78 // backup light for the forward crappy renderer
79 glEnable(GL_LIGHTING);
80 glEnable(GL_LIGHT0);
82 float ldir[] = {0, 0, -0.5, 1};
83 glLightfv(GL_LIGHT0, GL_POSITION, ldir);
84 float lcol[] = {1, 1, 1, 1};
85 glLightfv(GL_LIGHT0, GL_DIFFUSE, lcol);
86 glLightfv(GL_LIGHT0, GL_SPECULAR, lcol);
88 glEnable(GL_DEPTH_TEST);
89 glEnable(GL_CULL_FACE);
90 glEnable(GL_MULTISAMPLE);
92 add_data_path(".");
93 add_data_path("data");
94 add_data_path("sdr");
96 rend = new DeferredRenderer();
97 if(!cfg.use_deferred || !rend->init(xsz, ysz)) {
98 printf("falling back to crappy renderer...\n");
100 rend = new FwdRenderer();
101 if(!rend->init(xsz, ysz)) {
102 fprintf(stderr, "failed to create renderer\n");
103 return false;
104 }
105 }
107 if(!init_cmdcon()) {
108 return false;
109 }
111 psys_texture_loader(load_psys_tex, 0, 0);
113 // load a tileset
114 tileset = new TileSet;
115 printf("loading tileset: %s\n", cfg.tileset_file);
116 if(!tileset->load(datafile_path(cfg.tileset_file))) {
117 return false;
118 }
119 set_active_tileset(tileset);
121 level = new Level;
122 printf("loading level: %s\n", cfg.level_file);
123 if(!level->load(datafile_path(cfg.level_file))) {
124 return false;
125 }
127 cam.input_move(0, 0.5, 0);
129 if(cfg.sound && !init_audio()) {
130 fprintf(stderr, "failed to initialize audio, continuing silently\n");
131 cfg.sound = false;
132 }
134 return true;
135 }
137 void cleanup()
138 {
139 if(cfg.sound) {
140 destroy_audio();
141 }
143 delete level;
144 delete tileset;
145 delete rend;
147 cleanup_cmdcon();
148 }
150 void idle()
151 {
152 glutPostRedisplay();
153 }
155 void disp()
156 {
157 update(get_time_msec());
159 if(cfg.stereo) {
160 glDrawBuffer(GL_BACK_LEFT);
162 glMatrixMode(GL_PROJECTION);
163 glLoadIdentity();
164 proj_matrix(-1);
165 glMatrixMode(GL_MODELVIEW);
166 glLoadIdentity();
167 view_matrix(-1);
169 draw();
171 glDrawBuffer(GL_BACK_RIGHT);
173 glMatrixMode(GL_PROJECTION);
174 glLoadIdentity();
175 proj_matrix(1);
176 glMatrixMode(GL_MODELVIEW);
177 glLoadIdentity();
178 view_matrix(1);
180 draw();
181 } else {
182 glMatrixMode(GL_PROJECTION);
183 glLoadIdentity();
184 proj_matrix(0);
185 glMatrixMode(GL_MODELVIEW);
186 glLoadIdentity();
187 view_matrix(0);
189 draw();
190 }
192 glutSwapBuffers();
193 assert(glGetError() == GL_NO_ERROR);
194 }
196 void draw()
197 {
198 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
200 rend->render(level);
202 if(show_con) {
203 draw_cmdcon();
204 }
205 }
207 void view_matrix(int eye)
208 {
209 float offs = stereo_eye_sep * eye * 0.5;
210 glTranslatef(-offs, 0, 0);
211 cam.use_inverse();
212 }
214 void proj_matrix(int eye)
215 {
216 static const float fov = M_PI / 4.0;
217 static const float near_clip = 0.1;
218 static const float far_clip = 100.0;
220 float top = near_clip * tan(fov * 0.5);
221 float right = top * (float)cfg.width / (float)cfg.height;
223 float frust_shift = -(float)eye * (stereo_eye_sep * 0.5 * near_clip / stereo_focus_dist);
224 glFrustum(-right + frust_shift, right + frust_shift, -top, top, near_clip, far_clip);
225 }
228 void update(unsigned long msec)
229 {
230 static unsigned long last_upd;
232 if(last_upd == 0) {
233 last_upd = msec;
234 }
235 float dt = (float)(msec - last_upd) / 1000.0;
237 float offs = 2.5 * dt;
238 float dx = 0, dy = 0;
240 // handle key input
241 if(keystate['w'] || keystate['W']) {
242 dy -= offs;
243 }
244 if(keystate['s'] || keystate['S']) {
245 dy += offs;
246 }
247 if(keystate['d'] || keystate['D']) {
248 dx += offs;
249 }
250 if(keystate['a'] || keystate['A']) {
251 dx -= offs;
252 }
254 cam.input_move(dx, 0, dy);
256 tileset->update_tiles(msec);
257 level->update(msec, dt);
259 last_upd = msec;
260 }
262 void reshape(int x, int y)
263 {
264 glViewport(0, 0, x, y);
265 cfg.width = x;
266 cfg.height = y;
268 rend->resize(x, y);
269 }
271 static bool stereo_shift_pressed;
273 void keyb(unsigned char key, int x, int y)
274 {
275 switch(key) {
276 case 27:
277 exit(0);
279 case '`':
280 show_con = true;
281 glutKeyboardFunc(keyb_con);
282 glutKeyboardUpFunc(0);
283 glutPostRedisplay();
284 break;
286 case 'z':
287 stereo_shift_pressed = true;
288 break;
290 case '\n':
291 case '\r':
292 {
293 static bool fullscr;
294 if(glutGetModifiers() & GLUT_ACTIVE_ALT) {
295 fullscr = !fullscr;
296 if(fullscr) {
297 glutFullScreen();
298 } else {
299 glutPositionWindow(20, 20);
300 }
301 }
302 }
303 break;
305 default:
306 break;
307 }
309 keystate[key] = true;
310 }
312 void key_release(unsigned char key, int x, int y)
313 {
314 switch(key) {
315 case 'z':
316 stereo_shift_pressed = false;
317 break;
319 default:
320 break;
321 }
323 keystate[key] = false;
324 }
326 void keyb_con(unsigned char key, int x, int y)
327 {
328 if(key == '`' || key == 27) {
329 show_con = false;
330 glutKeyboardFunc(keyb);
331 glutKeyboardUpFunc(key_release);
332 glutPostRedisplay();
333 } else {
334 cmdcon_keypress(key);
335 }
336 }
338 static int prev_x, prev_y;
339 static bool bnstate[32];
341 void mouse(int bn, int state, int x, int y)
342 {
343 prev_x = x;
344 prev_y = y;
345 bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN;
346 }
348 void motion(int x, int y)
349 {
350 int dx = x - prev_x;
351 int dy = y - prev_y;
352 prev_x = x;
353 prev_y = y;
355 if(stereo_shift_pressed) {
356 if(dy != 0) {
357 stereo_focus_dist += dy * 0.01;
358 stereo_eye_sep = stereo_focus_dist / 30.0;
359 printf("foc: %f, sep: %f\n", stereo_focus_dist, stereo_eye_sep);
360 glutPostRedisplay();
361 }
362 return;
363 }
365 if(bnstate[0]) {
366 cam.input_rotate(dy * 0.01, dx * 0.01, 0);
367 glutPostRedisplay();
368 }
369 if(bnstate[2]) {
370 cam.input_zoom(dy * 0.1);
371 glutPostRedisplay();
372 }
373 }
375 unsigned int load_psys_tex(const char *fname, void *cls)
376 {
377 TextureSet *texset = tileset->get_textures();
378 return texset->get_texture(fname);
379 }