tilesets
[vrlugburz] / src / level.c
index 3a1a9bf..9e5fe44 100644 (file)
@@ -4,6 +4,9 @@
 #include <errno.h>
 #include <treestore.h>
 #include "level.h"
+#include "fs.h"
+
+static int load_tileset(struct level *lvl, struct ts_node *tsn);
 
 int init_level(struct level *lvl, int xsz, int ysz)
 {
@@ -20,17 +23,19 @@ void destroy_level(struct level *lvl)
 {
        if(!lvl) return;
        free(lvl->cells);
+       free(lvl->fname);
+       free(lvl->dirname);
 }
 
 int load_level(struct level *lvl, const char *fname)
 {
-       FILE *fp;
        struct ts_node *ts, *node, *iter;
        int sz, cx, cy;
        struct cell *cell;
 
-       if(!(fp = fopen(fname, "rb"))) {
-               return -1;
+       lvl->fname = strdup(fname);
+       if((lvl->dirname = malloc(strlen(fname) + 1))) {
+               path_dir(lvl->fname, lvl->dirname);
        }
 
        if(!(ts = ts_load(fname))) {
@@ -58,7 +63,10 @@ int load_level(struct level *lvl, const char *fname)
                node = iter;
                iter = iter->next;
 
-               if(strcmp(node->name, "cell") == 0) {
+               if(strcmp(node->name, "tileset") == 0) {
+                       load_tileset(lvl, node);
+
+               } else 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) {
@@ -75,6 +83,7 @@ int load_level(struct level *lvl, const char *fname)
        return 0;
 }
 
+/* TODO: save tileset info */
 int save_level(struct level *lvl, const char *fname)
 {
        int i, j;
@@ -141,3 +150,56 @@ err:
        ts_free_tree(root);
        return -1;
 }
+
+static int load_tileset(struct level *lvl, struct ts_node *tsn)
+{
+       static const char *tile_types[] = {"straight", "corner", "door", 0};
+
+       int i;
+       char *path;
+       const char *str;
+       struct ts_node *node;
+       struct tile *tile;
+
+       node = tsn->child_list;
+       while(node) {
+               if(strcmp(node->name, "tile") == 0) {
+                       if(!(tile = calloc(1, sizeof *tile))) {
+                               fprintf(stderr, "failed to allocate tile\n");
+                               return -1;
+                       }
+                       if((str = ts_get_attr_str(node, "name", 0))) {
+                               tile->name = strdup(str);
+                       }
+                       if((str = ts_get_attr_str(node, "type", 0))) {
+                               for(i=0; tile_types[i]; i++) {
+                                       if(strcmp(str, tile_types[i]) == 0) {
+                                               tile->type = i;
+                                               break;
+                                       }
+                               }
+                       }
+                       if((str = ts_get_attr_str(node, "scene", 0))) {
+                               if(lvl->dirname) {
+                                       path = alloca(strlen(lvl->dirname) + strlen(str) + 2);
+                                       combine_path(lvl->dirname, str, path);
+                               } else {
+                                       path = (char*)str;
+                               }
+                               load_scenefile(&tile->scn, path);
+                       }
+
+                       if(tile->name && tile->scn.meshlist) {  /* valid tile */
+                               tile->next = lvl->tiles;
+                               lvl->tiles = tile;
+                       } else {
+                               fprintf(stderr, "load_tileset: skipping invalid tile: %s\n",
+                                               tile->name ? tile->name : "missing tile name");
+                               free(tile);
+                       }
+               }
+               node = node->next;
+       }
+
+       return 0;
+}