cleaned up the level view code
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 19 Aug 2021 17:46:14 +0000 (20:46 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 19 Aug 2021 17:46:14 +0000 (20:46 +0300)
tools/dunger/src/level.c
tools/dunger/src/level.h
tools/dunger/src/lview.c [new file with mode: 0644]
tools/dunger/src/lview.h [new file with mode: 0644]
tools/dunger/src/main.c

index 1e88b5c..5825924 100644 (file)
@@ -1,18 +1,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <GL/gl.h>
 #include "level.h"
 
-extern int view_width, view_height;
-extern float view_panx, view_pany, view_zoom;
-
-extern int mousex, mousey, splitx;
-
-static int cellsz;
-static struct cell *selcell;
-
-
 struct level *create_level(int xsz, int ysz)
 {
        struct level *lvl;
@@ -35,87 +25,3 @@ void free_level(struct level *lvl)
        free(lvl->cells);
        free(lvl);
 }
-
-void cell_to_pos(struct level *lvl, int cx, int cy, float *px, float *py)
-{
-       if(px) *px = (cx - lvl->width / 2.0f) * cellsz - view_panx + view_width / 2.0f;
-       if(py) *py = (cy - lvl->height / 2.0f) * cellsz - view_pany + view_height / 2.0f;
-}
-
-struct cell *pos_to_cell(struct level *lvl, float px, float py, int *cx, int *cy)
-{
-       int col, row;
-
-       col = (px + view_panx - view_width / 2.0f) / cellsz + lvl->width / 2.0f;
-       row = (py + view_pany - view_height / 2.0f) / cellsz + lvl->height / 2.0f;
-
-       if(cx) *cx = col;
-       if(cy) *cy = row;
-
-       if(col >= 0 && col < lvl->width && row >= 0 && row < lvl->height) {
-               return lvl->cells + row * lvl->width + col;
-       }
-       return 0;
-}
-
-#define LTHICK 0.5f
-static void draw_cell(struct level *lvl, struct cell *cell)
-{
-       int cidx, row, col;
-       float x, y, hsz;
-       static const float colors[][3] = {{0, 0, 0}, {0.6, 0.6, 0.6}, {0.4, 0.2, 0.1}};
-
-       hsz = cellsz * 0.5f;
-
-       cidx = cell - lvl->cells;
-       row = cidx / lvl->width;
-       col = cidx % lvl->width;
-
-       cell_to_pos(lvl, col, row, &x, &y);
-       /*printf("c->p: %d,%d -> %f,%f\n", col, row, x, y);
-       pos_to_cell(lvl, x, y, &col, &row);
-       printf("p->c: %f,%f -> %d,%d\n", x, y, col, row);*/
-
-       if(selcell == cell) {
-               glColor3f(0.4, 1.0f, 0.4);
-       } else {
-               glColor3f(0.5f, 0.5f, 0.5f);
-       }
-       glVertex2f(x - hsz, y - hsz);
-       glVertex2f(x + hsz, y - hsz);
-       glVertex2f(x + hsz, y + hsz);
-       glVertex2f(x - hsz, y + hsz);
-
-       x += LTHICK / 2.0f;
-       y += LTHICK / 2.0f;
-       hsz -= LTHICK * 2.0f;
-
-       glColor3fv(colors[cell->type]);
-       glVertex2f(x - hsz, y - hsz);
-       glVertex2f(x + hsz, y - hsz);
-       glVertex2f(x + hsz, y + hsz);
-       glVertex2f(x - hsz, y + hsz);
-}
-
-void draw_level(struct level *lvl)
-{
-       int i, j;
-       float xsz, ysz, hsz;
-       struct cell *cell;
-
-       xsz = view_zoom * view_width / lvl->width;
-       ysz = view_zoom * view_height / lvl->height;
-       cellsz = xsz > ysz ? ysz : xsz;
-       hsz = cellsz / 2.0f;
-
-       selcell = pos_to_cell(lvl, mousex + hsz - splitx, view_height - mousey + hsz, 0, 0);
-
-       glBegin(GL_QUADS);
-       cell = lvl->cells;
-       for(i=0; i<lvl->height; i++) {
-               for(j=0; j<lvl->width; j++) {
-                       draw_cell(lvl, cell++);
-               }
-       }
-       glEnd();
-}
index 2df8b8e..7a10103 100644 (file)
@@ -22,6 +22,4 @@ struct level {
 struct level *create_level(int xsz, int ysz);
 void free_level(struct level *lvl);
 
-void draw_level(struct level *lvl);
-
 #endif /* LEVEL_H_ */
diff --git a/tools/dunger/src/lview.c b/tools/dunger/src/lview.c
new file mode 100644 (file)
index 0000000..16af530
--- /dev/null
@@ -0,0 +1,128 @@
+#include <GL/gl.h>
+#include "lview.h"
+
+static struct level *lvl;
+static struct cell *sel;
+static int vpx, vpy, vpw, vph;
+static float panx, pany, zoom;
+static float cellsz;   /* derived from zoom and level properties */
+
+int init_lview(struct level *l)
+{
+       lvl = l;
+       sel = 0;
+       panx = pany = 0;
+       zoom = 1;
+       zoom_lview(0);
+       return 0;
+}
+
+void destroy_lview(void)
+{
+}
+
+void lview_viewport(int x, int y, int xsz, int ysz)
+{
+       vpx = x;
+       vpy = y;
+       vpw = xsz;
+       vph = ysz;
+       zoom_lview(0);  /* recalc cell size */
+}
+
+void pan_lview(float dx, float dy)
+{
+       panx += dx;
+       pany += dy;
+}
+
+void zoom_lview(float dz)
+{
+       float xsz, ysz;
+
+       zoom += dz;
+       xsz = zoom * vpw / lvl->width;
+       ysz = zoom * vph / lvl->height;
+       cellsz = xsz > ysz ? ysz : xsz;
+}
+
+void lview_mouse(int x, int y)
+{
+       float hsz = cellsz / 2.0f;
+       sel = pos_to_cell(x + hsz - vpx, vph - y + hsz - vpy, 0, 0);
+}
+
+#define LTHICK 0.5f
+static void draw_cell(struct cell *cell)
+{
+       int cidx, row, col;
+       float x, y, hsz;
+       static const float colors[][3] = {{0, 0, 0}, {0.6, 0.6, 0.6}, {0.4, 0.2, 0.1}};
+
+       hsz = cellsz * 0.5f;
+
+       cidx = cell - lvl->cells;
+       row = cidx / lvl->width;
+       col = cidx % lvl->width;
+
+       cell_to_pos(col, row, &x, &y);
+
+       if(sel == cell) {
+               glColor3f(0.4, 1.0f, 0.4);
+       } else {
+               glColor3f(0.5f, 0.5f, 0.5f);
+       }
+       glVertex2f(x - hsz, y - hsz);
+       glVertex2f(x + hsz, y - hsz);
+       glVertex2f(x + hsz, y + hsz);
+       glVertex2f(x - hsz, y + hsz);
+
+       x += LTHICK / 2.0f;
+       y += LTHICK / 2.0f;
+       hsz -= LTHICK * 2.0f;
+
+       glColor3fv(colors[cell->type]);
+       glVertex2f(x - hsz, y - hsz);
+       glVertex2f(x + hsz, y - hsz);
+       glVertex2f(x + hsz, y + hsz);
+       glVertex2f(x - hsz, y + hsz);
+}
+
+
+void draw_lview(void)
+{
+       int i, j;
+       struct cell *cell;
+
+       glBegin(GL_QUADS);
+       cell = lvl->cells;
+       for(i=0; i<lvl->height; i++) {
+               for(j=0; j<lvl->width; j++) {
+                       draw_cell(cell++);
+               }
+       }
+       glEnd();
+
+}
+
+void cell_to_pos(int cx, int cy, float *px, float *py)
+{
+       if(px) *px = (cx - lvl->width / 2.0f) * cellsz - panx + vpw / 2.0f;
+       if(py) *py = (cy - lvl->height / 2.0f) * cellsz - pany + vph / 2.0f;
+}
+
+struct cell *pos_to_cell(float px, float py, int *cx, int *cy)
+{
+       int col, row;
+
+       col = (px + panx - vpw / 2.0f) / cellsz + lvl->width / 2.0f;
+       row = (py + pany - vph / 2.0f) / cellsz + lvl->height / 2.0f;
+
+       if(cx) *cx = col;
+       if(cy) *cy = row;
+
+       if(col >= 0 && col < lvl->width && row >= 0 && row < lvl->height) {
+               return lvl->cells + row * lvl->width + col;
+       }
+       return 0;
+}
diff --git a/tools/dunger/src/lview.h b/tools/dunger/src/lview.h
new file mode 100644 (file)
index 0000000..0788b71
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef LVIEW_H_
+#define LVIEW_H_
+
+#include "level.h"
+
+int init_lview(struct level *lvl);
+void destroy_lview(void);
+
+void lview_viewport(int x, int y, int xsz, int ysz);
+
+void pan_lview(float dx, float dy);
+void zoom_lview(float dz);
+
+void lview_mouse(int x, int y);
+
+void draw_lview(void);
+
+void cell_to_pos(int cx, int cy, float *px, float *py);
+struct cell *pos_to_cell(float px, float py, int *cx, int *cy);
+
+#endif /* LVIEW_H_ */
index bfc0d43..fbb24c4 100644 (file)
@@ -1,9 +1,11 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <GL/glut.h>
 #include <utk/cubertk.h>
 #include <drawtext.h>
 #include "level.h"
+#include "lview.h"
 
 static int init(void);
 static void cleanup(void);
@@ -23,6 +25,9 @@ static void utext(int x, int y, const char *txt, int sz);
 static int utextspacing(void);
 static int utextwidth(const char *txt, int sz);
 
+static int parse_args(int argc, char **argv);
+
+
 int win_width, win_height;
 int view_width, view_height;
 float view_panx, view_pany, view_zoom = 1.0f;
@@ -44,6 +49,11 @@ static struct level *lvl;
 int main(int argc, char **argv)
 {
        glutInit(&argc, argv);
+
+       if(parse_args(argc, argv) == -1) {
+               return 1;
+       }
+
        glutInitWindowSize(1280, 800);
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_MULTISAMPLE);
        glutCreateWindow("dunger");
@@ -107,6 +117,9 @@ static int init(void)
                fprintf(stderr, "failed to create level\n");
                return -1;
        }
+       if(init_lview(lvl) == -1) {
+               return -1;
+       }
 
        splitx = UISPLIT * uiscale;
        view_width = win_width - splitx;
@@ -117,6 +130,7 @@ static int init(void)
 
 static void cleanup(void)
 {
+       destroy_lview();
        free_level(lvl);
        dtx_close_font(uifont);
        utk_close(uiroot);
@@ -160,7 +174,7 @@ static void display(void)
        glVertex2f(0, view_height);
        glEnd();
 
-       draw_level(lvl);
+       draw_lview();
 
        glutSwapBuffers();
 }
@@ -173,6 +187,8 @@ static void reshape(int x, int y)
        if(uiroot) {
                utk_set_size(uiroot, x / uiscale, y / uiscale);
        }
+
+       lview_viewport(splitx, 0, x - splitx, y);
 }
 
 static void keyb(unsigned char key, int x, int y)
