aboutsummaryrefslogtreecommitdiff
path: root/src/effects
diff options
context:
space:
mode:
Diffstat (limited to 'src/effects')
-rw-r--r--src/effects/pulse.c75
-rw-r--r--src/effects/scheme.c8
-rw-r--r--src/effects/scheme.h23
3 files changed, 106 insertions, 0 deletions
diff --git a/src/effects/pulse.c b/src/effects/pulse.c
new file mode 100644
index 0000000..9e012e1
--- /dev/null
+++ b/src/effects/pulse.c
@@ -0,0 +1,75 @@
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "scheme.h"
+
+#include "../any_log.h"
+
+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->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);
+
+ // Make it a parameter
+ const double amplitude = *(unsigned int *)effect->state / 100.0;
+
+ // 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 void effect_pulse_finalize(effect_t *effect)
+{
+ free(effect->state);
+}
+
+static bool effect_pulse_validate(effect_t *effect, const effect_scheme_t *scheme)
+{
+ unsigned int amplitude = *(unsigned int *)effect->state;
+ if (amplitude > 100) {
+ log_error("Effect '%s' pulse amplitude must not exceed 100", effect->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",
+ .effect = {
+ .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..28ad69c
--- /dev/null
+++ b/src/effects/scheme.h
@@ -0,0 +1,23 @@
+#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_t *effect, const effect_scheme_t *scheme);
+
+struct effect_scheme {
+ const char *name;
+ effect_t effect;
+ size_t size;
+ const config_entry_t *entries;
+ effect_validate_t validate;
+};
+
+extern const effect_scheme_t *effect_schemes[];
+
+#endif
+