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