diff --git a/doc/plugin/LEDControl.md b/doc/plugin/LEDControl.md new file mode 100644 index 00000000..2a99e8d2 --- /dev/null +++ b/doc/plugin/LEDControl.md @@ -0,0 +1,19 @@ +# Kaleidoscope-LEDControl + +This is a plugin for [Kaleidoscope][fw], for controlling the LEDs, and LED +effects. + + [fw]: https://github.com/keyboardio/Kaleidoscope + +## Upgrading + +The `LEDUtils.h` and `LED-Off.h` headers are now included by default when using +``, and their explicit use is therefore deprecated. +The includes can be safely removed. + +Compatibility headers are in place for both, but will be removed by 2019-01-14. + +Furthermore, to implement LED modes, one should use +`kaleidoscope::plugin::LEDMode` as a base class now, instead of the former +`kaleidoscope::LEDMode`. There is a backwards compatible typedef, but like the +headers, it will be removed by 2019-01-14. diff --git a/src/Kaleidoscope-LEDControl.h b/src/Kaleidoscope-LEDControl.h new file mode 100644 index 00000000..3564aa5a --- /dev/null +++ b/src/Kaleidoscope-LEDControl.h @@ -0,0 +1,21 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include +#include +#include diff --git a/src/LED-Off.h b/src/LED-Off.h new file mode 100644 index 00000000..eeb13372 --- /dev/null +++ b/src/LED-Off.h @@ -0,0 +1,21 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#warning The "LED-Off.h" header is deprecated, the mode is included by default when using . It can be safely removed. + +#include "kaleidoscope/plugin/LEDControl/LED-Off.h" diff --git a/src/LEDUtils.h b/src/LEDUtils.h new file mode 100644 index 00000000..803e882e --- /dev/null +++ b/src/LEDUtils.h @@ -0,0 +1,21 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#warning The "LEDUtils.h" header is deprecated, the mode is included by default when using . It can be safely removed. + +#include "kaleidoscope/plugin/LEDControl/LEDUtils.h" diff --git a/src/kaleidoscope/plugin/LEDControl.cpp b/src/kaleidoscope/plugin/LEDControl.cpp new file mode 100644 index 00000000..cc710eb0 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDControl.cpp @@ -0,0 +1,282 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#include "Kaleidoscope-LEDControl.h" +#include "Kaleidoscope-FocusSerial.h" + +namespace kaleidoscope { +namespace plugin { + +LEDMode *LEDControl::modes[LED_MAX_MODES]; +uint8_t LEDControl::mode; +uint16_t LEDControl::syncDelay = 16; +uint16_t LEDControl::syncTimer; +bool LEDControl::paused = false; + +void LEDMode::activate(void) { + ::LEDControl.activate(this); +} + +kaleidoscope::EventHandlerResult LEDMode::onSetup() { + ::LEDControl.mode_add(this); + setup(); + + return EventHandlerResult::OK; +} + +LEDControl::LEDControl(void) { + mode = 0; + memset(modes, 0, LED_MAX_MODES * sizeof(modes[0])); +} + +void LEDControl::next_mode(void) { + mode++; + + if (mode >= LED_MAX_MODES || !modes[mode]) { + return set_mode(0); + } + + return set_mode(mode); +} + +void LEDControl::prev_mode(void) { + if (mode == 0) { + // wrap around + mode = LED_MAX_MODES - 1; + // then count down until reaching a valid mode + while (mode > 0 && !modes[mode]) mode--; + } else { + mode--; + } + + return set_mode(mode); +} + +void +LEDControl::set_mode(uint8_t mode_) { + if (mode_ >= LED_MAX_MODES) + return; + + mode = mode_; + refreshAll(); +} + +uint8_t LEDControl::get_mode_index(void) { + return mode; +} + +LEDMode *LEDControl::get_mode(void) { + return modes[mode]; +} + +void LEDControl::activate(LEDMode *mode) { + for (uint8_t i = 0; i < LED_MAX_MODES; i++) { + if (modes[i] == mode) + return set_mode(i); + } +} + +int8_t LEDControl::mode_add(LEDMode *mode) { + for (int i = 0; i < LED_MAX_MODES; i++) { + if (modes[i]) + continue; + + modes[i] = mode; + return i; + } + return -1; +} + +void LEDControl::set_all_leds_to(uint8_t r, uint8_t g, uint8_t b) { + cRGB color; + color.r = r; + color.g = g; + color.b = b; + set_all_leds_to(color); +} + +void LEDControl::set_all_leds_to(cRGB color) { + for (uint8_t i = 0; i < LED_COUNT; i++) { + setCrgbAt(i, color); + } +} + +void LEDControl::setCrgbAt(uint8_t i, cRGB crgb) { + KeyboardHardware.setCrgbAt(i, crgb); +} + +void LEDControl::setCrgbAt(byte row, byte col, cRGB color) { + KeyboardHardware.setCrgbAt(row, col, color); +} + +cRGB LEDControl::getCrgbAt(uint8_t i) { + return KeyboardHardware.getCrgbAt(i); +} + +void LEDControl::syncLeds(void) { + KeyboardHardware.syncLeds(); +} + +kaleidoscope::EventHandlerResult LEDControl::onSetup() { + set_all_leds_to({0, 0, 0}); + + for (uint8_t i = 0; i < LED_MAX_MODES; i++) { + if (modes[i]) + (modes[i]->setup)(); + } + + syncTimer = millis() + syncDelay; + + return EventHandlerResult::OK; +} + +kaleidoscope::EventHandlerResult LEDControl::onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState) { + if (mappedKey.flags != (SYNTHETIC | IS_INTERNAL | LED_TOGGLE)) + return kaleidoscope::EventHandlerResult::OK; + + if (keyToggledOn(keyState)) { + if (mappedKey == Key_LEDEffectNext) { + next_mode(); + } else if (mappedKey == Key_LEDEffectPrevious) { + prev_mode(); + } + } + + return kaleidoscope::EventHandlerResult::EVENT_CONSUMED; +} + +kaleidoscope::EventHandlerResult LEDControl::beforeReportingState(void) { + if (paused) + return kaleidoscope::EventHandlerResult::OK; + + // unsigned subtraction means that as syncTimer rolls over + // the same interval is kept + uint16_t elapsed = Kaleidoscope.millisAtCycleStart() - syncTimer; + // on some platforms, the subtraction in the comparison results in a signed + // operation, resulting in syncLeds() no longer getting called. + if (elapsed > syncDelay) { + syncLeds(); + syncTimer += syncDelay; + } + update(); + + return kaleidoscope::EventHandlerResult::OK; +} + +EventHandlerResult FocusLEDCommand::onFocusEvent(const char *command) { + enum { + SETALL, + MODE, + AT, + THEME, + } subCommand; + + if (::Focus.handleHelp(command, PSTR("led.at\n" + "led.setAll\n" + "led.mode\n" + "led.theme"))) + return EventHandlerResult::OK; + + if (strncmp_P(command, PSTR("led."), 4) != 0) + return EventHandlerResult::OK; + if (strcmp_P(command + 4, PSTR("at")) == 0) + subCommand = AT; + else if (strcmp_P(command + 4, PSTR("setAll")) == 0) + subCommand = SETALL; + else if (strcmp_P(command + 4, PSTR("mode")) == 0) + subCommand = MODE; + else if (strcmp_P(command + 4, PSTR("theme")) == 0) + subCommand = THEME; + else + return EventHandlerResult::OK; + + switch (subCommand) { + case AT: { + uint8_t idx = Serial.parseInt(); + + if (Serial.peek() == '\n') { + cRGB c = ::LEDControl.getCrgbAt(idx); + + ::Focus.printColor(c.r, c.g, c.b); + Serial.println(); + } else { + cRGB c; + + ::Focus.readColor(c); + + ::LEDControl.setCrgbAt(idx, c); + } + break; + } + case SETALL: { + cRGB c; + + ::Focus.readColor(c); + + ::LEDControl.set_all_leds_to(c); + + break; + } + case MODE: { + char peek = Serial.peek(); + if (peek == '\n') { + Serial.println(::LEDControl.get_mode_index()); + } else if (peek == 'n') { + ::LEDControl.next_mode(); + Serial.read(); + } else if (peek == 'p') { + ::LEDControl.prev_mode(); + Serial.read(); + } else { + uint8_t mode = Serial.parseInt(); + + ::LEDControl.set_mode(mode); + } + break; + } + case THEME: { + if (Serial.peek() == '\n') { + for (uint8_t idx = 0; idx < LED_COUNT; idx++) { + cRGB c = ::LEDControl.getCrgbAt(idx); + + ::Focus.printColor(c.r, c.g, c.b); + ::Focus.printSpace(); + } + Serial.println(); + break; + } + + uint8_t idx = 0; + while (idx < LED_COUNT && Serial.peek() != '\n') { + cRGB color; + + ::Focus.readColor(color); + + ::LEDControl.setCrgbAt(idx, color); + idx++; + } + break; + } + } + + return EventHandlerResult::EVENT_CONSUMED; +} + +} +} + +kaleidoscope::plugin::LEDControl LEDControl; +kaleidoscope::plugin::FocusLEDCommand FocusLEDCommand; diff --git a/src/kaleidoscope/plugin/LEDControl.h b/src/kaleidoscope/plugin/LEDControl.h new file mode 100644 index 00000000..246edfc8 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDControl.h @@ -0,0 +1,170 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include + +#define LED_MAX_MODES 24 + +#define LED_TOGGLE B00000001 // Synthetic, internal + +#define Key_LEDEffectNext (Key) { 0, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } +#define Key_LEDEffectPrevious (Key) { 1, KEY_FLAGS | SYNTHETIC | IS_INTERNAL | LED_TOGGLE } + +namespace kaleidoscope { +namespace plugin { +/** Base class for LED modes. + * + * LED modes are a special kind of plugin, they are in charge of updating LED + * colors, setting a theme. While it is possible to have other plugins + * override the mode's colors, the LED mode is the baseline. + * + * Most of its functionality is called via @ref LEDControl, with only a few + * public methods. + * + * A LED mode **must** implement at least one of @ref onActivate or @ref + * update, and possibly @ref refreshAt too. + */ +class LEDMode : public kaleidoscope::Plugin { + friend class LEDControl; + protected: + // These methods should only be called by LEDControl. + + /** One-time setup, called at keyboard boot. + * + * Any hooks that need registering, any one-time setup that needs to be + * performed, shall be done here. This is purely for preparation purposes, the + * LEDs should not be touched yet at this time. + */ + virtual void setup(void) {} + + /** Function to call whenever the mode is activated. + * + * Like @ref setup, this method need not touch LEDs, @ref update will be + * called right after it. The purpose of this callback is to allow a plugin to + * do some preparation whenever it is activated, instead of only on boot, or + * always at each cycle. + * + * However, unlike @ref setup, this method can change LED colors, if so + * desired. Either to provide an initial state, or a static color set. In the + * latter case, consider implementing @ref refreshAt too, because other + * plugins may override some of the colors set at activation time, and @ref + * refreshAt can be used to restore them when needed. + * + * Before the callback runs, LEDs will be blanked. + */ + virtual void onActivate(void) {} + + /** Update the LEDs once per cycle. + * + * Usually the brains of the plugin, which updates the LEDs each cycle. It is + * called after the matrix has been scanned, once per cycle. + */ + virtual void update(void) {} + + /** Refresh the color of a given key. + * + * If we have another plugin that overrides colors set by the active LED mode + * (either at @onActivate time, or via @ref update), if that plugin wants to + * restore whatever color the mode would set the key color to, this is the + * method it will call. + * + * @param row is the row coordinate of the key to refresh the color of. + * @param col is the column coordinate of the key to refresh the color of. + */ + virtual void refreshAt(byte row, byte col) {} + + public: + /** Activate the current object as the LED mode. + */ + void activate(void); + + /** Plugin initialization. + * + * Called via `Kaleidoscope.use()`, registers the LED mode, and does the + * necessary initialization steps. Calls @ref setup at the end. + */ + kaleidoscope::EventHandlerResult onSetup(); +}; + +class LEDControl : public kaleidoscope::Plugin { + public: + LEDControl(void); + + static void next_mode(void); + static void prev_mode(void); + static void setup(void); + static void update(void) { + if (modes[mode]) + modes[mode]->update(); + } + static void refreshAt(byte row, byte col) { + if (modes[mode]) + modes[mode]->refreshAt(row, col); + } + static void set_mode(uint8_t mode); + static uint8_t get_mode_index(); + static LEDMode *get_mode(); + static void refreshAll() { + if (paused) + return; + + set_all_leds_to({0, 0, 0}); + if (modes[mode]) + modes[mode]->onActivate(); + } + + static int8_t mode_add(LEDMode *mode); + + static void setCrgbAt(uint8_t i, cRGB crgb); + static void setCrgbAt(byte row, byte col, cRGB color); + static cRGB getCrgbAt(uint8_t i); + static void syncLeds(void); + + static void set_all_leds_to(uint8_t r, uint8_t g, uint8_t b); + static void set_all_leds_to(cRGB color); + + static void activate(LEDMode *mode); + + static uint16_t syncDelay; + static bool paused; + + kaleidoscope::EventHandlerResult onSetup(); + kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mappedKey, byte row, byte col, uint8_t keyState); + kaleidoscope::EventHandlerResult beforeReportingState(); + + private: + static uint16_t syncTimer; + static LEDMode *modes[LED_MAX_MODES]; + static uint8_t mode; +}; + +class FocusLEDCommand : public Plugin { + public: + FocusLEDCommand() {} + + EventHandlerResult onFocusEvent(const char *command); +}; + +} + +// Backwards compatibility +typedef plugin::LEDMode LEDMode; +} + +extern kaleidoscope::plugin::LEDControl LEDControl; +extern kaleidoscope::plugin::FocusLEDCommand FocusLEDCommand; diff --git a/src/kaleidoscope/plugin/LEDControl/BootAnimation.cpp b/src/kaleidoscope/plugin/LEDControl/BootAnimation.cpp new file mode 100644 index 00000000..2e7c0ba7 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDControl/BootAnimation.cpp @@ -0,0 +1,51 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#include "kaleidoscope/plugin/LEDControl/BootAnimation.h" +#include "Kaleidoscope-LEDControl.h" + +#ifdef ARDUINO_AVR_MODEL01 +static void +type_letter(uint8_t letter) { + LEDControl.setCrgbAt(letter, {255, 0, 0}); + LEDControl.syncLeds(); + delay(250); + LEDControl.setCrgbAt(letter, {0, 0, 0}); + LEDControl.syncLeds(); + delay(10); +} +#endif + +void +bootAnimation(void) { +#ifdef ARDUINO_AVR_MODEL01 + LEDControl.set_all_leds_to(0, 0, 0); + type_letter(LED_K); + type_letter(LED_E); + type_letter(LED_Y); + type_letter(LED_B); + type_letter(LED_O); + type_letter(LED_A); + type_letter(LED_R); + type_letter(LED_D); + type_letter(LED_I); + type_letter(LED_O); + type_letter(LED_SPACE); + type_letter(LED_0); + type_letter(LED_PERIOD); + type_letter(LED_9); +#endif +} diff --git a/src/kaleidoscope/plugin/LEDControl/BootAnimation.h b/src/kaleidoscope/plugin/LEDControl/BootAnimation.h new file mode 100644 index 00000000..5da98af2 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDControl/BootAnimation.h @@ -0,0 +1,19 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +void bootAnimation(void); diff --git a/src/kaleidoscope/plugin/LEDControl/LED-Off.cpp b/src/kaleidoscope/plugin/LEDControl/LED-Off.cpp new file mode 100644 index 00000000..175ccab1 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDControl/LED-Off.cpp @@ -0,0 +1,31 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#include "kaleidoscope/plugin/LEDControl/LED-Off.h" + +namespace kaleidoscope { +namespace plugin { +void LEDOff::onActivate(void) { + ::LEDControl.set_all_leds_to({0, 0, 0}); +} + +void LEDOff::refreshAt(byte row, byte col) { + ::LEDControl.setCrgbAt(row, col, {0, 0, 0}); +} +} +} + +kaleidoscope::plugin::LEDOff LEDOff; diff --git a/src/kaleidoscope/plugin/LEDControl/LED-Off.h b/src/kaleidoscope/plugin/LEDControl/LED-Off.h new file mode 100644 index 00000000..3a931e9d --- /dev/null +++ b/src/kaleidoscope/plugin/LEDControl/LED-Off.h @@ -0,0 +1,34 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include "Kaleidoscope-LEDControl.h" + +namespace kaleidoscope { +namespace plugin { +class LEDOff : public LEDMode { + public: + LEDOff(void) { } + + protected: + void onActivate(void) final; + void refreshAt(byte row, byte col) final; +}; +} +} + +extern kaleidoscope::plugin::LEDOff LEDOff; diff --git a/src/kaleidoscope/plugin/LEDControl/LEDUtils.cpp b/src/kaleidoscope/plugin/LEDControl/LEDUtils.cpp new file mode 100644 index 00000000..9f7f9c83 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDControl/LEDUtils.cpp @@ -0,0 +1,104 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#include "kaleidoscope/plugin/LEDControl/LEDUtils.h" + +cRGB +breath_compute(uint8_t hue, uint8_t saturation) { + // This code is adapted from FastLED lib8tion.h as of dd5d96c6b289cb6b4b891748a4aeef3ddceaf0e6 + // Eventually, we should consider just using FastLED + + // We do a bit shift here instead of division to ensure that there's no discontinuity + // in the output brightness when the integer overflows. + uint8_t i = (uint16_t)millis() >> 4; + + if (i & 0x80) { + i = 255 - i; + } + + i = i << 1; + uint8_t ii = (i * i) >> 8; + uint8_t iii = (ii * i) >> 8; + + i = (((3 * (uint16_t)(ii)) - (2 * (uint16_t)(iii))) / 2) + 80; + + return hsvToRgb(hue, saturation, i); +} + +//For rgb to hsv, might take a look at: http://web.mit.edu/storborg/Public/hsvtorgb.c + + +// From http://web.mit.edu/storborg/Public/hsvtorgb.c - talk to Scott about licensing +cRGB +hsvToRgb(uint16_t h, uint16_t s, uint16_t v) { + cRGB color; + + /* HSV to RGB conversion function with only integer + * math */ + uint16_t region, fpart, p, q, t; + + if (s == 0) { + /* color is grayscale */ + color.r = color.g = color.b = v; + return color; + } + + /* make hue 0-5 */ + region = (h * 6) >> 8; + /* find remainder part, make it from 0-255 */ + fpart = (h * 6) - (region << 8); + + /* calculate temp vars, doing integer multiplication */ + p = (v * (255 - s)) >> 8; + q = (v * (255 - ((s * fpart) >> 8))) >> 8; + t = (v * (255 - ((s * (255 - fpart)) >> 8))) >> 8; + + /* assign temp vars based on color cone region */ + switch (region) { + case 0: + color.r = v; + color.g = t; + color.b = p; + break; + case 1: + color.r = q; + color.g = v; + color.b = p; + break; + case 2: + color.r = p; + color.g = v; + color.b = t; + break; + case 3: + color.r = p; + color.g = q; + color.b = v; + break; + case 4: + color.r = t; + color.g = p; + color.b = v; + break; + default: + color.r = v; + color.g = p; + color.b = q; + break; + } + + return color; +} diff --git a/src/kaleidoscope/plugin/LEDControl/LEDUtils.h b/src/kaleidoscope/plugin/LEDControl/LEDUtils.h new file mode 100644 index 00000000..1de96922 --- /dev/null +++ b/src/kaleidoscope/plugin/LEDControl/LEDUtils.h @@ -0,0 +1,22 @@ +/* Kaleidoscope-LEDControl - LED control plugin for Kaleidoscope + * Copyright (C) 2017-2018 Keyboard.io, Inc. + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +#include + +cRGB breath_compute(uint8_t hue = 170, uint8_t saturation = 255); +cRGB hsvToRgb(uint16_t h, uint16_t s, uint16_t v);