demosystem tracks
authorJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 29 Dec 2021 18:04:47 +0000 (20:04 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 29 Dec 2021 18:04:47 +0000 (20:04 +0200)
src/android/main.c
src/darray.c [new file with mode: 0644]
src/darray.h [new file with mode: 0644]
src/demo.c
src/demosys.c
src/demosys.h
src/scr/testa.c
src/scr/testb.c

index dd9a2cf..88d7fb5 100644 (file)
@@ -42,6 +42,8 @@ void android_main(struct android_app *app_ptr)
 
        start_logger();
 
+       printf("Running %d bit version\n", (int)sizeof(void*) << 3);
+
        for(;;) {
                int num_events;
                struct android_poll_source *pollsrc;
diff --git a/src/darray.c b/src/darray.c
new file mode 100644 (file)
index 0000000..5abbf66
--- /dev/null
@@ -0,0 +1,121 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "darray.h"
+#include "util.h"
+
+/* The array descriptor keeps auxilliary information needed to manipulate
+ * the dynamic array. It's allocated adjacent to the array buffer.
+ */
+struct arrdesc {
+       int nelem, szelem;
+       int max_elem;
+       int bufsz;      /* not including the descriptor */
+};
+
+#define DESC(x)                ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc)))
+
+void *darr_alloc(int elem, int szelem)
+{
+       struct arrdesc *desc;
+
+       desc = malloc_nf(elem * szelem + sizeof *desc);
+       desc->nelem = desc->max_elem = elem;
+       desc->szelem = szelem;
+       desc->bufsz = elem * szelem;
+       return (char*)desc + sizeof *desc;
+}
+
+void darr_free(void *da)
+{
+       if(da) {
+               free(DESC(da));
+       }
+}
+
+void *darr_resize_impl(void *da, int elem)
+{
+       int newsz;
+       struct arrdesc *desc;
+
+       if(!da) return 0;
+       desc = DESC(da);
+
+       newsz = desc->szelem * elem;
+       desc = realloc_nf(desc, newsz + sizeof *desc);
+
+       desc->nelem = desc->max_elem = elem;
+       desc->bufsz = newsz;
+       return (char*)desc + sizeof *desc;
+}
+
+int darr_empty(void *da)
+{
+       return DESC(da)->nelem ? 0 : 1;
+}
+
+int darr_size(void *da)
+{
+       return DESC(da)->nelem;
+}
+
+
+void *darr_clear_impl(void *da)
+{
+       return darr_resize_impl(da, 0);
+}
+
+/* stack semantics */
+void *darr_push_impl(void *da, void *item)
+{
+       struct arrdesc *desc;
+       int nelem;
+
+       desc = DESC(da);
+       nelem = desc->nelem;
+
+       if(nelem >= desc->max_elem) {
+               /* need to resize */
+               int newsz = desc->max_elem ? desc->max_elem * 2 : 1;
+
+               da = darr_resize_impl(da, newsz);
+               desc = DESC(da);
+               desc->nelem = nelem;
+       }
+
+       if(item) {
+               memcpy((char*)da + desc->nelem * desc->szelem, item, desc->szelem);
+       }
+       desc->nelem++;
+       return da;
+}
+
+void *darr_pop_impl(void *da)
+{
+       struct arrdesc *desc;
+       int nelem;
+
+       desc = DESC(da);
+       nelem = desc->nelem;
+
+       if(!nelem) return da;
+
+       if(nelem <= desc->max_elem / 3) {
+               /* reclaim space */
+               int newsz = desc->max_elem / 2;
+
+               da = darr_resize_impl(da, newsz);
+               desc = DESC(da);
+               desc->nelem = nelem;
+       }
+       desc->nelem--;
+
+       return da;
+}
+
+void *darr_finalize(void *da)
+{
+       struct arrdesc *desc = DESC(da);
+       memmove(desc, da, desc->bufsz);
+       return desc;
+}
diff --git a/src/darray.h b/src/darray.h
new file mode 100644 (file)
index 0000000..154672c
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef DYNAMIC_ARRAY_H_
+#define DYNAMIC_ARRAY_H_
+
+void *darr_alloc(int elem, int szelem);
+void darr_free(void *da);
+void *darr_resize_impl(void *da, int elem);
+#define darr_resize(da, elem)  do { (da) = darr_resize_impl(da, elem); } while(0)
+
+int darr_empty(void *da);
+int darr_size(void *da);
+
+void *darr_clear_impl(void *da);
+#define darr_clear(da)                 do { (da) = darr_clear_impl(da); } while(0)
+
+/* stack semantics */
+void *darr_push_impl(void *da, void *item);
+#define darr_push(da, item)            do { (da) = darr_push_impl(da, item); } while(0)
+#define darr_pushi(da, val)            do { int v = val; (da) = darr_push_impl(da, &v); } while(0)
+#define darr_pushf(da, val)            do { float v = val; (da) = darr_push_impl(da, &v); } while(0)
+void *darr_pop_impl(void *da);
+#define darr_pop(da)                   do { (da) = darr_pop_impl(da); } while(0)
+
+/* Finalize the array. No more resizing is possible after this call.
+ * Use free() instead of dynarr_free() to deallocate a finalized array.
+ * Returns pointer to the finalized array.
+ * Complexity: O(n)
+ */
+void *darr_finalize(void *da);
+
+/* utility macros to push characters to a string. assumes and maintains
+ * the invariant that the last element is always a zero
+ */
+#define darr_strpush(da, c) \
+       do { \
+               char cnull = 0, ch = (char)(c); \
+               (da) = dynarr_pop_impl(da); \
+               (da) = dynarr_push_impl((da), &ch); \
+               (da) = dynarr_push_impl((da), &cnull); \
+       } while(0)
+
+#define darr_strpop(da) \
+       do { \
+               char cnull = 0; \
+               (da) = dynarr_pop_impl(da); \
+               (da) = dynarr_pop_impl(da); \
+               (da) = dynarr_push_impl((da), &cnull); \
+       } while(0)
+
+
+#endif /* DYNAMIC_ARRAY_H_ */
index 77c33d2..cebac7c 100644 (file)
@@ -60,9 +60,9 @@ void demo_reshape(int x, int y)
 
        glViewport(0, 0, x, y);
 
-       for(i=0; i<dsys_num_screens; i++) {
-               if(dsys_screens[i]->reshape) {
-                       dsys_screens[i]->reshape(x, y);
+       for(i=0; i<dsys.num_screens; i++) {
+               if(dsys.screens[i]->reshape) {
+                       dsys.screens[i]->reshape(x, y);
                }
        }
 }
@@ -73,7 +73,7 @@ void demo_keyboard(int key, int pressed)
 
        switch(key) {
        case ' ':
-               if(dsys_running) {
+               if(dsys.running) {
                        dsys_stop();
                } else {
                        dsys_run();
@@ -90,14 +90,14 @@ void demo_keyboard(int key, int pressed)
 
                } else if(key >= KEY_F1 && key <= KEY_F12) {
                        int idx = key - KEY_F1;
-                       if(idx < dsys_num_screens) {
-                               dsys_run_screen(dsys_screens[idx]);
+                       if(idx < dsys.num_screens) {
+                               dsys_run_screen(dsys.screens[idx]);
                        }
 
                } else {
                        int i;
-                       for(i=0; i<dsys_num_act; i++) {
-                               struct demoscreen *scr = dsys_act[i];
+                       for(i=0; i<dsys.num_act; i++) {
+                               struct demoscreen *scr = dsys.act[i];
                                if(scr->keyboard) scr->keyboard(key, pressed);
                        }
                }
@@ -107,8 +107,8 @@ void demo_keyboard(int key, int pressed)
 void demo_mouse(int bn, int pressed, int x, int y)
 {
        int i;
-       for(i=0; i<dsys_num_act; i++) {
-               struct demoscreen *scr = dsys_act[i];
+       for(i=0; i<dsys.num_act; i++) {
+               struct demoscreen *scr = dsys.act[i];
                if(scr->mouse) scr->mouse(bn, pressed, x, y);
        }
 }
@@ -116,8 +116,8 @@ void demo_mouse(int bn, int pressed, int x, int y)
 void demo_motion(int x, int y)
 {
        int i;
-       for(i=0; i<dsys_num_act; i++) {
-               struct demoscreen *scr = dsys_act[i];
+       for(i=0; i<dsys.num_act; i++) {
+               struct demoscreen *scr = dsys.act[i];
                if(scr->motion) scr->motion(x, y);
        }
 }
index 7ef4478..42ae20b 100644 (file)
@@ -4,11 +4,14 @@
 #include "demosys.h"
 #include "treestore.h"
 #include "assfile.h"
+#include "rbtree.h"
+#include "darray.h"
 
 void regscr_testa(void);
 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);
 
 
@@ -19,18 +22,25 @@ int dsys_init(const char *fname)
        struct ts_node *ts, *tsnode;
        struct demoscreen *scr;
 
+       memset(&dsys, 0, sizeof dsys);
+       if(!(dsys.trackmap = rb_create(RB_KEY_STRING))) {
+               return -1;
+       }
+       dsys.track = darr_alloc(0, sizeof *dsys.track);
+       dsys.value = darr_alloc(0, sizeof *dsys.value);
+
        regscr_testa();
        regscr_testb();
 
-       for(i=0; i<dsys_num_screens; i++) {
-               if(dsys_screens[i]->init() == -1) {
-                       fprintf(stderr, "failed to initialize demo screen: %s\n", dsys_screens[i]->name);
+       for(i=0; i<dsys.num_screens; i++) {
+               if(dsys.screens[i]->init() == -1) {
+                       fprintf(stderr, "failed to initialize demo screen: %s\n", dsys.screens[i]->name);
                        return -1;
                }
        }
 
        if(!fname || !(io.data = ass_fopen(fname, "rb"))) {
-               dsys_run_screen(dsys_screens[0]);
+               dsys_run_screen(dsys.screens[0]);
                return 0;
        }
        io.read = io_read;
@@ -46,6 +56,9 @@ int dsys_init(const char *fname)
                if(strcmp(tsnode->name, "screen") == 0 &&
                                (scr = dsys_find_screen(ts_get_attr_str(tsnode, "name", 0)))) {
                        proc_screen_script(scr, tsnode);
+
+               } else if(strcmp(tsnode->name, "track") == 0) {
+                       proc_track(tsnode, "");
                }
                tsnode = tsnode->next;
        }
@@ -56,6 +69,7 @@ int dsys_init(const char *fname)
 
 static void proc_screen_script(struct demoscreen *scr, struct ts_node *node)
 {
+       struct ts_node *sub;
        struct ts_attr *attr;
        long tm;
 
@@ -66,6 +80,19 @@ static void proc_screen_script(struct demoscreen *scr, struct ts_node *node)
                }
                attr = attr->next;
        }
+
+       sub = node->child_list;
+       while(sub) {
+               if(strcmp(sub->name, "track") == 0) {
+                       proc_track(sub, node->name);
+               }
+               sub = sub->next;
+       }
+}
+
+static void proc_track(struct ts_node *node, const char *pname)
+{
+       char *name, *fullname;
 }
 
 static long io_read(void *buf, size_t bytes, void *uptr)
@@ -78,13 +105,17 @@ void dsys_destroy(void)
 {
        int i;
 
-       for(i=0; i<dsys_num_screens; i++) {
-               anm_destroy_track(&dsys_screens[i]->track);
-               if(dsys_screens[i]->destroy) {
-                       dsys_screens[i]->destroy();
+       for(i=0; i<dsys.num_screens; i++) {
+               anm_destroy_track(&dsys.screens[i]->track);
+               if(dsys.screens[i]->destroy) {
+                       dsys.screens[i]->destroy();
                }
        }
-       dsys_num_screens = 0;
+       dsys.num_screens = 0;
+
+       darr_free(dsys.track);
+       darr_free(dsys.value);
+       rb_free(dsys.trackmap);
 }
 
 void dsys_update(void)
@@ -92,24 +123,24 @@ void dsys_update(void)
        int i, j, sort_needed = 0;
        struct demoscreen *scr;
 
-       dsys_time = time_msec;
+       dsys.tmsec = time_msec;
 
-       dsys_num_act = 0;
-       for(i=0; i<dsys_num_screens; i++) {
-               scr = dsys_screens[i];
-               scr->vis = anm_get_value(&scr->track, dsys_time);
+       dsys.num_act = 0;
+       for(i=0; i<dsys.num_screens; i++) {
+               scr = dsys.screens[i];
+               scr->vis = anm_get_value(&scr->track, dsys.tmsec);
 
                if(scr->vis > 0.0f) {
                        if(!scr->active) {
                                if(scr->start) scr->start();
                                scr->active = 1;
                        }
-                       if(scr->update) scr->update(dsys_time);
+                       if(scr->update) scr->update(dsys.tmsec);
 
-                       if(dsys_num_act && scr->prio != dsys_act[dsys_num_act - 1]->prio) {
+                       if(dsys.num_act && scr->prio != dsys.act[dsys.num_act - 1]->prio) {
                                sort_needed = 1;
                        }
-                       dsys_act[dsys_num_act++] = scr;
+                       dsys.act[dsys.num_act++] = scr;
                } else {
                        if(scr->active) {
                                if(scr->stop) scr->stop();
@@ -119,24 +150,29 @@ void dsys_update(void)
        }
 
        if(sort_needed) {
-               for(i=0; i<dsys_num_act; i++) {
-                       for(j=i+1; j<dsys_num_act; j++) {
-                               if(dsys_act[j]->prio > dsys_act[j - 1]->prio) {
-                                       void *tmp = dsys_act[j];
-                                       dsys_act[j] = dsys_act[j - 1];
-                                       dsys_act[j - 1] = tmp;
+               for(i=0; i<dsys.num_act; i++) {
+                       for(j=i+1; j<dsys.num_act; j++) {
+                               if(dsys.act[j]->prio > dsys.act[j - 1]->prio) {
+                                       void *tmp = dsys.act[j];
+                                       dsys.act[j] = dsys.act[j - 1];
+                                       dsys.act[j - 1] = tmp;
                                }
                        }
                }
        }
+
+       /* 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;
-       for(i=0; i<dsys_num_act; i++) {
-               dsys_act[i]->draw();
+       for(i=0; i<dsys.num_act; i++) {
+               dsys.act[i]->draw();
        }
 }
 
@@ -167,9 +203,9 @@ struct demoscreen *dsys_find_screen(const char *name)
 
        if(!name) return 0;
 
-       for(i=0; i<dsys_num_screens; i++) {
-               if(strcmp(dsys_screens[i]->name, name) == 0) {
-                       return dsys_screens[i];
+       for(i=0; i<dsys.num_screens; i++) {
+               if(strcmp(dsys.screens[i]->name, name) == 0) {
+                       return dsys.screens[i];
                }
        }
        return 0;
@@ -180,15 +216,15 @@ void dsys_run_screen(struct demoscreen *scr)
        int i;
 
        if(!scr) return;
-       if(dsys_num_act == 1 && dsys_act[0] == scr) return;
+       if(dsys.num_act == 1 && dsys.act[0] == scr) return;
 
-       for(i=0; i<dsys_num_act; i++) {
-               if(dsys_act[i]->stop) dsys_act[i]->stop();
-               dsys_act[i]->active = 0;
+       for(i=0; i<dsys.num_act; i++) {
+               if(dsys.act[i]->stop) dsys.act[i]->stop();
+               dsys.act[i]->active = 0;
        }
 
-       dsys_act[0] = scr;
-       dsys_num_act = 1;
+       dsys.act[0] = scr;
+       dsys.num_act = 1;
 
        if(scr->start) scr->start();
        scr->active = 1;
@@ -209,6 +245,41 @@ int dsys_add_screen(struct demoscreen *scr)
        anm_set_track_extrapolator(&scr->track, ANM_EXTRAP_CLAMP);
        anm_set_track_default(&scr->track, 0);
 
-       dsys_screens[dsys_num_screens++] = scr;
+       dsys.screens[dsys.num_screens++] = scr;
+       return 0;
+}
+
+int dsys_add_track(const char *name)
+{
+       struct anm_track trk;
+       int idx;
+
+       if(rb_find(dsys.trackmap, (char*)name)) {
+               fprintf(stderr, "ignoring duplicate track: %s\n", name);
+               return -1;
+       }
+
+       idx = darr_size(dsys.track);
+       darr_push(dsys.track, &trk);
+       darr_pushf(dsys.value, 0);
+
+       if(rb_insert(dsys.trackmap, (char*)name, (void*)(intptr_t)idx) == -1) {
+               fprintf(stderr, "failed to insert to track map: %s\n", name);
+               abort();
+       }
        return 0;
 }
+
+int dsys_find_track(const char *name)
+{
+       struct rbnode *n = rb_find(dsys.trackmap, (char*)name);
+       if(!n) return -1;
+
+       return (intptr_t)n->data;
+}
+
+float dsys_value(const char *name)
+{
+       int idx = dsys_find_track(name);
+       return idx == -1 ? 0.0f : dsys.value[idx];
+}
index abbc154..ab829be 100644 (file)
@@ -25,16 +25,24 @@ struct demoscreen {
        float vis;
 };
 
-/* global demo state */
-int dsys_running;      /* run/stop state */
-int dsys_eof;          /* end of demo flag, seek back to reset */
-long dsys_time;                /* demo time in milliseconds */
-
 #define MAX_DSYS_SCREENS       64
-struct demoscreen *dsys_screens[MAX_DSYS_SCREENS];
-int dsys_num_screens;
-struct demoscreen *dsys_act[MAX_DSYS_SCREENS];
-int dsys_num_act;
+struct demosystem {
+       int running;                    /* run/stop state */
+       int eof;                                /* end of demo flag, seek back to reset */
+       long tmsec;
+
+       struct demoscreen *screens[MAX_DSYS_SCREENS];
+       int num_screens;
+       struct demoscreen *act[MAX_DSYS_SCREENS];
+       int num_act;
+
+       void *trackmap;
+       struct anm_track *track;
+       float *value;                           /* values for each track, stored on update */
+       int num_tracks;
+};
+
+struct demosystem dsys;
 
 
 int dsys_init(const char *fname);
@@ -55,4 +63,10 @@ void dsys_run_screen(struct demoscreen *scr);
 
 int dsys_add_screen(struct demoscreen *scr);
 
+/* demo event tracks */
+int dsys_add_track(const char *name);
+int dsys_find_track(const char *name);
+
+float dsys_value(const char *name);
+
 #endif /* DEMOSYS_H_ */
index 561d8e3..5bf2e62 100644 (file)
@@ -30,7 +30,7 @@ static void destroy(void)
 static void draw(void)
 {
        int i;
-       float t = dsys_time / 1000.0f;
+       float t = dsys.tmsec / 1000.0f;
        float gap = cgm_lerp(0, 0.01, scr.vis);
 
        glUseProgram(sdr_foo);
index fb08f87..a9be6a4 100644 (file)
@@ -34,7 +34,7 @@ static void draw(void)
 {
        int i, j;
        float x, y, xr, yr, sz;
-       float t = dsys_time / 700.0f;
+       float t = dsys.tmsec / 700.0f;
 
        glUseProgram(sdr_foo);
        gl_begin(GL_QUADS);