better grid drawing
[vrlugburz] / tools / dunger / src / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <GL/glut.h>
4 #include <utk/cubertk.h>
5 #include <drawtext.h>
6 #include "level.h"
7
8 static int init(void);
9 static void cleanup(void);
10 static void display(void);
11 static void reshape(int x, int y);
12 static void keyb(unsigned char key, int x, int y);
13 static void keyup(unsigned char key, int x, int y);
14 static void mouse(int bn, int st, int x, int y);
15 static void motion(int x, int y);
16
17 static void ucolor(int r, int g, int b, int a);
18 static void uclip(int x1, int y1, int x2, int y2);
19 static void uimage(int x, int y, const void *pix, int xsz, int ysz);
20 static void urect(int x1, int y1, int x2, int y2);
21 static void uline(int x1, int y1, int x2, int y2, int width);
22 static void utext(int x, int y, const char *txt, int sz);
23 static int utextspacing(void);
24 static int utextwidth(const char *txt, int sz);
25
26 int win_width, win_height;
27 int view_width, view_height;
28 float view_panx, view_pany, view_zoom = 1.0f;
29
30 static int bnstate[8];
31 static int mousex, mousey, clickx, clicky;
32
33 static float uiscale = 1.0f;
34 #define UISPLIT 150
35 static int splitx;
36
37 #define FONTSZ  16
38 static struct dtx_font *uifont;
39 static utk_widget *uiroot;
40
41 static struct level *lvl;
42
43
44 int main(int argc, char **argv)
45 {
46         glutInit(&argc, argv);
47         glutInitWindowSize(1280, 800);
48         glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
49         glutCreateWindow("dunger");
50
51         win_width = glutGet(GLUT_WINDOW_WIDTH);
52         win_height = glutGet(GLUT_WINDOW_HEIGHT);
53
54         glutDisplayFunc(display);
55         glutReshapeFunc(reshape);
56         glutKeyboardFunc(keyb);
57         glutKeyboardUpFunc(keyup);
58         glutMouseFunc(mouse);
59         glutMotionFunc(motion);
60         glutPassiveMotionFunc(motion);
61
62         if(init() == -1) {
63                 return 1;
64         }
65         atexit(cleanup);
66
67         glutMainLoop();
68         return 0;
69 }
70
71
72 static int init(void)
73 {
74         utk_widget *win;
75
76         glClearColor(0.15, 0.15, 0.15, 1);
77
78         if(!(uifont = dtx_open_font("uifont.ttf", 0))) {
79                 fprintf(stderr, "failed to open uifont.ttf\n");
80                 return -1;
81         }
82         dtx_prepare_range(uifont, FONTSZ, ' ', 'z');
83         dtx_use_font(uifont, FONTSZ);
84
85         if(!(uiroot = utk_init(win_width / uiscale, win_height / uiscale))) {
86                 fprintf(stderr, "failed to initialized ubertk\n");
87                 return -1;
88         }
89         utk_set_color_func(ucolor);
90         utk_set_clip_func(uclip);
91         utk_set_image_func(uimage);
92         utk_set_rect_func(urect);
93         utk_set_line_func(uline);
94         utk_set_text_func(utext);
95         utk_set_text_spacing_func(utextspacing);
96         utk_set_text_width_func(utextwidth);
97
98         win = utk_vbox(uiroot, 0, UTK_DEF_SPACING);
99         utk_set_pos(win, 15, 15);
100         utk_button(win, "hello", 0, 0, 0, 0);
101         utk_button(win, "button 2", 0, 0, 0, 0);
102         utk_button(win, "button 3", 0, 0, 0, 0);
103
104         if(!(lvl = create_level(32, 32))) {
105                 fprintf(stderr, "failed to create level\n");
106                 return -1;
107         }
108
109         splitx = UISPLIT * uiscale;
110         view_width = win_width - splitx;
111         view_height = win_height;
112
113         return 0;
114 }
115
116 static void cleanup(void)
117 {
118         free_level(lvl);
119         dtx_close_font(uifont);
120         utk_close(uiroot);
121 }
122
123 static void display(void)
124 {
125         glClear(GL_COLOR_BUFFER_BIT);
126
127         glMatrixMode(GL_MODELVIEW);
128         glLoadIdentity();
129
130         /* draw UI */
131
132         glMatrixMode(GL_PROJECTION);
133         glLoadIdentity();
134         glOrtho(0, splitx, win_height, 0, -1, 1);
135         glViewport(0, 0, splitx, win_height);
136
137         glBegin(GL_QUADS);
138         glColor3f(0.25, 0.25, 0.25);
139         glVertex2f(0, 0);
140         glVertex2f(splitx, 0);
141         glVertex2f(splitx, win_height);
142         glVertex2f(0, win_height);
143         glEnd();
144         utk_draw(uiroot);
145
146         /* draw view */
147
148         glMatrixMode(GL_PROJECTION);
149         glLoadIdentity();
150         glOrtho(0, view_width, 0, view_height, -1, 1);
151         glViewport(splitx, 0, view_width, view_height);
152
153         glBegin(GL_QUADS);
154         glColor3f(0.1, 0.1, 0.1);
155         glVertex2f(0, 0);
156         glVertex2f(view_width, 0);
157         glVertex2f(view_width, view_height);
158         glVertex2f(0, view_height);
159         glEnd();
160
161         draw_level(lvl);
162
163         glutSwapBuffers();
164 }
165
166 static void reshape(int x, int y)
167 {
168         win_width = x;
169         win_height = y;
170
171         if(uiroot) {
172                 utk_set_size(uiroot, x / uiscale, y / uiscale);
173         }
174 }
175
176 static void keyb(unsigned char key, int x, int y)
177 {
178         if(key == 27) exit(0);
179         utk_keyboard_event(key, 1);
180         glutPostRedisplay();
181 }
182
183 static void keyup(unsigned char key, int x, int y)
184 {
185         utk_keyboard_event(key, 0);
186         glutPostRedisplay();
187 }
188
189 static void mouse(int bn, int st, int x, int y)
190 {
191         int bidx = bn - GLUT_LEFT_BUTTON;
192         int press = st == GLUT_DOWN;
193
194         bnstate[bidx] = press;
195         mousex = x;
196         mousey = y;
197
198         if(bn <= 2) {
199                 if(press) {
200                         clickx = x;
201                         clicky = y;
202                 } else {
203                         clickx = clicky = -1;
204                 }
205         } else if(bn == 3) {
206                 if(press) view_zoom += 0.1;
207         } else if(bn == 4) {
208                 if(press) view_zoom -= 0.1;
209         }
210
211         utk_mbutton_event(bidx, press, x / uiscale, y / uiscale);
212         glutPostRedisplay();
213 }
214
215 static void motion(int x, int y)
216 {
217         int dx, dy;
218         dx = x - mousex;
219         dy = y - mousey;
220         mousex = x;
221         mousey = y;
222
223         if(clickx >= splitx) {
224                 if(bnstate[1]) {
225                         view_panx -= dx;
226                         view_pany += dy;
227                 }
228         }
229
230         utk_mmotion_event(x / uiscale, y / uiscale);
231         glutPostRedisplay();
232 }
233
234 static void ucolor(int r, int g, int b, int a)
235 {
236         glColor4ub(r, g, b, a);
237 }
238
239 static void uclip(int x1, int y1, int x2, int y2)
240 {
241         if(!(x1 | y1 | x2 | y2)) {
242                 glDisable(GL_SCISSOR_TEST);
243         } else {
244                 glEnable(GL_SCISSOR_TEST);
245         }
246
247         x1 *= uiscale;
248         y1 *= uiscale;
249         x2 *= uiscale;
250         y2 *= uiscale;
251
252         glScissor(x1, win_height - y2, x2 - x1, y2 - y1);
253 }
254
255 static void uimage(int x, int y, const void *pix, int xsz, int ysz)
256 {
257         glPixelZoom(1, -1);
258         glRasterPos2f(x * uiscale, y * uiscale);
259         glDrawPixels(xsz, ysz, GL_BGRA, GL_UNSIGNED_BYTE, pix);
260 }
261
262 static void urect(int x1, int y1, int x2, int y2)
263 {
264         glRectf(x1 * uiscale, y1 * uiscale, x2 * uiscale, y2 * uiscale);
265 }
266
267 static void uline(int x1, int y1, int x2, int y2, int width)
268 {
269         glLineWidth(width);
270         glBegin(GL_LINES);
271         glVertex2f(x1 * uiscale, y1 * uiscale);
272         glVertex2f(x2 * uiscale, y2 * uiscale);
273         glEnd();
274 }
275
276 static void utext(int x, int y, const char *txt, int sz)
277 {
278         glMatrixMode(GL_PROJECTION);
279         glPushMatrix();
280         glTranslatef(x * uiscale, (y - dtx_baseline()) * uiscale, 0);
281         glScalef(uiscale, -uiscale, 1);
282
283         dtx_string(txt);
284         dtx_flush();
285
286         glPopMatrix();
287 }
288
289 static int utextspacing(void)
290 {
291         return dtx_line_height();
292 }
293
294 static int utextwidth(const char *txt, int sz)
295 {
296         return dtx_string_width(txt);
297 }