foo
[raydungeon] / src / scr_game.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include "opengl.h"
5 #include "cgmath/cgmath.h"
6 #include "game.h"
7 #include "sdr.h"
8 #include "level.h"
9 #include "util.h"
10
11 static int ginit(void);
12 static void gdestroy(void);
13 static int gstart(void);
14 static void gstop(void);
15 static void gdisplay(void);
16 static void greshape(int x, int y);
17 static void gkeyb(int key, int press);
18 static void gmouse(int bn, int press, int x, int y);
19 static void gmotion(int x, int y);
20
21 struct game_screen scr_game = {
22         "game",
23         ginit, gdestroy,
24         gstart, gstop,
25         gdisplay, greshape,
26         gkeyb, gmouse, gmotion
27 };
28
29 static struct level *lvl;
30
31 static float proj_mat[16], view_mat[16];
32
33 static float cam_theta, cam_phi = 20, cam_dist = 10;
34 static cgm_vec3 cam_pan;
35
36 static unsigned int sdr;
37
38
39 static int ginit(void)
40 {
41         if(!(sdr = create_program_load("sdr/raydungeon.v.glsl", "sdr/raydungeon.p.glsl"))) {
42                 return -1;
43         }
44         return 0;
45 }
46
47 static void gdestroy(void)
48 {
49         free_program(sdr);
50 }
51
52 static int gstart(void)
53 {
54         lvl = malloc_nf(sizeof *lvl);
55         init_level(lvl);
56         if(load_level(lvl, "data/test.lvl") == -1) {
57                 return -1;
58         }
59         cam_pan.x = -(lvl->xsz / 2.0f) * lvl->scale;
60         cam_pan.y = 0;
61         cam_pan.z = -(lvl->ysz / 2.0f) * lvl->scale;
62         return 0;
63 }
64
65 static void gstop(void)
66 {
67         destroy_level(lvl);
68         free(lvl);
69 }
70
71 static void gdisplay(void)
72 {
73         int i, j;
74         float x, y;
75         struct level_cell *cell;
76
77         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
78
79         cgm_mtranslation(view_mat, 0, 0, -cam_dist);
80         cgm_mprerotate_x(view_mat, cam_phi);
81         cgm_mprerotate_y(view_mat, cam_theta);
82         cgm_mpretranslate(view_mat, cam_pan.x, cam_pan.y, cam_pan.z);
83         glMatrixMode(GL_MODELVIEW);
84         glLoadMatrixf(view_mat);
85
86         glUseProgram(sdr);
87
88         glDepthMask(0);
89         glBegin(GL_TRIANGLES);
90         glTexCoord2f(0, 0); glVertex2f(-1, -1);
91         glTexCoord2f(2, 0); glVertex2f(4, -1);
92         glTexCoord2f(0, 2); glVertex2f(-1, 4);
93         glEnd();
94         glDepthMask(1);
95
96         glUseProgram(0);
97
98
99         cell = lvl->cells;
100         glBegin(GL_QUADS);
101         glColor3f(1, 1, 1);
102         glNormal3f(0, 1, 0);
103         for(i=0; i<lvl->ysz; i++) {
104                 y = (float)i * lvl->scale;
105                 for(j=0; j<lvl->xsz; j++) {
106                         x = (float)j * lvl->scale;
107                         if(cell->type) {
108                                 glVertex3f(x - 0.48, -1, y - 0.48);
109                                 glVertex3f(x + 0.48, -1, y - 0.48);
110                                 glVertex3f(x + 0.48, -1, y + 0.48);
111                                 glVertex3f(x - 0.48, -1, y + 0.48);
112                         }
113                         cell++;
114                 }
115         }
116         glEnd();
117 }
118
119 static void greshape(int x, int y)
120 {
121         cgm_mperspective(proj_mat, cgm_deg_to_rad(60), win_aspect, 0.5, 500.0);
122         glMatrixMode(GL_PROJECTION);
123         glLoadMatrixf(proj_mat);
124 }
125
126 static void gkeyb(int key, int press)
127 {
128         if(press) {
129                 switch(key) {
130                 case '`':
131                         if(!fullscr) {
132                                 game_grabmouse(-1);     /* toggle */
133                         }
134                         break;
135
136                 default:
137                         break;
138                 }
139         }
140 }
141
142 static void gmouse(int bn, int press, int x, int y)
143 {
144 }
145
146 static void gmotion(int x, int y)
147 {
148         int dx = x - mouse_x;
149         int dy = y - mouse_y;
150
151         if(!(dx | dy)) return;
152
153         if(mouse_state[0]) {
154                 cam_theta += dx * 0.02;
155                 cam_phi += dy * 0.02;
156                 if(cam_phi < -M_PI/2) cam_phi = -M_PI/2;
157                 if(cam_phi > M_PI/2) cam_phi = M_PI/2;
158         }
159         if(mouse_state[1]) {
160                 float up[3], right[3];
161
162                 up[0] = -sin(cam_theta) * sin(cam_phi);
163                 up[1] = -cos(cam_phi);
164                 up[2] = cos(cam_theta) * sin(cam_phi);
165                 right[0] = cos(cam_theta);
166                 right[1] = 0;
167                 right[2] = sin(cam_theta);
168
169                 cam_pan.x += (right[0] * dx + up[0] * dy) * 0.01;
170                 cam_pan.y += up[1] * dy * 0.01;
171                 cam_pan.z += (right[2] * dx + up[2] * dy) * 0.01;
172         }
173         if(mouse_state[2]) {
174                 cam_dist += dy * 0.01;
175                 if(cam_dist < 0) cam_dist = 0;
176         }
177 }