screen override
[andemo] / src / demosys.c
index 42ae20b..06aa8c2 100644 (file)
@@ -13,6 +13,7 @@ void regscr_testb(void);
 static void proc_screen_script(struct demoscreen *scr, struct ts_node *node);
 static void proc_track(struct ts_node *node, const char *pname);
 static long io_read(void *buf, size_t bytes, void *uptr);
+static void del_rbnode(struct rbnode *node, void *cls);
 
 
 int dsys_init(const char *fname)
@@ -26,6 +27,8 @@ int dsys_init(const char *fname)
        if(!(dsys.trackmap = rb_create(RB_KEY_STRING))) {
                return -1;
        }
+       rb_set_delete_func(dsys.trackmap, del_rbnode, 0);
+
        dsys.track = darr_alloc(0, sizeof *dsys.track);
        dsys.value = darr_alloc(0, sizeof *dsys.value);
 
@@ -58,7 +61,7 @@ int dsys_init(const char *fname)
                        proc_screen_script(scr, tsnode);
 
                } else if(strcmp(tsnode->name, "track") == 0) {
-                       proc_track(tsnode, "");
+                       proc_track(tsnode, 0);
                }
                tsnode = tsnode->next;
        }
@@ -84,7 +87,7 @@ static void proc_screen_script(struct demoscreen *scr, struct ts_node *node)
        sub = node->child_list;
        while(sub) {
                if(strcmp(sub->name, "track") == 0) {
-                       proc_track(sub, node->name);
+                       proc_track(sub, scr->name);
                }
                sub = sub->next;
        }
@@ -92,7 +95,33 @@ static void proc_screen_script(struct demoscreen *scr, struct ts_node *node)
 
 static void proc_track(struct ts_node *node, const char *pname)
 {
-       char *name, *fullname;
+       char *name, *buf;
+       struct ts_attr *attr;
+       long tm;
+       int tidx;
+       struct anm_track *trk;
+
+       if(!(name = (char*)ts_get_attr_str(node, "name", 0))) {
+               return;
+       }
+       if(pname) {
+               buf = alloca(strlen(name) + strlen(pname) + 2);
+               sprintf(buf, "%s.%s", pname, name);
+               name = buf;
+       }
+
+       if((tidx = dsys_add_track(name)) == -1) {
+               return;
+       }
+       trk = dsys.track + tidx;
+
+       attr = node->attr_list;
+       while(attr) {
+               if(sscanf(attr->name, "key_%ld", &tm) == 1 && attr->val.type == TS_NUMBER) {
+                       anm_set_value(trk, tm, attr->val.fnum);
+               }
+               attr = attr->next;
+       }
 }
 
 static long io_read(void *buf, size_t bytes, void *uptr)
@@ -125,6 +154,18 @@ void dsys_update(void)
 
        dsys.tmsec = time_msec;
 
+       /* evaluate tracks */
+       for(i=0; i<dsys.num_tracks; i++) {
+               dsys.value[i] = anm_get_value(dsys.track + i, dsys.tmsec);
+       }
+
+       if(dsys.scr_override) {
+               scr = dsys.scr_override;
+               scr->vis = 1;
+               if(scr->update) scr->update(dsys.tmsec);
+               return;
+       }
+
        dsys.num_act = 0;
        for(i=0; i<dsys.num_screens; i++) {
                scr = dsys.screens[i];
@@ -160,17 +201,18 @@ void dsys_update(void)
                        }
                }
        }
-
-       /* evaluate tracks */
-       for(i=0; i<dsys.num_tracks; i++) {
-               dsys.value[i] = anm_get_value(dsys.track + i, dsys.tmsec);
-       }
 }
 
 /* TODO: do something about draw ordering of the active screens */
 void dsys_draw(void)
 {
        int i;
+
+       if(dsys.scr_override) {
+               dsys.scr_override->draw();
+               return;
+       }
+
        for(i=0; i<dsys.num_act; i++) {
                dsys.act[i]->draw();
        }
@@ -215,16 +257,22 @@ void dsys_run_screen(struct demoscreen *scr)
 {
        int i;
 
-       if(!scr) return;
-       if(dsys.num_act == 1 && dsys.act[0] == scr) return;
+       if(!scr) {
+               if(dsys.scr_override) {
+                       scr = dsys.scr_override;
+                       if(scr->stop) scr->stop();
+               }
+               dsys.scr_override = 0;
+               return;
+       }
 
        for(i=0; i<dsys.num_act; i++) {
                if(dsys.act[i]->stop) dsys.act[i]->stop();
                dsys.act[i]->active = 0;
        }
+       dsys.num_act = 0;
 
-       dsys.act[0] = scr;
-       dsys.num_act = 1;
+       dsys.scr_override = scr;
 
        if(scr->start) scr->start();
        scr->active = 1;
@@ -263,11 +311,14 @@ int dsys_add_track(const char *name)
        darr_push(dsys.track, &trk);
        darr_pushf(dsys.value, 0);
 
-       if(rb_insert(dsys.trackmap, (char*)name, (void*)(intptr_t)idx) == -1) {
+       anm_init_track(dsys.track + idx);
+
+       if(rb_insert(dsys.trackmap, (char*)strdup_nf(name), (void*)(intptr_t)idx) == -1) {
                fprintf(stderr, "failed to insert to track map: %s\n", name);
                abort();
        }
-       return 0;
+       dsys.num_tracks = idx + 1;
+       return idx;
 }
 
 int dsys_find_track(const char *name)
@@ -283,3 +334,8 @@ float dsys_value(const char *name)
        int idx = dsys_find_track(name);
        return idx == -1 ? 0.0f : dsys.value[idx];
 }
+
+static void del_rbnode(struct rbnode *node, void *cls)
+{
+       free(node->key);
+}