kopia lustrzana https://github.com/Aircoookie/WLED
125 wiersze
3.8 KiB
C
125 wiersze
3.8 KiB
C
/**
|
|
* The LED effects influenced by dice rolls.
|
|
*/
|
|
#pragma once
|
|
|
|
#include "wled.h"
|
|
|
|
#include "dice_state.h"
|
|
|
|
// Reuse FX display functions.
|
|
extern uint16_t mode_breath();
|
|
extern uint16_t mode_blends();
|
|
extern uint16_t mode_glitter();
|
|
extern uint16_t mode_gravcenter();
|
|
|
|
static constexpr uint8_t USER_ANY_DIE = 0xFF;
|
|
/**
|
|
* Two custom effect parameters are used.
|
|
* c1 - Source Die. Sets which die from [0 - MAX_NUM_DICE) controls this effect.
|
|
* If this is set to 0xFF, use the latest event regardless of which die it
|
|
* came from.
|
|
* c2 - Target Roll. Sets the "success" criteria for a roll to >= this value.
|
|
*/
|
|
|
|
/**
|
|
* Return the last die roll based on the custom1 effect setting.
|
|
*/
|
|
static pixels::RollEvent GetLastRollForSegment() {
|
|
// If an invalid die is selected, fallback to using the most recent roll from
|
|
// any die.
|
|
if (SEGMENT.custom1 >= MAX_NUM_DICE) {
|
|
return GetLastRoll();
|
|
} else {
|
|
return last_die_events[SEGMENT.custom1];
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Alternating pixels running function (copied static function).
|
|
*/
|
|
// paletteBlend: 0 - wrap when moving, 1 - always wrap, 2 - never wrap, 3 - none (undefined)
|
|
#define PALETTE_SOLID_WRAP (strip.paletteBlend == 1 || strip.paletteBlend == 3)
|
|
static uint16_t running_copy(uint32_t color1, uint32_t color2, bool theatre = false) {
|
|
int width = (theatre ? 3 : 1) + (SEGMENT.intensity >> 4); // window
|
|
uint32_t cycleTime = 50 + (255 - SEGMENT.speed);
|
|
uint32_t it = strip.now / cycleTime;
|
|
bool usePalette = color1 == SEGCOLOR(0);
|
|
|
|
for (int i = 0; i < SEGLEN; i++) {
|
|
uint32_t col = color2;
|
|
if (usePalette) color1 = SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0);
|
|
if (theatre) {
|
|
if ((i % width) == SEGENV.aux0) col = color1;
|
|
} else {
|
|
int pos = (i % (width<<1));
|
|
if ((pos < SEGENV.aux0-width) || ((pos >= SEGENV.aux0) && (pos < SEGENV.aux0+width))) col = color1;
|
|
}
|
|
SEGMENT.setPixelColor(i,col);
|
|
}
|
|
|
|
if (it != SEGENV.step) {
|
|
SEGENV.aux0 = (SEGENV.aux0 +1) % (theatre ? width : (width<<1));
|
|
SEGENV.step = it;
|
|
}
|
|
return FRAMETIME;
|
|
}
|
|
|
|
static uint16_t simple_roll() {
|
|
auto roll = GetLastRollForSegment();
|
|
if (roll.state != pixels::RollState::ON_FACE) {
|
|
SEGMENT.fill(0);
|
|
} else {
|
|
uint16_t num_segments = float(roll.current_face + 1) / 20.0 * SEGLEN;
|
|
for (int i = 0; i <= num_segments; i++) {
|
|
SEGMENT.setPixelColor(i, SEGCOLOR(0));
|
|
}
|
|
for (int i = num_segments; i < SEGLEN; i++) {
|
|
SEGMENT.setPixelColor(i, SEGCOLOR(1));
|
|
}
|
|
}
|
|
return FRAMETIME;
|
|
}
|
|
// See https://kno.wled.ge/interfaces/json-api/#effect-metadata
|
|
// Name - DieSimple
|
|
// Parameters -
|
|
// * Selected Die (custom1)
|
|
// Colors - Uses color1 and color2
|
|
// Palette - Not used
|
|
// Flags - Effect is optimized for use on 1D LED strips.
|
|
// Defaults - Selected Die set to 0xFF (USER_ANY_DIE)
|
|
static const char _data_FX_MODE_SIMPLE_DIE[] PROGMEM =
|
|
"DieSimple@,,Selected Die;!,!;;1;c1=255";
|
|
|
|
static uint16_t pulse_roll() {
|
|
auto roll = GetLastRollForSegment();
|
|
if (roll.state != pixels::RollState::ON_FACE) {
|
|
return mode_breath();
|
|
} else {
|
|
uint16_t ret = mode_blends();
|
|
uint16_t num_segments = float(roll.current_face + 1) / 20.0 * SEGLEN;
|
|
for (int i = num_segments; i < SEGLEN; i++) {
|
|
SEGMENT.setPixelColor(i, SEGCOLOR(1));
|
|
}
|
|
return ret;
|
|
}
|
|
}
|
|
static const char _data_FX_MODE_PULSE_DIE[] PROGMEM =
|
|
"DiePulse@!,!,Selected Die;!,!;!;1;sx=24,pal=50,c1=255";
|
|
|
|
static uint16_t check_roll() {
|
|
auto roll = GetLastRollForSegment();
|
|
if (roll.state != pixels::RollState::ON_FACE) {
|
|
return running_copy(SEGCOLOR(0), SEGCOLOR(2));
|
|
} else {
|
|
if (roll.current_face + 1 >= SEGMENT.custom2) {
|
|
return mode_glitter();
|
|
} else {
|
|
return mode_gravcenter();
|
|
}
|
|
}
|
|
}
|
|
static const char _data_FX_MODE_CHECK_DIE[] PROGMEM =
|
|
"DieCheck@!,!,Selected Die,Target Roll;1,2,3;!;1;pal=0,ix=128,m12=2,si=0,c1=255,c2=10";
|