summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2022-09-04 23:32:55 -0700
committerVito Caputo <vcaputo@pengaru.com>2022-09-04 23:44:33 -0700
commitb4c9935b5d167ca2ef69b5a6a81ae207f462b45c (patch)
treeda526ecfbd90215d70420d2dce75d5eed0adfb9b /src
parentb5a2667f6c94d5a275251bf6cc359480100a651c (diff)
modules/strobe: add rudimentary strobe light module
After reading about the Dreamachine[0], I wanted to experience this phenomenon. The javascript-based web implementations struggled to hold a steady 10Hz rate and would flicker like crazy, so here we are. Only setting right now is period=float_seconds, defaults to .1 for 10Hz. One limitation in the current implementation is when the frame rate can't keep up with the period the strobe will just stick on without ever going off, because the period will always be expired. There should probably be a setting to force turning off for at least one frame when it can't keep up. [0] https://en.wikipedia.org/wiki/Dreamachine
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/modules/Makefile.am2
-rw-r--r--src/modules/strobe/Makefile.am3
-rw-r--r--src/modules/strobe/strobe.c155
-rw-r--r--src/til.c2
5 files changed, 162 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 84fdea1..88cd43d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,7 +3,7 @@ SUBDIRS = libs modules
noinst_LTLIBRARIES = libtil.la
libtil_la_SOURCES = til_args.c til_args.h til_fb.c til_fb.h til_knobs.h til.c til.h til_module_context.c til_module_context.h til_settings.h til_settings.c til_setup.c til_setup.h til_threads.c til_threads.h til_util.c til_util.h
libtil_la_CPPFLAGS = -I@top_srcdir@/src
-libtil_la_LIBADD = modules/blinds/libblinds.la modules/checkers/libcheckers.la modules/compose/libcompose.la modules/drizzle/libdrizzle.la modules/flui2d/libflui2d.la modules/julia/libjulia.la modules/meta2d/libmeta2d.la modules/moire/libmoire.la modules/montage/libmontage.la modules/pixbounce/libpixbounce.la modules/plasma/libplasma.la modules/plato/libplato.la modules/ray/libray.la modules/roto/libroto.la modules/rtv/librtv.la modules/shapes/libshapes.la modules/snow/libsnow.la modules/sparkler/libsparkler.la modules/spiro/libspiro.la modules/stars/libstars.la modules/submit/libsubmit.la modules/swab/libswab.la modules/swarm/libswarm.la modules/voronoi/libvoronoi.la libs/grid/libgrid.la libs/puddle/libpuddle.la libs/ray/libray.la libs/sig/libsig.la libs/txt/libtxt.la libs/ascii/libascii.la libs/din/libdin.la
+libtil_la_LIBADD = modules/blinds/libblinds.la modules/checkers/libcheckers.la modules/compose/libcompose.la modules/drizzle/libdrizzle.la modules/flui2d/libflui2d.la modules/julia/libjulia.la modules/meta2d/libmeta2d.la modules/moire/libmoire.la modules/montage/libmontage.la modules/pixbounce/libpixbounce.la modules/plasma/libplasma.la modules/plato/libplato.la modules/ray/libray.la modules/roto/libroto.la modules/rtv/librtv.la modules/shapes/libshapes.la modules/snow/libsnow.la modules/sparkler/libsparkler.la modules/spiro/libspiro.la modules/stars/libstars.la modules/strobe/libstrobe.la modules/submit/libsubmit.la modules/swab/libswab.la modules/swarm/libswarm.la modules/voronoi/libvoronoi.la libs/grid/libgrid.la libs/puddle/libpuddle.la libs/ray/libray.la libs/sig/libsig.la libs/txt/libtxt.la libs/ascii/libascii.la libs/din/libdin.la
bin_PROGRAMS = rototiller
rototiller_SOURCES = fps.c fps.h main.c mem_fb.c setup.h setup.c til.h til_fb.c til_fb.h til_knobs.h til_settings.c til_settings.h til_threads.c til_threads.h til_util.c til_util.h
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
index 83adbc5..f88879e 100644
--- a/src/modules/Makefile.am
+++ b/src/modules/Makefile.am
@@ -1 +1 @@
-SUBDIRS = blinds checkers compose drizzle flui2d julia meta2d moire montage pixbounce plasma plato ray roto rtv shapes snow sparkler spiro stars submit swab swarm voronoi
+SUBDIRS = blinds checkers compose drizzle flui2d julia meta2d moire montage pixbounce plasma plato ray roto rtv shapes snow sparkler spiro stars strobe submit swab swarm voronoi
diff --git a/src/modules/strobe/Makefile.am b/src/modules/strobe/Makefile.am
new file mode 100644
index 0000000..8bac057
--- /dev/null
+++ b/src/modules/strobe/Makefile.am
@@ -0,0 +1,3 @@
+noinst_LTLIBRARIES = libstrobe.la
+libstrobe_la_SOURCES = strobe.c
+libstrobe_la_CPPFLAGS = -I@top_srcdir@/src
diff --git a/src/modules/strobe/strobe.c b/src/modules/strobe/strobe.c
new file mode 100644
index 0000000..4616df4
--- /dev/null
+++ b/src/modules/strobe/strobe.c
@@ -0,0 +1,155 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "til.h"
+#include "til_fb.h"
+#include "til_module_context.h"
+
+/* Dead-simple strobe light, initially made to try simulate this contraption:
+ * https://en.wikipedia.org/wiki/Dreamachine
+ *
+ * But it might actually have some general utility in compositing.
+ */
+
+/* Copyright (C) 2022 Vito Caputo <vcaputo@pengaru.com> */
+
+/* TODO:
+ * - Make period setting more flexible
+ * - Currently if the frame rate can't keep up with the period, strobe will
+ * just stick on. There should probably be a force_flash={yes,no} setting
+ * to ensure a flash still occurs when the frame rate can't keep up.
+ */
+
+#define STROBE_DEFAULT_PERIOD .1
+
+typedef struct strobe_setup_t {
+ til_setup_t til_setup;
+ float period;
+} strobe_setup_t;
+
+typedef struct strobe_context_t {
+ til_module_context_t til_module_context;
+ strobe_setup_t setup;
+ unsigned ticks;
+ unsigned flash:1;
+} strobe_context_t;
+
+
+static strobe_setup_t strobe_default_setup = {
+ .period = STROBE_DEFAULT_PERIOD,
+};
+
+
+static til_module_context_t * strobe_create_context(unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup)
+{
+ strobe_context_t *ctxt;
+
+ if (!setup)
+ setup = &strobe_default_setup.til_setup;
+
+ ctxt = til_module_context_new(sizeof(strobe_context_t), seed, ticks, n_cpus);
+ if (!ctxt)
+ return NULL;
+
+ ctxt->setup = *(strobe_setup_t *)setup;
+ ctxt->ticks = ticks;
+
+ return &ctxt->til_module_context;
+}
+
+
+static void strobe_prepare_frame(til_module_context_t *context, unsigned ticks, til_fb_fragment_t **fragment_ptr, til_frame_plan_t *res_frame_plan)
+{
+ strobe_context_t *ctxt = (strobe_context_t *)context;
+
+ *res_frame_plan = (til_frame_plan_t){ .fragmenter = til_fragmenter_slice_per_cpu };
+
+ if (ticks - ctxt->ticks >= (unsigned)(ctxt->setup.period * 1000.f))
+ ctxt->flash = 1;
+}
+
+
+static void strobe_render_fragment(til_module_context_t *context, unsigned ticks, unsigned cpu, til_fb_fragment_t **fragment_ptr)
+{
+ strobe_context_t *ctxt = (strobe_context_t *)context;
+ til_fb_fragment_t *fragment = *fragment_ptr;
+
+ if (!ctxt->flash)
+ return til_fb_fragment_clear(fragment);
+
+ til_fb_fragment_fill(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, 0xffffffff);
+}
+
+
+static void strobe_finish_frame(til_module_context_t *context, unsigned int ticks, til_fb_fragment_t **fragment_ptr)
+{
+ strobe_context_t *ctxt = (strobe_context_t *)context;
+
+ if (!ctxt->flash)
+ return;
+
+ ctxt->flash = 0;
+ ctxt->ticks = ticks;
+}
+
+
+static int strobe_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, til_setup_t **res_setup)
+{
+ const char *period;
+ const char *period_values[] = {
+ ".0166",
+ ".02",
+ ".025",
+ ".05",
+ ".1",
+ ".25",
+ ".5",
+ "1",
+ NULL
+ };
+ int r;
+
+ r = til_settings_get_and_describe_value(settings,
+ &(til_setting_desc_t){
+ .name = "Strobe period",
+ .key = "period",
+ .regex = "\\.[0-9]+",
+ .preferred = TIL_SETTINGS_STR(STROBE_DEFAULT_PERIOD),
+ .values = period_values,
+ .annotations = NULL
+ },
+ &period,
+ res_setting,
+ res_desc);
+ if (r)
+ return r;
+
+ if (res_setup) {
+ strobe_setup_t *setup;
+
+ setup = til_setup_new(sizeof(*setup), (void(*)(til_setup_t *))free);
+ if (!setup)
+ return -ENOMEM;
+
+ sscanf(period, "%f", &setup->period);
+
+ *res_setup = &setup->til_setup;
+ }
+
+ return 0;
+}
+
+
+til_module_t strobe_module = {
+ .create_context = strobe_create_context,
+ .prepare_frame = strobe_prepare_frame,
+ .render_fragment = strobe_render_fragment,
+ .finish_frame = strobe_finish_frame,
+ .setup = strobe_setup,
+ .name = "strobe",
+ .description = "Strobe light (threaded)",
+ .author = "Vito Caputo <vcaputo@pengaru.com>",
+ .flags = TIL_MODULE_OVERLAYABLE,
+};
diff --git a/src/til.c b/src/til.c
index 151f690..f7e3225 100644
--- a/src/til.c
+++ b/src/til.c
@@ -44,6 +44,7 @@ extern til_module_t snow_module;
extern til_module_t sparkler_module;
extern til_module_t spiro_module;
extern til_module_t stars_module;
+extern til_module_t strobe_module;
extern til_module_t submit_module;
extern til_module_t swab_module;
extern til_module_t swarm_module;
@@ -70,6 +71,7 @@ static const til_module_t *modules[] = {
&sparkler_module,
&spiro_module,
&stars_module,
+ &strobe_module,
&submit_module,
&swab_module,
&swarm_module,
© All Rights Reserved