added scr_lvled, a bunch of libraries, and improved framework code
[raydungeon] / src / scr_lvled.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <GL/gl.h>
5 #include "game.h"
6 #include "level.h"
7 #include "util.h"
8 #include "darray.h"
9
10 static int init(void);
11 static void destroy(void);
12 static int start(void);
13 static void stop(void);
14 static void display(void);
15 static void reshape(int x, int y);
16 static void keyb(int key, int press);
17 static void mouse(int bn, int press, int x, int y);
18 static void motion(int x, int y);
19
20 struct game_screen scr_lvled = {
21         "lvled",
22         init, destroy,
23         start, stop,
24         display, reshape,
25         keyb, mouse, motion
26 };
27
28 static struct level *lvl;
29
30 static float cam_theta, cam_phi = 20, cam_dist = 10;
31 static float cam_pan[3];
32
33 static int init(void)
34 {
35         return 0;
36 }
37
38 static void destroy(void)
39 {
40 }
41
42 static int start(void)
43 {
44         lvl = malloc_nf(sizeof *lvl);
45         init_level(lvl);
46         if(load_level(lvl, "data/test.lvl") == -1) {
47                 return -1;
48         }
49         cam_pan[0] = -(lvl->xsz / 2.0f) * lvl->scale;
50         cam_pan[2] = -(lvl->ysz / 2.0f) * lvl->scale;
51         return 0;
52 }
53
54 static void stop(void)
55 {
56         destroy_level(lvl);
57         free(lvl);
58 }
59
60 static void display(void)
61 {
62         int i, j;
63         float x, y, rad;
64         struct level_cell *cell;
65         struct level_rect *rect;
66
67         glMatrixMode(GL_MODELVIEW);
68         glLoadIdentity();
69         glTranslatef(0, 0, -cam_dist);
70         glRotatef(cam_phi, 1, 0, 0);
71         glRotatef(cam_theta, 0, 1, 0);
72         glTranslatef(cam_pan[0], cam_pan[1], cam_pan[2]);
73
74         cell = lvl->cells;
75         glBegin(GL_QUADS);
76         glColor3f(0.4, 0.4, 0.4);
77         glNormal3f(0, 1, 0);
78         rad = lvl->scale * 0.48;
79         for(i=0; i<lvl->ysz; i++) {
80                 y = (float)i * lvl->scale;
81                 for(j=0; j<lvl->xsz; j++) {
82                         x = (float)j * lvl->scale;
83                         if(cell->type) {
84                                 glVertex3f(x - rad, -1, y - rad);
85                                 glVertex3f(x + rad, -1, y - rad);
86                                 glVertex3f(x + rad, -1, y + rad);
87                                 glVertex3f(x - rad, -1, y + rad);
88                         }
89                         cell++;
90                 }
91         }
92         glEnd();
93
94         glLineWidth(2);
95         rect = lvl->rects;
96         for(i=0; i<darr_size(lvl->rects); i++) {
97                 float x = (rect->x - 0.55) * lvl->scale;
98                 float y = (rect->y - 0.55) * lvl->scale;
99                 float w = (rect->w + 0.1) * lvl->scale;
100                 float h = (rect->h + 0.1) * lvl->scale;
101
102                 glBegin(GL_LINE_LOOP);
103                 glColor3ubv(rect->dbgcol);
104                 glVertex3f(x, 0, y);
105                 glVertex3f(x + w, 0, y);
106                 glVertex3f(x + w, 0, y + h);
107                 glVertex3f(x, 0, y + h);
108                 glEnd();
109                 rect++;
110         }
111         glLineWidth(1);
112 }
113
114 static void reshape(int x, int y)
115 {
116 }
117
118 static void keyb(int key, int press)
119 {
120         if(!press) return;
121
122         switch(key) {
123         case 'g':
124                 lvl_gen_rects(lvl);
125                 break;
126
127         case 's':
128                 printf("saving level\n");
129                 save_level(lvl, "data/test.lvl");
130                 break;
131
132         default:
133                 break;
134         }
135 }
136
137 static void mouse(int bn, int press, int x, int y)
138 {
139 }
140
141 static void motion(int x, int y)
142 {
143         int dx = x - mouse_x;
144         int dy = y - mouse_y;
145
146         if(!(dx | dy)) return;
147
148         if(mouse_state[0]) {
149                 cam_theta += dx * 0.5;
150                 cam_phi += dy * 0.5;
151                 if(cam_phi < -90) cam_phi = -90;
152                 if(cam_phi > 90) cam_phi = 90;
153         }
154         if(mouse_state[1]) {
155                 float up[3], right[3];
156                 float theta = cam_theta * M_PI / 180.0f;
157                 float phi = cam_phi * M_PI / 180.0f;
158
159                 up[0] = -sin(theta) * sin(phi);
160                 up[1] = -cos(phi);
161                 up[2] = cos(theta) * sin(phi);
162                 right[0] = cos(theta);
163                 right[1] = 0;
164                 right[2] = sin(theta);
165
166                 cam_pan[0] += (right[0] * dx + up[0] * dy) * 0.01;
167                 cam_pan[1] += up[1] * dy * 0.01;
168                 cam_pan[2] += (right[2] * dx + up[2] * dy) * 0.01;
169         }
170         if(mouse_state[2]) {
171                 cam_dist += dy * 0.1;
172                 if(cam_dist < 0) cam_dist = 0;
173         }
174 }