dunger now saves player start position and cell size
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 16 Sep 2021 20:43:33 +0000 (23:43 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 16 Sep 2021 20:43:33 +0000 (23:43 +0300)
src/game.c
src/game.h
src/level.c
src/player.c
tools/dunger/Makefile
tools/dunger/src/app.h [new file with mode: 0644]
tools/dunger/src/lview.c
tools/dunger/src/lview.h
tools/dunger/src/main.c

index a997b69..3194196 100644 (file)
@@ -18,7 +18,7 @@ float win_aspect;
 int mouse_x, mouse_y;
 int bnstate[8];
 
-float cam_dist = 10;
+float cam_dist;
 float view_matrix[16], proj_matrix[16];
 
 unsigned int sdr_foo;
@@ -60,26 +60,51 @@ void game_shutdown(void)
        free_program(sdr_foo);
 }
 
-#define STEP_INTERVAL  1000
+#define STEP_INTERVAL  128
 
 void update(float dt)
 {
        static long prev_step;
-       int step[][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
+       int dir;
+       int step[][2] = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
 
        cgm_vec3 vdir = {0, 0, -1};
 
-       upd_player_xform(&player);
        cgm_vmul_m3v3(&vdir, player.view_xform);
 
-       player.dir = (int)(2.0f * (atan2(vdir.z, vdir.x) + M_PI) / M_PI + 0.5f);
+       player.dir = (int)(2.0f * (-atan2(vdir.z, vdir.x) + M_PI) / M_PI + 0.5f) & 3;
 
-       /*
        if(time_msec - prev_step >= STEP_INTERVAL) {
-               if(input[INP_FWD]) {
+               if(input_state[INP_FWD]) {
+                       player.cx += step[player.dir][0];
+                       player.cy += step[player.dir][1];
+                       prev_step = time_msec;
+                       printf("step[%d] %d,%d\n", player.dir, player.cx, player.cy);
+               }
+               if(input_state[INP_BACK]) {
+                       player.cx -= step[player.dir][0];
+                       player.cy -= step[player.dir][1];
+                       prev_step = time_msec;
+                       printf("step[%d] %d,%d\n", player.dir, player.cx, player.cy);
+               }
+               if(input_state[INP_LEFT]) {
+                       dir = (player.dir + 3) & 3;
+                       player.cx += step[dir][0];
+                       player.cy += step[dir][1];
+                       prev_step = time_msec;
+                       printf("step[%d] %d,%d\n", player.dir, player.cx, player.cy);
                }
+               if(input_state[INP_RIGHT]) {
+                       dir = (player.dir + 1) & 3;
+                       player.cx += step[dir][0];
+                       player.cy += step[dir][1];
+                       prev_step = time_msec;
+                       printf("step[%d] %d,%d\n", player.dir, player.cx, player.cy);
+               }
+               memset(input_state, 0, sizeof input_state);
        }
-       */
+
+       upd_player_xform(&player);
 }
 
 void game_display(void)
@@ -101,7 +126,9 @@ void game_display(void)
        glLoadMatrixf(proj_matrix);
 
        glMatrixMode(GL_MODELVIEW);
-       glLoadMatrixf(player.view_xform);
+       glLoadIdentity();
+       glTranslatef(0, 0, -cam_dist);
+       glMultMatrixf(player.view_xform);
 
        draw_level();
 
@@ -120,7 +147,7 @@ static void draw_level(void)
        cell = lvl.cells;
        for(i=0; i<lvl.height; i++) {
                for(j=0; j<lvl.width; j++) {
-                       cgm_mtranslation(xform, j * lvl.cell_size, 0, i * lvl.cell_size);
+                       cgm_mtranslation(xform, j * lvl.cell_size, 0, -i * lvl.cell_size);
 
                        glPushMatrix();
                        glMultMatrixf(xform);
@@ -151,6 +178,24 @@ void game_keyboard(int key, int press)
                game_quit();
                return;
        }
+
+       switch(key) {
+       case 'w':
+               input_state[INP_FWD] = press;
+               break;
+
+       case 'a':
+               input_state[INP_LEFT] = press;
+               break;
+
+       case 's':
+               input_state[INP_BACK] = press;
+               break;
+
+       case 'd':
+               input_state[INP_RIGHT] = press;
+               break;
+       }
 }
 
 void game_mbutton(int bn, int press, int x, int y)
index 4551f63..10d7658 100644 (file)
@@ -2,6 +2,17 @@
 #define GAME_H_
 
 enum {
+       INP_LEFT,
+       INP_RIGHT,
+       INP_FWD,
+       INP_BACK,
+       INP_LTURN,
+       INP_RTURN,
+
+       MAX_INP
+};
+
+enum {
        KEY_LEFT = 256,
        KEY_RIGHT,
        KEY_UP,
@@ -11,6 +22,7 @@ enum {
 };
 
 long time_msec;
+int input_state[MAX_INP];
 
 int game_init(void);
 void game_shutdown(void);
index 566b1c3..ced5b69 100644 (file)
@@ -19,6 +19,7 @@ int init_level(struct level *lvl, int xsz, int ysz)
        lvl->width = xsz;
        lvl->height = ysz;
        lvl->cell_size = DEF_CELL_SIZE;
+       lvl->px = lvl->py = -1;
        return 0;
 }
 
@@ -37,13 +38,6 @@ int load_level(struct level *lvl, const char *fname)
        struct cell *cell;
        float *vecptr;
 
-       lvl->fname = strdup(fname);
-       if((lvl->dirname = malloc(strlen(fname) + 1))) {
-#ifndef LEVEL_EDITOR
-               path_dir(lvl->fname, lvl->dirname);
-#endif
-       }
-
        if(!(ts = ts_load(fname))) {
                fprintf(stderr, "failed to load level: %s\n", fname);
                return -1;
@@ -63,6 +57,14 @@ int load_level(struct level *lvl, const char *fname)
                ts_free_tree(ts);
                return -1;
        }
+
+       lvl->fname = strdup(fname);
+       if((lvl->dirname = malloc(strlen(fname) + 1))) {
+#ifndef LEVEL_EDITOR
+               path_dir(lvl->fname, lvl->dirname);
+#endif
+       }
+
        lvl->cell_size = ts_get_attr_num(ts, "cellsize", DEF_CELL_SIZE);
 
        if((vecptr = ts_get_attr_vec(ts, "player", 0))) {
@@ -147,6 +149,20 @@ int save_level(struct level *lvl, const char *fname)
        ts_set_valuei(&attr->val, lvl->width);
        ts_add_attr(root, attr);
 
+       if(lvl->cell_size && (attr = ts_alloc_attr())) {
+               ts_set_attr_name(attr, "cellsize");
+               ts_set_valuef(&attr->val, lvl->cell_size);
+               ts_add_attr(root, attr);
+       }
+
+       if(lvl->px >= 0 && lvl->px < lvl->width && lvl->py >= 0 && lvl->py < lvl->height) {
+               if((attr = ts_alloc_attr())) {
+                       ts_set_attr_name(attr, "player");
+                       ts_set_valueiv(&attr->val, 2, lvl->px, lvl->py);
+                       ts_add_attr(root, attr);
+               }
+       }
+
        for(i=0; i<lvl->height; i++) {
                for(j=0; j<lvl->width; j++) {
                        cell = lvl->cells + i * lvl->width + j;
index 0e68393..820dfbd 100644 (file)
@@ -15,7 +15,7 @@ void upd_player_xform(struct player *p)
        cgm_vec3 pos;
        float celld = p->lvl ? p->lvl->cell_size : DEF_CELL_SIZE;
 
-       cgm_vcons(&pos, p->cx * celld, p->height, p->cy * celld);
+       cgm_vcons(&pos, p->cx * celld, p->height, -p->cy * celld);
        cgm_vadd(&pos, &p->cpos);
 
        cgm_midentity(p->view_xform);
index 81ff599..3edc3de 100644 (file)
@@ -3,7 +3,7 @@ obj = $(src:.c=.o)
 dep = $(src:.c=.d)
 bin = dunger
 
-CFLAGS = -pedantic -Wall -g -DLEVEL_EDITOR -I../../src
+CFLAGS = -pedantic -Wall -g -DLEVEL_EDITOR -I../../src -fcommon
 LDFLAGS = -lGL -lGLU -lglut -lutk -ldrawtext -ltreestore
 
 $(bin): $(obj)
diff --git a/tools/dunger/src/app.h b/tools/dunger/src/app.h
new file mode 100644 (file)
index 0000000..480d7c9
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef APP_H_
+#define APP_H_
+
+enum {
+       TOOL_DRAW,
+       TOOL_PSTART
+};
+
+int tool;
+
+#endif
index e0001fe..48014cc 100644 (file)
@@ -1,6 +1,7 @@
 #include <GL/gl.h>
 #include <drawtext.h>
 #include "lview.h"
+#include "app.h"
 
 static struct level *lvl;
 static struct cell *sel;
@@ -12,7 +13,8 @@ int init_lview(struct level *l)
 {
        lvl = l;
        sel = 0;
-       panx = pany = 0;
+       panx = 0;
+       pany = -12;
        zoom = 1;
        zoom_lview(0);
        return 0;
@@ -51,16 +53,36 @@ static int bnstate[8];
 
 void lview_mbutton(int bn, int press, int x, int y)
 {
+       int cx, cy;
        float hsz = cellsz / 2.0f;
        sel = pos_to_cell(x + hsz - vpx, vph - y + hsz - vpy, 0, 0);
        bnstate[bn] = press;
 
        if(press) {
                if(!sel) return;
-               if(bn == 0) {
-                       sel->type = CELL_WALK;
-               } else if(bn == 2) {
-                       sel->type = CELL_SOLID;
+
+               switch(tool) {
+               case TOOL_DRAW:
+                       if(bn == 0) {
+                               sel->type = CELL_WALK;
+                       } else if(bn == 2) {
+                               sel->type = CELL_SOLID;
+                       }
+                       break;
+
+               case TOOL_PSTART:
+                       cell_coords(sel, &cx, &cy);
+                       if(bn == 0) {
+                               if(sel->type == CELL_WALK) {
+                                       lvl->px = cx;
+                                       lvl->py = cy;
+                               }
+                       } else if(bn == 2) {
+                               if(lvl->px == cx && lvl->py == cy) {
+                                       lvl->px = lvl->py = -1;
+                               }
+                       }
+                       break;
                }
        }
 }
@@ -72,32 +94,37 @@ void lview_mouse(int x, int y)
                return;
        }
 
-       if(bnstate[0]) {
-               sel->type = CELL_WALK;
-       } else if(bnstate[2]) {
-               sel->type = CELL_SOLID;
+       switch(tool) {
+       case TOOL_DRAW:
+               if(bnstate[0]) {
+                       sel->type = CELL_WALK;
+               } else if(bnstate[2]) {
+                       sel->type = CELL_SOLID;
+               }
+               break;
        }
 }
 
 #define LTHICK 0.5f
 static void draw_cell(struct cell *cell)
 {
-       int cidx, row, col;
+       int 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_coords(cell, &col, &row);
        cell_to_pos(col, row, &x, &y);
 
        if(sel == cell) {
-               glColor3f(0.4, 1.0f, 0.4);
+               glColor3f(1, 1, 1);
        } else {
-               glColor3f(0.5f, 0.5f, 0.5f);
+               if(col == lvl->px && row == lvl->py) {
+                       glColor3f(0, 1, 0);
+               } else {
+                       glColor3f(0.5f, 0.5f, 0.5f);
+               }
        }
        glVertex2f(x - hsz, y - hsz);
        glVertex2f(x + hsz, y - hsz);
@@ -118,7 +145,7 @@ static void draw_cell(struct cell *cell)
 
 void draw_lview(void)
 {
-       int i, j;
+       int i, j, row, col;
        struct cell *cell;
 
        glBegin(GL_QUADS);
@@ -131,9 +158,7 @@ void draw_lview(void)
        glEnd();
 
        if(sel) {
-               int cidx = sel - lvl->cells;
-               int row = cidx / lvl->width;
-               int col = cidx % lvl->width;
+               cell_coords(sel, &col, &row);
 
                glMatrixMode(GL_MODELVIEW);
                glPushMatrix();
@@ -168,3 +193,10 @@ struct cell *pos_to_cell(float px, float py, int *cx, int *cy)
        }
        return 0;
 }
+
+void cell_coords(struct cell *cell, int *col, int *row)
+{
+       int cidx = cell - lvl->cells;
+       *row = cidx / lvl->width;
+       *col = cidx % lvl->width;
+}
index 07d3c57..408b410 100644 (file)
@@ -18,5 +18,6 @@ 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);
+void cell_coords(struct cell *cell, int *col, int *row);
 
 #endif /* LVIEW_H_ */
index ec5a827..6bc37a7 100644 (file)
@@ -6,6 +6,7 @@
 #include <drawtext.h>
 #include "level.h"
 #include "lview.h"
+#include "app.h"
 
 static int init(void);
 static void cleanup(void);
@@ -25,6 +26,8 @@ static void cb_save_ok(utk_event *ev, void *data);
 
 static void cb_cancel(utk_event *ev, void *data);
 
+static void cb_toolselect(utk_event *ev, void *data);
+
 static int parse_args(int argc, char **argv);
 
 
@@ -127,6 +130,9 @@ static int init(void)
        utk_button(win, "New", 0, 0, cb_new, 0);
        utk_button(win, "Open ...", 0, 0, cb_open, 0);
        utk_button(win, "Save ...", 0, 0, cb_save, 0);
+       utk_label(win, "-- Tools --");
+       utk_radiobox(win, "Draw", 1, cb_toolselect, (void*)TOOL_DRAW);
+       utk_radiobox(win, "Player start", 0, cb_toolselect, (void*)TOOL_PSTART);
 
        uiwin_new = utk_window(uiroot, (win_width - 220) / 2, (win_height - 150) / 2,
                        220, 150, "New level");
@@ -407,6 +413,14 @@ static void cb_cancel(utk_event *ev, void *data)
        uigrab = 0;
 }
 
+static void cb_toolselect(utk_event *ev, void *data)
+{
+       utk_widget *w = utk_event_widget(ev);
+       if(utk_is_checked(w)) {
+               tool = (intptr_t)data;
+       }
+}
+
 static int parse_args(int argc, char **argv)
 {
        int i;