+#include "metascene.h"
+#include "scene.h"
+#include "datamap.h"
+#include "treestore.h"
+
+#ifdef WIN32
+#include <malloc.h>
+#else
+#include <alloca.h>
+#endif
+
+static bool proc_node(Scene *scn, struct ts_node *node);
+static struct ts_attr *attr_inscope(struct ts_node *node, const char *name);
+
+bool load_scene(Scene *scn, const char *fname)
+{
+ struct ts_node *root = ts_load(fname);
+ if(!root || strcmp(root->name, "scene") != 0) {
+ ts_free_tree(root);
+ fprintf(stderr, "failed to load scene metadata: %s\n", fname);
+ return false;
+ }
+
+ bool res = proc_node(scn, root);
+ ts_free_tree(root);
+ return res;
+}
+
+static bool proc_node(Scene *scn, struct ts_node *node)
+{
+ struct ts_node *c = node->child_list;
+ while(c) {
+ if(!proc_node(scn, c)) {
+ return false;
+ }
+ c = c->next;
+ }
+
+ // do this last to allow other contents of the node to do their thing
+ if(strcmp(node->name, "scenefile") == 0) {
+ const char *fname = ts_get_attr_str(node, "file");
+ if(fname) {
+ struct ts_attr *adpath = attr_inscope(node, "datapath");
+ if(adpath && adpath->val.type == TS_STRING) {
+ printf("adding data path: %s\n", adpath->val.str);
+ datamap_set_path(adpath->val.str);
+ }
+
+ int namesz = datamap_lookup(fname, 0, 0);
+ char *namebuf = (char*)alloca(namesz + 1);
+ if(datamap_lookup(fname, namebuf, namesz + 1)) {
+ fname = namebuf;
+ }
+
+ if(!(scn->load(fname, SCNLOAD_FLIPTEX))) {
+ return false;
+ }
+ }
+ datamap_reset();
+
+ } else if(strcmp(node->name, "remap") == 0) {
+ const char *match = ts_get_attr_str(node, "match");
+ const char *replace = ts_get_attr_str(node, "replace");
+ if(match && replace) {
+ datamap_map(match, replace);
+ }
+ }
+
+ return true;
+}
+
+static struct ts_attr *attr_inscope(struct ts_node *node, const char *name)
+{
+ struct ts_attr *attr = 0;
+
+ while(node && !(attr = ts_get_attr(node, name))) {
+ node = node->parent;
+ }
+ return attr;
+}