X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=tools%2Fdunger%2Fsrc%2Flevel.c;h=3a1a9bf9349d6c95fcaf89a2e1081de5083b6271;hb=8d36df2b04dfa5d747dd21ae2ddf7d349524674a;hp=6fb5706f60570eaa1810ec96d15fc1adc316e842;hpb=5f481bfc3af614919e31b97bfd4af1f8b829c4c2;p=vrlugburz diff --git a/tools/dunger/src/level.c b/tools/dunger/src/level.c index 6fb5706..3a1a9bf 100644 --- a/tools/dunger/src/level.c +++ b/tools/dunger/src/level.c @@ -1,82 +1,143 @@ #include #include #include -#include +#include +#include #include "level.h" -extern int view_width, view_height; -extern float view_panx, view_pany, view_zoom; - - -struct level *create_level(int xsz, int ysz) +int init_level(struct level *lvl, int xsz, int ysz) { - struct level *lvl; - - if(!(lvl = malloc(sizeof *lvl))) { - return 0; - } if(!(lvl->cells = calloc(xsz * ysz, sizeof *lvl->cells))) { free(lvl); - return 0; + return -1; } lvl->width = xsz; lvl->height = ysz; - return lvl; + return 0; } -void free_level(struct level *lvl) +void destroy_level(struct level *lvl) { if(!lvl) return; free(lvl->cells); - free(lvl); } -#define LTHICK 0.5f -static void draw_cell(struct level *lvl, struct cell *cell) +int load_level(struct level *lvl, const char *fname) { - int cidx, row, col; - float x, y, xsz, ysz, sz; - static const float colors[][3] = {{0, 0, 0}, {0.6, 0.6, 0.6}, {0.4, 0.2, 0.1}}; - - xsz = view_zoom * view_width / lvl->width; - ysz = view_zoom * view_height / lvl->height; - sz = xsz > ysz ? ysz : xsz; - - cidx = cell - lvl->cells; - row = cidx / lvl->width; - col = cidx % lvl->width; - - x = col * sz - view_panx; - y = row * sz - view_pany; - - glColor3f(1, 1, 1); - glVertex2f(x, y); - glVertex2f(x + sz, y); - glVertex2f(x + sz, y + sz); - glVertex2f(x, y + sz); - - x += LTHICK; - y += LTHICK; - sz -= LTHICK * 2.0f; - - glColor3fv(colors[cell->type]); - glVertex2f(x, y); - glVertex2f(x + sz, y); - glVertex2f(x + sz, y + sz); - glVertex2f(x, y + sz); + FILE *fp; + struct ts_node *ts, *node, *iter; + int sz, cx, cy; + struct cell *cell; + + if(!(fp = fopen(fname, "rb"))) { + return -1; + } + + if(!(ts = ts_load(fname))) { + fprintf(stderr, "failed to load level: %s\n", fname); + return -1; + } + if(strcmp(ts->name, "dunged_level") != 0) { + fprintf(stderr, "invalid or corrupted level file: %s\n", fname); + ts_free_tree(ts); + return -1; + } + + if((sz = ts_get_attr_int(ts, "size", 0)) <= 0) { + sz = 32; + } + + if(init_level(lvl, sz, sz) == -1) { + fprintf(stderr, "failed to initialize a %dx%d level\n", sz, sz); + ts_free_tree(ts); + return -1; + } + + iter = ts->child_list; + while(iter) { + node = iter; + iter = iter->next; + + if(strcmp(node->name, "cell") == 0) { + cx = ts_get_attr_int(node, "x", -1); + cy = ts_get_attr_int(node, "y", -1); + if(cx < 0 || cy < 0 || cx >= sz || cy >= sz) { + fprintf(stderr, "ignoring cell with invalid or missing coordinates\n"); + continue; + } + cell = lvl->cells + cy * sz + cx; + cell->type = ts_get_attr_int(node, "blocked", 0) ? CELL_BLOCKED : CELL_WALK; + /* TODO wall tiles and detail objects */ + } + } + + ts_free_tree(ts); + return 0; } -void draw_level(struct level *lvl) +int save_level(struct level *lvl, const char *fname) { int i, j; + struct ts_node *root, *node; + struct ts_attr *attr; struct cell *cell; - glBegin(GL_QUADS); - cell = lvl->cells; + if(!(root = ts_alloc_node()) || ts_set_node_name(root, "dunged_level") == -1) { + goto err; + } + + if(!(attr = ts_alloc_attr()) || ts_set_attr_name(attr, "size") == -1) { + ts_free_attr(attr); + goto err; + } + ts_set_valuei(&attr->val, lvl->width); + ts_add_attr(root, attr); + for(i=0; iheight; i++) { for(j=0; jwidth; j++) { - draw_cell(lvl, cell++); + cell = lvl->cells + i * lvl->width + j; + if(cell->type == CELL_SOLID) continue; + + if(!(node = ts_alloc_node()) || ts_set_node_name(node, "cell") == -1) { + ts_free_node(node); + goto err; + } + if(!(attr = ts_alloc_attr()) || ts_set_attr_name(attr, "x") == -1) { + ts_free_attr(attr); + goto err; + } + ts_set_valuei(&attr->val, j); + ts_add_attr(node, attr); + if(!(attr = ts_alloc_attr()) || ts_set_attr_name(attr, "y") == -1) { + ts_free_attr(attr); + goto err; + } + ts_set_valuei(&attr->val, i); + ts_add_attr(node, attr); + + if(cell->type == CELL_BLOCKED) { + if(!(attr = ts_alloc_attr()) || ts_set_attr_name(attr, "blocked") == -1) { + ts_free_attr(attr); + goto err; + } + ts_set_valuei(&attr->val, 1); + ts_add_attr(node, attr); + } + + ts_add_child(root, node); } } - glEnd(); + + if(ts_save(root, fname) == -1) { + fprintf(stderr, "failed to save level: %s\n", fname); + ts_free_tree(root); + return -1; + } + ts_free_tree(root); + return 0; + +err: + fprintf(stderr, "failed to construct treestore tree\n"); + ts_free_tree(root); + return -1; }