player movement (to be cont.)
[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         return 0;
55 }
56
57 void game_shutdown(void)
58 {
59         destroy_level(&lvl);
60         free_program(sdr_foo);
61 }
62
63 #define STEP_INTERVAL   1000
64
65 void update(float dt)
66 {
67         static long prev_step;
68         int step[][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
69
70         cgm_vec3 vdir = {0, 0, -1};
71
72         upd_player_xform(&player);
73         cgm_vmul_m3v3(&vdir, player.view_xform);
74
75         player.dir = (int)(2.0f * (atan2(vdir.z, vdir.x) + M_PI) / M_PI + 0.5f);
76
77         /*
78         if(time_msec - prev_step >= STEP_INTERVAL) {
79                 if(input[INP_FWD]) {
80                 }
81         }
82         */
83 }
84
85 void game_display(void)
86 {
87         float dt;
88         static long prev_msec;
89
90         dt = (prev_msec - time_msec) / 1000.0f;
91         prev_msec = time_msec;
92
93         update(dt);
94
95         glClearColor(0.1, 0.1, 0.1, 1);
96         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
97
98         cgm_midentity(proj_matrix);
99         cgm_mperspective(proj_matrix, cgm_deg_to_rad(50), win_aspect, 0.5, 500.0);
100         glMatrixMode(GL_PROJECTION);
101         glLoadMatrixf(proj_matrix);
102
103         glMatrixMode(GL_MODELVIEW);
104         glLoadMatrixf(player.view_xform);
105
106         draw_level();
107
108         game_swap_buffers();
109         assert(glGetError() == GL_NO_ERROR);
110 }
111
112 static void draw_level(void)
113 {
114         int i, j, k;
115         struct cell *cell;
116         float xform[16];
117
118         glUseProgram(sdr_foo);
119
120         cell = lvl.cells;
121         for(i=0; i<lvl.height; i++) {
122                 for(j=0; j<lvl.width; j++) {
123                         cgm_mtranslation(xform, j * lvl.cell_size, 0, i * lvl.cell_size);
124
125                         glPushMatrix();
126                         glMultMatrixf(xform);
127
128                         for(k=0; k<cell->num_mgrp; k++) {
129                                 draw_meshgroup(cell->mgrp + k);
130                         }
131                         cell++;
132
133                         glPopMatrix();
134                 }
135         }
136
137         glUseProgram(0);
138 }
139
140 void game_reshape(int x, int y)
141 {
142         glViewport(0, 0, x, y);
143         win_width = x;
144         win_height = y;
145         win_aspect = (float)x / (float)y;
146 }
147
148 void game_keyboard(int key, int press)
149 {
150         if(press && key == 27) {
151                 game_quit();
152                 return;
153         }
154 }
155
156 void game_mbutton(int bn, int press, int x, int y)
157 {
158         bnstate[bn] = press;
159         mouse_x = x;
160         mouse_y = y;
161 }
162
163 void game_mmotion(int x, int y)
164 {
165         int dx = x - mouse_x;
166         int dy = y - mouse_y;
167         mouse_x = x;
168         mouse_y = y;
169
170         if(!(dx | dy)) return;
171
172         if(bnstate[0]) {
173                 player.theta -= cgm_deg_to_rad(dx * 0.5f);
174                 player.phi -= cgm_deg_to_rad(dy * 0.5f);
175                 if(player.phi < -M_PI/2) player.phi = -M_PI/2;
176                 if(player.phi > M_PI/2) player.phi = M_PI/2;
177         }
178         if(bnstate[2]) {
179                 cam_dist += dy * 0.1;
180                 if(cam_dist < 0) cam_dist = 0;
181         }
182 }