@@ -229,10 +245,43 @@ static void motion(int x, int y)
                }
        }
 
+       lview_mouse(x, y);
+
        utk_mmotion_event(x / uiscale, y / uiscale);
        glutPostRedisplay();
 }
 
+static int parse_args(int argc, char **argv)
+{
+       int i;
+
+       for(i=1; i<argc; i++) {
+               if(argv[i][0] == '-') {
+                       if(strcmp(argv[i], "-uiscale") == 0) {
+                               if(!argv[++i] || !(uiscale = atoi(argv[i]))) {
+                                       fprintf(stderr, "-uiscale should be followed by a positive number\n");
+                                       return -1;
+                               }
+                       } else if(strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0) {
+                               printf("Usage: %s [options]\n", argv[0]);
+                               printf("Options:\n");
+                               printf(" -uiscale <scale>: UI scale factor (default: 1)\n");
+                               printf(" -h,-help: print usage and exit\n");
+                               exit(0);
+                       } else {
+                               fprintf(stderr, "unknown option: %s\n", argv[i]);
+                               return -1;
+                       }
+               } else {
+                       fprintf(stderr, "unexpected argument: %s\n", argv[i]);
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+/* --- ubertk callbacks --- */
+
 static void ucolor(int r, int g, int b, int a)
 {
        glColor4ub(r, g, b, a);