dungeon generation first step
authorJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 15 Sep 2021 10:24:21 +0000 (13:24 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 15 Sep 2021 10:24:21 +0000 (13:24 +0300)
src/game.c
src/level.c
src/level.h
src/player.c [new file with mode: 0644]
src/player.h [new file with mode: 0644]

index 8ee1989..65c7636 100644 (file)
@@ -1,21 +1,24 @@
+#include <stdio.h>
 #include <assert.h>
 #include "cgmath/cgmath.h"
 #include "game.h"
 #include "opengl.h"
 #include "level.h"
+#include "player.h"
 #include "scenefile.h"
 #include "sdr.h"
 
 static void draw_level(void);
 
 struct level lvl;
+struct player player;
 
 int win_width, win_height;
 float win_aspect;
 int mouse_x, mouse_y;
 int bnstate[8];
 
-float cam_theta, cam_phi, cam_dist = 10;
+float cam_dist = 10;
 float view_matrix[16], proj_matrix[16];
 
 unsigned int sdr_foo;
@@ -41,6 +44,14 @@ int game_init(void)
        if(load_level(&lvl, "data/test.lvl") == -1) {
                return -1;
        }
+       gen_level_geom(&lvl);
+
+       init_player(&player);
+       player.lvl = &lvl;
+       player.cx = lvl.px;
+       player.cy = lvl.py;
+
+       printf("start pos: %d,%d\n", player.cx, player.cy);
 
        return 0;
 }
@@ -61,12 +72,9 @@ void game_display(void)
        glMatrixMode(GL_PROJECTION);
        glLoadMatrixf(proj_matrix);
 
-       cgm_midentity(view_matrix);
-       cgm_mpretranslate(view_matrix, 0, -1.7, -cam_dist);
-       cgm_mprerotate(view_matrix, cam_phi, 1, 0, 0);
-       cgm_mprerotate(view_matrix, cam_theta, 0, 1, 0);
+       upd_player_xform(&player);
        glMatrixMode(GL_MODELVIEW);
-       glLoadMatrixf(view_matrix);
+       glLoadMatrixf(player.view_xform);
 
        draw_level();
 
@@ -78,16 +86,24 @@ static void draw_level(void)
 {
        int i, j, k;
        struct cell *cell;
+       float xform[16];
 
        glUseProgram(sdr_foo);
 
        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);
+
+                       glPushMatrix();
+                       glMultMatrixf(xform);
+
                        for(k=0; k<cell->num_mgrp; k++) {
                                draw_meshgroup(cell->mgrp + k);
                        }
                        cell++;
+
+                       glPopMatrix();
                }
        }
 
@@ -127,10 +143,10 @@ void game_mmotion(int x, int y)
        if(!(dx | dy)) return;
 
        if(bnstate[0]) {
-               cam_theta += cgm_deg_to_rad(dx * 0.5f);
-               cam_phi += cgm_deg_to_rad(dy * 0.5f);
-               if(cam_phi < -M_PI/2) cam_phi = -M_PI/2;
-               if(cam_phi > M_PI/2) cam_phi = M_PI/2;
+               player.theta -= cgm_deg_to_rad(dx * 0.5f);
+               player.phi -= cgm_deg_to_rad(dy * 0.5f);
+               if(player.phi < -M_PI/2) player.phi = -M_PI/2;
+               if(player.phi > M_PI/2) player.phi = M_PI/2;
        }
        if(bnstate[2]) {
                cam_dist += dy * 0.1;
index 70af648..6f265c3 100644 (file)
@@ -16,6 +16,7 @@ int init_level(struct level *lvl, int xsz, int ysz)
        }
        lvl->width = xsz;
        lvl->height = ysz;
+       lvl->cell_size = DEF_CELL_SIZE;
        return 0;
 }
 
@@ -32,6 +33,7 @@ int load_level(struct level *lvl, const char *fname)
        struct ts_node *ts, *node, *iter;
        int i, j, sz, cx, cy;
        struct cell *cell;
+       float *vecptr;
 
        lvl->fname = strdup(fname);
        if((lvl->dirname = malloc(strlen(fname) + 1))) {
@@ -57,6 +59,12 @@ int load_level(struct level *lvl, const char *fname)
                ts_free_tree(ts);
                return -1;
        }
