dungeon generation first step
[vrlugburz] / src / game.c
1 #include <stdio.h>
2 #include <assert.h>
3 #include "cgmath/cgmath.h"
4 #include "game.h"
5 #include "opengl.h"
6 #include "level.h"
7 #include "player.h"
8 #include "scenefile.h"
9 #include "sdr.h"
10
11 static void draw_level(void);
12
13 struct level lvl;
14 struct player player;
15
16 int win_width, win_height;
17 float win_aspect;
18 int mouse_x, mouse_y;
19 int bnstate[8];
20
21 float cam_dist = 10;
22 float view_matrix[16], proj_matrix[16];
23
24 unsigned int sdr_foo;
25
26 int game_init(void)
27 {
28         if(init_opengl() == -1) {
29                 return -1;
30         }
31
32         glEnable(GL_DEPTH_TEST);
33         glEnable(GL_CULL_FACE);
34
35         if(!(sdr_foo = create_program_load("sdr/foo.v.glsl", "sdr/foo.p.glsl"))) {
36                 return -1;
37         }
38         glBindAttribLocation(sdr_foo, MESH_ATTR_VERTEX, "apos");
39         glBindAttribLocation(sdr_foo, MESH_ATTR_NORMAL, "anorm");
40         glBindAttribLocation(sdr_foo, MESH_ATTR_TANGENT, "atang");
41         glBindAttribLocation(sdr_foo, MESH_ATTR_TEXCOORD, "atex");
42         link_program(sdr_foo);
43
44         if(load_level(&lvl, "data/test.lvl") == -1) {
45                 return -1;
46         }
47         gen_level_geom(&lvl);
48
49         init_player(&player);
50         player.lvl = &lvl;
51         player.cx = lvl.px;
52         player.cy = lvl.py;
53
54         printf("start pos: %d,%d\n", player.cx, player.cy);
55
56         return 0;
57 }
58
59 void game_shutdown(void)
60 {
61         destroy_level(&lvl);
62         free_program(sdr_foo);
63 }
64
65 void game_display(void)
66 {
67         glClearColor(0.1, 0.1, 0.1, 1);
68         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
69
70         cgm_midentity(proj_matrix);
71         cgm_mperspective(proj_matrix, cgm_deg_to_rad(50), win_aspect, 0.5, 500.0);
72         glMatrixMode(GL_PROJECTION);
73         glLoadMatrixf(proj_matrix);
74
75         upd_player_xform(&player);
76         glMatrixMode(GL_MODELVIEW);
77         glLoadMatrixf(player.view_xform);
78
79         draw_level();
80
81         game_swap_buffers();
82         assert(glGetError() == GL_NO_ERROR);
83 }
84
85 static void draw_level(void)
86 {
87         int i, j, k;
88         struct cell *cell;
89         float xform[16];
90
91         glUseProgram(sdr_foo);
92
93         cell = lvl.cells;
94         for(i=0; i<lvl.height; i++) {
95                 for(j=0; j<lvl.width; j++) {
96                         cgm_mtranslation(xform, j * lvl.cell_size, 0, i * lvl.cell_size);
97
98                         glPushMatrix();
99                         glMultMatrixf(xform);
100
101                         for(k=0; k<cell->num_mgrp; k++) {
102                                 draw_meshgroup(cell->mgrp + k);
103                         }
104                         cell++;
105
106                         glPopMatrix();
107                 }
108         }
109
110         glUseProgram(0);
111 }
112
113 void game_reshape(int x, int y)
114 {
115         glViewport(0, 0, x, y);
116         win_width = x;
117         win_height = y;
118         win_aspect = (float)x / (float)y;
119 }
120
121 void game_keyboard(int key, int press)
122 {
123         if(press && key == 27) {
124                 game_quit();
125                 return;
126         }
127 }
128
129 void game_mbutton(int bn, int press, int x, int y)
130 {
131         bnstate[bn] = press;
132         mouse_x = x;
133         mouse_y = y;
134 }
135
136 void game_mmotion(int x, int y)
137 {
138         int dx = x - mouse_x;
139         int dy = y - mouse_y;
140         mouse_x = x;
141         mouse_y = y;
142
143         if(!(dx | dy)) return;
144
145         if(bnstate[0]) {
146                 player.theta -= cgm_deg_to_rad(dx * 0.5f);
147                 player.phi -= cgm_deg_to_rad(dy * 0.5f);
148                 if(player.phi < -M_PI/2) player.phi = -M_PI/2;
149                 if(player.phi > M_PI/2) player.phi = M_PI/2;
150         }
151         if(bnstate[2]) {
152                 cam_dist += dy * 0.1;
153                 if(cam_dist < 0) cam_dist = 0;
154         }
155 }