X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;ds=inline;f=src%2Ftileset.c;h=28adf31790f1caab624992890d8f48d4ebe2ba4c;hb=594c18e3671a27624a867071b5bafd08148652b3;hp=cde3021fdb48aa8243ea18e285335f7a9ae7f416;hpb=9089b4a32162a85cb3d244c915f31cc5adc3c389;p=vrlugburz diff --git a/src/tileset.c b/src/tileset.c index cde3021..28adf31 100644 --- a/src/tileset.c +++ b/src/tileset.c @@ -7,12 +7,21 @@ #include "level.h" #include "fs.h" +static int match_prefix(const char *str, const char *prefix); + +static struct tileset *tset_list; + int load_tileset(struct tileset *tset, const char *fname) { struct ts_node *ts, *node, *iter; - const char *str; + const char *str, *prefix; char *path; struct mesh *mesh; + struct tile *tile; + int type; + float xform[16], *vec; + + memset(tset, 0, sizeof *tset); if(!(ts = ts_load(fname))) { fprintf(stderr, "failed to load tileset: %s\n", fname); @@ -30,7 +39,7 @@ int load_tileset(struct tileset *tset, const char *fname) return -1; } path = alloca(strlen(fname) + strlen(str) + 2); - path_dir(str, path); + path_dir(fname, path); combine_path(path, str, path); if(load_scenefile(&tset->scn, path) == -1) { @@ -39,23 +48,149 @@ int load_tileset(struct tileset *tset, const char *fname) return -1; } + tset->fname = strdup(fname); tset->name = strdup(ts_get_attr_str(ts, "name", fname)); + tset->tile_size = ts_get_attr_num(ts, "tilesize", DEF_TILE_SIZE); + iter = ts->child_list; - while(node) { + while(iter) { node = iter; iter = iter->next; if(strcmp(node->name, "tile") == 0) { - if(!(str = ts_get_attr_str(node, "prefix", 0))) { + if(!(prefix = ts_get_attr_str(node, "prefix", 0))) { + continue; + } + + if(!(str = ts_get_attr_str(node, "type", 0))) { + fprintf(stderr, "load_tileset: missing tile type\n"); continue; } - if(!(mesh = find_mesh_prefix(&tset->scn, str))) { - fprintf(stderr, "load_tileset: failed to find mesh with prefix: %s\n", str); + if((type = tile_type(str)) == -1) { + fprintf(stderr, "load_tileset: invalid tile type: %s\n", str); continue; } - /* TOOD cont */ + + if(!(tile = malloc(sizeof *tile))) { + fprintf(stderr, "load_tileset: failed to allocate tile\n"); + continue; + } + tile->type = type; + + cgm_midentity(xform); + if((vec = ts_get_attr_vec(node, "pos", 0))) { + cgm_mtranslation(xform, -vec[0], -vec[1], -vec[2]); + } + + init_meshgroup(&tile->mgrp); + + mesh = tset->scn.meshlist; + while(mesh) { + if(mesh->name && match_prefix(mesh->name, prefix)) { + if(vec) { + xform_mesh(mesh, xform); + } + add_meshgroup_mesh(&tile->mgrp, mesh); + } + mesh = mesh->next; + } + + tile->next = tset->tiles; + tset->tiles = tile; } } return 0; } + +void destroy_tileset(struct tileset *tset) +{ + struct tile *tile; + + free(tset->name); + free(tset->fname); + + while(tset->tiles) { + tile = tset->tiles; + tset->tiles = tile->next; + + free(tile->name); + free(tile); + } + + destroy_scenefile(&tset->scn); +} + +struct tileset *get_tileset(const char *fname) +{ + struct tileset *ts = tset_list; + while(ts) { + if(strcmp(ts->fname, fname) == 0) { + return ts; + } + ts = ts->next; + } + + if(!(ts = malloc(sizeof *ts))) { + fprintf(stderr, "failed to allocate tileset\n"); + return 0; + } + if(load_tileset(ts, fname) == -1) { + free(ts); + return 0; + } + ts->next = tset_list; + tset_list = ts; + return ts; +} + +void free_all_tilesets(void) +{ + struct tileset *ts; + + while(tset_list) { + ts = tset_list; + tset_list = ts->next; + destroy_tileset(ts); + free(ts); + } +} + +struct tile *get_tile(struct tileset *tset, int ttype) +{ + struct tile *tile = tset->tiles; + while(tile) { + if(tile->type == ttype) { + return tile; + } + tile = tile->next; + } + return 0; +} + +int tile_type(const char *tstr) +{ + static const char *typenames[] = { + "open", "straight", "corner", "opencorner", "tee", "cross", "str2open", "stropen", 0 + }; + int i; + + if(!tstr) return -1; + + for(i=0; typenames[i]; i++) { + if(strcmp(tstr, typenames[i]) == 0) { + return i; + } + } + return -1; +} + +static int match_prefix(const char *str, const char *prefix) +{ + while(*str && *prefix) { + if(*str++ != *prefix++) { + return 0; + } + } + return 1; +}