diff --git a/README.md b/README.md index 7a15fdd7..cd6fddc4 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,13 @@ [st:broken]: https://img.shields.io/badge/broken-X-black.png?style=flat&colorA=e05d44&colorB=494e52 [st:experimental]: https://img.shields.io/badge/experimental----black.png?style=flat&colorA=dfb317&colorB=494e52 -A haunting effect, where the lights follow your fingers as you keep typing. -Always behind, always watching, always stalking the fingertips... - -The plugin simply lights up the LED below keys you press, and fades them away -soon after, producing a haunting trail effect. +The `StalkerEffect` plugin provides an interesting new typing experience: the +LEDs light up as you tap keys, and play one of the selected effects: a haunting +trail of ghostly white lights, or a blazing trail of fire. ## Using the plugin -To use the plugin, one needs to include the header, and activate the effect. It -is also possible to use a custom color instead of the white-ish default. +To use the plugin, one needs to include the header, and select the effect. ```c++ #include @@ -23,6 +20,7 @@ is also possible to use a custom color instead of the white-ish default. void setup () { Keyboardio.setup (KEYMAP_SIZE); + StalkerEffect.configure (STALKER (Haunt, {0xff, 0, 0})); Keyboardio.use (&StalkerEffect, NULL); StalkerEffect.configure ({0x00, 0xff, 0xff}); @@ -31,13 +29,37 @@ void setup () { It is recommended to place the activation of the plugin (the `Keyboardio.use` call) as early as possible, so the plugin can catch all relevant key presses. +The configuration can happen at any time, but using the `STALKER` macro is +highly recommended. ## Plugin methods The plugin provides the `StalkerEffect` object, which has the following method: -### `.configure(color)` +### `.configure(effect)` + +> Set the effect to use with the plugin. See below for a list. +> +> It is recommended to use the `STALKER` macro to declare the effect itself. + +## Plugin helpers + +### `STALKER(effect, params...)` + +> Returns an effect, to be used by the `.configure` method of the +> `StalkerEffect` object. Any arguments given to the macro, are also passed on +> to the effect. If the effect takes no arguments, use `NULL`. + +## Plugin effects + +The plugin provides the following effects: + +### `Haunt([color])` + +> A ghostly haunt effect, that trails the key taps with a ghostly white color +> (or any other color, if specified). + +### `BlazingTrail()` -> Set the color to use for highlighting pressed keys. If unset, will use the -> default white-ish color. +> A blazing trail of fire will follow our fingers! diff --git a/src/Akela/LED-Stalker.cpp b/src/Akela/LED-Stalker.cpp index 847dc2a1..c62d52eb 100644 --- a/src/Akela/LED-Stalker.cpp +++ b/src/Akela/LED-Stalker.cpp @@ -20,24 +20,24 @@ namespace Akela { namespace LEDEffects { - cRGB StalkerEffect::highlightColor = (cRGB) {64, 128, 128}; uint8_t StalkerEffect::map[ROWS][COLS]; + StalkerEffect::ColorComputer *StalkerEffect::colorComputer; StalkerEffect::StalkerEffect (void) { } void - StalkerEffect::begin (void) { - event_handler_hook_add (eventHandlerHook); - loop_hook_add (loopHook); + StalkerEffect::configure (ColorComputer *colorComputer_) { + colorComputer = colorComputer_; } void - StalkerEffect::configure (const cRGB highlightColor_) { - highlightColor = highlightColor_; + StalkerEffect::begin (void) { + event_handler_hook_add (eventHandlerHook); + loop_hook_add (loopHook); } - Key + Key StalkerEffect::eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState) { if (row >= ROWS || col >= COLS) return mappedKey; @@ -53,18 +53,13 @@ namespace Akela { if (postClear) return; - float mb = highlightColor.b / 255.0; - float mg = highlightColor.g / 255.0; - float mr = highlightColor.r / 255.0; + if (!colorComputer) + return; for (byte r = 0; r < ROWS; r++) { for (byte c = 0; c < COLS; c++) { - cRGB color = {(uint8_t)min(map[r][c] * mb, 255), - (uint8_t)min(map[r][c] * mg, 255), - (uint8_t)min(map[r][c] * mr, 255)}; - if (map[r][c]) - led_set_crgb_at (r, c, color); + led_set_crgb_at (r, c, colorComputer->compute (map[r][c])); if (map[r][c] >= 0xf0) map[r][c]--; @@ -78,6 +73,50 @@ namespace Akela { } } + namespace Stalker { + + // Haunt + float Haunt::mb; + float Haunt::mg; + float Haunt::mr; + + Haunt::Haunt (const cRGB highlightColor) { + mb = highlightColor.b / 255.0; + mg = highlightColor.g / 255.0; + mr = highlightColor.r / 255.0; + } + + cRGB + Haunt::compute (uint8_t step) { + cRGB color = {(uint8_t)min(step * mb, 255), + (uint8_t)min(step * mg, 255), + (uint8_t)min(step * mr, 255)}; + + return color; + } + + // BlazingTrail + BlazingTrail::BlazingTrail (...) { + } + + cRGB + BlazingTrail::compute (uint8_t step) { + cRGB color; + + color.b = 0; + color.r = step; + + if (step >= 0xf0) { + } else if (step >= 0x80) { + color.g = 0xa0 - step / 2; + } else + color.g = step; + + return color; + } + + }; + }; }; diff --git a/src/Akela/LED-Stalker.h b/src/Akela/LED-Stalker.h index 60a6debe..75fc3137 100644 --- a/src/Akela/LED-Stalker.h +++ b/src/Akela/LED-Stalker.h @@ -18,22 +18,53 @@ #include +#define STALKER(n, ...) (({static Akela::LEDEffects::Stalker::n _effect (__VA_ARGS__); &_effect;})) + namespace Akela { namespace LEDEffects { class StalkerEffect : public KeyboardioPlugin { public: + class ColorComputer { + public: + virtual cRGB compute (uint8_t step) = 0; + }; + StalkerEffect (void); - static void configure (const cRGB highlightColor); virtual void begin (void) final; + static void configure (ColorComputer *colorComputer); private: - static cRGB highlightColor; + static ColorComputer *colorComputer; static uint8_t map[ROWS][COLS]; static Key eventHandlerHook (Key mappedKey, byte row, byte col, uint8_t keyState); static void loopHook (bool postClear); }; + + namespace Stalker { + + class Haunt : public StalkerEffect::ColorComputer { + public: + Haunt (const cRGB highlightColor); + Haunt (void) : Haunt ({0x40, 0x80, 0x80}) {}; + Haunt (void *) : Haunt () {}; + + virtual cRGB compute (uint8_t step) final; + + private: + static float mr, mg, mb; + }; + + class BlazingTrail : public StalkerEffect::ColorComputer { + public: + BlazingTrail (...); + + virtual cRGB compute (uint8_t step) final; + }; + + }; + }; };