diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/modules/Makefile.am | 2 | ||||
-rw-r--r-- | src/modules/strobe/Makefile.am | 3 | ||||
-rw-r--r-- | src/modules/strobe/strobe.c | 155 | ||||
-rw-r--r-- | src/til.c | 2 |
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, +}; @@ -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, |