#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;
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();
-}
struct level *create_level(int xsz, int ysz);
void free_level(struct level *lvl);
-void draw_level(struct level *lvl);
-
#endif /* LEVEL_H_ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
#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);
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;
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");
fprintf(stderr, "failed to create level\n");
return -1;
}
+ if(init_lview(lvl) == -1) {
+ return -1;
+ }
splitx = UISPLIT * uiscale;
view_width = win_width - splitx;
static void cleanup(void)
{
+ destroy_lview();
free_level(lvl);
dtx_close_font(uifont);
utk_close(uiroot);
glVertex2f(0, view_height);
glEnd();
- draw_level(lvl);
+ draw_lview();
glutSwapBuffers();
}
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)
}
}
+ 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);