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