Remove FRAMETIME return value from all FX (#5314)
* remove "return FRAMETIME" from all FX, fix timing for some FX - all FX now render every frame, no more "speed up" during transitions * fix missing return by adding FS_FALLBACK_STATIC macro * add FX_FALLBACK_STATIC also to user_fx * remove obsolete seg.next_time
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
#include "UsermodTemperature.h"
|
#include "UsermodTemperature.h"
|
||||||
|
|
||||||
static uint16_t mode_temperature();
|
static void mode_temperature();
|
||||||
|
|
||||||
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
|
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
|
||||||
float UsermodTemperature::readDallas() {
|
float UsermodTemperature::readDallas() {
|
||||||
@@ -369,13 +369,12 @@ const char UsermodTemperature::_temperature[] PROGMEM = "temperature";
|
|||||||
const char UsermodTemperature::_Temperature[] PROGMEM = "/temperature";
|
const char UsermodTemperature::_Temperature[] PROGMEM = "/temperature";
|
||||||
const char UsermodTemperature::_data_fx[] PROGMEM = "Temperature@Min,Max;;!;01;pal=54,sx=255,ix=0";
|
const char UsermodTemperature::_data_fx[] PROGMEM = "Temperature@Min,Max;;!;01;pal=54,sx=255,ix=0";
|
||||||
|
|
||||||
static uint16_t mode_temperature() {
|
static void mode_temperature() {
|
||||||
float low = roundf(mapf((float)SEGMENT.speed, 0.f, 255.f, -150.f, 150.f)); // default: 15°C, range: -15°C to 15°C
|
float low = roundf(mapf((float)SEGMENT.speed, 0.f, 255.f, -150.f, 150.f)); // default: 15°C, range: -15°C to 15°C
|
||||||
float high = roundf(mapf((float)SEGMENT.intensity, 0.f, 255.f, 300.f, 600.f)); // default: 30°C, range 30°C to 60°C
|
float high = roundf(mapf((float)SEGMENT.intensity, 0.f, 255.f, 300.f, 600.f)); // default: 30°C, range 30°C to 60°C
|
||||||
float temp = constrain(UsermodTemperature::getInstance()->getTemperatureC()*10.f, low, high); // get a little better resolution (*10)
|
float temp = constrain(UsermodTemperature::getInstance()->getTemperatureC()*10.f, low, high); // get a little better resolution (*10)
|
||||||
unsigned i = map(roundf(temp), (unsigned)low, (unsigned)high, 0, 248);
|
unsigned i = map(roundf(temp), (unsigned)low, (unsigned)high, 0, 248);
|
||||||
SEGMENT.fill(SEGMENT.color_from_palette(i, false, false, 255));
|
SEGMENT.fill(SEGMENT.color_from_palette(i, false, false, 255));
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -98,13 +98,13 @@ void drawGrid(TetrisAIGame* tetris, TetrisAI_data* tetrisai_data)
|
|||||||
////////////////////////////
|
////////////////////////////
|
||||||
// 2D Tetris AI //
|
// 2D Tetris AI //
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
uint16_t mode_2DTetrisAI()
|
void mode_2DTetrisAI()
|
||||||
{
|
{
|
||||||
if (!strip.isMatrix || !SEGENV.allocateData(sizeof(tetrisai_data)))
|
if (!strip.isMatrix || !SEGENV.allocateData(sizeof(tetrisai_data)))
|
||||||
{
|
{
|
||||||
// not a 2D set-up
|
// not a 2D set-up
|
||||||
SEGMENT.fill(SEGCOLOR(0));
|
SEGMENT.fill(SEGCOLOR(0));
|
||||||
return 350;
|
return;
|
||||||
}
|
}
|
||||||
TetrisAI_data* tetrisai_data = reinterpret_cast<TetrisAI_data*>(SEGENV.data);
|
TetrisAI_data* tetrisai_data = reinterpret_cast<TetrisAI_data*>(SEGENV.data);
|
||||||
|
|
||||||
@@ -222,8 +222,6 @@ uint16_t mode_2DTetrisAI()
|
|||||||
{
|
{
|
||||||
tetrisai_data->tetris.poll();
|
tetrisai_data->tetris.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
return FRAMETIME;
|
|
||||||
} // mode_2DTetrisAI()
|
} // mode_2DTetrisAI()
|
||||||
static const char _data_FX_MODE_2DTETRISAI[] PROGMEM = "Tetris AI@!,Look ahead,Intelligence,Rotate color,Mistake free,Show next,Border,Mistakes;Game Over,!,Border;!;2;sx=127,ix=64,c1=255,c2=0,c3=31,o1=1,o2=1,o3=0,pal=11";
|
static const char _data_FX_MODE_2DTETRISAI[] PROGMEM = "Tetris AI@!,Look ahead,Intelligence,Rotate color,Mistake free,Show next,Border,Mistakes;Game Over,!,Border;!;2;sx=127,ix=64,c1=255,c2=0,c3=31,o1=1,o2=1,o3=0,pal=11";
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
#include "dice_state.h"
|
#include "dice_state.h"
|
||||||
|
|
||||||
// Reuse FX display functions.
|
// Reuse FX display functions.
|
||||||
extern uint16_t mode_breath();
|
extern void mode_breath();
|
||||||
extern uint16_t mode_blends();
|
extern void mode_blends();
|
||||||
extern uint16_t mode_glitter();
|
extern void mode_glitter();
|
||||||
extern uint16_t mode_gravcenter();
|
extern void mode_gravcenter();
|
||||||
|
|
||||||
static constexpr uint8_t USER_ANY_DIE = 0xFF;
|
static constexpr uint8_t USER_ANY_DIE = 0xFF;
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +41,7 @@ static pixels::RollEvent GetLastRollForSegment() {
|
|||||||
*/
|
*/
|
||||||
// paletteBlend: 0 - wrap when moving, 1 - always wrap, 2 - never wrap, 3 - none (undefined)
|
// paletteBlend: 0 - wrap when moving, 1 - always wrap, 2 - never wrap, 3 - none (undefined)
|
||||||
#define PALETTE_SOLID_WRAP (strip.paletteBlend == 1 || strip.paletteBlend == 3)
|
#define PALETTE_SOLID_WRAP (strip.paletteBlend == 1 || strip.paletteBlend == 3)
|
||||||
static uint16_t running_copy(uint32_t color1, uint32_t color2, bool theatre = false) {
|
static void running_copy(uint32_t color1, uint32_t color2, bool theatre = false) {
|
||||||
int width = (theatre ? 3 : 1) + (SEGMENT.intensity >> 4); // window
|
int width = (theatre ? 3 : 1) + (SEGMENT.intensity >> 4); // window
|
||||||
uint32_t cycleTime = 50 + (255 - SEGMENT.speed);
|
uint32_t cycleTime = 50 + (255 - SEGMENT.speed);
|
||||||
uint32_t it = strip.now / cycleTime;
|
uint32_t it = strip.now / cycleTime;
|
||||||
@@ -63,10 +63,9 @@ static uint16_t running_copy(uint32_t color1, uint32_t color2, bool theatre = fa
|
|||||||
SEGENV.aux0 = (SEGENV.aux0 +1) % (theatre ? width : (width<<1));
|
SEGENV.aux0 = (SEGENV.aux0 +1) % (theatre ? width : (width<<1));
|
||||||
SEGENV.step = it;
|
SEGENV.step = it;
|
||||||
}
|
}
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t simple_roll() {
|
static void simple_roll() {
|
||||||
auto roll = GetLastRollForSegment();
|
auto roll = GetLastRollForSegment();
|
||||||
if (roll.state != pixels::RollState::ON_FACE) {
|
if (roll.state != pixels::RollState::ON_FACE) {
|
||||||
SEGMENT.fill(0);
|
SEGMENT.fill(0);
|
||||||
@@ -79,7 +78,6 @@ static uint16_t simple_roll() {
|
|||||||
SEGMENT.setPixelColor(i, SEGCOLOR(1));
|
SEGMENT.setPixelColor(i, SEGCOLOR(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
// See https://kno.wled.ge/interfaces/json-api/#effect-metadata
|
// See https://kno.wled.ge/interfaces/json-api/#effect-metadata
|
||||||
// Name - DieSimple
|
// Name - DieSimple
|
||||||
@@ -92,31 +90,34 @@ static uint16_t simple_roll() {
|
|||||||
static const char _data_FX_MODE_SIMPLE_DIE[] PROGMEM =
|
static const char _data_FX_MODE_SIMPLE_DIE[] PROGMEM =
|
||||||
"DieSimple@,,Selected Die;!,!;;1;c1=255";
|
"DieSimple@,,Selected Die;!,!;;1;c1=255";
|
||||||
|
|
||||||
static uint16_t pulse_roll() {
|
static void pulse_roll() {
|
||||||
auto roll = GetLastRollForSegment();
|
auto roll = GetLastRollForSegment();
|
||||||
if (roll.state != pixels::RollState::ON_FACE) {
|
if (roll.state != pixels::RollState::ON_FACE) {
|
||||||
return mode_breath();
|
mode_breath();
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
uint16_t ret = mode_blends();
|
mode_blends();
|
||||||
uint16_t num_segments = float(roll.current_face + 1) / 20.0 * SEGLEN;
|
uint16_t num_segments = float(roll.current_face + 1) / 20.0 * SEGLEN;
|
||||||
for (int i = num_segments; i < SEGLEN; i++) {
|
for (int i = num_segments; i < SEGLEN; i++) {
|
||||||
SEGMENT.setPixelColor(i, SEGCOLOR(1));
|
SEGMENT.setPixelColor(i, SEGCOLOR(1));
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_PULSE_DIE[] PROGMEM =
|
static const char _data_FX_MODE_PULSE_DIE[] PROGMEM =
|
||||||
"DiePulse@!,!,Selected Die;!,!;!;1;sx=24,pal=50,c1=255";
|
"DiePulse@!,!,Selected Die;!,!;!;1;sx=24,pal=50,c1=255";
|
||||||
|
|
||||||
static uint16_t check_roll() {
|
static void check_roll() {
|
||||||
auto roll = GetLastRollForSegment();
|
auto roll = GetLastRollForSegment();
|
||||||
if (roll.state != pixels::RollState::ON_FACE) {
|
if (roll.state != pixels::RollState::ON_FACE) {
|
||||||
return running_copy(SEGCOLOR(0), SEGCOLOR(2));
|
running_copy(SEGCOLOR(0), SEGCOLOR(2));
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (roll.current_face + 1 >= SEGMENT.custom2) {
|
if (roll.current_face + 1 >= SEGMENT.custom2) {
|
||||||
return mode_glitter();
|
mode_glitter();
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
return mode_gravcenter();
|
mode_gravcenter();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,37 +5,37 @@ static const char _data_FX_MODE_POV_IMAGE[] PROGMEM = "POV Image@!;;;;";
|
|||||||
|
|
||||||
static POV s_pov;
|
static POV s_pov;
|
||||||
|
|
||||||
uint16_t mode_pov_image(void) {
|
void mode_pov_image(void) {
|
||||||
Segment& mainseg = strip.getMainSegment();
|
Segment& mainseg = strip.getMainSegment();
|
||||||
const char* segName = mainseg.name;
|
const char* segName = mainseg.name;
|
||||||
if (!segName) {
|
if (!segName) {
|
||||||
return FRAMETIME;
|
return;
|
||||||
}
|
}
|
||||||
// Only proceed for files ending with .bmp (case-insensitive)
|
// Only proceed for files ending with .bmp (case-insensitive)
|
||||||
size_t segLen = strlen(segName);
|
size_t segLen = strlen(segName);
|
||||||
if (segLen < 4) return FRAMETIME;
|
if (segLen < 4) return;
|
||||||
const char* ext = segName + (segLen - 4);
|
const char* ext = segName + (segLen - 4);
|
||||||
// compare case-insensitive to ".bmp"
|
// compare case-insensitive to ".bmp"
|
||||||
if (!((ext[0]=='.') &&
|
if (!((ext[0]=='.') &&
|
||||||
(ext[1]=='b' || ext[1]=='B') &&
|
(ext[1]=='b' || ext[1]=='B') &&
|
||||||
(ext[2]=='m' || ext[2]=='M') &&
|
(ext[2]=='m' || ext[2]=='M') &&
|
||||||
(ext[3]=='p' || ext[3]=='P'))) {
|
(ext[3]=='p' || ext[3]=='P'))) {
|
||||||
return FRAMETIME;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* current = s_pov.getFilename();
|
const char* current = s_pov.getFilename();
|
||||||
if (current && strcmp(segName, current) == 0) {
|
if (current && strcmp(segName, current) == 0) {
|
||||||
s_pov.showNextLine();
|
s_pov.showNextLine();
|
||||||
return FRAMETIME;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long s_lastLoadAttemptMs = 0;
|
static unsigned long s_lastLoadAttemptMs = 0;
|
||||||
unsigned long nowMs = millis();
|
unsigned long nowMs = millis();
|
||||||
// Retry at most twice per second if the image is not yet loaded.
|
// Retry at most twice per second if the image is not yet loaded.
|
||||||
if (nowMs - s_lastLoadAttemptMs < 500) return FRAMETIME;
|
if (nowMs - s_lastLoadAttemptMs < 500) return;
|
||||||
s_lastLoadAttemptMs = nowMs;
|
s_lastLoadAttemptMs = nowMs;
|
||||||
s_pov.loadImage(segName);
|
s_pov.loadImage(segName);
|
||||||
return FRAMETIME;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PovDisplayUsermod : public Usermod {
|
class PovDisplayUsermod : public Usermod {
|
||||||
|
|||||||
@@ -88,12 +88,14 @@ The first line of the code imports the [wled.h](https://github.com/wled/WLED/blo
|
|||||||
### Static Effect Definition
|
### Static Effect Definition
|
||||||
The next code block is the `mode_static` definition. This is usually left as `SEGMENT.fill(SEGCOLOR(0));` to leave all pixels off if the effect fails to load, but in theory one could use this as a 'fallback effect' to take on a different behavior, such as displaying some other color instead of leaving the pixels off.
|
The next code block is the `mode_static` definition. This is usually left as `SEGMENT.fill(SEGCOLOR(0));` to leave all pixels off if the effect fails to load, but in theory one could use this as a 'fallback effect' to take on a different behavior, such as displaying some other color instead of leaving the pixels off.
|
||||||
|
|
||||||
|
`FX_FALLBACK_STATIC` is a macro that calls `mode_static()` and then returns.
|
||||||
|
|
||||||
### User Effect Definitions
|
### User Effect Definitions
|
||||||
Pre-loaded in this template is an example 2D Effect called "Diffusion Fire". (This is the name that would be shown in the UI once the binary is compiled and run on your device, as defined in the metadata string.)
|
Pre-loaded in this template is an example 2D Effect called "Diffusion Fire". (This is the name that would be shown in the UI once the binary is compiled and run on your device, as defined in the metadata string.)
|
||||||
The effect starts off by checking to see if the segment that the effect is being applied to is a 2D Matrix, and if it is not, then it returns the static effect which displays no pattern:
|
The effect starts off by checking to see if the segment that the effect is being applied to is a 2D Matrix, and if it is not, then it runs the static effect which displays no pattern:
|
||||||
```cpp
|
```cpp
|
||||||
if (!strip.isMatrix || !SEGMENT.is2D())
|
if (!strip.isMatrix || !SEGMENT.is2D())
|
||||||
return mode_static(); // not a 2D set-up
|
FX_FALLBACK_STATIC; // not a 2D set-up
|
||||||
```
|
```
|
||||||
The next code block contains several constant variable definitions which essentially serve to extract the dimensions of the user's 2D matrix and allow WLED to interpret the matrix as a 1D coordinate system (WLED must do this for all 2D animations):
|
The next code block contains several constant variable definitions which essentially serve to extract the dimensions of the user's 2D matrix and allow WLED to interpret the matrix as a 1D coordinate system (WLED must do this for all 2D animations):
|
||||||
```cpp
|
```cpp
|
||||||
@@ -140,7 +142,7 @@ unsigned dataSize = cols * rows; // SEGLEN (virtual length) is equivalent to vW
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
if (!SEGENV.allocateData(dataSize))
|
if (!SEGENV.allocateData(dataSize))
|
||||||
return mode_static(); // allocation failed
|
FX_FALLBACK_STATIC; // allocation failed
|
||||||
```
|
```
|
||||||
* Upon the first call, this section allocates a persistent data buffer tied to the segment environment (`SEGENV.data`). All subsequent calls simply ensure that the data is still valid.
|
* Upon the first call, this section allocates a persistent data buffer tied to the segment environment (`SEGENV.data`). All subsequent calls simply ensure that the data is still valid.
|
||||||
* The syntax `SEGENV.allocateData(n)` requests a buffer of size n bytes (1 byte per pixel here).
|
* The syntax `SEGENV.allocateData(n)` requests a buffer of size n bytes (1 byte per pixel here).
|
||||||
@@ -262,20 +264,14 @@ After calculating tmp_row, we now handle rendering the pixels by updating the ac
|
|||||||
* `SEGCOLOR(0)` gets the first user-selected color for the segment.
|
* `SEGCOLOR(0)` gets the first user-selected color for the segment.
|
||||||
* The final line of code fades that base color according to the heat value (acts as brightness multiplier).
|
* The final line of code fades that base color according to the heat value (acts as brightness multiplier).
|
||||||
|
|
||||||
The final piece of this custom effect returns the frame time:
|
* Even though the effect logic itself controls when to update based on refresh_ms, WLED will still call this function at roughly FRAMETIME intervals (the FPS limit set in config) to check whether an update is needed. If nothing needs to change, the frame still needs to be re-rendered so color or brightness transitions will be smooth.
|
||||||
```cpp
|
|
||||||
}
|
|
||||||
return FRAMETIME;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
* The first bracket closes the earlier `if ((strip.now - SEGENV.step) >= refresh_ms)` block.
|
|
||||||
* It ensures that the fire simulation (scrolling, sparking, diffusion, rendering) only runs when enough time has passed since the last update.
|
|
||||||
* returning the frame time tells WLED how soon this effect wants to be called again.
|
|
||||||
* `FRAMETIME` is a predefined macro in WLED, typically set to ~16ms, corresponding to ~60 FPS (frames per second).
|
|
||||||
* Even though the effect logic itself controls when to update based on refresh_ms, WLED will still call this function at roughly FRAMETIME intervals to check whether an update is needed.
|
|
||||||
* ⚠️ Important: Because the actual frame logic is gated by strip.now - SEGENV.step, returning FRAMETIME here doesn’t cause excessive updates — it just keeps the engine responsive. **Also note that an Effect should ALWAYS return FRAMETIME. Not doing so can cause glitches.**
|
|
||||||
* The final bracket closes the `mode_diffusionfire()` function itself.
|
|
||||||
|
|
||||||
|
If you want to run your effect at a fixed frame rate you can use the following code to not update your effect state, be aware however that transitions for your effect will also run at this frame rate - for example if you limit your effect to say 5 FPS, brightness changes and color changes may not look smooth. Also `SEGMENT.call` is still incremented on each function call.
|
||||||
|
```cpp
|
||||||
|
//limit update rate
|
||||||
|
if (strip.now - SEGENV.step < FRAMETIME_FIXED) return;
|
||||||
|
SEGENV.step = strip.now;
|
||||||
|
```
|
||||||
|
|
||||||
### The Metadata String
|
### The Metadata String
|
||||||
At the end of every effect is an important line of code called the **metadata string**.
|
At the end of every effect is an important line of code called the **metadata string**.
|
||||||
@@ -322,13 +318,13 @@ We will break this effect down step by step.
|
|||||||
(This effect was originally one of the FastLED example effects; more information on FastLED can be found [here](https://fastled.io/).)
|
(This effect was originally one of the FastLED example effects; more information on FastLED can be found [here](https://fastled.io/).)
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
static uint16_t sinelon_base(bool dual, bool rainbow=false) {
|
static void sinelon_base(bool dual, bool rainbow=false) {
|
||||||
```
|
```
|
||||||
* The first line of code defines `sinelon base` as static helper function. This is how all effects are initially defined.
|
* The first line of code defines `sinelon base` as static helper function. This is how all effects are initially defined.
|
||||||
* Notice that it has some optional flags; these parameters will allow us to easily define the effect in different ways in the UI.
|
* Notice that it has some optional flags; these parameters will allow us to easily define the effect in different ways in the UI.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
if (SEGLEN <= 1) return mode_static();
|
if (SEGLEN <= 1) FX_FALLBACK_STATIC;
|
||||||
```
|
```
|
||||||
* If segment length ≤ 1, there’s nothing to animate. Just show static mode.
|
* If segment length ≤ 1, there’s nothing to animate. Just show static mode.
|
||||||
|
|
||||||
@@ -408,28 +404,21 @@ This final part of the effect function will fill in the 'trailing' pixels to com
|
|||||||
* Works in both directions: Forward (if new pos > old pos), and Backward (if new pos < old pos).
|
* Works in both directions: Forward (if new pos > old pos), and Backward (if new pos < old pos).
|
||||||
* Updates `SEGENV.aux0` to current position at the end.
|
* Updates `SEGENV.aux0` to current position at the end.
|
||||||
|
|
||||||
Finally, we return the `FRAMETIME`, as with all effect functions:
|
|
||||||
```cpp
|
|
||||||
return FRAMETIME;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
* Returns `FRAMETIME` constant to set effect update rate (usually ~16 ms).
|
|
||||||
|
|
||||||
The last part of this effect has the Wrapper functions for different Sinelon modes.
|
The last part of this effect has the Wrapper functions for different Sinelon modes.
|
||||||
Notice that there are three different modes that we can define from the single effect definition by leveraging the arguments in the function:
|
Notice that there are three different modes that we can define from the single effect definition by leveraging the arguments in the function:
|
||||||
```cpp
|
```cpp
|
||||||
uint16_t mode_sinelon(void) {
|
void mode_sinelon(void) {
|
||||||
return sinelon_base(false);
|
sinelon_base(false);
|
||||||
}
|
}
|
||||||
// Calls sinelon_base with dual = false and rainbow = false
|
// Calls sinelon_base with dual = false and rainbow = false
|
||||||
|
|
||||||
uint16_t mode_sinelon_dual(void) {
|
void mode_sinelon_dual(void) {
|
||||||
return sinelon_base(true);
|
sinelon_base(true);
|
||||||
}
|
}
|
||||||
// Calls sinelon_base with dual = true and rainbow = false
|
// Calls sinelon_base with dual = true and rainbow = false
|
||||||
|
|
||||||
uint16_t mode_sinelon_rainbow(void) {
|
void mode_sinelon_rainbow(void) {
|
||||||
return sinelon_base(false, true);
|
sinelon_base(false, true);
|
||||||
}
|
}
|
||||||
// Calls sinelon_base with dual = false and rainbow = true
|
// Calls sinelon_base with dual = false and rainbow = true
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
// for information how FX metadata strings work see https://kno.wled.ge/interfaces/json-api/#effect-metadata
|
// 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 effect, used if an effect fails to initialize
|
||||||
static uint16_t mode_static(void) {
|
static void mode_static(void) {
|
||||||
SEGMENT.fill(SEGCOLOR(0));
|
SEGMENT.fill(SEGCOLOR(0));
|
||||||
return strip.isOffRefreshRequired() ? FRAMETIME : 350;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FX_FALLBACK_STATIC { mode_static(); return; }
|
||||||
|
|
||||||
// If you define configuration options in your class and need to reference them in your effect function, add them here.
|
// If you define configuration options in your class and need to reference them in your effect function, add them here.
|
||||||
// If you only need to use them in your class you can define them as class members instead.
|
// If you only need to use them in your class you can define them as class members instead.
|
||||||
// bool myConfigValue = false;
|
// bool myConfigValue = false;
|
||||||
@@ -17,9 +18,9 @@ static uint16_t mode_static(void) {
|
|||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
|
||||||
// Diffusion Fire: fire effect intended for 2D setups smaller than 16x16
|
// Diffusion Fire: fire effect intended for 2D setups smaller than 16x16
|
||||||
static uint16_t mode_diffusionfire(void) {
|
static void mode_diffusionfire(void) {
|
||||||
if (!strip.isMatrix || !SEGMENT.is2D())
|
if (!strip.isMatrix || !SEGMENT.is2D())
|
||||||
return mode_static(); // not a 2D set-up
|
FX_FALLBACK_STATIC; // not a 2D set-up
|
||||||
|
|
||||||
const int cols = SEG_W;
|
const int cols = SEG_W;
|
||||||
const int rows = SEG_H;
|
const int rows = SEG_H;
|
||||||
@@ -33,7 +34,7 @@ static uint16_t mode_diffusionfire(void) {
|
|||||||
|
|
||||||
unsigned dataSize = cols * rows; // SEGLEN (virtual length) is equivalent to vWidth()*vHeight() for 2D
|
unsigned dataSize = cols * rows; // SEGLEN (virtual length) is equivalent to vWidth()*vHeight() for 2D
|
||||||
if (!SEGENV.allocateData(dataSize))
|
if (!SEGENV.allocateData(dataSize))
|
||||||
return mode_static(); // allocation failed
|
FX_FALLBACK_STATIC; // allocation failed
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
@@ -88,7 +89,6 @@ unsigned dataSize = cols * rows; // SEGLEN (virtual length) is equivalent to vW
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_DIFFUSIONFIRE[] PROGMEM = "Diffusion Fire@!,Spark rate,Diffusion Speed,Turbulence,,Use palette;;Color;;2;pal=35";
|
static const char _data_FX_MODE_DIFFUSIONFIRE[] PROGMEM = "Diffusion Fire@!,Spark rate,Diffusion Speed,Turbulence,,Use palette;;Color;;2;pal=35";
|
||||||
|
|
||||||
|
|||||||
@@ -85,266 +85,214 @@ class ANIMartRIXMod:public ANIMartRIX {
|
|||||||
};
|
};
|
||||||
ANIMartRIXMod anim;
|
ANIMartRIXMod anim;
|
||||||
|
|
||||||
uint16_t mode_Module_Experiment10() {
|
void mode_Module_Experiment10() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Module_Experiment10();
|
anim.Module_Experiment10();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Module_Experiment9() {
|
void mode_Module_Experiment9() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Module_Experiment9();
|
anim.Module_Experiment9();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Module_Experiment8() {
|
void mode_Module_Experiment8() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Module_Experiment8();
|
anim.Module_Experiment8();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Module_Experiment7() {
|
void mode_Module_Experiment7() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Module_Experiment7();
|
anim.Module_Experiment7();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Module_Experiment6() {
|
void mode_Module_Experiment6() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Module_Experiment6();
|
anim.Module_Experiment6();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Module_Experiment5() {
|
void mode_Module_Experiment5() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Module_Experiment5();
|
anim.Module_Experiment5();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Module_Experiment4() {
|
void mode_Module_Experiment4() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Module_Experiment4();
|
anim.Module_Experiment4();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Zoom2() {
|
void mode_Zoom2() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Zoom2();
|
anim.Zoom2();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Module_Experiment3() {
|
void mode_Module_Experiment3() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Module_Experiment3();
|
anim.Module_Experiment3();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Module_Experiment2() {
|
void mode_Module_Experiment2() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Module_Experiment2();
|
anim.Module_Experiment2();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Module_Experiment1() {
|
void mode_Module_Experiment1() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Module_Experiment1();
|
anim.Module_Experiment1();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Parametric_Water() {
|
void mode_Parametric_Water() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Parametric_Water();
|
anim.Parametric_Water();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Water() {
|
void mode_Water() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Water();
|
anim.Water();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Complex_Kaleido_6() {
|
void mode_Complex_Kaleido_6() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Complex_Kaleido_6();
|
anim.Complex_Kaleido_6();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Complex_Kaleido_5() {
|
void mode_Complex_Kaleido_5() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Complex_Kaleido_5();
|
anim.Complex_Kaleido_5();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Complex_Kaleido_4() {
|
void mode_Complex_Kaleido_4() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Complex_Kaleido_4();
|
anim.Complex_Kaleido_4();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Complex_Kaleido_3() {
|
void mode_Complex_Kaleido_3() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Complex_Kaleido_3();
|
anim.Complex_Kaleido_3();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Complex_Kaleido_2() {
|
void mode_Complex_Kaleido_2() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Complex_Kaleido_2();
|
anim.Complex_Kaleido_2();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Complex_Kaleido() {
|
void mode_Complex_Kaleido() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Complex_Kaleido();
|
anim.Complex_Kaleido();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_SM10() {
|
void mode_SM10() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.SM10();
|
anim.SM10();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_SM9() {
|
void mode_SM9() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.SM9();
|
anim.SM9();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_SM8() {
|
void mode_SM8() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.SM8();
|
anim.SM8();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
// uint16_t mode_SM7() {
|
// void mode_SM7() {
|
||||||
// anim.initEffect();
|
// anim.initEffect();
|
||||||
// anim.SM7();
|
// anim.SM7();
|
||||||
//
|
//
|
||||||
// return FRAMETIME;
|
|
||||||
// }
|
// }
|
||||||
uint16_t mode_SM6() {
|
void mode_SM6() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.SM6();
|
anim.SM6();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_SM5() {
|
void mode_SM5() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.SM5();
|
anim.SM5();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_SM4() {
|
void mode_SM4() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.SM4();
|
anim.SM4();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_SM3() {
|
void mode_SM3() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.SM3();
|
anim.SM3();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_SM2() {
|
void mode_SM2() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.SM2();
|
anim.SM2();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_SM1() {
|
void mode_SM1() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.SM1();
|
anim.SM1();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Big_Caleido() {
|
void mode_Big_Caleido() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Big_Caleido();
|
anim.Big_Caleido();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_RGB_Blobs5() {
|
void mode_RGB_Blobs5() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.RGB_Blobs5();
|
anim.RGB_Blobs5();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_RGB_Blobs4() {
|
void mode_RGB_Blobs4() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.RGB_Blobs4();
|
anim.RGB_Blobs4();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_RGB_Blobs3() {
|
void mode_RGB_Blobs3() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.RGB_Blobs3();
|
anim.RGB_Blobs3();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_RGB_Blobs2() {
|
void mode_RGB_Blobs2() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.RGB_Blobs2();
|
anim.RGB_Blobs2();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_RGB_Blobs() {
|
void mode_RGB_Blobs() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.RGB_Blobs();
|
anim.RGB_Blobs();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Polar_Waves() {
|
void mode_Polar_Waves() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Polar_Waves();
|
anim.Polar_Waves();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Slow_Fade() {
|
void mode_Slow_Fade() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Slow_Fade();
|
anim.Slow_Fade();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Zoom() {
|
void mode_Zoom() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Zoom();
|
anim.Zoom();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Hot_Blob() {
|
void mode_Hot_Blob() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Hot_Blob();
|
anim.Hot_Blob();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Spiralus2() {
|
void mode_Spiralus2() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Spiralus2();
|
anim.Spiralus2();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Spiralus() {
|
void mode_Spiralus() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Spiralus();
|
anim.Spiralus();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Yves() {
|
void mode_Yves() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Yves();
|
anim.Yves();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Scaledemo1() {
|
void mode_Scaledemo1() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Scaledemo1();
|
anim.Scaledemo1();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Lava1() {
|
void mode_Lava1() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Lava1();
|
anim.Lava1();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Caleido3() {
|
void mode_Caleido3() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Caleido3();
|
anim.Caleido3();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Caleido2() {
|
void mode_Caleido2() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Caleido2();
|
anim.Caleido2();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Caleido1() {
|
void mode_Caleido1() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Caleido1();
|
anim.Caleido1();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Distance_Experiment() {
|
void mode_Distance_Experiment() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Distance_Experiment();
|
anim.Distance_Experiment();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Center_Field() {
|
void mode_Center_Field() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Center_Field();
|
anim.Center_Field();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Waves() {
|
void mode_Waves() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Waves();
|
anim.Waves();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Chasing_Spirals() {
|
void mode_Chasing_Spirals() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Chasing_Spirals();
|
anim.Chasing_Spirals();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
uint16_t mode_Rotating_Blob() {
|
void mode_Rotating_Blob() {
|
||||||
anim.initEffect();
|
anim.initEffect();
|
||||||
anim.Rotating_Blob();
|
anim.Rotating_Blob();
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1375
wled00/FX.cpp
1375
wled00/FX.cpp
File diff suppressed because it is too large
Load Diff
@@ -466,7 +466,6 @@ class Segment {
|
|||||||
char *name; // segment name
|
char *name; // segment name
|
||||||
|
|
||||||
// runtime data
|
// runtime data
|
||||||
mutable unsigned long next_time; // millis() of next update
|
|
||||||
mutable uint32_t step; // custom "step" var
|
mutable uint32_t step; // custom "step" var
|
||||||
mutable uint32_t call; // call counter
|
mutable uint32_t call; // call counter
|
||||||
mutable uint16_t aux0; // custom var
|
mutable uint16_t aux0; // custom var
|
||||||
@@ -592,7 +591,6 @@ class Segment {
|
|||||||
, check3(false)
|
, check3(false)
|
||||||
, blendMode(0)
|
, blendMode(0)
|
||||||
, name(nullptr)
|
, name(nullptr)
|
||||||
, next_time(0)
|
|
||||||
, step(0)
|
, step(0)
|
||||||
, call(0)
|
, call(0)
|
||||||
, aux0(0)
|
, aux0(0)
|
||||||
@@ -823,13 +821,13 @@ class Segment {
|
|||||||
|
|
||||||
// main "strip" class (108 bytes)
|
// main "strip" class (108 bytes)
|
||||||
class WS2812FX {
|
class WS2812FX {
|
||||||
typedef uint16_t (*mode_ptr)(); // pointer to mode function
|
typedef void (*mode_ptr)(); // pointer to mode function
|
||||||
typedef void (*show_callback)(); // pre show callback
|
typedef void (*show_callback)(); // pre show callback
|
||||||
typedef struct ModeData {
|
typedef struct ModeData {
|
||||||
uint8_t _id; // mode (effect) id
|
uint8_t _id; // mode (effect) id
|
||||||
mode_ptr _fcn; // mode (effect) function
|
mode_ptr _fcn; // mode (effect) function
|
||||||
const char *_data; // mode (effect) name and its UI control data
|
const char *_data; // mode (effect) name and its UI control data
|
||||||
ModeData(uint8_t id, uint16_t (*fcn)(void), const char *data) : _id(id), _fcn(fcn), _data(data) {}
|
ModeData(uint8_t id, void (*fcn)(void), const char *data) : _id(id), _fcn(fcn), _data(data) {}
|
||||||
} mode_data_t;
|
} mode_data_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ void Segment::resetIfRequired() {
|
|||||||
DEBUG_PRINTF_P(PSTR("-- Segment %p reset, data cleared\n"), this);
|
DEBUG_PRINTF_P(PSTR("-- Segment %p reset, data cleared\n"), this);
|
||||||
}
|
}
|
||||||
if (pixels) for (size_t i = 0; i < length(); i++) pixels[i] = BLACK; // clear pixel buffer
|
if (pixels) for (size_t i = 0; i < length(); i++) pixels[i] = BLACK; // clear pixel buffer
|
||||||
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
|
step = 0; call = 0; aux0 = 0; aux1 = 0;
|
||||||
reset = false;
|
reset = false;
|
||||||
#ifdef WLED_ENABLE_GIF
|
#ifdef WLED_ENABLE_GIF
|
||||||
endImagePlayback(this);
|
endImagePlayback(this);
|
||||||
@@ -1282,10 +1282,9 @@ void WS2812FX::service() {
|
|||||||
if (!seg.isActive()) continue;
|
if (!seg.isActive()) continue;
|
||||||
|
|
||||||
// last condition ensures all solid segments are updated at the same time
|
// last condition ensures all solid segments are updated at the same time
|
||||||
if (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC))
|
if (nowUp > _lastServiceShow + _frametime || _triggered || (doShow && seg.mode == FX_MODE_STATIC))
|
||||||
{
|
{
|
||||||
doShow = true;
|
doShow = true;
|
||||||
unsigned frameDelay = FRAMETIME;
|
|
||||||
|
|
||||||
if (!seg.freeze) { //only run effect function if not frozen
|
if (!seg.freeze) { //only run effect function if not frozen
|
||||||
// Effect blending
|
// Effect blending
|
||||||
@@ -1293,7 +1292,7 @@ void WS2812FX::service() {
|
|||||||
seg.beginDraw(prog); // set up parameters for get/setPixelColor() (will also blend colors and palette if blend style is FADE)
|
seg.beginDraw(prog); // set up parameters for get/setPixelColor() (will also blend colors and palette if blend style is FADE)
|
||||||
_currentSegment = &seg; // set current segment for effect functions (SEGMENT & SEGENV)
|
_currentSegment = &seg; // set current segment for effect functions (SEGMENT & SEGENV)
|
||||||
// workaround for on/off transition to respect blending style
|
// workaround for on/off transition to respect blending style
|
||||||
frameDelay = (*_mode[seg.mode])(); // run new/current mode (needed for bri workaround)
|
_mode[seg.mode](); // run new/current mode (needed for bri workaround)
|
||||||
seg.call++;
|
seg.call++;
|
||||||
// if segment is in transition and no old segment exists we don't need to run the old mode
|
// if segment is in transition and no old segment exists we don't need to run the old mode
|
||||||
// (blendSegments() takes care of On/Off transitions and clipping)
|
// (blendSegments() takes care of On/Off transitions and clipping)
|
||||||
@@ -1304,14 +1303,11 @@ void WS2812FX::service() {
|
|||||||
segO->beginDraw(prog); // set up palette & colors (also sets draw dimensions), parent segment has transition progress
|
segO->beginDraw(prog); // set up palette & colors (also sets draw dimensions), parent segment has transition progress
|
||||||
_currentSegment = segO; // set current segment
|
_currentSegment = segO; // set current segment
|
||||||
// workaround for on/off transition to respect blending style
|
// workaround for on/off transition to respect blending style
|
||||||
frameDelay = min(frameDelay, (unsigned)(*_mode[segO->mode])()); // run old mode (needed for bri workaround; semaphore!!)
|
_mode[segO->mode](); // run old mode (needed for bri workaround; semaphore!!)
|
||||||
segO->call++; // increment old mode run counter
|
segO->call++; // increment old mode run counter
|
||||||
Segment::modeBlend(false); // unset semaphore
|
Segment::modeBlend(false); // unset semaphore
|
||||||
}
|
}
|
||||||
if (seg.isInTransition() && frameDelay > FRAMETIME) frameDelay = FRAMETIME; // force faster updates during transition
|
|
||||||
}
|
}
|
||||||
|
|
||||||
seg.next_time = nowUp + frameDelay;
|
|
||||||
}
|
}
|
||||||
_segment_index++;
|
_segment_index++;
|
||||||
}
|
}
|
||||||
@@ -1725,7 +1721,7 @@ void WS2812FX::setBrightness(uint8_t b, bool direct) {
|
|||||||
BusManager::setBrightness(scaledBri(b));
|
BusManager::setBrightness(scaledBri(b));
|
||||||
if (!direct) {
|
if (!direct) {
|
||||||
unsigned long t = millis();
|
unsigned long t = millis();
|
||||||
if (_segments[0].next_time > t + 22 && t - _lastShow > MIN_SHOW_DELAY) trigger(); //apply brightness change immediately if no refresh soon
|
if (t - _lastShow > MIN_SHOW_DELAY) trigger(); //apply brightness change immediately if no refresh soon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,9 +79,8 @@ void ParticleSystem2D::update(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update function for fire animation
|
// update function for fire animation
|
||||||
void ParticleSystem2D::updateFire(const uint8_t intensity,const bool renderonly) {
|
void ParticleSystem2D::updateFire(const uint8_t intensity) {
|
||||||
if (!renderonly)
|
fireParticleupdate();
|
||||||
fireParticleupdate();
|
|
||||||
fireIntesity = intensity > 0 ? intensity : 1; // minimum of 1, zero checking is used in render function
|
fireIntesity = intensity > 0 ? intensity : 1; // minimum of 1, zero checking is used in render function
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
@@ -1096,7 +1095,11 @@ bool allocateParticleSystemMemory2D(uint32_t numparticles, uint32_t numsources,
|
|||||||
// initialize Particle System, allocate additional bytes if needed (pointer to those bytes can be read from particle system class: PSdataEnd)
|
// initialize Particle System, allocate additional bytes if needed (pointer to those bytes can be read from particle system class: PSdataEnd)
|
||||||
bool initParticleSystem2D(ParticleSystem2D *&PartSys, uint32_t requestedsources, uint32_t additionalbytes, bool advanced, bool sizecontrol) {
|
bool initParticleSystem2D(ParticleSystem2D *&PartSys, uint32_t requestedsources, uint32_t additionalbytes, bool advanced, bool sizecontrol) {
|
||||||
PSPRINT("PS 2D init ");
|
PSPRINT("PS 2D init ");
|
||||||
if (!strip.isMatrix) return false; // only for 2D
|
if (!strip.isMatrix) {
|
||||||
|
errorFlag = ERR_NOT_IMPL; // TODO: need a better error code if more codes are added
|
||||||
|
SEGMENT.deallocateData(); // deallocate any data to make sure data is null (there is no valid PS in data and data can only be checked for null)
|
||||||
|
return false; // only for 2D
|
||||||
|
}
|
||||||
uint32_t cols = SEGMENT.virtualWidth();
|
uint32_t cols = SEGMENT.virtualWidth();
|
||||||
uint32_t rows = SEGMENT.virtualHeight();
|
uint32_t rows = SEGMENT.virtualHeight();
|
||||||
uint32_t pixels = cols * rows;
|
uint32_t pixels = cols * rows;
|
||||||
@@ -1844,7 +1847,11 @@ bool allocateParticleSystemMemory1D(const uint32_t numparticles, const uint32_t
|
|||||||
// initialize Particle System, allocate additional bytes if needed (pointer to those bytes can be read from particle system class: PSdataEnd)
|
// initialize Particle System, allocate additional bytes if needed (pointer to those bytes can be read from particle system class: PSdataEnd)
|
||||||
// note: percentofparticles is in uint8_t, for example 191 means 75%, (deafaults to 255 or 100% meaning one particle per pixel), can be more than 100% (but not recommended, can cause out of memory)
|
// note: percentofparticles is in uint8_t, for example 191 means 75%, (deafaults to 255 or 100% meaning one particle per pixel), can be more than 100% (but not recommended, can cause out of memory)
|
||||||
bool initParticleSystem1D(ParticleSystem1D *&PartSys, const uint32_t requestedsources, const uint8_t fractionofparticles, const uint32_t additionalbytes, const bool advanced) {
|
bool initParticleSystem1D(ParticleSystem1D *&PartSys, const uint32_t requestedsources, const uint8_t fractionofparticles, const uint32_t additionalbytes, const bool advanced) {
|
||||||
if (SEGLEN == 1) return false; // single pixel not supported
|
if (SEGLEN == 1) {
|
||||||
|
errorFlag = ERR_NOT_IMPL; // TODO: need a better error code if more codes are added
|
||||||
|
SEGMENT.deallocateData(); // deallocate any data to make sure data is null (there is no valid PS in data and data can only be checked for null)
|
||||||
|
return false; // single pixel not supported
|
||||||
|
}
|
||||||
uint32_t numparticles = calculateNumberOfParticles1D(fractionofparticles, advanced);
|
uint32_t numparticles = calculateNumberOfParticles1D(fractionofparticles, advanced);
|
||||||
uint32_t numsources = calculateNumberOfSources1D(requestedsources);
|
uint32_t numsources = calculateNumberOfSources1D(requestedsources);
|
||||||
bool allocsuccess = false;
|
bool allocsuccess = false;
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ public:
|
|||||||
ParticleSystem2D(const uint32_t width, const uint32_t height, const uint32_t numberofparticles, const uint32_t numberofsources, const bool isadvanced = false, const bool sizecontrol = false); // constructor
|
ParticleSystem2D(const uint32_t width, const uint32_t height, const uint32_t numberofparticles, const uint32_t numberofsources, const bool isadvanced = false, const bool sizecontrol = false); // constructor
|
||||||
// note: memory is allcated in the FX function, no deconstructor needed
|
// note: memory is allcated in the FX function, no deconstructor needed
|
||||||
void update(void); //update the particles according to set options and render to the matrix
|
void update(void); //update the particles according to set options and render to the matrix
|
||||||
void updateFire(const uint8_t intensity, const bool renderonly); // update function for fire, if renderonly is set, particles are not updated (required to fix transitions with frameskips)
|
void updateFire(const uint8_t intensity); // update function for fire
|
||||||
void updateSystem(void); // call at the beginning of every FX, updates pointers and dimensions
|
void updateSystem(void); // call at the beginning of every FX, updates pointers and dimensions
|
||||||
void particleMoveUpdate(PSparticle &part, PSparticleFlags &partFlags, PSsettings2D *options = NULL, PSadvancedParticle *advancedproperties = NULL); // move function
|
void particleMoveUpdate(PSparticle &part, PSparticleFlags &partFlags, PSsettings2D *options = NULL, PSadvancedParticle *advancedproperties = NULL); // move function
|
||||||
// particle emitters
|
// particle emitters
|
||||||
|
|||||||
Reference in New Issue
Block a user