From 6b8790a22c38e0d5419eb5a4dac5e30f684ae473 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Fri, 1 Apr 2022 17:47:19 -0700 Subject: modules/*: instantiate and use setups Now modules allocate and return an opaque setup pointer in res_setup when they implement a setup method. Defaults are utilized when ${module}_create_context() receives a NULL setup. The default setup used in this case should match the defaults/preferred values emitted by the module's setup method. But performing setup should always be optional, so a NULL setup provided to create_context() is to be expected. No cleanup of these setup instances is currently performed, so it's a small memory leak for now. Since these are opaque and may contain nested references to other allocations, simply using free() somewhere in the frontend is insufficient. There will probably need to be something like a til_module_t.setup_free() method added in the future which modules may assign libc's free() to when appropriate, or their own more elaborate version. Lifecycle for the settings is very simple; the setup method returns an instance, the caller is expected to free it when no longer needed (once free is implemented). The create_context consumer of a given setup must make its own copy of the settings if necessary, and may not keep a reference - it must assume the setup will be freed immediately after create_context() returns. This enables the ability to reuse a setup instance across multiple create_context() calls if desired, one can imagine something like running the same module with the same settings multiple times across multiple displays for instance. If the module has significant entropy the output will differ despite being configured identically... With this commit one may change settings for any of the modules *while* the modules are actively rendering a given context, and the settings should *not* be visible. They should only affect the context they're supplied to. --- src/modules/compose/compose.c | 38 ++++++---- src/modules/drizzle/drizzle.c | 38 ++++++++-- src/modules/flui2d/flui2d.c | 51 +++++++++---- src/modules/rtv/rtv.c | 159 +++++++++++++++++++++++++--------------- src/modules/sparkler/sparkler.c | 73 ++++++++++++------ src/modules/stars/stars.c | 28 ++++++- src/modules/submit/submit.c | 29 ++++++-- src/modules/swarm/swarm.c | 43 ++++++++--- 8 files changed, 319 insertions(+), 140 deletions(-) (limited to 'src/modules') diff --git a/src/modules/compose/compose.c b/src/modules/compose/compose.c index adf638c..da9215b 100644 --- a/src/modules/compose/compose.c +++ b/src/modules/compose/compose.c @@ -36,13 +36,19 @@ typedef struct compose_context_t { compose_layer_t layers[]; } compose_context_t; +typedef struct compose_setup_t { + size_t n_layers; + char *layers[]; +} compose_setup_t; + static void * compose_create_context(unsigned ticks, unsigned num_cpus, void *setup); static void compose_destroy_context(void *context); static void compose_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, til_fb_fragment_t *fragment, til_fragmenter_t *res_fragmenter); static int compose_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, void **res_setup); -static char *compose_default_layers[] = { "drizzle", "stars", "spiro", "plato", NULL }; -static char **compose_layers; +static compose_setup_t compose_default_setup = { + .layers = { "drizzle", "stars", "spiro", "plato", NULL }, +}; til_module_t compose_module = { @@ -57,14 +63,13 @@ til_module_t compose_module = { static void * compose_create_context(unsigned ticks, unsigned num_cpus, void *setup) { - char **layers = compose_default_layers; compose_context_t *ctxt; - int n; + size_t n; - if (compose_layers) - layers = compose_layers; + if (!setup) + setup = &compose_default_setup; - for (n = 0; layers[n]; n++); + for (n = 0; ((compose_setup_t *)setup)->layers[n]; n++); ctxt = calloc(1, sizeof(compose_context_t) + n * sizeof(compose_layer_t)); if (!ctxt) @@ -75,7 +80,7 @@ static void * compose_create_context(unsigned ticks, unsigned num_cpus, void *se for (int i = 0; i < n; i++) { const til_module_t *module; - module = til_lookup_module(layers[i]); + module = til_lookup_module(((compose_setup_t *)setup)->layers[i]); ctxt->layers[i].module = module; (void) til_module_create_context(module, ticks, NULL, &ctxt->layers[i].module_ctxt); @@ -127,7 +132,8 @@ static int compose_setup(const til_settings_t *settings, til_setting_t **res_set return r; /* turn layers colon-separated list into a null-terminated array of strings */ - { + if (res_setup) { + compose_setup_t *setup = NULL; const til_module_t **modules; size_t n_modules; char *toklayers, *layer; @@ -144,8 +150,8 @@ static int compose_setup(const til_settings_t *settings, til_setting_t **res_set return -EINVAL; do { - char **new; - size_t i; + compose_setup_t *new; + size_t i; /* other meta-modules like montage and rtv may need to * have some consideration here, but for now I'm just @@ -163,16 +169,18 @@ static int compose_setup(const til_settings_t *settings, til_setting_t **res_set if (i >= n_modules) return -EINVAL; - new = realloc(compose_layers, n * sizeof(*compose_layers)); + new = realloc(setup, sizeof(*setup) + n * sizeof(*setup->layers)); if (!new) return -ENOMEM; - new[n - 2] = layer; - new[n - 1] = NULL; + new->layers[n - 2] = layer; + new->layers[n - 1] = NULL; n++; - compose_layers = new; + setup = new; } while (layer = strtok(NULL, ":")); + + *res_setup = setup; } return 0; diff --git a/src/modules/drizzle/drizzle.c b/src/modules/drizzle/drizzle.c index 0a53492..d3d3c3e 100644 --- a/src/modules/drizzle/drizzle.c +++ b/src/modules/drizzle/drizzle.c @@ -14,6 +14,7 @@ * along with this program. If not, see . */ +#include #include #include @@ -26,11 +27,6 @@ #define DRIZZLE_CNT 20 #define DEFAULT_VISCOSITY .01 -typedef struct drizzle_context_t { - puddle_t *puddle; - unsigned n_cpus; -} drizzle_context_t; - typedef struct v3f_t { float x, y, z; } v3f_t; @@ -39,7 +35,19 @@ typedef struct v2f_t { float x, y; } v2f_t; -static float drizzle_viscosity = DEFAULT_VISCOSITY; +typedef struct drizzle_setup_t { + float viscosity; +} drizzle_setup_t; + +typedef struct drizzle_context_t { + puddle_t *puddle; + unsigned n_cpus; + drizzle_setup_t setup; +} drizzle_context_t; + +static drizzle_setup_t drizzle_default_setup = { + .viscosity = DEFAULT_VISCOSITY, +}; /* convert a color into a packed, 32-bit rgb pixel value (taken from libs/ray/ray_color.h) */ @@ -68,6 +76,9 @@ static void * drizzle_create_context(unsigned ticks, unsigned num_cpus, void *se { drizzle_context_t *ctxt; + if (!setup) + setup = &drizzle_default_setup; + ctxt = calloc(1, sizeof(drizzle_context_t)); if (!ctxt) return NULL; @@ -79,6 +90,7 @@ static void * drizzle_create_context(unsigned ticks, unsigned num_cpus, void *se } ctxt->n_cpus = num_cpus; + ctxt->setup = *(drizzle_setup_t *)setup; return ctxt; } @@ -121,7 +133,7 @@ static void drizzle_prepare_frame(void *context, unsigned ticks, unsigned n_cpus puddle_set(ctxt->puddle, x + 1, y + 1, 1.f); } - puddle_tick(ctxt->puddle, drizzle_viscosity); + puddle_tick(ctxt->puddle, ctxt->setup.viscosity); } @@ -180,7 +192,17 @@ static int drizzle_setup(const til_settings_t *settings, til_setting_t **res_set if (r) return r; - sscanf(viscosity, "%f", &drizzle_viscosity); + if (res_setup) { + drizzle_setup_t *setup; + + setup = calloc(1, sizeof(*setup)); + if (!setup) + return -ENOMEM; + + sscanf(viscosity, "%f", &setup->viscosity); + + *res_setup = setup; + } return 0; } diff --git a/src/modules/flui2d/flui2d.c b/src/modules/flui2d/flui2d.c index cf6024b..d5b3b72 100644 --- a/src/modules/flui2d/flui2d.c +++ b/src/modules/flui2d/flui2d.c @@ -27,10 +27,6 @@ #define IX(i, j) ((i) + (ROOT + 2) * (j)) #define SWAP(x0, x) {float *tmp = x0; x0 = x; x = tmp;} -static float flui2d_viscosity = DEFAULT_VISCOSITY; -static float flui2d_diffusion = DEFAULT_DIFFUSION; -static float flui2d_decay = DEFAULT_DECAY; - typedef struct flui2d_t { float u[SIZE], v[SIZE], u_prev[SIZE], v_prev[SIZE]; float dens[SIZE], dens_prev[SIZE]; @@ -184,18 +180,33 @@ typedef struct flui2d_context_t { float xf, yf; } flui2d_context_t; +typedef struct flui2d_setup_t { + float viscosity; + float diffusion; + float decay; +} flui2d_setup_t; + +static flui2d_setup_t flui2d_default_setup = { + .viscosity = DEFAULT_VISCOSITY, + .diffusion = DEFAULT_DIFFUSION, + .decay = DEFAULT_DECAY, +}; + static void * flui2d_create_context(unsigned ticks, unsigned num_cpus, void *setup) { flui2d_context_t *ctxt; + if (!setup) + setup = &flui2d_default_setup; + ctxt = calloc(1, sizeof(flui2d_context_t)); if (!ctxt) return NULL; - ctxt->fluid.visc = flui2d_viscosity; - ctxt->fluid.diff = flui2d_diffusion; - ctxt->fluid.decay = flui2d_decay; + ctxt->fluid.visc = ((flui2d_setup_t *)setup)->viscosity; + ctxt->fluid.diff = ((flui2d_setup_t *)setup)->diffusion; + ctxt->fluid.decay = ((flui2d_setup_t *)setup)->decay; return ctxt; } @@ -354,14 +365,26 @@ static int flui2d_setup(const til_settings_t *settings, til_setting_t **res_sett if (r) return r; - /* TODO: return -EINVAL on parse errors? */ - sscanf(viscosity, "%f", &flui2d_viscosity); - sscanf(diffusion, "%f", &flui2d_diffusion); - sscanf(decay, "%f", &flui2d_decay); + if (res_setup) { + flui2d_setup_t *setup; - /* prevent overflow in case an explicit out of range setting is supplied */ - if (flui2d_decay > 1.f || flui2d_decay < 0.f) - return -EINVAL; + setup = calloc(1, sizeof(*setup)); + if (!setup) + return -ENOMEM; + + /* TODO: return -EINVAL on parse errors? */ + sscanf(viscosity, "%f", &setup->viscosity); + sscanf(diffusion, "%f", &setup->diffusion); + sscanf(decay, "%f", &setup->decay); + + /* prevent overflow in case an explicit out of range setting is supplied */ + if (setup->decay > 1.f || setup->decay < 0.f) { + free(setup); + return -EINVAL; + } + + *res_setup = setup; + } return 0; } diff --git a/src/modules/rtv/rtv.c b/src/modules/rtv/rtv.c index b49ac37..217368c 100644 --- a/src/modules/rtv/rtv.c +++ b/src/modules/rtv/rtv.c @@ -20,6 +20,7 @@ #define RTV_DURATION_SECS 15 #define RTV_CAPTION_DURATION_SECS 5 #define RTV_CONTEXT_DURATION_SECS 60 +#define RTV_DEFAULT_SNOW_MODULE "snow" typedef struct rtv_channel_t { const til_module_t *module; @@ -38,12 +39,26 @@ typedef struct rtv_context_t { rtv_channel_t *channel, *last_channel; txt_t *caption; + unsigned duration; + unsigned context_duration; + unsigned snow_duration; + unsigned caption_duration; + rtv_channel_t snow_channel; size_t n_channels; rtv_channel_t channels[]; } rtv_context_t; +typedef struct rtv_setup_t { + unsigned duration; + unsigned context_duration; + unsigned snow_duration; + unsigned caption_duration; + char *snow_module; + char *channels[]; +} rtv_setup_t; + static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks); static void * rtv_create_context(unsigned ticks, unsigned num_cpus, void *setup); static void rtv_destroy_context(void *context); @@ -51,12 +66,14 @@ static void rtv_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, ti static void rtv_finish_frame(void *context, unsigned ticks, til_fb_fragment_t *fragment); static int rtv_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, void **res_setup); -static unsigned rtv_duration = RTV_DURATION_SECS; -static unsigned rtv_context_duration = RTV_CONTEXT_DURATION_SECS; -static unsigned rtv_snow_duration = RTV_SNOW_DURATION_SECS; -static unsigned rtv_caption_duration = RTV_CAPTION_DURATION_SECS; -static char **rtv_channels; -static char *rtv_snow_module; +static rtv_setup_t rtv_default_setup = { + .duration = RTV_DURATION_SECS, + .context_duration = RTV_CONTEXT_DURATION_SECS, + .snow_duration = RTV_SNOW_DURATION_SECS, + .caption_duration = RTV_CAPTION_DURATION_SECS, + .snow_module = RTV_DEFAULT_SNOW_MODULE, + .channels = { NULL }, /* NULL == "all" */ +}; til_module_t rtv_module = { @@ -143,7 +160,7 @@ static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks) */ if (ctxt->channel) { ctxt->channel->cumulative_time += now - ctxt->channel->last_on_time; - if (ctxt->channel->cumulative_time >= rtv_context_duration) { + if (ctxt->channel->cumulative_time >= ctxt->context_duration) { ctxt->channel->cumulative_time = 0; ctxt->channel->module_ctxt = til_module_destroy_context(ctxt->channel->module, ctxt->channel->module_ctxt); @@ -159,7 +176,7 @@ static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks) ctxt->last_channel = ctxt->channel; ctxt->channel = &ctxt->snow_channel; ctxt->caption = NULL; - ctxt->next_switch = now + rtv_snow_duration; + ctxt->next_switch = now + ctxt->snow_duration; } else { size_t i; @@ -195,8 +212,8 @@ static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks) ctxt->channel->settings = settings ? settings : strdup(""); } - ctxt->next_switch = now + rtv_duration; - ctxt->next_hide_caption = now + rtv_caption_duration; + ctxt->next_switch = now + ctxt->duration; + ctxt->next_hide_caption = now + ctxt->caption_duration; } if (!ctxt->channel->module_ctxt) @@ -206,16 +223,19 @@ static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks) } -static int rtv_should_skip_module(const rtv_context_t *ctxt, const til_module_t *module) +static int rtv_should_skip_module(const rtv_setup_t *setup, const til_module_t *module) { if (module == &rtv_module || - module == ctxt->snow_channel.module) + (setup->snow_module && !strcmp(module->name, setup->snow_module))) return 1; - if (!rtv_channels) + /* An empty channels list is a special case for representing "all", an + * empty channels setting returns -EINVAL during _setup(). + */ + if (!setup->channels[0]) return 0; - for (char **channel = rtv_channels; *channel; channel++) { + for (char * const *channel = setup->channels; *channel; channel++) { if (!strcmp(module->name, *channel)) return 0; } @@ -228,28 +248,39 @@ static void * rtv_create_context(unsigned ticks, unsigned num_cpus, void *setup) { rtv_context_t *ctxt; const til_module_t **modules; - size_t n_modules; + size_t n_modules, n_channels = 0; static til_module_t none_module = {}; + if (!setup) + setup = &rtv_default_setup; + til_get_modules(&modules, &n_modules); - ctxt = calloc(1, sizeof(rtv_context_t) + n_modules * sizeof(rtv_channel_t)); + /* how many modules are in the setup? */ + for (size_t i = 0; i < n_modules; i++) { + if (!rtv_should_skip_module(setup, modules[i])) + n_channels++; + } + + ctxt = calloc(1, sizeof(rtv_context_t) + n_channels * sizeof(rtv_channel_t)); if (!ctxt) return NULL; ctxt->n_cpus = num_cpus; + ctxt->duration = ((rtv_setup_t *)setup)->duration; + ctxt->context_duration = ((rtv_setup_t *)setup)->context_duration; + ctxt->snow_duration = ((rtv_setup_t *)setup)->snow_duration; + ctxt->caption_duration = ((rtv_setup_t *)setup)->caption_duration; ctxt->snow_channel.module = &none_module; - if (rtv_snow_module) { - ctxt->snow_channel.module = til_lookup_module(rtv_snow_module); + if (((rtv_setup_t *)setup)->snow_module) { + ctxt->snow_channel.module = til_lookup_module(((rtv_setup_t *)setup)->snow_module); (void) til_module_create_context(ctxt->snow_channel.module, ticks, NULL, &ctxt->snow_channel.module_ctxt); } for (size_t i = 0; i < n_modules; i++) { - if (rtv_should_skip_module(ctxt, modules[i])) - continue; - - ctxt->channels[ctxt->n_channels++].module = modules[i]; + if (!rtv_should_skip_module(setup, modules[i])) + ctxt->channels[ctxt->n_channels++].module = modules[i]; } setup_next_channel(ctxt, ticks); @@ -400,52 +431,64 @@ static int rtv_setup(const til_settings_t *settings, til_setting_t **res_setting if (r) return r; - /* turn channels colon-separated list into a null-terminated array of strings */ - if (strcmp(channels, "all")) { - const til_module_t **modules; - size_t n_modules; - char *tokchannels, *channel; - int n = 2; - - til_get_modules(&modules, &n_modules); + if (res_setup) { + rtv_setup_t *setup; - tokchannels = strdup(channels); - if (!tokchannels) + setup = calloc(1, sizeof(*setup) + sizeof(setup->channels[0])); + if (!setup) return -ENOMEM; - channel = strtok(tokchannels, ":"); - do { - char **new; - size_t i; + /* turn channels colon-separated list into a null-terminated array of strings */ + if (strcmp(channels, "all")) { + const til_module_t **modules; + size_t n_modules; + char *tokchannels, *channel; + int n = 2; - for (i = 0; i < n_modules; i++) { - if (!strcmp(channel, modules[i]->name)) - break; - } - - if (i >= n_modules) - return -EINVAL; + til_get_modules(&modules, &n_modules); - new = realloc(rtv_channels, n * sizeof(*rtv_channels)); - if (!new) + tokchannels = strdup(channels); + if (!tokchannels) return -ENOMEM; - new[n - 2] = channel; - new[n - 1] = NULL; - n++; + channel = strtok(tokchannels, ":"); + do { + rtv_setup_t *new; + size_t i; - rtv_channels = new; - } while (channel = strtok(NULL, ":")); - } + for (i = 0; i < n_modules; i++) { + if (!strcmp(channel, modules[i]->name)) + break; + } + + if (i >= n_modules) + return -EINVAL; + + new = realloc(setup, sizeof(*setup) + n * sizeof(setup->channels[0])); + if (!new) { + free(setup); + return -ENOMEM; + } - if (strcmp(snow_module, "none")) - rtv_snow_module = strdup(snow_module); + new->channels[n - 2] = channel; + new->channels[n - 1] = NULL; + n++; - /* TODO FIXME: parse errors */ - sscanf(duration, "%u", &rtv_duration); - sscanf(context_duration, "%u", &rtv_context_duration); - sscanf(caption_duration, "%u", &rtv_caption_duration); - sscanf(snow_duration, "%u", &rtv_snow_duration); + setup = new; + } while (channel = strtok(NULL, ":")); + } + + if (strcmp(snow_module, "none")) + setup->snow_module = strdup(snow_module); + + /* TODO FIXME: parse errors */ + sscanf(duration, "%u", &setup->duration); + sscanf(context_duration, "%u", &setup->context_duration); + sscanf(caption_duration, "%u", &setup->caption_duration); + sscanf(snow_duration, "%u", &setup->snow_duration); + + *res_setup = setup; + } return 0; } diff --git a/src/modules/sparkler/sparkler.c b/src/modules/sparkler/sparkler.c index 51184b1..272c0fd 100644 --- a/src/modules/sparkler/sparkler.c +++ b/src/modules/sparkler/sparkler.c @@ -16,20 +16,31 @@ #define INIT_PARTS 100 +typedef struct sparkler_setup_t { + unsigned show_bsp_leafs:1; + unsigned show_bsp_matches:1; + unsigned show_bsp_matches_affected_only:1; + unsigned show_bsp_leafs_min_depth; +} sparkler_setup_t; + typedef struct sparkler_context_t { - particles_t *particles; - unsigned n_cpus; + particles_t *particles; + unsigned n_cpus; + sparkler_setup_t setup; } sparkler_context_t; extern particle_ops_t simple_ops; -static particles_conf_t sparkler_conf; +static sparkler_setup_t sparkler_default_setup; static void * sparkler_create_context(unsigned ticks, unsigned num_cpus, void *setup) { static int initialized; sparkler_context_t *ctxt; + if (!setup) + setup = &sparkler_default_setup; + if (!initialized) { srand(time(NULL) + getpid()); initialized = 1; @@ -39,7 +50,14 @@ static void * sparkler_create_context(unsigned ticks, unsigned num_cpus, void *s if (!ctxt) return NULL; - ctxt->particles = particles_new(&sparkler_conf); + ctxt->setup = *(sparkler_setup_t *)setup; + + ctxt->particles = particles_new(&(particles_conf_t){ + .show_bsp_leafs = ((sparkler_setup_t *)setup)->show_bsp_leafs, + .show_bsp_matches = ((sparkler_setup_t *)setup)->show_bsp_matches, + .show_bsp_leafs_min_depth = ((sparkler_setup_t *)setup)->show_bsp_leafs_min_depth, + .show_bsp_matches_affected_only = ((sparkler_setup_t *)setup)->show_bsp_matches_affected_only, + }); if (!ctxt->particles) { free(ctxt); return NULL; @@ -74,7 +92,7 @@ static void sparkler_prepare_frame(void *context, unsigned ticks, unsigned ncpus *res_fragmenter = sparkler_fragmenter; ctxt->n_cpus = ncpus; - if (sparkler_conf.show_bsp_matches) + if (ctxt->setup.show_bsp_matches) til_fb_fragment_zero(fragment); particles_sim(ctxt->particles, fragment); @@ -88,7 +106,7 @@ static void sparkler_render_fragment(void *context, unsigned ticks, unsigned cpu { sparkler_context_t *ctxt = context; - if (!sparkler_conf.show_bsp_matches) + if (!ctxt->setup.show_bsp_matches) til_fb_fragment_zero(fragment); particles_draw(ctxt->particles, fragment); @@ -99,7 +117,9 @@ static void sparkler_render_fragment(void *context, unsigned ticks, unsigned cpu static int sparkler_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, void **res_setup) { const char *show_bsp_leafs; + const char *show_bsp_leafs_min_depth; const char *show_bsp_matches; + const char *show_bsp_matches_affected_only; const char *values[] = { "off", "on", @@ -131,9 +151,6 @@ static int sparkler_setup(const til_settings_t *settings, til_setting_t **res_se "10", NULL }; - const char *show_bsp_leafs_min_depth; - - sparkler_conf.show_bsp_leafs = 1; r = til_settings_get_and_describe_value(settings, &(til_setting_desc_t){ @@ -147,10 +164,6 @@ static int sparkler_setup(const til_settings_t *settings, til_setting_t **res_se res_desc); if (r) return r; - - sscanf(show_bsp_leafs_min_depth, "%u", &sparkler_conf.show_bsp_leafs_min_depth); - } else { - sparkler_conf.show_bsp_leafs = 0; } r = til_settings_get_and_describe_value(settings, @@ -166,14 +179,7 @@ static int sparkler_setup(const til_settings_t *settings, til_setting_t **res_se if (r) return r; - if (!strcasecmp(show_bsp_matches, "on")) - sparkler_conf.show_bsp_matches = 1; - else - sparkler_conf.show_bsp_matches = 0; - if (!strcasecmp(show_bsp_matches, "on")) { - const char *show_bsp_matches_affected_only; - r = til_settings_get_and_describe_value(settings, &(til_setting_desc_t){ .name = "Show only narrow-phase affected match results", @@ -187,10 +193,29 @@ static int sparkler_setup(const til_settings_t *settings, til_setting_t **res_se if (r) return r; - if (!strcasecmp(show_bsp_matches_affected_only, "on")) - sparkler_conf.show_bsp_matches_affected_only = 1; - else - sparkler_conf.show_bsp_matches_affected_only = 0; + } + + if (res_setup) { + sparkler_setup_t *setup; + + setup = calloc(1, sizeof(*setup)); + if (!setup) + return -ENOMEM; + + if (!strcasecmp(show_bsp_leafs, "on")) { + setup->show_bsp_leafs = 1; + + sscanf(show_bsp_leafs_min_depth, "%u", &setup->show_bsp_leafs_min_depth); + } + + if (!strcasecmp(show_bsp_matches, "on")) { + setup->show_bsp_matches = 1; + + if (!strcasecmp(show_bsp_matches_affected_only, "on")) + setup->show_bsp_matches_affected_only = 1; + } + + *res_setup = setup; } return 0; diff --git a/src/modules/stars/stars.c b/src/modules/stars/stars.c index 055a495..288057f 100644 --- a/src/modules/stars/stars.c +++ b/src/modules/stars/stars.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -17,8 +18,6 @@ #define DEFAULT_ROT_ADJ .00003 -static float stars_rot_adj = DEFAULT_ROT_ADJ; - struct points { float x, y, z; @@ -35,6 +34,14 @@ typedef struct stars_context_t { float offset_angle; } stars_context_t; +typedef struct stars_setup_t { + float rot_adj; +} stars_setup_t; + +static stars_setup_t stars_default_setup = { + .rot_adj = DEFAULT_ROT_ADJ, +}; + float get_random_unit_coord() { return (((float)rand()/(float)RAND_MAX)*2.0)-1.0; @@ -47,12 +54,15 @@ static void * stars_create_context(unsigned ticks, unsigned num_cpus, void *setu float z; struct points* p_ptr = NULL; + if (!setup) + setup = &stars_default_setup; + ctxt = malloc(sizeof(stars_context_t)); if (!ctxt) return NULL; ctxt->points = NULL; - ctxt->rot_adj = stars_rot_adj; + ctxt->rot_adj = ((stars_setup_t *)setup)->rot_adj; ctxt->rot_rate = 0.00; ctxt->rot_angle = 0; ctxt->offset_x = 0.5; @@ -230,7 +240,17 @@ int stars_setup(const til_settings_t *settings, til_setting_t **res_setting, con if (r) return r; - sscanf(rot_adj, "%f", &stars_rot_adj); + if (res_setup) { + stars_setup_t *setup; + + setup = calloc(1, sizeof(*setup)); + if (!setup) + return -ENOMEM; + + sscanf(rot_adj, "%f", &setup->rot_adj); + + *res_setup = setup; + } return 0; } diff --git a/src/modules/submit/submit.c b/src/modules/submit/submit.c index a2dea77..e1f6008 100644 --- a/src/modules/submit/submit.c +++ b/src/modules/submit/submit.c @@ -53,12 +53,15 @@ typedef struct submit_context_t { grid_player_t *players[NUM_PLAYERS]; uint32_t seq; uint32_t game_winner; + unsigned bilerp:1; uint8_t cells[GRID_SIZE * GRID_SIZE]; } submit_context_t; +typedef struct submit_setup_t { + unsigned bilerp:1; +} submit_setup_t; -static int bilerp_setting; - +static submit_setup_t submit_default_setup; /* convert a color into a packed, 32-bit rgb pixel value (taken from libs/ray/ray_color.h) */ static inline uint32_t color_to_uint32(color_t color) { @@ -265,10 +268,14 @@ static void * submit_create_context(unsigned ticks, unsigned num_cpus, void *set { submit_context_t *ctxt; + if (!setup) + setup = &submit_default_setup; + ctxt = calloc(1, sizeof(submit_context_t)); if (!ctxt) return NULL; + ctxt->bilerp = ((submit_setup_t *)setup)->bilerp; setup_grid(ctxt); return ctxt; @@ -315,7 +322,7 @@ static void submit_render_fragment(void *context, unsigned ticks, unsigned cpu, { submit_context_t *ctxt = context; - if (!bilerp_setting) + if (!ctxt->bilerp) draw_grid(ctxt, fragment); else draw_grid_bilerp(ctxt, fragment); @@ -347,10 +354,18 @@ static int submit_setup(const til_settings_t *settings, til_setting_t **res_sett if (r) return r; - if (!strcasecmp(bilerp, "on")) - bilerp_setting = 1; - else - bilerp_setting = 0; + if (res_setup) { + submit_setup_t *setup; + + setup = calloc(1, sizeof(*setup)); + if (!setup) + return -ENOMEM; + + if (!strcasecmp(bilerp, "on")) + setup->bilerp = 1; + + *res_setup = setup; + } return 0; } diff --git a/src/modules/swarm/swarm.c b/src/modules/swarm/swarm.c index ffaaa1d..a41e388 100644 --- a/src/modules/swarm/swarm.c +++ b/src/modules/swarm/swarm.c @@ -20,6 +20,7 @@ * https://en.wikipedia.org/wiki/Swarm_intelligence */ +#include #include #include #include @@ -27,11 +28,6 @@ #include "til.h" #include "til_fb.h" -typedef enum swarm_draw_style_t { - SWARM_DRAW_STYLE_POINTS, /* simple opaque pixel per particle */ - SWARM_DRAW_STYLE_LINES, /* simple opaque lines per particle, oriented and sized by direction and velocity */ -} swarm_draw_style_t; - typedef struct v3f_t { float x, y, z; } v3f_t; @@ -46,9 +42,19 @@ typedef struct boid_t { float velocity; } boid_t; +typedef enum swarm_draw_style_t { + SWARM_DRAW_STYLE_POINTS, /* simple opaque pixel per particle */ + SWARM_DRAW_STYLE_LINES, /* simple opaque lines per particle, oriented and sized by direction and velocity */ +} swarm_draw_style_t; + +typedef struct swarm_setup_t { + swarm_draw_style_t draw_style; +} swarm_setup_t; + typedef struct swarm_context_t { v3f_t color; float ztweak; + swarm_setup_t setup; boid_t boids[]; } swarm_context_t; @@ -56,7 +62,9 @@ typedef struct swarm_context_t { #define SWARM_ZCONST 4.f #define SWARM_DEFAULT_STYLE SWARM_DRAW_STYLE_LINES -static swarm_draw_style_t swarm_draw_style = SWARM_DEFAULT_STYLE; +static swarm_setup_t swarm_default_setup = { + .draw_style = SWARM_DEFAULT_STYLE, +}; static inline float randf(float min, float max) @@ -174,10 +182,15 @@ static void * swarm_create_context(unsigned ticks, unsigned num_cpus, void *setu { swarm_context_t *ctxt; + if (!setup) + setup = &swarm_default_setup; + ctxt = calloc(1, sizeof(swarm_context_t) + sizeof(*(ctxt->boids)) * SWARM_SIZE); if (!ctxt) return NULL; + ctxt->setup = *(swarm_setup_t *)setup; + for (unsigned i = 0; i < SWARM_SIZE; i++) boid_randomize(&ctxt->boids[i]); @@ -399,7 +412,7 @@ static void swarm_render_fragment(void *context, unsigned ticks, unsigned cpu, t til_fb_fragment_zero(fragment); - switch (swarm_draw_style) { + switch (ctxt->setup.draw_style) { case SWARM_DRAW_STYLE_POINTS: return swarm_draw_as_points(ctxt, fragment); case SWARM_DRAW_STYLE_LINES: @@ -432,9 +445,19 @@ static int swarm_setup(const til_settings_t *settings, til_setting_t **res_setti if (r) return r; - for (int i = 0; styles[i]; i++) { - if (!strcmp(styles[i], style)) - swarm_draw_style = i; + if (res_setup) { + swarm_setup_t *setup; + + setup = calloc(1, sizeof(*setup)); + if (!setup) + return -ENOMEM; + + for (int i = 0; styles[i]; i++) { + if (!strcmp(styles[i], style)) + setup->draw_style = i; + } + + *res_setup = setup; } return 0; -- cgit v1.2.3