start_logger();
+ printf("Running %d bit version\n", (int)sizeof(void*) << 3);
+
for(;;) {
int num_events;
struct android_poll_source *pollsrc;
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
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);
}
}
}
switch(key) {
case ' ':
- if(dsys_running) {
+ if(dsys.running) {
dsys_stop();
} else {
dsys_run();
} 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);
}
}
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);
}
}
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);
}
}
#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);
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;
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;
}
static void proc_screen_script(struct demoscreen *scr, struct ts_node *node)
{
+ struct ts_node *sub;
struct ts_attr *attr;
long tm;
}
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)
{
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)
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();
}
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();
}
}
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;
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;
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];
+}
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);
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_ */
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);
{
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);