+       lvl->cell_size = ts_get_attr_num(ts, "cellsize", DEF_CELL_SIZE);
+
+       if((vecptr = ts_get_attr_vec(ts, "player", 0))) {
+               lvl->px = vecptr[0];
+               lvl->py = vecptr[1];
+       }
 
        iter = ts->child_list;
        while(iter) {
@@ -186,7 +194,7 @@ err:
 
 static int load_tileset(struct level *lvl, struct ts_node *tsn)
 {
-       static const char *tile_types[] = {"straight", "corner", "door", 0};
+       static const char *tile_types[] = {"empty", "straight", "corner", "door", 0};
 
        int i;
        char *path;
@@ -237,11 +245,11 @@ static int load_tileset(struct level *lvl, struct ts_node *tsn)
        return 0;
 }
 
-struct tile *find_level_tile(struct level *lvl, const char *tname)
+struct tile *find_level_tile(struct level *lvl, int type)
 {
        struct tile *tile = lvl->tiles;
        while(tile) {
-               if(strcmp(tile->name, tname) == 0) {
+               if(tile->type == type) {
                        return tile;
                }
                tile = tile->next;
@@ -257,9 +265,7 @@ int gen_cell_geom(struct level *lvl, struct cell *cell)
        struct mesh *mesh, *tmesh;
        float xform[16];
 
-       printf("foo!\n");
-
-       if(!(tstr = find_level_tile(lvl, "straight"))) {
+       if(!(tstr = find_level_tile(lvl, TILE_STRAIGHT))) {
                return -1;
        }
 
@@ -318,6 +324,7 @@ int gen_level_geom(struct level *lvl)
                        cell = lvl->cells + i * lvl->width + j;
                        if(cell->type != CELL_SOLID) {
                                if(gen_cell_geom(lvl, cell) == -1) {
+                                       printf("failed to generate cell\n");
                                        return -1;
                                }
                        }
index 53eb9c1..dd1c988 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "scenefile.h"
 
+#define DEF_CELL_SIZE  3.0f
+
 enum {
        TILE_EMPTY,
        TILE_STRAIGHT,
@@ -38,6 +40,8 @@ struct level {
        char *fname, *dirname;
 
        int width, height;
+       int px, py;                             /* player start position */
+       float cell_size;
        struct cell *cells;
 
        struct tile *tiles;
@@ -55,7 +59,7 @@ void destroy_level(struct level *lvl);
 int load_level(struct level *lvl, const char *fname);
 int save_level(struct level *lvl, const char *fname);
 
-struct tile *find_level_tile(struct level *lvl, const char *tname);
+struct tile *find_level_tile(struct level *lvl, int type);
 
 int gen_cell_geom(struct level *lvl, struct cell *cell);
 int gen_level_geom(struct level *lvl);
diff --git a/src/player.c b/src/player.c
new file mode 100644 (file)
index 0000000..0e68393
--- /dev/null
@@ -0,0 +1,26 @@
+#include "player.h"
+
+void init_player(struct player *p)
+{
+       memset(p, 0, sizeof *p);
+       cgm_qcons(&p->vrot, 0, 0, 0, 1);
+
+       p->height = 1.75;
+       p->hp = p->hp_max = 10;
+       p->mp = p->mp_max = 10;
+}
+
+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_vadd(&pos, &p->cpos);
+
+       cgm_midentity(p->view_xform);
+       cgm_mprerotate_x(p->view_xform, -p->phi);
+       cgm_mprerotate_y(p->view_xform, -p->theta);
+       cgm_mrotate_quat(p->view_xform, &p->vrot);
+       cgm_mpretranslate(p->view_xform, -pos.x, -pos.y, -pos.z);
+}
diff --git a/src/player.h b/src/player.h
new file mode 100644 (file)
index 0000000..d4d47b3
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef PLAYER_H_
+#define PLAYER_H_
+
+#include "cgmath/cgmath.h"
+#include "level.h"
+
+struct player {
+       struct level *lvl;
+
+       int cx, cy;
+       cgm_vec3 cpos;          /* cell position (derived from cx,cy) */
+       float theta, phi;       /* mouselook/VR controller rotation (theta only) */
+       cgm_vec3 vpos;          /* VR position within the cell */
+       cgm_quat vrot;          /* VR orientation */
+
+       float height;
+
+       /* view matrix, derived from all of the above by upd_player_xform */
+       float view_xform[16];
+
+       int hp, mp, hp_max, mp_max;
+};
+
+void init_player(struct player *p);
+void upd_player_xform(struct player *p);
+
+#endif /* PLAYER_H_ */