Merge remote-tracking branch 'plugin/GhostInTheFirmware/f/monorepo' into f/monorepo-stage2

pull/389/head
Gergely Nagy 6 years ago
commit 6471c110d0
No known key found for this signature in database
GPG Key ID: AC1E90BAC433F68F

@ -0,0 +1,84 @@
# Kaleidoscope-GhostInTheFirmware
Born out of the desire to demo LED effects on the keyboard without having to
touch it by hand (which would obstruct the video), the `GhostInTheFirmware`
plugin allows one to inject events at various delays, by telling it which keys
to press. Unlike macros, these press keys at given positions, as if they were
pressed by someone typing on it - the firmware will not see the difference.
Given a sequence (with press- and delay times), the plugin will walk through it
once activated, and hold the key for the specified amount, release it, and move
on to the next after the delay time.
## Using the plugin
To use the plugin, one needs to include the header, and configure it with a list
of key coordinates, a press time, and a delay time quartett. One also needs a
way to trigger starting the sequence, and a macro is the most convenient way for
that.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-GhostInTheFirmware.h>
#include <Kaleidoscope-Macros.h>
const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) {
if (macro_index == 0 && keyToggledOn(key_state))
GhostInTheFirmware.activate();
return MACRO_NONE;
}
static const kaleidoscope::plugin::GhostInTheFirmware::GhostKey ghost_keys[] PROGMEM = {
{0, 0, 200, 50},
{0, 0, 0}
};
KALEIDOSCOPE_INIT_PLUGINS(GhostInTheFirmware,
Macros);
void setup() {
Kaleidoscope.setup ();
GhostInTheFirmware.ghost_keys = ghost_keys;
}
```
The plugin won't be doing anything until its `activate()` method is called -
hence the macro.
## Plugin methods
The plugin provides the `GhostInTheFirmware` object, which has the following
methods and properties:
### `.activate()`
> Start playing back the sequence. Best called from a macro.
### `.ghost_keys`
> Set this property to the sequence of keys to press, by assigning a sequence to
> this variable. Each element is a quartett of `row`, `column`, a `pressTime`,
> and a `delay`. Each of these will be pressed in different cycles, unlike
> macros which play back within a single cycle.
>
> The key at `row`, `column` will be held for `pressTime` milliseconds, and
> after an additional `delay` milliseconds, the plugin will move on to the next
> entry in the sequence.
>
> The sequence *MUST* reside in `PROGMEM`.
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/GhostInTheFirmware/GhostInTheFirmware.ino
## Upgrading
Previous versions of `GhostInTheFirmware` used
`kaleidoscope::GhostInTheFirmware::GhostKey` as a type for defining keys. In
newer versions, this is `kaleidoscope::plugin::GhostInTheFirmware::GhostKey`.
The old name still works, but will be removed by 2019-01-14.

@ -0,0 +1,145 @@
/* -*- mode: c++ -*-
* Kaleidoscope-GhostInTheFirmware -- Let the keyboard write for you!
* 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 <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-GhostInTheFirmware.h>
#include <Kaleidoscope-LED-Stalker.h>
#include <Kaleidoscope-Macros.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(___, ___, ___, ___, ___, ___, M(0),
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___),
};
// *INDENT-ON*
class EventDropper_ : public kaleidoscope::Plugin {
public:
EventDropper_() {}
kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) {
return kaleidoscope::EventHandlerResult::EVENT_CONSUMED;
}
};
static EventDropper_ EventDropper;
const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) {
if (macro_index == 0 && keyToggledOn(key_state))
GhostInTheFirmware.activate();
return MACRO_NONE;
}
static const kaleidoscope::plugin::GhostInTheFirmware::GhostKey ghost_keys[] PROGMEM = {
{0, 6, 200, 50},
{0, 5, 200, 50},
{0, 4, 200, 50},
{0, 3, 200, 50},
{0, 2, 200, 50},
{0, 1, 200, 50},
{0, 0, 200, 50},
{1, 0, 200, 50},
{1, 1, 200, 50},
{1, 2, 200, 50},
{1, 3, 200, 50},
{1, 4, 200, 50},
{1, 5, 200, 50},
{1, 6, 200, 50},
{2, 6, 200, 50},
{2, 5, 200, 50},
{2, 4, 200, 50},
{2, 3, 200, 50},
{2, 2, 200, 50},
{2, 1, 200, 50},
{2, 0, 200, 50},
{3, 0, 200, 50},
{3, 1, 200, 50},
{3, 3, 200, 50},
{3, 4, 200, 50},
{3, 5, 200, 50},
{0, 7, 200, 50},
{1, 7, 200, 50},
{2, 7, 200, 50},
{3, 7, 200, 50},
{3, 6, 200, 50},
{3, 9, 200, 50},
{3, 8, 200, 50},
{2, 8, 200, 50},
{1, 8, 200, 50},
{0, 8, 200, 50},
{3, 10, 200, 50},
{3, 11, 200, 50},
{3, 12, 200, 50},
{3, 13, 200, 50},
{3, 14, 200, 50},
{3, 15, 200, 50},
{2, 15, 200, 50},
{2, 14, 200, 50},
{2, 13, 200, 50},
{2, 12, 200, 50},
{2, 11, 200, 50},
{2, 10, 200, 50},
{2, 9, 200, 50},
{1, 9, 200, 50},
{1, 10, 200, 50},
{1, 11, 200, 50},
{1, 12, 200, 50},
{1, 13, 200, 50},
{1, 14, 200, 50},
{1, 15, 200, 50},
{0, 15, 200, 50},
{0, 14, 200, 50},
{0, 13, 200, 50},
{0, 12, 200, 50},
{0, 11, 200, 50},
{0, 10, 200, 50},
{0, 9, 200, 50},
{0, 0, 0, 0}
};
KALEIDOSCOPE_INIT_PLUGINS(GhostInTheFirmware,
StalkerEffect,
Macros,
EventDropper);
void setup() {
Kaleidoscope.setup();
StalkerEffect.variant = STALKER(BlazingTrail);
GhostInTheFirmware.ghost_keys = ghost_keys;
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-GhostInTheFirmware -- Let the keyboard write for you!
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/GhostInTheFirmware.h>

@ -0,0 +1,76 @@
/* -*- mode: c++ -*-
* Kaleidoscope-GhostInTheFirmware -- Let the keyboard write for you!
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-GhostInTheFirmware.h>
namespace kaleidoscope {
namespace plugin {
const GhostInTheFirmware::GhostKey *GhostInTheFirmware::ghost_keys;
bool GhostInTheFirmware::is_active_;
bool GhostInTheFirmware::is_pressed_;
uint16_t GhostInTheFirmware::current_pos_;
uint32_t GhostInTheFirmware::start_time_;
uint16_t GhostInTheFirmware::press_timeout_;
uint16_t GhostInTheFirmware::delay_timeout_;
void GhostInTheFirmware::activate(void) {
is_active_ = true;
}
EventHandlerResult GhostInTheFirmware::beforeReportingState() {
if (!is_active_)
return EventHandlerResult::OK;
if (press_timeout_ == 0) {
press_timeout_ = pgm_read_word(&(ghost_keys[current_pos_].pressTime));
delay_timeout_ = pgm_read_word(&(ghost_keys[current_pos_].delay));
if (press_timeout_ == 0) {
current_pos_ = 0;
is_active_ = false;
return EventHandlerResult::OK;
}
is_pressed_ = true;
start_time_ = millis();
} else {
if (is_pressed_ && ((millis() - start_time_) > press_timeout_)) {
is_pressed_ = false;
start_time_ = millis();
byte row = pgm_read_byte(&(ghost_keys[current_pos_].row));
byte col = pgm_read_byte(&(ghost_keys[current_pos_].col));
handleKeyswitchEvent(Key_NoKey, row, col, WAS_PRESSED);
} else if (is_pressed_) {
byte row = pgm_read_byte(&(ghost_keys[current_pos_].row));
byte col = pgm_read_byte(&(ghost_keys[current_pos_].col));
handleKeyswitchEvent(Key_NoKey, row, col, IS_PRESSED);
} else if ((millis() - start_time_) > delay_timeout_) {
current_pos_++;
press_timeout_ = 0;
}
}
return EventHandlerResult::OK;
}
}
}
kaleidoscope::plugin::GhostInTheFirmware GhostInTheFirmware;

@ -0,0 +1,56 @@
/* -*- mode: c++ -*-
* Kaleidoscope-GhostInTheFirmware -- Let the keyboard write for you!
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
namespace kaleidoscope {
namespace plugin {
class GhostInTheFirmware : public kaleidoscope::Plugin {
public:
typedef struct {
byte row;
byte col;
uint16_t pressTime;
uint16_t delay;
} GhostKey;
static const GhostKey *ghost_keys;
GhostInTheFirmware(void) {}
static void activate(void);
EventHandlerResult beforeReportingState();
private:
static bool is_active_;
static bool is_pressed_;
static uint16_t current_pos_;
static uint32_t start_time_;
static uint16_t press_timeout_;
static uint16_t delay_timeout_;
static void loopHook(bool is_post_clear);
};
}
// For backwards compatibility
typedef kaleidoscope::plugin::GhostInTheFirmware GhostInTheFirmware;
}
extern kaleidoscope::plugin::GhostInTheFirmware GhostInTheFirmware;
Loading…
Cancel
Save