From 9b30c8adb9ae6f562f3ef1c8b3b5ab57824b9ba3 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Wed, 29 Dec 2021 20:04:47 +0200 Subject: [PATCH] demosystem tracks --- src/android/main.c | 2 + src/darray.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ src/darray.h | 50 +++++++++++++++++++ src/demo.c | 24 ++++----- src/demosys.c | 141 +++++++++++++++++++++++++++++++++++++++------------- src/demosys.h | 32 ++++++++---- src/scr/testa.c | 2 +- src/scr/testb.c | 2 +- 8 files changed, 316 insertions(+), 58 deletions(-) create mode 100644 src/darray.c create mode 100644 src/darray.h diff --git a/src/android/main.c b/src/android/main.c index dd9a2cf..88d7fb5 100644 --- a/src/android/main.c +++ b/src/android/main.c @@ -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 index 0000000..5abbf66 --- /dev/null +++ b/src/darray.c @@ -0,0 +1,121 @@ +#include +#include +#include +#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 index 0000000..154672c --- /dev/null +++ b/src/darray.h @@ -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_ */ diff --git a/src/demo.c b/src/demo.c index 77c33d2..cebac7c 100644 --- a/src/demo.c +++ b/src/demo.c @@ -60,9 +60,9 @@ void demo_reshape(int x, int y) glViewport(0, 0, x, y); - for(i=0; ireshape) { - dsys_screens[i]->reshape(x, y); + for(i=0; ireshape) { + 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; ikeyboard) 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; imouse) 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; imotion) scr->motion(x, y); } } diff --git a/src/demosys.c b/src/demosys.c index 7ef4478..42ae20b 100644 --- a/src/demosys.c +++ b/src/demosys.c @@ -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; iinit() == -1) { - fprintf(stderr, "failed to initialize demo screen: %s\n", dsys_screens[i]->name); + for(i=0; iinit() == -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; itrack); - if(dsys_screens[i]->destroy) { - dsys_screens[i]->destroy(); + for(i=0; itrack); + 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; ivis = anm_get_value(&scr->track, dsys_time); + dsys.num_act = 0; + for(i=0; ivis = 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; iprio > 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; iprio > 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; idraw(); + for(i=0; idraw(); } } @@ -167,9 +203,9 @@ struct demoscreen *dsys_find_screen(const char *name) if(!name) return 0; - for(i=0; iname, name) == 0) { - return dsys_screens[i]; + for(i=0; iname, 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; istop) dsys_act[i]->stop(); - dsys_act[i]->active = 0; + for(i=0; istop) 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]; +} diff --git a/src/demosys.h b/src/demosys.h index abbc154..ab829be 100644 --- a/src/demosys.h +++ b/src/demosys.h @@ -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_ */ diff --git a/src/scr/testa.c b/src/scr/testa.c index 561d8e3..5bf2e62 100644 --- a/src/scr/testa.c +++ b/src/scr/testa.c @@ -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); diff --git a/src/scr/testb.c b/src/scr/testb.c index fb08f87..a9be6a4 100644 --- a/src/scr/testb.c +++ b/src/scr/testb.c @@ -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); -- 1.7.10.4