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;
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)
glLoadMatrixf(proj_matrix);
glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(player.view_xform);
+ glLoadIdentity();
+ glTranslatef(0, 0, -cam_dist);
+ glMultMatrixf(player.view_xform);
draw_level();
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);
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)
#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,
};
long time_msec;
+int input_state[MAX_INP];
int game_init(void);
void game_shutdown(void);
lvl->width = xsz;
lvl->height = ysz;
lvl->cell_size = DEF_CELL_SIZE;
+ lvl->px = lvl->py = -1;
return 0;
}
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;
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))) {
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;
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);
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)
--- /dev/null
+#ifndef APP_H_
+#define APP_H_
+
+enum {
+ TOOL_DRAW,
+ TOOL_PSTART
+};
+
+int tool;
+
+#endif
#include <GL/gl.h>
#include <drawtext.h>
#include "lview.h"
+#include "app.h"
static struct level *lvl;
static struct cell *sel;
{
lvl = l;
sel = 0;
- panx = pany = 0;
+ panx = 0;
+ pany = -12;
zoom = 1;
zoom_lview(0);
return 0;
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;
}
}
}
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);
void draw_lview(void)
{
- int i, j;
+ int i, j, row, col;
struct cell *cell;
glBegin(GL_QUADS);
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();
}
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;
+}
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_ */
#include <drawtext.h>
#include "level.h"
#include "lview.h"
+#include "app.h"
static int init(void);
static void cleanup(void);
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);
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");
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;