Early working version of wavepool effect... is buggy.

pull/510/head
Selene Scriven 7 years ago
parent f402fb2ead
commit b0f6e350d3

@ -1,15 +1,15 @@
# Kaleidoscope-LED-Stalker # Kaleidoscope-LED-Wavepool
![status][st:experimental] [![Build Status][travis:image]][travis:status] ![status][st:experimental] [![Build Status][travis:image]][travis:status]
[travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker.svg?branch=master [travis:image]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Wavepool.svg?branch=master
[travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Stalker [travis:status]: https://travis-ci.org/keyboardio/Kaleidoscope-LED-Wavepool
[st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52 [st:stable]: https://img.shields.io/badge/stable-✔-black.svg?style=flat&colorA=44cc11&colorB=494e52
[st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52 [st:broken]: https://img.shields.io/badge/broken-X-black.svg?style=flat&colorA=e05d44&colorB=494e52
[st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52 [st:experimental]: https://img.shields.io/badge/experimental----black.svg?style=flat&colorA=dfb317&colorB=494e52
The `StalkerEffect` plugin provides an interesting new typing experience: the The `WavepoolEffect` plugin provides an interesting new typing experience: the
LEDs light up as you tap keys and play one of the selected effects: a haunting 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. trail of ghostly white lights, or a blazing trail of fire.
@ -19,32 +19,32 @@ To use the plugin, one needs to include the header and select the effect.
```c++ ```c++
#include <Kaleidoscope.h> #include <Kaleidoscope.h>
#include <Kaleidoscope-LED-Stalker.h> #include <Kaleidoscope-LED-Wavepool.h>
void setup (){ void setup (){
Kaleidoscope.use(&StalkerEffect); Kaleidoscope.use(&WavepoolEffect);
Kaleidoscope.setup(); Kaleidoscope.setup();
StalkerEffect.variant = STALKER(Haunt, (CRGB(0, 128, 0))); WavepoolEffect.variant = WAVEPOOL(Haunt, (CRGB(0, 128, 0)));
StalkerEffect.activate(); WavepoolEffect.activate();
} }
``` ```
It is recommended to place the activation of the plugin (the `USE_PLUGINS` call) It is recommended to place the activation of the plugin (the `USE_PLUGINS` call)
as early as possible, so the plugin can catch all relevant key presses. The as early as possible, so the plugin can catch all relevant key presses. The
configuration can happen at any time and should use the `STALKER` macro to do so. configuration can happen at any time and should use the `WAVEPOOL` macro to do so.
## Plugin methods ## Plugin methods
The plugin provides the `StalkerEffect` object, which has the following The plugin provides the `WavepoolEffect` object, which has the following
properties: properties:
### `.variant` ### `.variant`
> Set the effect to use with the plugin. See below for a list. > 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. > It is recommended to use the `WAVEPOOL` macro to declare the effect itself.
### `.stepLength` ### `.stepLength`
@ -55,10 +55,10 @@ properties:
## Plugin helpers ## Plugin helpers
### `STALKER(effect, params)` ### `WAVEPOOL(effect, params)`
> Returns an effect, to be used to assign a value the `.variant` property of the > Returns an effect, to be used to assign a value the `.variant` property of the
> `StalkerEffect` object. Any arguments given to the macro are passed on > `WavepoolEffect` object. Any arguments given to the macro are passed on
> to the effect. If the effect takes no arguments, use an empty `params` list. > to the effect. If the effect takes no arguments, use an empty `params` list.
## Plugin effects ## Plugin effects
@ -84,4 +84,4 @@ The plugin provides the following effects:
Starting from the [example][plugin:example] is the recommended way of getting Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin. started with the plugin.
[plugin:example]: https://github.com/keyboardio/Kaleidoscope-LED-Stalker/blob/master/examples/LED-Stalker/LED-Stalker.ino [plugin:example]: https://github.com/keyboardio/Kaleidoscope-LED-Wavepool/blob/master/examples/LED-Wavepool/LED-Wavepool.ino

@ -1,6 +1,6 @@
/* -*- mode: c++ -*- /* -*- mode: c++ -*-
* Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Kaleidoscope-LED-Wavepool
* Copyright (C) 2017 Gergely Nagy * Copyright (C) 2017 Selene Scriven
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -17,7 +17,7 @@
*/ */
#include <Kaleidoscope.h> #include <Kaleidoscope.h>
#include <Kaleidoscope-LED-Stalker.h> #include <Kaleidoscope-LED-Wavepool.h>
#include "LED-Off.h" #include "LED-Off.h"
const Key keymaps[][ROWS][COLS] PROGMEM = { const Key keymaps[][ROWS][COLS] PROGMEM = {
@ -41,12 +41,12 @@ const Key keymaps[][ROWS][COLS] PROGMEM = {
}; };
void setup() { void setup() {
Kaleidoscope.use(&LEDOff, &StalkerEffect); Kaleidoscope.use(&LEDOff, &WavepoolEffect);
Kaleidoscope.setup(); Kaleidoscope.setup();
StalkerEffect.variant = STALKER(BlazingTrail); WavepoolEffect.variant = WAVEPOOL(BlazingTrail);
StalkerEffect.activate(); WavepoolEffect.activate();
} }
void loop() { void loop() {

@ -1,10 +1,10 @@
name=Kaleidoscope-LED-Stalker name=Kaleidoscope-LED-Wavepool
version=0.0.0 version=0.0.0
author=Gergely Nagy author=Gergely Nagy
maintainer=Gergely Nagy <akela@gergo.csillger.hu> maintainer=Gergely Nagy <akela@gergo.csillger.hu>
sentence=Stalk keys pressed by lighting up and fading back the LED under them. sentence=Splash water on each keypress.
paragraph=Stalk keys pressed by lighting up and fading back the LED under them. paragraph=Splash water on each keypress.
category=Communication category=Communication
url=https://github.com/keyboardio/Kaleidoscope-LED-Stalker url=https://github.com/keyboardio/Kaleidoscope-LED-Wavepool
architectures=avr architectures=avr
dot_a_linkage=true dot_a_linkage=true

@ -1,6 +1,6 @@
/* -*- mode: c++ -*- /* -*- mode: c++ -*-
* Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Kaleidoscope-LED-Wavepool
* Copyright (C) 2017 Gergely Nagy * Copyright (C) 2017 Selene Scriven
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,4 +18,4 @@
#pragma once #pragma once
#include <Kaleidoscope/LED-Stalker.h> #include <Kaleidoscope/LED-Wavepool.h>

@ -1,140 +0,0 @@
/* -*- mode: c++ -*-
* Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them
* Copyright (C) 2017 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope-LED-Stalker.h>
#include <LEDUtils.h>
namespace kaleidoscope {
uint8_t StalkerEffect::map_[ROWS][COLS];
StalkerEffect::ColorComputer *StalkerEffect::variant;
uint16_t StalkerEffect::step_length = 50;
uint32_t StalkerEffect::step_end_time_;
StalkerEffect::StalkerEffect(void) {
}
void StalkerEffect::begin(void) {
event_handler_hook_use(eventHandlerHook);
LEDMode::begin();
}
void StalkerEffect::init(void) {
memset(map_, 0, sizeof(map_));
}
Key StalkerEffect::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state) {
if (row >= ROWS || col >= COLS)
return mapped_key;
if (keyIsPressed(key_state)) {
map_[row][col] = 0xff;
}
return mapped_key;
}
void StalkerEffect::update(void) {
if (!variant)
return;
bool time_out = millis() >= step_end_time_;
for (byte r = 0; r < ROWS; r++) {
for (byte c = 0; c < COLS; c++) {
uint8_t step = map_[r][c];
if (step) {
LEDControl.setCrgbAt(r, c, variant->compute(&step));
}
bool was_zero = (map_[r][c] == 0);
if (time_out) {
map_[r][c] = step;
}
if (!was_zero && !map_[r][c])
LEDControl.setCrgbAt(r, c, (cRGB) {
0, 0, 0
});
}
}
if (time_out)
step_end_time_ = millis() + step_length;
}
namespace stalker {
cRGB Haunt::highlight_color_;
// Haunt
Haunt::Haunt(const cRGB highlight_color) {
highlight_color_ = highlight_color;
}
cRGB Haunt::compute(uint8_t *step) {
cRGB color = CRGB((uint8_t)min(*step * highlight_color_.r / 255, 255),
(uint8_t)min(*step * highlight_color_.g / 255, 255),
(uint8_t)min(*step * highlight_color_.b / 255, 255));
if (*step >= 0xf0)
*step -= 1;
else if (*step >= 0x40)
*step -= 16;
else if (*step >= 32)
*step -= 32;
else
*step = 0;
return color;
}
// BlazingTrail
BlazingTrail::BlazingTrail(void) {
}
cRGB BlazingTrail::compute(uint8_t *step) {
cRGB color;
if (*step >= 0xff - 30) {
color = hsvToRgb(0xff - *step, 255, 255);
} else {
color = hsvToRgb(30, 255, 255);
color.r = min(*step * color.r / 255, 255);
color.g = min(*step * color.g / 255, 255);
}
if (*step >= 0xf0 - 30)
*step -= 1;
else if (*step >= 0x40)
*step -= 16;
else if (*step >= 32)
*step -= 32;
else
*step = 0;
return color;
}
}
}
kaleidoscope::StalkerEffect StalkerEffect;

@ -0,0 +1,287 @@
/* -*- mode: c++ -*-
* Kaleidoscope-LED-Wavepool
* Copyright (C) 2017 Selene Scriven
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope-LED-Wavepool.h>
#include <LEDUtils.h>
namespace kaleidoscope {
int8_t WavepoolEffect::map_[2][WP_WID*WP_HGT];
uint8_t WavepoolEffect::page = 0;
WavepoolEffect::ColorComputer *WavepoolEffect::variant;
uint16_t WavepoolEffect::step_length = 50;
uint32_t WavepoolEffect::step_end_time_;
uint8_t WavepoolEffect::frames_since_event = 0;
uint8_t WavepoolEffect::positions[WP_HGT*WP_WID] = {
0, 1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 64, 64, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 22, 25, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 37, 40, 58, 59, 60, 61, 62, 63,
64, 64, 7, 23, 39, 55, 54, 57, 56, 40, 24, 8, 64, 64,
};
uint8_t WavepoolEffect::rc2pos[ROWS*COLS] = {
0, 1, 2, 3, 4, 5, 6, 58, 67, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 34, 59, 66, 35, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 48, 60, 65, 49, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 62,61,63,64, 50, 51, 52, 53, 54, 55,
};
WavepoolEffect::WavepoolEffect(void) {
}
void WavepoolEffect::begin(void) {
event_handler_hook_use(eventHandlerHook);
LEDMode::begin();
}
void WavepoolEffect::init(void) {
memset(map_, 0, sizeof(map_));
}
Key WavepoolEffect::eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state) {
if (row >= ROWS || col >= COLS)
return mapped_key;
if (keyIsPressed(key_state)) {
uint8_t offset = (row*COLS)+col;
map_[page][rc2pos[offset]] = 0x7f;
frames_since_event = 0;
}
return mapped_key;
}
void WavepoolEffect::update(void) {
// limit the frame rate; one frame every 64 ms
static uint8_t prev_time = 0;
uint8_t now = (millis()>>6) % 0xff;
if (now != prev_time) {
prev_time = now;
} else {
return;
}
// rotate the colors over time
// (side note: it's weird that this is a 16-bit int instead of 8-bit,
// but that's what the library function wants)
//static uint16_t current_hue = 0;
//current_hue ++;
//current_hue &= 0xff;
static uint8_t current_hue = 0;
current_hue ++;
frames_since_event ++;
// needs two pages of height map to do the calculations
int8_t *newpg = &map_[page^1][0];
int8_t *oldpg = &map_[page][0];
// rain a bit while idle
if ((frames_since_event & 0x1f) == 0x1f) {
uint8_t x = rand() % WP_WID;
uint8_t y = rand() % WP_HGT;
uint8_t rainspot = (y*WP_WID) + x;
oldpg[rainspot] = 0x7f;
if (y > 0) oldpg[rainspot-WP_WID] = 0x50;
if (y < (WP_HGT-1)) oldpg[rainspot+WP_WID] = 0x50;
if (x > 0) oldpg[rainspot-1] = 0x50;
if (x < (WP_WID-1)) oldpg[rainspot+1] = 0x50;
}
// calculate water movement
//for (uint8_t y = 1; y < WP_HGT-1; y++) {
// for (uint8_t x = 1; x < WP_WID-1; x++) {
for (uint8_t y = 0; y < WP_HGT; y++) {
for (uint8_t x = 0; x < WP_WID; x++) {
uint8_t offset = (y*WP_WID) + x;
/*
int8_t value;
int8_t offsets[] = { -WP_WID, WP_WID, -1, 1, };
if (y==0) offsets[0] = 0;
else if (y==WP_HGT-1) offsets[1] = 0;
if (x==0) offsets[2] = 0;
else if (x==WP_WID-1) offsets[3] = 0;
value = ((oldpg[offset + offsets[0]]
+oldpg[offset + offsets[1]]
+oldpg[offset + offsets[2]]
+oldpg[offset + offsets[3]]
) >> 1)
- newpg[offset];
*/
int16_t value;
int8_t offsets[] = { -WP_WID, WP_WID, -1, 1,
-WP_WID-1, -WP_WID+1,
WP_WID-1, WP_WID+1
};
if (y==0) {
offsets[0] = 0;
offsets[4] = 0;
offsets[5] = 0;
}
else if (y==WP_HGT-1) {
offsets[1] = 0;
offsets[6] = 0;
offsets[7] = 0;
}
if (x==0) {
offsets[2] = 0;
offsets[4] = 0;
offsets[6] = 0;
}
else if (x==WP_WID-1) {
offsets[3] = 0;
offsets[5] = 0;
offsets[7] = 0;
}
value = ((oldpg[offset + offsets[0]]
+oldpg[offset + offsets[1]]
+oldpg[offset + offsets[2]]
+oldpg[offset + offsets[3]]
+oldpg[offset + offsets[4]]
+oldpg[offset + offsets[5]]
+oldpg[offset + offsets[6]]
+oldpg[offset + offsets[7]]
) >> 2)
- newpg[offset];
//value = oldpg[offset];
//if (value > 0) value --;
//oldpg[offset] = value;
//newpg[offset] = value;
newpg[offset] = value - (value >> 3);
}
}
for (byte r = 0; r < ROWS; r++) {
for (byte c = 0; c < COLS; c++) {
uint8_t offset = (r*COLS) + c;
int8_t value = oldpg[rc2pos[offset]];
uint8_t step;
/*
if (value < 0) step = 0;
else step = value;
step <<= 1;
*/
//step = value;
//LEDControl.setCrgbAt(r, c, CRGB(step,step,step));
cRGB color;
uint16_t intensity;
if (value >= 0) intensity = value * 2;
else intensity = (-value) * 2;
color = hsvToRgb(current_hue + (uint16_t)value + (uint16_t)value,
0xff - intensity,
(intensity*5)/3);
LEDControl.setCrgbAt(r, c, color);
//LEDControl.setCrgbAt(r, c, variant->compute(&step));
/*
if (offset == (now & 63)) {
LEDControl.setCrgbAt(r, c, CRGB(100,100,100));
} else {
LEDControl.setCrgbAt(r, c, CRGB(0,0,0));
}
*/
}
}
page ^= 1;
}
namespace wavepool {
cRGB Haunt::highlight_color_;
// Haunt
Haunt::Haunt(const cRGB highlight_color) {
highlight_color_ = highlight_color;
}
cRGB Haunt::compute(uint8_t *step) {
cRGB color = CRGB((uint8_t)min(*step * highlight_color_.r / 255, 255),
(uint8_t)min(*step * highlight_color_.g / 255, 255),
(uint8_t)min(*step * highlight_color_.b / 255, 255));
if (*step >= 0xf0)
*step -= 1;
else if (*step >= 0x40)
*step -= 16;
else if (*step >= 32)
*step -= 32;
else
*step = 0;
return color;
}
// BlazingTrail
BlazingTrail::BlazingTrail(void) {
}
cRGB BlazingTrail::compute(uint8_t *step) {
cRGB color;
if (*step >= 0xff - 30) {
color = hsvToRgb(0xff - *step, 255, 255);
} else {
color = hsvToRgb(30, 255, 255);
color.r = min(*step * color.r / 255, 255);
color.g = min(*step * color.g / 255, 255);
}
if (*step >= 0xf0 - 30)
*step -= 1;
else if (*step >= 0x40)
*step -= 16;
else if (*step >= 32)
*step -= 32;
else
*step = 0;
return color;
}
// Rainbow
Rainbow::Rainbow(void) {
}
cRGB Rainbow::compute(uint8_t *step) {
cRGB color;
uint8_t intensity;
if ((*step) <= 127) intensity = (*step) * 2;
else intensity = (255 - (*step)) * 2;
color = hsvToRgb(intensity,
0xff - intensity,
intensity);
return color;
}
}
}
kaleidoscope::WavepoolEffect WavepoolEffect;

@ -1,6 +1,6 @@
/* -*- mode: c++ -*- /* -*- mode: c++ -*-
* Kaleidoscope-LED-Stalker -- Stalk keys pressed by lighting up and fading back the LED under them * Kaleidoscope-LED-Wavepool
* Copyright (C) 2017 Gergely Nagy * Copyright (C) 2017 Selene Scriven
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -21,17 +21,20 @@
#include <Kaleidoscope.h> #include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h> #include <Kaleidoscope-LEDControl.h>
#define STALKER(v, ...) ({static kaleidoscope::stalker::v _effect __VA_ARGS__; &_effect;}) #define WAVEPOOL(v, ...) ({static kaleidoscope::wavepool::v _effect __VA_ARGS__; &_effect;})
#define WP_WID 14
#define WP_HGT 5
namespace kaleidoscope { namespace kaleidoscope {
class StalkerEffect : public LEDMode { class WavepoolEffect : public LEDMode {
public: public:
class ColorComputer { class ColorComputer {
public: public:
virtual cRGB compute(uint8_t *step) = 0; virtual cRGB compute(uint8_t *step) = 0;
}; };
StalkerEffect(void); WavepoolEffect(void);
void begin(void) final; void begin(void) final;
void init(void) final; void init(void) final;
@ -41,15 +44,19 @@ class StalkerEffect : public LEDMode {
static uint16_t step_length; static uint16_t step_length;
private: private:
static uint8_t frames_since_event;
static uint32_t step_end_time_; static uint32_t step_end_time_;
static uint8_t map_[ROWS][COLS]; static int8_t map_[2][WP_WID*WP_HGT];
static uint8_t page;
static uint8_t positions[WP_HGT*WP_WID];
static uint8_t rc2pos[ROWS*COLS];
static Key eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state); static Key eventHandlerHook(Key mapped_key, byte row, byte col, uint8_t key_state);
}; };
namespace stalker { namespace wavepool {
class Haunt : public StalkerEffect::ColorComputer { class Haunt : public WavepoolEffect::ColorComputer {
public: public:
explicit Haunt(const cRGB highlight_color); explicit Haunt(const cRGB highlight_color);
Haunt(void) : Haunt(CRGB(0x40, 0x80, 0x80)) {} Haunt(void) : Haunt(CRGB(0x40, 0x80, 0x80)) {}
@ -59,14 +66,21 @@ class Haunt : public StalkerEffect::ColorComputer {
static cRGB highlight_color_; static cRGB highlight_color_;
}; };
class BlazingTrail : public StalkerEffect::ColorComputer { class BlazingTrail : public WavepoolEffect::ColorComputer {
public: public:
BlazingTrail(void); BlazingTrail(void);
cRGB compute(uint8_t *step) final; cRGB compute(uint8_t *step) final;
}; };
class Rainbow : public WavepoolEffect::ColorComputer {
public:
Rainbow(void);
cRGB compute(uint8_t *step) final;
};
} }
} }
extern kaleidoscope::StalkerEffect StalkerEffect; extern kaleidoscope::WavepoolEffect WavepoolEffect;
Loading…
Cancel
Save