mirror of
https://github.com/wled/WLED.git
synced 2025-07-15 06:46:34 +00:00
Added new "effect usermod"
- Added new effect - Diffusion Fire - UM is intended as a base / tutorial (work in progress)
This commit is contained in:
parent
8b65d873b3
commit
fc7d4dfcb0
4
usermods/user_fx/README.md
Normal file
4
usermods/user_fx/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Usermod user FX
|
||||
|
||||
This Usermod is a common place to put various user's LED effects.
|
||||
|
3
usermods/user_fx/library.json
Normal file
3
usermods/user_fx/library.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "user_fx"
|
||||
}
|
116
usermods/user_fx/user_fx.cpp
Normal file
116
usermods/user_fx/user_fx.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include "wled.h"
|
||||
|
||||
// for information how FX metadata strings work see https://kno.wled.ge/interfaces/json-api/#effect-metadata
|
||||
|
||||
// static effect, used if an effect fails to initialize
|
||||
static uint16_t mode_static(void) {
|
||||
SEGMENT.fill(SEGCOLOR(0));
|
||||
return strip.isOffRefreshRequired() ? FRAMETIME : 350;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// User FX functions //
|
||||
/////////////////////////
|
||||
|
||||
// Diffusion Fire: fire effect intended for 2D setups smaller than 16x16
|
||||
static uint16_t mode_diffusionfire(void) {
|
||||
if (!strip.isMatrix || !SEGMENT.is2D())
|
||||
return mode_static(); // not a 2D set-up
|
||||
|
||||
const int cols = SEG_W;
|
||||
const int rows = SEG_H;
|
||||
const auto XY = [&](int x, int y) { return x + y * cols; };
|
||||
|
||||
const uint8_t refresh_hz = map(SEGMENT.speed, 0, 255, 20, 80);
|
||||
const unsigned refresh_ms = 1000 / refresh_hz;
|
||||
const int16_t diffusion = map(SEGMENT.custom1, 0, 255, 0, 100);
|
||||
const uint8_t spark_rate = SEGMENT.intensity;
|
||||
const uint8_t turbulence = SEGMENT.custom2;
|
||||
|
||||
unsigned dataSize = SEGMENT.length(); // allocate persistent data for heat value for each pixel
|
||||
if (!SEGENV.allocateData(dataSize))
|
||||
return mode_static(); // allocation failed
|
||||
|
||||
if (SEGENV.call == 0) {
|
||||
SEGMENT.fill(BLACK);
|
||||
SEGENV.step = 0;
|
||||
}
|
||||
|
||||
if ((strip.now - SEGENV.step) >= refresh_ms) {
|
||||
uint8_t tmp_row[cols];
|
||||
SEGENV.step = strip.now;
|
||||
// scroll up
|
||||
for (unsigned y = 1; y < rows; y++)
|
||||
for (unsigned x = 0; x < cols; x++) {
|
||||
unsigned src = XY(x, y);
|
||||
unsigned dst = XY(x, y - 1);
|
||||
SEGMENT.data[dst] = SEGMENT.data[src];
|
||||
}
|
||||
|
||||
if (hw_random8() > turbulence) {
|
||||
// create new sparks at bottom row
|
||||
for (unsigned x = 0; x < cols; x++) {
|
||||
uint8_t p = hw_random8();
|
||||
if (p < spark_rate) {
|
||||
unsigned dst = XY(x, rows - 1);
|
||||
SEGMENT.data[dst] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// diffuse
|
||||
for (unsigned y = 0; y < rows; y++) {
|
||||
for (unsigned x = 0; x < cols; x++) {
|
||||
unsigned v = SEGMENT.data[XY(x, y)];
|
||||
if (x > 0) {
|
||||
v += SEGMENT.data[XY(x - 1, y)];
|
||||
}
|
||||
if (x < (cols - 1)) {
|
||||
v += SEGMENT.data[XY(x + 1, y)];
|
||||
}
|
||||
tmp_row[x] = min(255, (int)(v * 100 / (300 + diffusion)));
|
||||
}
|
||||
|
||||
for (unsigned x = 0; x < cols; x++) {
|
||||
SEGMENT.data[XY(x, y)] = tmp_row[x];
|
||||
if (SEGMENT.check1) {
|
||||
uint32_t color = ColorFromPalette(SEGPALETTE, tmp_row[x], 255, LINEARBLEND_NOWRAP);
|
||||
SEGMENT.setPixelColorXY(x, y, color);
|
||||
} else {
|
||||
uint32_t color = SEGCOLOR(0);
|
||||
SEGMENT.setPixelColorXY(x, y, color_fade(color, tmp_row[x]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return FRAMETIME;
|
||||
}
|
||||
static const char _data_FX_MODE_DIFFUSIONFIRE[] PROGMEM = "Diffusion Fire@!,Spark rate,Diffusion Speed,Turbulence,,Use palette;;Color;;2;pal=35";
|
||||
|
||||
|
||||
/////////////////////
|
||||
// UserMod Class //
|
||||
/////////////////////
|
||||
|
||||
class UserFxUsermod : public Usermod {
|
||||
private:
|
||||
public:
|
||||
void setup() override {
|
||||
strip.addEffect(255, &mode_diffusionfire, _data_FX_MODE_DIFFUSIONFIRE);
|
||||
|
||||
////////////////////////////////////////
|
||||
// add your effect function(s) here //
|
||||
////////////////////////////////////////
|
||||
|
||||
// use id=255 for all custom user FX (the final id is assigned when adding the effect)
|
||||
|
||||
// strip.addEffect(255, &mode_your_effect, _data_FX_MODE_YOUR_EFFECT);
|
||||
// strip.addEffect(255, &mode_your_effect2, _data_FX_MODE_YOUR_EFFECT2);
|
||||
// strip.addEffect(255, &mode_your_effect3, _data_FX_MODE_YOUR_EFFECT3);
|
||||
}
|
||||
void loop() override {} // nothing to do in the loop
|
||||
uint16_t getId() override { return USERMOD_ID_USER_FX; }
|
||||
};
|
||||
|
||||
static UserFxUsermod user_fx;
|
||||
REGISTER_USERMOD(user_fx);
|
@ -198,6 +198,7 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
|
||||
#define USERMOD_ID_DEEP_SLEEP 55 //Usermod "usermod_deep_sleep.h"
|
||||
#define USERMOD_ID_RF433 56 //Usermod "usermod_v2_RF433.h"
|
||||
#define USERMOD_ID_BRIGHTNESS_FOLLOW_SUN 57 //Usermod "usermod_v2_brightness_follow_sun.h"
|
||||
#define USERMOD_ID_USER_FX 58 //Usermod "user_fx"
|
||||
|
||||
//Access point behavior
|
||||
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
|
||||
|
Loading…
x
Reference in New Issue
Block a user