cell select
[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 int mousex, mousey, clickx, clicky;
32
33 static float uiscale = 1.0f;
34 #define UISPLIT 150
35 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 | GLUT_MULTISAMPLE);
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         glEnable(GL_MULTISAMPLE);
77
78         glClearColor(0.15, 0.15, 0.15, 1);
79
80         if(!(uifont = dtx_open_font("uifont.ttf", 0))) {
81                 fprintf(stderr, "failed to open uifont.ttf\n");
82                 return -1;
83         }
84         dtx_prepare_range(uifont, FONTSZ, ' ', 'z');
85         dtx_use_font(uifont, FONTSZ);
86
87         if(!(uiroot = utk_init(win_width / uiscale, win_height / uiscale))) {
88                 fprintf(stderr, "failed to initialized ubertk\n");
89                 return -1;
90         }
91         utk_set_color_func(ucolor);
92         utk_set_clip_func(uclip);
93         utk_set_image_func(uimage);
94         utk_set_rect_func(urect);
95         utk_set_line_func(uline);
96         utk_set_text_func(utext);
97         utk_set_text_spacing_func(utextspacing);
98         utk_set_text_width_func(utextwidth);
99
100         win = utk_vbox(uiroot, 0, UTK_DEF_SPACING);
101         utk_set_pos(win, 15, 15);
102         utk_button(win, "hello", 0, 0, 0, 0);
103         utk_button(win, "button 2", 0, 0, 0, 0);
104         utk_button(win, "button 3", 0, 0, 0, 0);
105
106         if(!(lvl = create_level(32, 32))) {
107                 fprintf(stderr, "failed to create level\n");
108                 return -1;
109         }
110
111         splitx = UISPLIT * uiscale;
112         view_width = win_width - splitx;
113         view_height = win_height;
114
115         return 0;
116 }
117
118 static void cleanup(void)
119 {
120         free_level(lvl);
121         dtx_close_font(uifont);
122         utk_close(uiroot);
123 }
124
125 static void display(void)
126 {
127         glClear(GL_COLOR_BUFFER_BIT);
128
129         glMatrixMode(GL_MODELVIEW);
130         glLoadIdentity();
131
132         /* draw UI */
133
134         glMatrixMode(GL_PROJECTION);
135         glLoadIdentity();
136         glOrtho(0, splitx, win_height, 0, -1, 1);
137         glViewport(0, 0, splitx, win_height);
138
139         glBegin(GL_QUADS);
140         glColor3f(0.25, 0.25, 0.25);
141         glVertex2f(0, 0);
142         glVertex2f(splitx, 0);
143         glVertex2f(splitx, win_height);
144         glVertex2f(0, win_height);
145         glEnd();
146         utk_draw(uiroot);
147
148         /* draw view */
149
150         glMatrixMode(GL_PROJECTION);
151         glLoadIdentity();
152         glOrtho(0, view_width, 0, view_height, -1, 1);
153         glViewport(splitx, 0, view_width, view_height);
154
155         glBegin(GL_QUADS);
156         glColor3f(0.1, 0.1, 0.1);
157         glVertex2f(0, 0);
158         glVertex2f(view_width, 0);
159         glVertex2f(view_width, view_height);
160         glVertex2f(0, view_height);
161         glEnd();
162
163         draw_level(lvl);
164
165         glutSwapBuffers();
166 }
167
168 static void reshape(int x, int y)
169 {
170         win_width = x;
171         win_height = y;
172
173         if(uiroot) {
174                 utk_set_size(uiroot, x / uiscale, y / uiscale);
175         }
176 }
177
178 static void keyb(unsigned char key, int x, int y)
179 {
180         if(key == 27) exit(0);
181         utk_keyboard_event(key, 1);
182         glutPostRedisplay();
183 }
184
185 static void keyup(unsigned char key, int x, int y)
186 {
187         utk_keyboard_event(key, 0);
188         glutPostRedisplay();
189 }
190
191 static void mouse(int bn, int st, int x, int y)
192 {
193         int bidx = bn - GLUT_LEFT_BUTTON;
194         int press = st == GLUT_DOWN;
195
196         bnstate[bidx] = press;
197         mousex = x;
198         mousey = y;
199
200         if(bn <= 2) {
201                 if(press) {
202                         clickx = x;
203                         clicky = y;
204                 } else {
205                         clickx = clicky = -1;
206                 }
207         } else if(bn == 3) {
208                 if(press) view_zoom += 0.1;
209         } else if(bn == 4) {
210                 if(press) view_zoom -= 0.1;
211         }
212
213         utk_mbutton_event(bidx, press, x / uiscale, y / uiscale);
214         glutPostRedisplay();
215 }
216
217 static void motion(int x, int y)
218 {
219         int dx, dy;
220         dx = x - mousex;
221         dy = y - mousey;
222         mousex = x;
223         mousey = y;
224
225         if(clickx >= splitx) {
226                 if(bnstate[1]) {
227                         view_panx -= dx;
228                         view_pany += dy;
229                 }
230         }
231
232         utk_mmotion_event(x / uiscale, y / uiscale);
233         glutPostRedisplay();
234 }
235
236 static void ucolor(int r, int g, int b, int a)
237 {
238         glColor4ub(r, g, b, a);
239 }
240
241 static void uclip(int x1, int y1, int x2, int y2)
242 {
243         if(!(x1 | y1 | x2 | y2)) {
244                 glDisable(GL_SCISSOR_TEST);
245         } else {
246                 glEnable(GL_SCISSOR_TEST);
247         }
248
249         x1 *= uiscale;
250         y1 *= uiscale;
251         x2 *= uiscale;
252         y2 *= uiscale;
253
254         glScissor(x1, win_height - y2, x2 - x1, y2 - y1);
255 }
256
257 static void uimage(int x, int y, const void *pix, int xsz, int ysz)
258 {
259         glPixelZoom(1, -1);
260         glRasterPos2f(x * uiscale, y * uiscale);
261         glDrawPixels(xsz, ysz, GL_BGRA, GL_UNSIGNED_BYTE, pix);
262 }
263
264 static void urect(int x1, int y1, int x2, int y2)
265 {
266         glRectf(x1 * uiscale, y1 * uiscale, x2 * uiscale, y2 * uiscale);
267 }
268
269 static void uline(int x1, int y1, int x2, int y2, int width)
270 {
271         glLineWidth(width);
272         glBegin(GL_LINES);
273         glVertex2f(x1 * uiscale, y1 * uiscale);
274         glVertex2f(x2 * uiscale, y2 * uiscale);
275         glEnd();
276 }
277
278 static void utext(int x, int y, const char *txt, int sz)
279 {
280         glMatrixMode(GL_PROJECTION);
281         glPushMatrix();
282         glTranslatef(x * uiscale, (y - dtx_baseline()) * uiscale, 0);
283         glScalef(uiscale, -uiscale, 1);
284
285         dtx_string(txt);
286         dtx_flush();
287
288         glPopMatrix();
289 }
290
291 static int utextspacing(void)
292 {
293         return dtx_line_height();
294 }
295
296 static int utextwidth(const char *txt, int sz)
297 {
298         return dtx_string_width(txt);
299 }