aboutsummaryrefslogtreecommitdiff
path: root/src/effects
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-09-20 23:57:19 +0200
committerFederico Angelilli <code@fedang.net>2024-09-20 23:57:19 +0200
commitae59c294bfd4b73f6e751a3103c2ee7501068492 (patch)
treeefbcded195dfd24f9534f69f47f728ecca34b762 /src/effects
parentbc70dead7fb518f073fecb21a04fa374e9ad6dd0 (diff)
Start parsing effects
Diffstat (limited to 'src/effects')
-rw-r--r--src/effects/pulse.c91
-rw-r--r--src/effects/scheme.c8
-rw-r--r--src/effects/scheme.h22
3 files changed, 121 insertions, 0 deletions
diff --git a/src/effects/pulse.c b/src/effects/pulse.c
new file mode 100644
index 0000000..c2a324a
--- /dev/null
+++ b/src/effects/pulse.c
@@ -0,0 +1,91 @@
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "scheme.h"
+
+#include "../any_log.h"
+
+typedef struct {
+ effect_t effect;
+ double amplitude;
+} effect_pulse_t;
+
+double cubic_bezier(double x, double a, double b, double c, double d)
+{
+ const double t = 1 - x;
+ return a * (t * t * t) + 3 * b * (t * t * x) + 3 * c * (t * x * x) + d * (x * x * x);
+}
+
+static void effect_pulse_pre(effect_t *effect, layout_t *layout, cairo_t *cr)
+{
+ struct timespec now;
+ timespec_get(&now, TIME_UTC);
+
+ // After half the duration we invert direction
+ struct timespec midpoint = timespec_div(effect->info->duration, 2);
+ struct timespec diff = timespec_diff(now, effect->start);
+
+ double t = timespec_greater(midpoint, diff)
+ ? (double)timespec_to_ms(diff) / timespec_to_ms(midpoint)
+ : 1.0 - (double)timespec_to_ms(timespec_diff(diff, midpoint)) / timespec_to_ms(midpoint);
+
+ // Make it customizable
+ double s = cubic_bezier(t, 0.19, 1.0, 0.22, 1.0);
+
+ const double amplitude = ((effect_pulse_t *)effect)->amplitude;
+
+ // FIXME: The intent was to scale the animation for long blocks, but it needs more love
+ //
+ int x_max = amplitude * (layout->height + (layout->width / (double)layout->height) - 1);
+ int y_max = amplitude * layout->height;
+
+ layout->x_padding = layout->block->x_padding + x_max * s;
+ layout->y_padding = layout->block->y_padding + y_max * s;
+}
+
+static effect_t *effect_pulse_allocate(const effect_info_t *info)
+{
+ effect_pulse_t *effect = calloc(1, sizeof(effect_pulse_t));
+ assert(effect != NULL);
+ effect->amplitude = *(unsigned int *)info->state / 100.0;
+ return (effect_t *)effect;
+}
+
+static void effect_pulse_finalize(effect_t *effect)
+{
+ free(effect);
+}
+
+static bool effect_pulse_validate(effect_info_t *info, const effect_scheme_t *scheme)
+{
+ unsigned int amplitude = *(unsigned int *)info->state;
+ if (amplitude > 100) {
+ log_error("Effect '%s' pulse amplitude must not exceed 100", info->label);
+ return false;
+ }
+
+ return true;
+}
+
+static const config_entry_t effect_pulse_entries[] = {
+ { "amplitude", CONFIG_UINT, NULL, 0 },
+ { 0 },
+};
+
+const effect_scheme_t effect_pulse_scheme = {
+ .name = "pulse",
+ .info = {
+ .duration = {
+ .tv_sec = 0,
+ .tv_nsec = 200000000,
+ },
+ .allocate = effect_pulse_allocate,
+ .finalize = effect_pulse_finalize,
+ .pre = effect_pulse_pre,
+ },
+ .size = sizeof(unsigned int),
+ .entries = effect_pulse_entries,
+ .validate = effect_pulse_validate,
+};
diff --git a/src/effects/scheme.c b/src/effects/scheme.c
new file mode 100644
index 0000000..0d70dec
--- /dev/null
+++ b/src/effects/scheme.c
@@ -0,0 +1,8 @@
+#include "scheme.h"
+
+extern const effect_scheme_t effect_pulse_scheme;
+
+const effect_scheme_t *effect_schemes[] = {
+ &effect_pulse_scheme,
+ NULL
+};
diff --git a/src/effects/scheme.h b/src/effects/scheme.h
new file mode 100644
index 0000000..6026b12
--- /dev/null
+++ b/src/effects/scheme.h
@@ -0,0 +1,22 @@
+#ifndef COMET_EFFECTS_SCHEME_H
+#define COMET_EFFECTS_SCHEME_H
+
+#include "../effect.h"
+#include "../config.h"
+#include "../layout.h"
+
+typedef struct effect_scheme effect_scheme_t;
+
+typedef bool (*effect_validate_t)(effect_info_t *info, const effect_scheme_t *scheme);
+
+struct effect_scheme {
+ const char *name;
+ effect_info_t info;
+ size_t size;
+ const config_entry_t *entries;
+ effect_validate_t validate;
+};
+
+extern const effect_scheme_t *effect_schemes[];
+
+#endif