summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2020-01-26 18:02:54 -0800
committerVito Caputo <vcaputo@pengaru.com>2020-01-26 18:02:54 -0800
commitf07b311173e1231f6c0c85a47d6068de7aa00761 (patch)
tree08dbd7cf930602921e0d2504147701c82c3c4146
parent827f6626b672c817df23728742b0d76f215ca09e (diff)
knobs: add experimental rudimentary knobs API
This is intended for modules to expose bindings for floats affecting rendering output that may be varied at runtime frame-to-frame. See the comment in knobs.h for more information. This commit only introduces the concept, no modules utilize it yet.
-rw-r--r--src/Makefile.am2
-rw-r--r--src/knobs.h91
-rw-r--r--src/rototiller.h2
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;
© All Rights Reserved