fixed dunger build, added current cell coordinates readout
[vrlugburz] / tools / dunger / src / lview.c
1 #include <GL/gl.h>
2 #include <drawtext.h>
3 #include "lview.h"
4
5 static struct level *lvl;
6 static struct cell *sel;
7 static int vpx, vpy, vpw, vph;
8 static float panx, pany, zoom;
9 static float cellsz;    /* derived from zoom and level properties */
10
11 int init_lview(struct level *l)
12 {
13         lvl = l;
14         sel = 0;
15         panx = pany = 0;
16         zoom = 1;
17         zoom_lview(0);
18         return 0;
19 }
20
21 void destroy_lview(void)
22 {
23 }
24
25 void lview_viewport(int x, int y, int xsz, int ysz)
26 {
27         vpx = x;
28         vpy = y;
29         vpw = xsz;
30         vph = ysz;
31         zoom_lview(0);  /* recalc cell size */
32 }
33
34 void pan_lview(float dx, float dy)
35 {
36         panx += dx;
37         pany += dy;
38 }
39
40 void zoom_lview(float dz)
41 {
42         float xsz, ysz;
43
44         zoom += dz;
45         xsz = zoom * vpw / lvl->width;
46         ysz = zoom * vph / lvl->height;
47         cellsz = xsz > ysz ? ysz : xsz;
48 }
49
50 static int bnstate[8];
51
52 void lview_mbutton(int bn, int press, int x, int y)
53 {
54         float hsz = cellsz / 2.0f;
55         sel = pos_to_cell(x + hsz - vpx, vph - y + hsz - vpy, 0, 0);
56         bnstate[bn] = press;
57
58         if(press) {
59                 if(!sel) return;
60                 if(bn == 0) {
61                         sel->type = CELL_WALK;
62                 } else if(bn == 2) {
63                         sel->type = CELL_SOLID;
64                 }
65         }
66 }
67
68 void lview_mouse(int x, int y)
69 {
70         float hsz = cellsz / 2.0f;
71         if(!(sel = pos_to_cell(x + hsz - vpx, vph - y + hsz - vpy, 0, 0))) {
72                 return;
73         }
74
75         if(bnstate[0]) {
76                 sel->type = CELL_WALK;
77         } else if(bnstate[2]) {
78                 sel->type = CELL_SOLID;
79         }
80 }
81
82 #define LTHICK  0.5f
83 static void draw_cell(struct cell *cell)
84 {
85         int cidx, row, col;
86         float x, y, hsz;
87         static const float colors[][3] = {{0, 0, 0}, {0.6, 0.6, 0.6}, {0.4, 0.2, 0.1}};
88
89         hsz = cellsz * 0.5f;
90
91         cidx = cell - lvl->cells;
92         row = cidx / lvl->width;
93         col = cidx % lvl->width;
94
95         cell_to_pos(col, row, &x, &y);
96
97         if(sel == cell) {
98                 glColor3f(0.4, 1.0f, 0.4);
99         } else {
100                 glColor3f(0.5f, 0.5f, 0.5f);
101         }
102         glVertex2f(x - hsz, y - hsz);
103         glVertex2f(x + hsz, y - hsz);
104         glVertex2f(x + hsz, y + hsz);
105         glVertex2f(x - hsz, y + hsz);
106
107         x += LTHICK / 2.0f;
108         y += LTHICK / 2.0f;
109         hsz -= LTHICK * 2.0f;
110
111         glColor3fv(colors[cell->type]);
112         glVertex2f(x - hsz, y - hsz);
113         glVertex2f(x + hsz, y - hsz);
114         glVertex2f(x + hsz, y + hsz);
115         glVertex2f(x - hsz, y + hsz);
116 }
117
118
119 void draw_lview(void)
120 {
121         int i, j;
122         struct cell *cell;
123
124         glBegin(GL_QUADS);
125         cell = lvl->cells;
126         for(i=0; i<lvl->height; i++) {
127                 for(j=0; j<lvl->width; j++) {
128                         draw_cell(cell++);
129                 }
130         }
131         glEnd();
132
133         if(sel) {
134                 int cidx = sel - lvl->cells;
135                 int row = cidx / lvl->width;
136                 int col = cidx % lvl->width;
137
138                 glMatrixMode(GL_MODELVIEW);
139                 glPushMatrix();
140                 glTranslatef(10, 10, 0);
141
142                 glColor3f(1, 1, 1);
143                 dtx_printf("(%d, %d)", col, row);
144                 dtx_flush();
145
146                 glPopMatrix();
147         }
148 }
149
150 void cell_to_pos(int cx, int cy, float *px, float *py)
151 {
152         if(px) *px = (cx - lvl->width / 2.0f) * cellsz - panx + vpw / 2.0f;
153         if(py) *py = (cy - lvl->height / 2.0f) * cellsz - pany + vph / 2.0f;
154 }
155
156 struct cell *pos_to_cell(float px, float py, int *cx, int *cy)
157 {
158         int col, row;
159
160         col = (px + panx - vpw / 2.0f) / cellsz + lvl->width / 2.0f;
161         row = (py + pany - vph / 2.0f) / cellsz + lvl->height / 2.0f;
162
163         if(cx) *cx = col;
164         if(cy) *cy = row;
165
166         if(col >= 0 && col < lvl->width && row >= 0 && row < lvl->height) {
167                 return lvl->cells + row * lvl->width + col;
168         }
169         return 0;
170 }