cleaned up the level view code
[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 void lview_mouse(int x, int y)
50 {
51         float hsz = cellsz / 2.0f;
52         sel = pos_to_cell(x + hsz - vpx, vph - y + hsz - vpy, 0, 0);
53 }
54
55 #define LTHICK  0.5f
56 static void draw_cell(struct cell *cell)
57 {
58         int cidx, row, col;
59         float x, y, hsz;
60         static const float colors[][3] = {{0, 0, 0}, {0.6, 0.6, 0.6}, {0.4, 0.2, 0.1}};
61
62         hsz = cellsz * 0.5f;
63
64         cidx = cell - lvl->cells;
65         row = cidx / lvl->width;
66         col = cidx % lvl->width;
67
68         cell_to_pos(col, row, &x, &y);
69
70         if(sel == cell) {
71                 glColor3f(0.4, 1.0f, 0.4);
72         } else {
73                 glColor3f(0.5f, 0.5f, 0.5f);
74         }
75         glVertex2f(x - hsz, y - hsz);
76         glVertex2f(x + hsz, y - hsz);
77         glVertex2f(x + hsz, y + hsz);
78         glVertex2f(x - hsz, y + hsz);
79
80         x += LTHICK / 2.0f;
81         y += LTHICK / 2.0f;
82         hsz -= LTHICK * 2.0f;
83
84         glColor3fv(colors[cell->type]);
85         glVertex2f(x - hsz, y - hsz);
86         glVertex2f(x + hsz, y - hsz);
87         glVertex2f(x + hsz, y + hsz);
88         glVertex2f(x - hsz, y + hsz);
89 }
90
91
92 void draw_lview(void)
93 {
94         int i, j;
95         struct cell *cell;
96
97         glBegin(GL_QUADS);
98         cell = lvl->cells;
99         for(i=0; i<lvl->height; i++) {
100                 for(j=0; j<lvl->width; j++) {
101                         draw_cell(cell++);
102                 }
103         }
104         glEnd();
105
106 }
107
108 void cell_to_pos(int cx, int cy, float *px, float *py)
109 {
110         if(px) *px = (cx - lvl->width / 2.0f) * cellsz - panx + vpw / 2.0f;
111         if(py) *py = (cy - lvl->height / 2.0f) * cellsz - pany + vph / 2.0f;
112 }
113
114 struct cell *pos_to_cell(float px, float py, int *cx, int *cy)
115 {
116         int col, row;
117
118         col = (px + panx - vpw / 2.0f) / cellsz + lvl->width / 2.0f;
119         row = (py + pany - vph / 2.0f) / cellsz + lvl->height / 2.0f;
120
121         if(cx) *cx = col;
122         if(cy) *cy = row;
123
124         if(col >= 0 && col < lvl->width && row >= 0 && row < lvl->height) {
125                 return lvl->cells + row * lvl->width + col;
126         }
127         return 0;
128 }