diff options
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/knobs.h | 91 | ||||
-rw-r--r-- | src/rototiller.h | 2 |
3 files changed, 93 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2dda6d5..cd7acf1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ SUBDIRS = libs modules bin_PROGRAMS = rototiller -rototiller_SOURCES = fb.c fb.h fps.c fps.h rototiller.c rototiller.h sdl_fb.c settings.h settings.c setup.h setup.c threads.c threads.h util.c util.h +rototiller_SOURCES = fb.c fb.h fps.c fps.h knobs.h rototiller.c rototiller.h sdl_fb.c settings.h settings.c setup.h setup.c threads.c threads.h util.c util.h if ENABLE_DRM rototiller_SOURCES += drm_fb.c endif diff --git a/src/knobs.h b/src/knobs.h new file mode 100644 index 0000000..25c13eb --- /dev/null +++ b/src/knobs.h @@ -0,0 +1,91 @@ +#ifndef _KNOBS_H +#define _KNOBS_H + +#include <assert.h> + +/* A knob exposes a binding for some float in a module's context + * which can be varied at runtime between frames to influence + * the output. There's some overlap with settings, but settings + * are more intended for configuration applied at context + * creation, which won't vary frame-to-frame, but may influence + * the initial value and/or automatic behavior of knobs for + * instance, or even which knobs are available. + * + * At this time knobs will only apply to floats, accompanied by + * some rudimentary bounds. + * + * Integer types would probably be useful, and maybe a precision + * specifier, those can be added in the future as needed, but I'd + * like to keep it simple for now and see what kind of problems + * emerge. + * + * The current expectation is that a module context struct will + * incorporate an array of knobs, replacing loose floats already + * being automatically varied within the module frame-to-frame. + * + * The module will then use the knob_auto_* helpers below to + * access and manipulate the values, instead of directly + * accessing the loose floats as before. + * + * External manipulators of the knobs will use the knob_* + * helpers, instead of the knob_auto_* helpers, to + * access+manipulate the knobs. These helpers are basically just + * to get external and internal manipulators to agree on which + * side owns control via the managed field. + */ +typedef struct knob_t { + const char *name; /* Short API-oriented name */ + const char *desc; /* Longer UI-oriented name */ + const float min, max; /* Value bounds */ + float value; /* Value knob affects */ + unsigned managed:1; /* Set when knob control of value is active, + * suppress automagic control of value when set. + */ +} knob_t; + + +/* helper for modules automating knob controls, use this to + * change values intead of direct manipulation to respect active. + * returns new (or unchanged) value + */ +static inline float knob_auto_set(knob_t *knob, float value) +{ + assert(knob); + + if (knob->managed) + return knob->value; + + return knob->value = value; +} + +/* identical to knob_auto_set, except adds to existing value. + */ +static inline float knob_auto_add(knob_t *knob, float value) +{ + assert(knob); + + return knob_auto_set(knob, knob->value + value); +} + + +/* identical to knob_auto* variants, except intended for + * external knob-twisters, i.e. the "managed" knob entrypoints. + */ +static inline float knob_set(knob_t *knob, float value) +{ + assert(knob); + + knob->managed = 1; + + return knob->value = value; +} + + +static inline float knob_add(knob_t *knob, float value) +{ + assert(knob); + + return knob_set(knob, knob->value + value); +} + +#endif diff --git a/src/rototiller.h b/src/rototiller.h index e13a29a..e185624 100644 --- a/src/rototiller.h +++ b/src/rototiller.h @@ -18,7 +18,7 @@ typedef struct rototiller_module_t { void (*render_fragment)(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment); void (*finish_frame)(void *context, unsigned ticks, fb_fragment_t *fragment); int (*setup)(const settings_t *settings, setting_desc_t **next_setting); - knob_t *(*knobs)(void *context); /* when present, returns NULL-terminated array knobs for the supplied context, not to be freed - likely context-resident. */ + size_t (*knobs)(void *context, knob_t **res_knobs); char *name; char *description; char *author; |