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