kopia lustrzana https://github.com/Aircoookie/WLED
Merge branch '0_14_1' into power-supply
commit
4f5816f42e
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wled",
|
||||
"version": "0.14.0",
|
||||
"version": "0.14.1-a1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wled",
|
||||
"version": "0.14.0",
|
||||
"version": "0.14.1-a1",
|
||||
"description": "Tools for WLED project",
|
||||
"main": "tools/cdata.js",
|
||||
"directories": {
|
||||
|
|
|
@ -217,7 +217,7 @@ build_flags =
|
|||
; restrict to minimal mime-types
|
||||
-DMIMETYPE_MINIMAL
|
||||
; other special-purpose framework flags (see https://docs.platformio.org/en/latest/platforms/espressif8266.html)
|
||||
; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;; in case of linker errors like "section `.text1' will not fit in region `iram1_0_seg'"
|
||||
-D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;; in case of linker errors like "section `.text1' will not fit in region `iram1_0_seg'"
|
||||
; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED ;; (experimental) adds some extra heap, but may cause slowdown
|
||||
|
||||
lib_deps =
|
||||
|
|
|
@ -52,9 +52,15 @@ class PWMFanUsermod : public Usermod {
|
|||
uint8_t tachoUpdateSec = 30;
|
||||
float targetTemperature = 35.0;
|
||||
uint8_t minPWMValuePct = 0;
|
||||
uint8_t maxPWMValuePct = 100;
|
||||
uint8_t numberOfInterrupsInOneSingleRotation = 2; // Number of interrupts ESP32 sees on tacho signal on a single fan rotation. All the fans I've seen trigger two interrups.
|
||||
uint8_t pwmValuePct = 0;
|
||||
|
||||
// constant values
|
||||
static const uint8_t _pwmMaxValue = 255;
|
||||
static const uint8_t _pwmMaxStepCount = 7;
|
||||
float _pwmTempStepSize = 0.5f;
|
||||
|
||||
// strings to reduce flash memory usage (used more than twice)
|
||||
static const char _name[];
|
||||
static const char _enabled[];
|
||||
|
@ -63,6 +69,7 @@ class PWMFanUsermod : public Usermod {
|
|||
static const char _temperature[];
|
||||
static const char _tachoUpdateSec[];
|
||||
static const char _minPWMValuePct[];
|
||||
static const char _maxPWMValuePct[];
|
||||
static const char _IRQperRotation[];
|
||||
static const char _speed[];
|
||||
static const char _lock[];
|
||||
|
@ -156,31 +163,25 @@ class PWMFanUsermod : public Usermod {
|
|||
|
||||
void setFanPWMbasedOnTemperature(void) {
|
||||
float temp = getActualTemperature();
|
||||
float difftemp = temp - targetTemperature;
|
||||
// Default to run fan at full speed.
|
||||
int newPWMvalue = 255;
|
||||
int pwmStep = ((100 - minPWMValuePct) * newPWMvalue) / (7*100);
|
||||
int pwmMinimumValue = (minPWMValuePct * newPWMvalue) / 100;
|
||||
// dividing minPercent and maxPercent into equal pwmvalue sizes
|
||||
int pwmStepSize = ((maxPWMValuePct - minPWMValuePct) * _pwmMaxValue) / (_pwmMaxStepCount*100);
|
||||
int pwmStep = calculatePwmStep(temp - targetTemperature);
|
||||
// minimum based on full speed - not entered MaxPercent
|
||||
int pwmMinimumValue = (minPWMValuePct * _pwmMaxValue) / 100;
|
||||
updateFanSpeed(pwmMinimumValue + pwmStep*pwmStepSize);
|
||||
}
|
||||
|
||||
if ((temp == NAN) || (temp <= -100.0)) {
|
||||
uint8_t calculatePwmStep(float diffTemp){
|
||||
if ((diffTemp == NAN) || (diffTemp <= -100.0)) {
|
||||
DEBUG_PRINTLN(F("WARNING: no temperature value available. Cannot do temperature control. Will set PWM fan to 255."));
|
||||
} else if (difftemp <= 0.0) {
|
||||
// Temperature is below target temperature. Run fan at minimum speed.
|
||||
newPWMvalue = pwmMinimumValue;
|
||||
} else if (difftemp <= 0.5) {
|
||||
newPWMvalue = pwmMinimumValue + pwmStep;
|
||||
} else if (difftemp <= 1.0) {
|
||||
newPWMvalue = pwmMinimumValue + 2*pwmStep;
|
||||
} else if (difftemp <= 1.5) {
|
||||
newPWMvalue = pwmMinimumValue + 3*pwmStep;
|
||||
} else if (difftemp <= 2.0) {
|
||||
newPWMvalue = pwmMinimumValue + 4*pwmStep;
|
||||
} else if (difftemp <= 2.5) {
|
||||
newPWMvalue = pwmMinimumValue + 5*pwmStep;
|
||||
} else if (difftemp <= 3.0) {
|
||||
newPWMvalue = pwmMinimumValue + 6*pwmStep;
|
||||
return _pwmMaxStepCount;
|
||||
}
|
||||
updateFanSpeed(newPWMvalue);
|
||||
if(diffTemp <=0){
|
||||
return 0;
|
||||
}
|
||||
int calculatedStep = (diffTemp / _pwmTempStepSize)+1;
|
||||
// anything greater than max stepcount gets max
|
||||
return (uint8_t)min((int)_pwmMaxStepCount,calculatedStep);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -312,6 +313,7 @@ class PWMFanUsermod : public Usermod {
|
|||
top[FPSTR(_tachoUpdateSec)] = tachoUpdateSec;
|
||||
top[FPSTR(_temperature)] = targetTemperature;
|
||||
top[FPSTR(_minPWMValuePct)] = minPWMValuePct;
|
||||
top[FPSTR(_maxPWMValuePct)] = maxPWMValuePct;
|
||||
top[FPSTR(_IRQperRotation)] = numberOfInterrupsInOneSingleRotation;
|
||||
DEBUG_PRINTLN(F("Autosave config saved."));
|
||||
}
|
||||
|
@ -345,6 +347,8 @@ class PWMFanUsermod : public Usermod {
|
|||
targetTemperature = top[FPSTR(_temperature)] | targetTemperature;
|
||||
minPWMValuePct = top[FPSTR(_minPWMValuePct)] | minPWMValuePct;
|
||||
minPWMValuePct = (uint8_t) min(100,max(0,(int)minPWMValuePct)); // bounds checking
|
||||
maxPWMValuePct = top[FPSTR(_maxPWMValuePct)] | maxPWMValuePct;
|
||||
maxPWMValuePct = (uint8_t) min(100,max((int)minPWMValuePct,(int)maxPWMValuePct)); // bounds checking
|
||||
numberOfInterrupsInOneSingleRotation = top[FPSTR(_IRQperRotation)] | numberOfInterrupsInOneSingleRotation;
|
||||
numberOfInterrupsInOneSingleRotation = (uint8_t) max(1,(int)numberOfInterrupsInOneSingleRotation); // bounds checking
|
||||
|
||||
|
@ -389,6 +393,7 @@ const char PWMFanUsermod::_pwmPin[] PROGMEM = "PWM-pin";
|
|||
const char PWMFanUsermod::_temperature[] PROGMEM = "target-temp-C";
|
||||
const char PWMFanUsermod::_tachoUpdateSec[] PROGMEM = "tacho-update-s";
|
||||
const char PWMFanUsermod::_minPWMValuePct[] PROGMEM = "min-PWM-percent";
|
||||
const char PWMFanUsermod::_maxPWMValuePct[] PROGMEM = "max-PWM-percent";
|
||||
const char PWMFanUsermod::_IRQperRotation[] PROGMEM = "IRQs-per-rotation";
|
||||
const char PWMFanUsermod::_speed[] PROGMEM = "speed";
|
||||
const char PWMFanUsermod::_lock[] PROGMEM = "lock";
|
||||
|
|
|
@ -24,6 +24,9 @@ Enables the inverted mode in which the background should be enabled and the digi
|
|||
### Colon-blinking
|
||||
Enables the blinking colon(s) if they are defined
|
||||
|
||||
### Leading-Zero
|
||||
Shows the leading zero of the hour if it exists (i.e. shows `07` instead of `7`)
|
||||
|
||||
### enable-auto-brightness
|
||||
Enables the auto brightness feature. Can be used only when the usermod SN_Photoresistor is installed.
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ private:
|
|||
bool umSSDRDisplayTime = false;
|
||||
bool umSSDRInverted = false;
|
||||
bool umSSDRColonblink = true;
|
||||
bool umSSDRLeadingZero = false;
|
||||
bool umSSDREnableLDR = false;
|
||||
String umSSDRHours = "";
|
||||
String umSSDRMinutes = "";
|
||||
|
@ -79,6 +80,7 @@ private:
|
|||
static const char _str_timeEnabled[];
|
||||
static const char _str_inverted[];
|
||||
static const char _str_colonblink[];
|
||||
static const char _str_leadingZero[];
|
||||
static const char _str_displayMask[];
|
||||
static const char _str_hours[];
|
||||
static const char _str_minutes[];
|
||||
|
@ -105,15 +107,15 @@ private:
|
|||
switch (umSSDRDisplayMask[index]) {
|
||||
case 'h':
|
||||
timeVar = hourFormat12(localTime);
|
||||
_showElements(&umSSDRHours, timeVar, 0, 1);
|
||||
_showElements(&umSSDRHours, timeVar, 0, !umSSDRLeadingZero);
|
||||
break;
|
||||
case 'H':
|
||||
timeVar = hour(localTime);
|
||||
_showElements(&umSSDRHours, timeVar, 0, 1);
|
||||
_showElements(&umSSDRHours, timeVar, 0, !umSSDRLeadingZero);
|
||||
break;
|
||||
case 'k':
|
||||
timeVar = hour(localTime) + 1;
|
||||
_showElements(&umSSDRHours, timeVar, 0, 0);
|
||||
_showElements(&umSSDRHours, timeVar, 0, !umSSDRLeadingZero);
|
||||
break;
|
||||
case 'm':
|
||||
timeVar = minute(localTime);
|
||||
|
@ -309,6 +311,9 @@ private:
|
|||
if (_cmpIntSetting_P(topic, payload, _str_colonblink, &umSSDRColonblink)) {
|
||||
return true;
|
||||
}
|
||||
if (_cmpIntSetting_P(topic, payload, _str_leadingZero, &umSSDRLeadingZero)) {
|
||||
return true;
|
||||
}
|
||||
if (strcmp_P(topic, _str_displayMask) == 0) {
|
||||
umSSDRDisplayMask = String(payload);
|
||||
_publishMQTTstr_P(_str_displayMask, umSSDRDisplayMask);
|
||||
|
@ -323,6 +328,7 @@ private:
|
|||
_publishMQTTint_P(_str_ldrEnabled, umSSDREnableLDR);
|
||||
_publishMQTTint_P(_str_inverted, umSSDRInverted);
|
||||
_publishMQTTint_P(_str_colonblink, umSSDRColonblink);
|
||||
_publishMQTTint_P(_str_leadingZero, umSSDRLeadingZero);
|
||||
|
||||
_publishMQTTstr_P(_str_hours, umSSDRHours);
|
||||
_publishMQTTstr_P(_str_minutes, umSSDRMinutes);
|
||||
|
@ -347,6 +353,7 @@ private:
|
|||
ssdrObj[FPSTR(_str_ldrEnabled)] = umSSDREnableLDR;
|
||||
ssdrObj[FPSTR(_str_inverted)] = umSSDRInverted;
|
||||
ssdrObj[FPSTR(_str_colonblink)] = umSSDRColonblink;
|
||||
ssdrObj[FPSTR(_str_leadingZero)] = umSSDRLeadingZero;
|
||||
ssdrObj[FPSTR(_str_displayMask)] = umSSDRDisplayMask;
|
||||
ssdrObj[FPSTR(_str_hours)] = umSSDRHours;
|
||||
ssdrObj[FPSTR(_str_minutes)] = umSSDRMinutes;
|
||||
|
@ -425,6 +432,8 @@ public:
|
|||
invert.add(umSSDRInverted);
|
||||
JsonArray blink = user.createNestedArray("Blinking colon");
|
||||
blink.add(umSSDRColonblink);
|
||||
JsonArray zero = user.createNestedArray("Show the hour leading zero");
|
||||
zero.add(umSSDRLeadingZero);
|
||||
JsonArray ldrEnable = user.createNestedArray("Auto Brightness enabled");
|
||||
ldrEnable.add(umSSDREnableLDR);
|
||||
|
||||
|
@ -454,6 +463,7 @@ public:
|
|||
umSSDREnableLDR = ssdrObj[FPSTR(_str_ldrEnabled)] | umSSDREnableLDR;
|
||||
umSSDRInverted = ssdrObj[FPSTR(_str_inverted)] | umSSDRInverted;
|
||||
umSSDRColonblink = ssdrObj[FPSTR(_str_colonblink)] | umSSDRColonblink;
|
||||
umSSDRLeadingZero = ssdrObj[FPSTR(_str_leadingZero)] | umSSDRLeadingZero;
|
||||
umSSDRDisplayMask = ssdrObj[FPSTR(_str_displayMask)] | umSSDRDisplayMask;
|
||||
}
|
||||
}
|
||||
|
@ -516,6 +526,7 @@ public:
|
|||
umSSDREnableLDR = (top[FPSTR(_str_ldrEnabled)] | umSSDREnableLDR);
|
||||
umSSDRInverted = (top[FPSTR(_str_inverted)] | umSSDRInverted);
|
||||
umSSDRColonblink = (top[FPSTR(_str_colonblink)] | umSSDRColonblink);
|
||||
umSSDRLeadingZero = (top[FPSTR(_str_leadingZero)] | umSSDRLeadingZero);
|
||||
|
||||
umSSDRDisplayMask = top[FPSTR(_str_displayMask)] | umSSDRDisplayMask;
|
||||
umSSDRHours = top[FPSTR(_str_hours)] | umSSDRHours;
|
||||
|
@ -546,6 +557,7 @@ const char UsermodSSDR::_str_name[] PROGMEM = "UsermodSSDR";
|
|||
const char UsermodSSDR::_str_timeEnabled[] PROGMEM = "enabled";
|
||||
const char UsermodSSDR::_str_inverted[] PROGMEM = "inverted";
|
||||
const char UsermodSSDR::_str_colonblink[] PROGMEM = "Colon-blinking";
|
||||
const char UsermodSSDR::_str_leadingZero[] PROGMEM = "Leading-Zero";
|
||||
const char UsermodSSDR::_str_displayMask[] PROGMEM = "Display-Mask";
|
||||
const char UsermodSSDR::_str_hours[] PROGMEM = "LED-Numbers-Hours";
|
||||
const char UsermodSSDR::_str_minutes[] PROGMEM = "LED-Numbers-Minutes";
|
||||
|
|
|
@ -177,11 +177,11 @@ uint16_t color_wipe(bool rev, bool useRandomColors) {
|
|||
SEGENV.step = 3;
|
||||
}
|
||||
if (SEGENV.step == 1) { //if flag set, change to new random color
|
||||
SEGENV.aux1 = SEGMENT.get_random_wheel_index(SEGENV.aux0);
|
||||
SEGENV.aux1 = get_random_wheel_index(SEGENV.aux0);
|
||||
SEGENV.step = 2;
|
||||
}
|
||||
if (SEGENV.step == 3) {
|
||||
SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux1);
|
||||
SEGENV.aux0 = get_random_wheel_index(SEGENV.aux1);
|
||||
SEGENV.step = 0;
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ uint16_t mode_random_color(void) {
|
|||
if (it != SEGENV.step) //new color
|
||||
{
|
||||
SEGENV.aux1 = SEGENV.aux0;
|
||||
SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux0); //aux0 will store our random color wheel index
|
||||
SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); //aux0 will store our random color wheel index
|
||||
SEGENV.step = it;
|
||||
}
|
||||
|
||||
|
@ -816,7 +816,7 @@ uint16_t chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palett
|
|||
if (a < SEGENV.step) //we hit the start again, choose new color for Chase random
|
||||
{
|
||||
SEGENV.aux1 = SEGENV.aux0; //store previous random color
|
||||
SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux0);
|
||||
SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0);
|
||||
}
|
||||
color1 = SEGMENT.color_wheel(SEGENV.aux0);
|
||||
}
|
||||
|
@ -1056,7 +1056,7 @@ uint16_t mode_chase_flash_random(void) {
|
|||
SEGENV.aux1 = (SEGENV.aux1 + 1) % SEGLEN;
|
||||
|
||||
if (SEGENV.aux1 == 0) {
|
||||
SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux0);
|
||||
SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0);
|
||||
}
|
||||
}
|
||||
return delay;
|
||||
|
@ -2590,14 +2590,14 @@ uint16_t mode_twinklefox()
|
|||
{
|
||||
return twinklefox_base(false);
|
||||
}
|
||||
static const char _data_FX_MODE_TWINKLEFOX[] PROGMEM = "Twinklefox@!,Twinkle rate,,,,Cool;;!";
|
||||
static const char _data_FX_MODE_TWINKLEFOX[] PROGMEM = "Twinklefox@!,Twinkle rate,,,,Cool;!,!;!";
|
||||
|
||||
|
||||
uint16_t mode_twinklecat()
|
||||
{
|
||||
return twinklefox_base(true);
|
||||
}
|
||||
static const char _data_FX_MODE_TWINKLECAT[] PROGMEM = "Twinklecat@!,Twinkle rate,,,,Cool;;!";
|
||||
static const char _data_FX_MODE_TWINKLECAT[] PROGMEM = "Twinklecat@!,Twinkle rate,,,,Cool;!,!;!";
|
||||
|
||||
|
||||
//inspired by https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectBlinkingHalloweenEyes
|
||||
|
@ -5946,6 +5946,8 @@ uint16_t mode_2Dscrollingtext(void) {
|
|||
else if (!strncmp_P(text,PSTR("#MMDD"),5)) sprintf_P(text, zero?PSTR("%02d/%02d") :PSTR("%d/%d"), month(localTime), day(localTime));
|
||||
else if (!strncmp_P(text,PSTR("#TIME"),5)) sprintf_P(text, zero?PSTR("%02d:%02d%s") :PSTR("%2d:%02d%s"), AmPmHour, minute(localTime), sec);
|
||||
else if (!strncmp_P(text,PSTR("#HHMM"),5)) sprintf_P(text, zero?PSTR("%02d:%02d") :PSTR("%d:%02d"), AmPmHour, minute(localTime));
|
||||
else if (!strncmp_P(text,PSTR("#HH"),3)) sprintf_P(text, zero?PSTR("%02d") :PSTR("%d"), AmPmHour);
|
||||
else if (!strncmp_P(text,PSTR("#MM"),3)) sprintf_P(text, zero?PSTR("%02d") :PSTR("%d"), minute(localTime));
|
||||
}
|
||||
|
||||
const int numberOfLetters = strlen(text);
|
||||
|
|
53
wled00/FX.h
53
wled00/FX.h
|
@ -109,20 +109,15 @@
|
|||
#define PINK (uint32_t)0xFF1493
|
||||
#define ULTRAWHITE (uint32_t)0xFFFFFFFF
|
||||
#define DARKSLATEGRAY (uint32_t)0x2F4F4F
|
||||
#define DARKSLATEGREY (uint32_t)0x2F4F4F
|
||||
#define DARKSLATEGREY DARKSLATEGRAY
|
||||
|
||||
// options
|
||||
// bit 7: segment is in transition mode
|
||||
// bits 4-6: TBD
|
||||
// bit 3: mirror effect within segment
|
||||
// bit 2: segment is on
|
||||
// bit 1: reverse segment
|
||||
// bit 0: segment is selected
|
||||
// segment options
|
||||
#define NO_OPTIONS (uint16_t)0x0000
|
||||
#define TRANSPOSED (uint16_t)0x0400 // rotated 90deg & reversed
|
||||
#define REVERSE_Y_2D (uint16_t)0x0200
|
||||
#define MIRROR_Y_2D (uint16_t)0x0100
|
||||
#define TRANSITIONAL (uint16_t)0x0080
|
||||
#define TRANSPOSED (uint16_t)0x0100 // rotated 90deg & reversed
|
||||
#define MIRROR_Y_2D (uint16_t)0x0080
|
||||
#define REVERSE_Y_2D (uint16_t)0x0040
|
||||
#define RESET_REQ (uint16_t)0x0020
|
||||
#define FROZEN (uint16_t)0x0010
|
||||
#define MIRROR (uint16_t)0x0008
|
||||
#define SEGMENT_ON (uint16_t)0x0004
|
||||
#define REVERSE (uint16_t)0x0002
|
||||
|
@ -348,12 +343,11 @@ typedef struct Segment {
|
|||
bool mirror : 1; // 3 : mirrored
|
||||
bool freeze : 1; // 4 : paused/frozen
|
||||
bool reset : 1; // 5 : indicates that Segment runtime requires reset
|
||||
bool transitional: 1; // 6 : transitional (there is transition occuring)
|
||||
bool reverse_y : 1; // 7 : reversed Y (2D)
|
||||
bool mirror_y : 1; // 8 : mirrored Y (2D)
|
||||
bool transpose : 1; // 9 : transposed (2D, swapped X & Y)
|
||||
uint8_t map1D2D : 3; // 10-12 : mapping for 1D effect on 2D (0-use as strip, 1-expand vertically, 2-circular/arc, 3-rectangular/corner, ...)
|
||||
uint8_t soundSim : 1; // 13 : 0-1 sound simulation types ("soft" & "hard" or "on"/"off")
|
||||
bool reverse_y : 1; // 6 : reversed Y (2D)
|
||||
bool mirror_y : 1; // 7 : mirrored Y (2D)
|
||||
bool transpose : 1; // 8 : transposed (2D, swapped X & Y)
|
||||
uint8_t map1D2D : 3; // 9-11 : mapping for 1D effect on 2D (0-use as strip, 1-expand vertically, 2-circular/arc, 3-rectangular/corner, ...)
|
||||
uint8_t soundSim : 2; // 12-13 : 0-3 sound simulation types ("soft" & "hard" or "on"/"off")
|
||||
uint8_t set : 2; // 14-15 : 0-3 UI segment sets/groups
|
||||
};
|
||||
};
|
||||
|
@ -484,7 +478,6 @@ typedef struct Segment {
|
|||
_dataLen(0),
|
||||
_t(nullptr)
|
||||
{
|
||||
//refreshLightCapabilities();
|
||||
#ifdef WLED_DEBUG
|
||||
//Serial.printf("-- Creating segment: %p\n", this);
|
||||
#endif
|
||||
|
@ -519,6 +512,7 @@ typedef struct Segment {
|
|||
|
||||
inline bool getOption(uint8_t n) const { return ((options >> n) & 0x01); }
|
||||
inline bool isSelected(void) const { return selected; }
|
||||
inline bool isInTransition(void) const { return _t != nullptr; }
|
||||
inline bool isActive(void) const { return stop > start; }
|
||||
inline bool is2D(void) const { return (width()>1 && height()>1); }
|
||||
inline bool hasRGB(void) const { return _isRGB; }
|
||||
|
@ -569,15 +563,16 @@ typedef struct Segment {
|
|||
void restoreSegenv(tmpsegd_t &tmpSegD);
|
||||
#endif
|
||||
uint16_t progress(void); //transition progression between 0-65535
|
||||
uint8_t currentBri(uint8_t briNew, bool useCct = false);
|
||||
uint8_t currentMode(uint8_t modeNew);
|
||||
uint32_t currentColor(uint8_t slot, uint32_t colorNew);
|
||||
uint8_t currentBri(bool useCct = false);
|
||||
uint8_t currentMode(void);
|
||||
uint32_t currentColor(uint8_t slot);
|
||||
CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal);
|
||||
CRGBPalette16 ¤tPalette(CRGBPalette16 &tgt, uint8_t paletteID);
|
||||
|
||||
// 1D strip
|
||||
uint16_t virtualLength(void) const;
|
||||
void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color
|
||||
void setPixelColor(unsigned n, uint32_t c) { setPixelColor(int(n), c); }
|
||||
void setPixelColor(int n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } // automatically inline
|
||||
void setPixelColor(int n, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); } // automatically inline
|
||||
void setPixelColor(float i, uint32_t c, bool aa = true);
|
||||
|
@ -595,7 +590,6 @@ typedef struct Segment {
|
|||
void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(n, RGBW32(r,g,b,w), fast); } // automatically inline
|
||||
void addPixelColor(int n, CRGB c, bool fast = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), fast); } // automatically inline
|
||||
void fadePixelColor(uint16_t n, uint8_t fade);
|
||||
uint8_t get_random_wheel_index(uint8_t pos);
|
||||
uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255);
|
||||
uint32_t color_wheel(uint8_t pos);
|
||||
|
||||
|
@ -606,6 +600,7 @@ typedef struct Segment {
|
|||
#ifndef WLED_DISABLE_2D
|
||||
uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment
|
||||
void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
|
||||
void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColorXY(int(x), int(y), c); }
|
||||
void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline
|
||||
void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } // automatically inline
|
||||
void setPixelColorXY(float x, float y, uint32_t c, bool aa = true);
|
||||
|
@ -881,16 +876,14 @@ class WS2812FX { // 96 bytes
|
|||
std::vector<Panel> panel;
|
||||
#endif
|
||||
|
||||
void
|
||||
setUpMatrix(),
|
||||
setPixelColorXY(int x, int y, uint32_t c);
|
||||
void setUpMatrix();
|
||||
|
||||
// outsmart the compiler :) by correctly overloading
|
||||
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline
|
||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); }
|
||||
inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(y * Segment::maxWidth + x, c); }
|
||||
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); }
|
||||
|
||||
uint32_t
|
||||
getPixelColorXY(uint16_t, uint16_t);
|
||||
inline uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(isMatrix ? y * Segment::maxWidth + x : x);}
|
||||
|
||||
// end 2D support
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ void WS2812FX::setUpMatrix() {
|
|||
|
||||
#ifdef WLED_DEBUG
|
||||
DEBUG_PRINT(F("Matrix ledmap:"));
|
||||
for (uint16_t i=0; i<customMappingSize; i++) {
|
||||
for (unsigned i=0; i<customMappingSize; i++) {
|
||||
if (!(i%Segment::maxWidth)) DEBUG_PRINTLN();
|
||||
DEBUG_PRINTF("%4d,", customMappingTable[i]);
|
||||
}
|
||||
|
@ -155,31 +155,6 @@ void WS2812FX::setUpMatrix() {
|
|||
#endif
|
||||
}
|
||||
|
||||
// absolute matrix version of setPixelColor()
|
||||
void /*IRAM_ATTR*/ WS2812FX::setPixelColorXY(int x, int y, uint32_t col)
|
||||
{
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (!isMatrix) return; // not a matrix set-up
|
||||
uint16_t index = y * Segment::maxWidth + x;
|
||||
#else
|
||||
uint16_t index = x;
|
||||
#endif
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
if (index >= _length) return;
|
||||
busses.setPixelColor(index, col);
|
||||
}
|
||||
|
||||
// returns RGBW values of pixel
|
||||
uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
uint16_t index = (y * Segment::maxWidth + x);
|
||||
#else
|
||||
uint16_t index = x;
|
||||
#endif
|
||||
if (index < customMappingSize) index = customMappingTable[index];
|
||||
if (index >= _length) return 0;
|
||||
return busses.getPixelColor(index);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Segment:: routines
|
||||
|
@ -188,18 +163,19 @@ uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) {
|
|||
#ifndef WLED_DISABLE_2D
|
||||
|
||||
// XY(x,y) - gets pixel index within current segment (often used to reference leds[] array element)
|
||||
uint16_t /*IRAM_ATTR*/ Segment::XY(uint16_t x, uint16_t y) {
|
||||
uint16_t IRAM_ATTR Segment::XY(uint16_t x, uint16_t y)
|
||||
{
|
||||
uint16_t width = virtualWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||
uint16_t height = virtualHeight(); // segment height in logical pixels (is always >= 1)
|
||||
return isActive() ? (x%width) + (y%height) * width : 0;
|
||||
}
|
||||
|
||||
void /*IRAM_ATTR*/ Segment::setPixelColorXY(int x, int y, uint32_t col)
|
||||
void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
|
||||
{
|
||||
if (!isActive()) return; // not active
|
||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||
|
||||
uint8_t _bri_t = currentBri(on ? opacity : 0);
|
||||
uint8_t _bri_t = currentBri();
|
||||
if (_bri_t < 255) {
|
||||
byte r = scale8(R(col), _bri_t);
|
||||
byte g = scale8(G(col), _bri_t);
|
||||
|
@ -310,32 +286,17 @@ void Segment::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t
|
|||
void Segment::addPixelColorXY(int x, int y, uint32_t color, bool fast) {
|
||||
if (!isActive()) return; // not active
|
||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||
uint32_t col = getPixelColorXY(x,y);
|
||||
uint8_t r = R(col);
|
||||
uint8_t g = G(col);
|
||||
uint8_t b = B(col);
|
||||
uint8_t w = W(col);
|
||||
if (fast) {
|
||||
r = qadd8(r, R(color));
|
||||
g = qadd8(g, G(color));
|
||||
b = qadd8(b, B(color));
|
||||
w = qadd8(w, W(color));
|
||||
col = RGBW32(r,g,b,w);
|
||||
} else {
|
||||
col = color_add(col, color);
|
||||
}
|
||||
setPixelColorXY(x, y, col);
|
||||
setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color, fast));
|
||||
}
|
||||
|
||||
void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) {
|
||||
if (!isActive()) return; // not active
|
||||
CRGB pix = CRGB(getPixelColorXY(x,y)).nscale8_video(fade);
|
||||
setPixelColorXY(x, y, pix);
|
||||
setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), fade, true));
|
||||
}
|
||||
|
||||
// blurRow: perform a blur on a row of a rectangular matrix
|
||||
void Segment::blurRow(uint16_t row, fract8 blur_amount) {
|
||||
if (!isActive()) return; // not active
|
||||
if (!isActive() || blur_amount == 0) return; // not active
|
||||
const uint_fast16_t cols = virtualWidth();
|
||||
const uint_fast16_t rows = virtualHeight();
|
||||
|
||||
|
@ -344,7 +305,7 @@ void Segment::blurRow(uint16_t row, fract8 blur_amount) {
|
|||
uint8_t keep = 255 - blur_amount;
|
||||
uint8_t seep = blur_amount >> 1;
|
||||
CRGB carryover = CRGB::Black;
|
||||
for (uint_fast16_t x = 0; x < cols; x++) {
|
||||
for (unsigned x = 0; x < cols; x++) {
|
||||
CRGB cur = getPixelColorXY(x, row);
|
||||
CRGB before = cur; // remember color before blur
|
||||
CRGB part = cur;
|
||||
|
@ -363,7 +324,7 @@ void Segment::blurRow(uint16_t row, fract8 blur_amount) {
|
|||
|
||||
// blurCol: perform a blur on a column of a rectangular matrix
|
||||
void Segment::blurCol(uint16_t col, fract8 blur_amount) {
|
||||
if (!isActive()) return; // not active
|
||||
if (!isActive() || blur_amount == 0) return; // not active
|
||||
const uint_fast16_t cols = virtualWidth();
|
||||
const uint_fast16_t rows = virtualHeight();
|
||||
|
||||
|
@ -372,7 +333,7 @@ void Segment::blurCol(uint16_t col, fract8 blur_amount) {
|
|||
uint8_t keep = 255 - blur_amount;
|
||||
uint8_t seep = blur_amount >> 1;
|
||||
CRGB carryover = CRGB::Black;
|
||||
for (uint_fast16_t y = 0; y < rows; y++) {
|
||||
for (unsigned y = 0; y < rows; y++) {
|
||||
CRGB cur = getPixelColorXY(col, y);
|
||||
CRGB part = cur;
|
||||
CRGB before = cur; // remember color before blur
|
||||
|
@ -391,7 +352,7 @@ void Segment::blurCol(uint16_t col, fract8 blur_amount) {
|
|||
|
||||
// 1D Box blur (with added weight - blur_amount: [0=no blur, 255=max blur])
|
||||
void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) {
|
||||
if (!isActive()) return; // not active
|
||||
if (!isActive() || blur_amount == 0) return; // not active
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
const uint16_t dim1 = vertical ? rows : cols;
|
||||
|
@ -401,7 +362,7 @@ void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) {
|
|||
const float keep = 3.f - 2.f*seep;
|
||||
// 1D box blur
|
||||
CRGB tmp[dim1];
|
||||
for (uint16_t j = 0; j < dim1; j++) {
|
||||
for (int j = 0; j < dim1; j++) {
|
||||
uint16_t x = vertical ? i : j;
|
||||
uint16_t y = vertical ? j : i;
|
||||
int16_t xp = vertical ? x : x-1; // "signed" to prevent underflow
|
||||
|
@ -417,7 +378,7 @@ void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) {
|
|||
b = (curr.b*keep + (prev.b + next.b)*seep) / 3;
|
||||
tmp[j] = CRGB(r,g,b);
|
||||
}
|
||||
for (uint16_t j = 0; j < dim1; j++) {
|
||||
for (int j = 0; j < dim1; j++) {
|
||||
uint16_t x = vertical ? i : j;
|
||||
uint16_t y = vertical ? j : i;
|
||||
setPixelColorXY(x, y, tmp[j]);
|
||||
|
@ -440,7 +401,7 @@ void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) {
|
|||
|
||||
void Segment::blur1d(fract8 blur_amount) {
|
||||
const uint16_t rows = virtualHeight();
|
||||
for (uint16_t y = 0; y < rows; y++) blurRow(y, blur_amount);
|
||||
for (unsigned y = 0; y < rows; y++) blurRow(y, blur_amount);
|
||||
}
|
||||
|
||||
void Segment::moveX(int8_t delta, bool wrap) {
|
||||
|
@ -498,7 +459,7 @@ void Segment::move(uint8_t dir, uint8_t delta, bool wrap) {
|
|||
}
|
||||
|
||||
void Segment::draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
||||
if (!isActive()) return; // not active
|
||||
if (!isActive() || radius == 0) return; // not active
|
||||
// Bresenham’s Algorithm
|
||||
int d = 3 - (2*radius);
|
||||
int y = radius, x = 0;
|
||||
|
@ -523,7 +484,7 @@ void Segment::draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
|||
|
||||
// by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs
|
||||
void Segment::fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
||||
if (!isActive()) return; // not active
|
||||
if (!isActive() || radius == 0) return; // not active
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
for (int16_t y = -radius; y <= radius; y++) {
|
||||
|
@ -540,7 +501,7 @@ void Segment::nscale8(uint8_t scale) {
|
|||
if (!isActive()) return; // not active
|
||||
const uint16_t cols = virtualWidth();
|
||||
const uint16_t rows = virtualHeight();
|
||||
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
||||
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) {
|
||||
setPixelColorXY(x, y, CRGB(getPixelColorXY(x, y)).nscale8(scale));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,25 +89,19 @@ bool Segment::_modeBlend = false;
|
|||
Segment::Segment(const Segment &orig) {
|
||||
//DEBUG_PRINTF("-- Copy segment constructor: %p -> %p\n", &orig, this);
|
||||
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
||||
transitional = false; // copied segment cannot be in transition
|
||||
name = nullptr;
|
||||
data = nullptr;
|
||||
_dataLen = 0;
|
||||
_t = nullptr;
|
||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
||||
if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); }
|
||||
//if (orig._t) { _t = new Transition(orig._t->_dur); }
|
||||
_t = nullptr; // copied segment cannot be in transition
|
||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); } else { name = nullptr; }
|
||||
if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); } else { data = nullptr; _dataLen = 0; }
|
||||
}
|
||||
|
||||
// move constructor
|
||||
Segment::Segment(Segment &&orig) noexcept {
|
||||
//DEBUG_PRINTF("-- Move segment constructor: %p -> %p\n", &orig, this);
|
||||
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
||||
orig.transitional = false; // old segment cannot be in transition any more
|
||||
orig.name = nullptr;
|
||||
orig.data = nullptr;
|
||||
orig._dataLen = 0;
|
||||
orig._t = nullptr;
|
||||
orig._t = nullptr; // old segment cannot be in transition any more
|
||||
}
|
||||
|
||||
// copy assignment
|
||||
|
@ -115,27 +109,23 @@ Segment& Segment::operator= (const Segment &orig) {
|
|||
//DEBUG_PRINTF("-- Copying segment: %p -> %p\n", &orig, this);
|
||||
if (this != &orig) {
|
||||
// clean destination
|
||||
transitional = false; // copied segment cannot be in transition
|
||||
if (name) delete[] name;
|
||||
if (name) { delete[] name; name = nullptr; }
|
||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
||||
if (_t) {
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (_t->_segT._dataT) free(_t->_segT._dataT);
|
||||
#endif
|
||||
delete _t;
|
||||
_t = nullptr; // copied segment cannot be in transition
|
||||
}
|
||||
deallocateData();
|
||||
// copy source
|
||||
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
||||
transitional = false;
|
||||
// erase pointers to allocated data
|
||||
name = nullptr;
|
||||
data = nullptr;
|
||||
_dataLen = 0;
|
||||
_t = nullptr;
|
||||
// copy source data
|
||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
||||
if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); }
|
||||
//if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -144,9 +134,7 @@ Segment& Segment::operator= (const Segment &orig) {
|
|||
Segment& Segment::operator= (Segment &&orig) noexcept {
|
||||
//DEBUG_PRINTF("-- Moving segment: %p -> %p\n", &orig, this);
|
||||
if (this != &orig) {
|
||||
transitional = false; // just temporary
|
||||
if (name) { delete[] name; name = nullptr; } // free old name
|
||||
deallocateData(); // free old runtime data
|
||||
if (_t) {
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (_t->_segT._dataT) free(_t->_segT._dataT);
|
||||
|
@ -154,12 +142,12 @@ Segment& Segment::operator= (Segment &&orig) noexcept {
|
|||
delete _t;
|
||||
_t = nullptr;
|
||||
}
|
||||
deallocateData(); // free old runtime data
|
||||
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
||||
orig.transitional = false; // old segment cannot be in transition
|
||||
orig.name = nullptr;
|
||||
orig.data = nullptr;
|
||||
orig._dataLen = 0;
|
||||
orig._t = nullptr;
|
||||
orig._t = nullptr; // old segment cannot be in transition
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -237,7 +225,7 @@ CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
|
|||
switch (pal) {
|
||||
case 0: //default palette. Exceptions for specific effects above
|
||||
targetPalette = PartyColors_p; break;
|
||||
case 1: {//periodically replace palette with a random one. Transition palette change in 500ms
|
||||
case 1: {//periodically replace palette with a random one
|
||||
unsigned long timeSinceLastChange = millis() - _lastPaletteChange;
|
||||
if (timeSinceLastChange > randomPaletteChangeTime * 1000U) {
|
||||
_randomPalette = _newRandomPalette;
|
||||
|
@ -301,47 +289,45 @@ CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
|
|||
}
|
||||
|
||||
void Segment::startTransition(uint16_t dur) {
|
||||
if (!dur) {
|
||||
if (_t) _t->_dur = dur; // this will stop transition in next handleTransisiton()
|
||||
else transitional = false;
|
||||
if (dur == 0) {
|
||||
if (isInTransition()) _t->_dur = dur; // this will stop transition in next handleTransisiton()
|
||||
return;
|
||||
}
|
||||
if (transitional && _t) return; // already in transition no need to store anything
|
||||
if (isInTransition()) return; // already in transition no need to store anything
|
||||
|
||||
// starting a transition has to occur before change so we get current values 1st
|
||||
_t = new Transition(dur); // no previous transition running
|
||||
if (!_t) return; // failed to allocate data
|
||||
|
||||
//DEBUG_PRINTF("-- Started transition: %p\n", this);
|
||||
CRGBPalette16 _palT = CRGBPalette16(DEFAULT_COLOR); loadPalette(_palT, palette);
|
||||
_t->_palT = _palT;
|
||||
loadPalette(_t->_palT, palette);
|
||||
_t->_briT = on ? opacity : 0;
|
||||
_t->_cctT = cct;
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
swapSegenv(_t->_segT);
|
||||
_t->_modeT = mode;
|
||||
_t->_segT._optionsT |= 0b0000000001000000; // mark old segment transitional
|
||||
_t->_segT._dataLenT = 0;
|
||||
_t->_segT._dataT = nullptr;
|
||||
if (_dataLen > 0 && data) {
|
||||
_t->_segT._dataT = (byte *)malloc(_dataLen);
|
||||
if (_t->_segT._dataT) {
|
||||
//DEBUG_PRINTF("-- Allocated duplicate data (%d): %p\n", _dataLen, _t->_segT._dataT);
|
||||
memcpy(_t->_segT._dataT, data, _dataLen);
|
||||
_t->_segT._dataLenT = _dataLen;
|
||||
if (modeBlending) {
|
||||
swapSegenv(_t->_segT);
|
||||
_t->_modeT = mode;
|
||||
_t->_segT._dataLenT = 0;
|
||||
_t->_segT._dataT = nullptr;
|
||||
if (_dataLen > 0 && data) {
|
||||
_t->_segT._dataT = (byte *)malloc(_dataLen);
|
||||
if (_t->_segT._dataT) {
|
||||
//DEBUG_PRINTF("-- Allocated duplicate data (%d): %p\n", _dataLen, _t->_segT._dataT);
|
||||
memcpy(_t->_segT._dataT, data, _dataLen);
|
||||
_t->_segT._dataLenT = _dataLen;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<NUM_COLORS; i++) _t->_segT._colorT[i] = colors[i];
|
||||
}
|
||||
#else
|
||||
for (size_t i=0; i<NUM_COLORS; i++) _t->_colorT[i] = colors[i];
|
||||
#endif
|
||||
transitional = true; // setOption(SEG_OPTION_TRANSITIONAL, true);
|
||||
}
|
||||
|
||||
void Segment::stopTransition() {
|
||||
if (!transitional) return;
|
||||
transitional = false; // finish transitioning segment
|
||||
//DEBUG_PRINTF("-- Stopping transition: %p\n", this);
|
||||
if (_t) {
|
||||
if (isInTransition()) {
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (_t->_segT._dataT && _t->_segT._dataLenT > 0) {
|
||||
//DEBUG_PRINTF("-- Released duplicate data (%d): %p\n", _t->_segT._dataLenT, _t->_segT._dataT);
|
||||
|
@ -356,14 +342,13 @@ void Segment::stopTransition() {
|
|||
}
|
||||
|
||||
void Segment::handleTransition() {
|
||||
if (!transitional) return;
|
||||
uint16_t _progress = progress();
|
||||
if (_progress == 0xFFFFU) stopTransition();
|
||||
}
|
||||
|
||||
// transition progression between 0-65535
|
||||
uint16_t Segment::progress() {
|
||||
if (transitional && _t) {
|
||||
if (isInTransition()) {
|
||||
unsigned long timeNow = millis();
|
||||
if (_t->_dur > 0 && timeNow - _t->_start < _t->_dur) return (timeNow - _t->_start) * 0xFFFFU / _t->_dur;
|
||||
}
|
||||
|
@ -420,8 +405,8 @@ void Segment::restoreSegenv(tmpsegd_t &tmpSeg) {
|
|||
_t->_segT._stepT = step;
|
||||
_t->_segT._callT = call;
|
||||
//if (_t->_segT._dataT != data) DEBUG_PRINTF("--- data re-allocated: (%p) %p -> %p\n", this, _t->_segT._dataT, data);
|
||||
_t->_segT._dataT = data; // sometimes memory gets re-allocated (!! INVESTIGATE WHY !!)
|
||||
_t->_segT._dataLenT = _dataLen; // sometimes memory gets re-allocated (!! INVESTIGATE WHY !!)
|
||||
_t->_segT._dataT = data;
|
||||
_t->_segT._dataLenT = _dataLen;
|
||||
}
|
||||
options = tmpSeg._optionsT;
|
||||
for (size_t i=0; i<NUM_COLORS; i++) colors[i] = tmpSeg._colorT[i];
|
||||
|
@ -443,39 +428,40 @@ void Segment::restoreSegenv(tmpsegd_t &tmpSeg) {
|
|||
}
|
||||
#endif
|
||||
|
||||
uint8_t Segment::currentBri(uint8_t briNew, bool useCct) {
|
||||
uint8_t Segment::currentBri(bool useCct) {
|
||||
uint32_t prog = progress();
|
||||
if (prog < 0xFFFFU) {
|
||||
if (useCct) return ((briNew * prog) + _t->_cctT * (0xFFFFU - prog)) >> 16;
|
||||
else return ((briNew * prog) + _t->_briT * (0xFFFFU - prog)) >> 16;
|
||||
uint32_t curBri = (useCct ? cct : (on ? opacity : 0)) * prog;
|
||||
curBri += (useCct ? _t->_cctT : (on ? _t->_briT : 0)) * (0xFFFFU - prog);
|
||||
return curBri / 0xFFFFU;
|
||||
}
|
||||
return briNew;
|
||||
return (useCct ? cct : (on ? opacity : 0));
|
||||
}
|
||||
|
||||
uint8_t Segment::currentMode(uint8_t newMode) {
|
||||
uint8_t Segment::currentMode() {
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
uint16_t prog = progress(); // implicit check for transitional & _t in progress()
|
||||
if (prog < 0xFFFFU) return _t->_modeT;
|
||||
uint16_t prog = progress();
|
||||
if (modeBlending && prog < 0xFFFFU) return _t->_modeT;
|
||||
#endif
|
||||
return newMode;
|
||||
return mode;
|
||||
}
|
||||
|
||||
uint32_t Segment::currentColor(uint8_t slot, uint32_t colorNew) {
|
||||
uint32_t Segment::currentColor(uint8_t slot) {
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
return transitional && _t ? color_blend(_t->_segT._colorT[slot], colorNew, progress(), true) : colorNew;
|
||||
return isInTransition() ? color_blend(_t->_segT._colorT[slot], colors[slot], progress(), true) : colors[slot];
|
||||
#else
|
||||
return transitional && _t ? color_blend(_t->_colorT[slot], colorNew, progress(), true) : colorNew;
|
||||
return isInTransition() ? color_blend(_t->_colorT[slot], colors[slot], progress(), true) : colors[slot];
|
||||
#endif
|
||||
}
|
||||
|
||||
CRGBPalette16 &Segment::currentPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
|
||||
loadPalette(targetPalette, pal);
|
||||
if (progress() < 0xFFFFU) {
|
||||
uint16_t prog = progress();
|
||||
if (strip.paletteFade && prog < 0xFFFFU) {
|
||||
// blend palettes
|
||||
// there are about 255 blend passes of 48 "blends" to completely blend two palettes (in _dur time)
|
||||
// minimum blend time is 100ms maximum is 65535ms
|
||||
unsigned long timeMS = millis() - _t->_start;
|
||||
uint16_t noOfBlends = (255U * timeMS / _t->_dur) - _t->_prevPaletteBlends;
|
||||
uint16_t noOfBlends = ((255U * prog) / 0xFFFFU) - _t->_prevPaletteBlends;
|
||||
for (int i=0; i<noOfBlends; i++, _t->_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, targetPalette, 48);
|
||||
targetPalette = _t->_palT; // copy transitioning/temporary palette
|
||||
}
|
||||
|
@ -500,6 +486,8 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t
|
|||
&& (!grp || (grouping == grp && spacing == spc))
|
||||
&& (ofs == UINT16_MAX || ofs == offset)) return;
|
||||
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
|
||||
if (stop) fill(BLACK); // turn old segment range off (clears pixels if changing spacing)
|
||||
if (grp) { // prevent assignment of 0
|
||||
grouping = grp;
|
||||
|
@ -510,6 +498,10 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t
|
|||
}
|
||||
if (ofs < UINT16_MAX) offset = ofs;
|
||||
|
||||
DEBUG_PRINT(F("setUp segment: ")); DEBUG_PRINT(i1);
|
||||
DEBUG_PRINT(','); DEBUG_PRINT(i2);
|
||||
DEBUG_PRINT(F(" -> ")); DEBUG_PRINT(i1Y);
|
||||
DEBUG_PRINT(','); DEBUG_PRINTLN(i2Y);
|
||||
markForReset();
|
||||
if (boundsUnchanged) return;
|
||||
|
||||
|
@ -564,7 +556,6 @@ void Segment::setCCT(uint16_t k) {
|
|||
void Segment::setOpacity(uint8_t o) {
|
||||
if (opacity == o) return;
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change
|
||||
DEBUG_PRINT(F("-- Setting opacity: ")); DEBUG_PRINTLN(o);
|
||||
opacity = o;
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
|
@ -574,14 +565,16 @@ void Segment::setOption(uint8_t n, bool val) {
|
|||
if (fadeTransition && n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change
|
||||
if (val) options |= 0x01 << n;
|
||||
else options &= ~(0x01 << n);
|
||||
if (!(n == SEG_OPTION_SELECTED || n == SEG_OPTION_RESET || n == SEG_OPTION_TRANSITIONAL)) stateChanged = true; // send UDP/WS broadcast
|
||||
if (!(n == SEG_OPTION_SELECTED || n == SEG_OPTION_RESET)) stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
|
||||
void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
||||
// if we have a valid mode & is not reserved
|
||||
if (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4)) {
|
||||
if (fx != mode) {
|
||||
if (fadeTransition) startTransition(strip.getTransition()); // set effect transitions
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (modeBlending) startTransition(strip.getTransition()); // set effect transitions
|
||||
#endif
|
||||
mode = fx;
|
||||
// load default values from effect string
|
||||
if (loadDefaults) {
|
||||
|
@ -743,7 +736,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
|||
#endif
|
||||
|
||||
uint16_t len = length();
|
||||
uint8_t _bri_t = currentBri(on ? opacity : 0);
|
||||
uint8_t _bri_t = currentBri();
|
||||
if (_bri_t < 255) {
|
||||
byte r = scale8(R(col), _bri_t);
|
||||
byte g = scale8(G(col), _bri_t);
|
||||
|
@ -877,10 +870,11 @@ uint8_t Segment::differs(Segment& b) const {
|
|||
if (startY != b.startY) d |= SEG_DIFFERS_BOUNDS;
|
||||
if (stopY != b.stopY) d |= SEG_DIFFERS_BOUNDS;
|
||||
|
||||
//bit pattern: (msb first) set:2, sound:1, mapping:3, transposed, mirrorY, reverseY, [transitional, reset,] paused, mirrored, on, reverse, [selected]
|
||||
if ((options & 0b1111111110011110U) != (b.options & 0b1111111110011110U)) d |= SEG_DIFFERS_OPT;
|
||||
//bit pattern: (msb first)
|
||||
// set:2, sound:2, mapping:3, transposed, mirrorY, reverseY, [reset,] paused, mirrored, on, reverse, [selected]
|
||||
if ((options & 0b1111111111011110U) != (b.options & 0b1111111111011110U)) d |= SEG_DIFFERS_OPT;
|
||||
if ((options & 0x0001U) != (b.options & 0x0001U)) d |= SEG_DIFFERS_SEL;
|
||||
for (uint8_t i = 0; i < NUM_COLORS; i++) if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL;
|
||||
for (unsigned i = 0; i < NUM_COLORS; i++) if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
@ -912,7 +906,7 @@ void Segment::refreshLightCapabilities() {
|
|||
segStopIdx = stop;
|
||||
}
|
||||
|
||||
for (uint8_t b = 0; b < busses.getNumBusses(); b++) {
|
||||
for (unsigned b = 0; b < busses.getNumBusses(); b++) {
|
||||
Bus *bus = busses.getBus(b);
|
||||
if (bus == nullptr || bus->getLength()==0) break;
|
||||
if (!bus->isOk()) continue;
|
||||
|
@ -942,7 +936,7 @@ void Segment::fill(uint32_t c) {
|
|||
if (!isActive()) return; // not active
|
||||
const uint16_t cols = is2D() ? virtualWidth() : virtualLength();
|
||||
const uint16_t rows = virtualHeight(); // will be 1 for 1D
|
||||
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
||||
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) {
|
||||
if (is2D()) setPixelColorXY(x, y, c);
|
||||
else setPixelColor(x, c);
|
||||
}
|
||||
|
@ -956,27 +950,12 @@ void Segment::blendPixelColor(int n, uint32_t color, uint8_t blend) {
|
|||
// Adds the specified color with the existing pixel color perserving color balance.
|
||||
void Segment::addPixelColor(int n, uint32_t color, bool fast) {
|
||||
if (!isActive()) return; // not active
|
||||
uint32_t col = getPixelColor(n);
|
||||
uint8_t r = R(col);
|
||||
uint8_t g = G(col);
|
||||
uint8_t b = B(col);
|
||||
uint8_t w = W(col);
|
||||
if (fast) {
|
||||
r = qadd8(r, R(color));
|
||||
g = qadd8(g, G(color));
|
||||
b = qadd8(b, B(color));
|
||||
w = qadd8(w, W(color));
|
||||
col = RGBW32(r,g,b,w);
|
||||
} else {
|
||||
col = color_add(col, color);
|
||||
}
|
||||
setPixelColor(n, col);
|
||||
setPixelColor(n, color_add(getPixelColor(n), color, fast));
|
||||
}
|
||||
|
||||
void Segment::fadePixelColor(uint16_t n, uint8_t fade) {
|
||||
if (!isActive()) return; // not active
|
||||
CRGB pix = CRGB(getPixelColor(n)).nscale8_video(fade);
|
||||
setPixelColor(n, pix);
|
||||
setPixelColor(n, color_fade(getPixelColor(n), fade, true));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -996,7 +975,7 @@ void Segment::fade_out(uint8_t rate) {
|
|||
int g2 = G(color);
|
||||
int b2 = B(color);
|
||||
|
||||
for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
||||
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) {
|
||||
color = is2D() ? getPixelColorXY(x, y) : getPixelColor(x);
|
||||
int w1 = W(color);
|
||||
int r1 = R(color);
|
||||
|
@ -1025,9 +1004,9 @@ void Segment::fadeToBlackBy(uint8_t fadeBy) {
|
|||
const uint16_t cols = is2D() ? virtualWidth() : virtualLength();
|
||||
const uint16_t rows = virtualHeight(); // will be 1 for 1D
|
||||
|
||||
for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
||||
if (is2D()) setPixelColorXY(x, y, CRGB(getPixelColorXY(x,y)).nscale8(255-fadeBy));
|
||||
else setPixelColor(x, CRGB(getPixelColor(x)).nscale8(255-fadeBy));
|
||||
for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) {
|
||||
if (is2D()) setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), 255-fadeBy));
|
||||
else setPixelColor(x, color_fade(getPixelColor(x), 255-fadeBy));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1040,34 +1019,26 @@ void Segment::blur(uint8_t blur_amount)
|
|||
#ifndef WLED_DISABLE_2D
|
||||
if (is2D()) {
|
||||
// compatibility with 2D
|
||||
const uint_fast16_t cols = virtualWidth();
|
||||
const uint_fast16_t rows = virtualHeight();
|
||||
for (uint_fast16_t i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows
|
||||
for (uint_fast16_t k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns
|
||||
const unsigned cols = virtualWidth();
|
||||
const unsigned rows = virtualHeight();
|
||||
for (unsigned i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows
|
||||
for (unsigned k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
uint8_t keep = 255 - blur_amount;
|
||||
uint8_t seep = blur_amount >> 1;
|
||||
CRGB carryover = CRGB::Black;
|
||||
uint_fast16_t vlength = virtualLength();
|
||||
for(uint_fast16_t i = 0; i < vlength; i++)
|
||||
{
|
||||
CRGB cur = CRGB(getPixelColor(i));
|
||||
CRGB part = cur;
|
||||
CRGB before = cur; // remember color before blur
|
||||
part.nscale8(seep);
|
||||
cur.nscale8(keep);
|
||||
cur += carryover;
|
||||
if(i > 0) {
|
||||
uint32_t carryover = BLACK;
|
||||
unsigned vlength = virtualLength();
|
||||
for (unsigned i = 0; i < vlength; i++) {
|
||||
uint32_t cur = getPixelColor(i);
|
||||
uint32_t part = color_fade(cur, seep);
|
||||
cur = color_add(color_fade(cur, keep), carryover, true);
|
||||
if (i > 0) {
|
||||
uint32_t c = getPixelColor(i-1);
|
||||
uint8_t r = R(c);
|
||||
uint8_t g = G(c);
|
||||
uint8_t b = B(c);
|
||||
setPixelColor((uint16_t)(i-1), qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue));
|
||||
setPixelColor(i-1, color_add(c, part, true));
|
||||
}
|
||||
if (before != cur) // optimization: only set pixel if color has changed
|
||||
setPixelColor((uint16_t)i,cur.red, cur.green, cur.blue);
|
||||
setPixelColor(i, cur);
|
||||
carryover = part;
|
||||
}
|
||||
}
|
||||
|
@ -1080,7 +1051,7 @@ void Segment::blur(uint8_t blur_amount)
|
|||
uint32_t Segment::color_wheel(uint8_t pos) {
|
||||
if (palette) return color_from_palette(pos, false, true, 0);
|
||||
pos = 255 - pos;
|
||||
if(pos < 85) {
|
||||
if (pos < 85) {
|
||||
return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3);
|
||||
} else if(pos < 170) {
|
||||
pos -= 85;
|
||||
|
@ -1091,21 +1062,6 @@ uint32_t Segment::color_wheel(uint8_t pos) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a new, random wheel index with a minimum distance of 42 from pos.
|
||||
*/
|
||||
uint8_t Segment::get_random_wheel_index(uint8_t pos) {
|
||||
uint8_t r = 0, x = 0, y = 0, d = 0;
|
||||
|
||||
while(d < 42) {
|
||||
r = random8();
|
||||
x = abs(pos - r);
|
||||
y = 255 - x;
|
||||
d = MIN(x, y);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets a single color from the currently selected palette.
|
||||
* @param i Palette Index (if mapping is true, the full palette will be _virtualSegmentLength long, if false, 255). Will wrap around automatically.
|
||||
|
@ -1119,20 +1075,20 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_
|
|||
{
|
||||
// default palette or no RGB support on segment
|
||||
if ((palette == 0 && mcol < NUM_COLORS) || !_isRGB) {
|
||||
uint32_t color = currentColor(mcol, colors[mcol]);
|
||||
uint32_t color = currentColor(mcol);
|
||||
color = gamma32(color);
|
||||
if (pbri == 255) return color;
|
||||
return RGBW32(scale8_video(R(color),pbri), scale8_video(G(color),pbri), scale8_video(B(color),pbri), scale8_video(W(color),pbri));
|
||||
return color_fade(color, pbri, true);
|
||||
}
|
||||
|
||||
uint8_t paletteIndex = i;
|
||||
if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1);
|
||||
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
||||
CRGB fastled_col;
|
||||
if (!wrap && strip.paletteBlend != 3) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
||||
CRGBPalette16 curPal;
|
||||
if (transitional && _t) curPal = _t->_palT;
|
||||
else loadPalette(curPal, palette);
|
||||
fastled_col = ColorFromPalette(curPal, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
|
||||
curPal = currentPalette(curPal, palette);
|
||||
//if (isInTransition()) curPal = _t->_palT;
|
||||
//else loadPalette(curPal, palette);
|
||||
CRGB fastled_col = ColorFromPalette(curPal, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
|
||||
|
||||
return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, 0);
|
||||
}
|
||||
|
@ -1166,7 +1122,7 @@ void WS2812FX::finalizeInit(void)
|
|||
const uint8_t defNumBusses = ((sizeof defDataPins) / (sizeof defDataPins[0]));
|
||||
const uint8_t defNumCounts = ((sizeof defCounts) / (sizeof defCounts[0]));
|
||||
uint16_t prevLen = 0;
|
||||
for (uint8_t i = 0; i < defNumBusses && i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
|
||||
for (int i = 0; i < defNumBusses && i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
|
||||
uint8_t defPin[] = {defDataPins[i]};
|
||||
uint16_t start = prevLen;
|
||||
uint16_t count = defCounts[(i < defNumCounts) ? i : defNumCounts -1];
|
||||
|
@ -1177,7 +1133,7 @@ void WS2812FX::finalizeInit(void)
|
|||
}
|
||||
|
||||
_length = 0;
|
||||
for (uint8_t i=0; i<busses.getNumBusses(); i++) {
|
||||
for (int i=0; i<busses.getNumBusses(); i++) {
|
||||
Bus *bus = busses.getBus(i);
|
||||
if (bus == nullptr) continue;
|
||||
if (bus->getStart() + bus->getLength() > MAX_LEDS) break;
|
||||
|
@ -1234,24 +1190,24 @@ void WS2812FX::service() {
|
|||
|
||||
if (!seg.freeze) { //only run effect function if not frozen
|
||||
_virtualSegmentLength = seg.virtualLength();
|
||||
_colors_t[0] = seg.currentColor(0, seg.colors[0]);
|
||||
_colors_t[1] = seg.currentColor(1, seg.colors[1]);
|
||||
_colors_t[2] = seg.currentColor(2, seg.colors[2]);
|
||||
seg.currentPalette(_currentPalette, seg.palette);
|
||||
_colors_t[0] = seg.currentColor(0);
|
||||
_colors_t[1] = seg.currentColor(1);
|
||||
_colors_t[2] = seg.currentColor(2);
|
||||
seg.currentPalette(_currentPalette, seg.palette); // we need to pass reference
|
||||
|
||||
if (!cctFromRgb || correctWB) busses.setSegmentCCT(seg.currentBri(seg.cct, true), correctWB);
|
||||
for (uint8_t c = 0; c < NUM_COLORS; c++) _colors_t[c] = gamma32(_colors_t[c]);
|
||||
if (!cctFromRgb || correctWB) busses.setSegmentCCT(seg.currentBri(true), correctWB);
|
||||
for (int c = 0; c < NUM_COLORS; c++) _colors_t[c] = gamma32(_colors_t[c]);
|
||||
|
||||
// Effect blending
|
||||
// When two effects are being blended, each may have different segment data, this
|
||||
// data needs to be saved first and then restored before running previous/transitional mode.
|
||||
// data needs to be saved first and then restored before running previous mode.
|
||||
// The blending will largely depend on the effect behaviour since actual output (LEDs) may be
|
||||
// overwritten by later effect. To enable seamless blending for every effect, additional LED buffer
|
||||
// would need to be allocated for each effect and then blended together for each pixel.
|
||||
[[maybe_unused]] uint8_t tmpMode = seg.currentMode(seg.mode); // this will return old mode while in transition
|
||||
[[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition
|
||||
delay = (*_mode[seg.mode])(); // run new/current mode
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (seg.mode != tmpMode) {
|
||||
if (modeBlending && seg.mode != tmpMode) {
|
||||
Segment::tmpsegd_t _tmpSegData;
|
||||
Segment::modeBlend(true); // set semaphore
|
||||
seg.swapSegenv(_tmpSegData); // temporarily store new mode state (and swap it with transitional state)
|
||||
|
@ -1262,7 +1218,7 @@ void WS2812FX::service() {
|
|||
}
|
||||
#endif
|
||||
if (seg.mode != FX_MODE_HALLOWEEN_EYES) seg.call++;
|
||||
if (seg.transitional && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition
|
||||
if (seg.isInTransition() && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition
|
||||
}
|
||||
|
||||
seg.next_time = nowUp + delay;
|
||||
|
@ -1399,12 +1355,12 @@ void WS2812FX::show(void) {
|
|||
// or async show has a separate buffer (ESP32 RMT and I2S are ok)
|
||||
if (newBri < _brightness) busses.setBrightness(_brightness);
|
||||
|
||||
unsigned long now = millis();
|
||||
size_t diff = now - _lastShow;
|
||||
unsigned long showNow = millis();
|
||||
size_t diff = showNow - _lastShow;
|
||||
size_t fpsCurr = 200;
|
||||
if (diff > 0) fpsCurr = 1000 / diff;
|
||||
_cumulativeFps = (3 * _cumulativeFps + fpsCurr +2) >> 2; // "+2" for proper rounding (2/4 = 0.5)
|
||||
_lastShow = now;
|
||||
_lastShow = showNow;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1597,10 +1553,12 @@ void WS2812FX::setSegment(uint8_t segId, uint16_t i1, uint16_t i2, uint8_t group
|
|||
_qStart = i1; _qStop = i2; _qStartY = startY; _qStopY = stopY;
|
||||
_qGrouping = grouping; _qSpacing = spacing; _qOffset = offset;
|
||||
_queuedChangesSegId = segId;
|
||||
DEBUG_PRINT(F("Segment queued: ")); DEBUG_PRINTLN(segId);
|
||||
return; // queued changes are applied immediately after effect function returns
|
||||
}
|
||||
|
||||
_segments[segId].setUp(i1, i2, grouping, spacing, offset, startY, stopY);
|
||||
if (segId > 0 && segId == getSegmentsNum()-1 && i2 <= i1) _segments.pop_back(); // if last segment was deleted remove it from vector
|
||||
}
|
||||
|
||||
void WS2812FX::setUpSegmentFromQueuedChanges() {
|
||||
|
@ -1729,7 +1687,7 @@ void WS2812FX::fixInvalidSegments() {
|
|||
bool WS2812FX::checkSegmentAlignment() {
|
||||
bool aligned = false;
|
||||
for (segment &seg : _segments) {
|
||||
for (uint8_t b = 0; b<busses.getNumBusses(); b++) {
|
||||
for (unsigned b = 0; b<busses.getNumBusses(); b++) {
|
||||
Bus *bus = busses.getBus(b);
|
||||
if (seg.start == bus->getStart() && seg.stop == bus->getStart() + bus->getLength()) aligned = true;
|
||||
}
|
||||
|
@ -1752,13 +1710,8 @@ uint8_t WS2812FX::setPixelSegment(uint8_t n) {
|
|||
}
|
||||
|
||||
void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col) {
|
||||
if (i2 >= i)
|
||||
{
|
||||
for (uint16_t x = i; x <= i2; x++) setPixelColor(x, col);
|
||||
} else
|
||||
{
|
||||
for (uint16_t x = i2; x <= i; x++) setPixelColor(x, col);
|
||||
}
|
||||
if (i2 < i) std::swap(i,i2);
|
||||
for (unsigned x = i; x <= i2; x++) setPixelColor(x, col);
|
||||
}
|
||||
|
||||
void WS2812FX::setTransitionMode(bool t) {
|
||||
|
@ -1793,7 +1746,7 @@ void WS2812FX::loadCustomPalettes() {
|
|||
|
||||
if (readObjectFromFile(fileName, nullptr, &pDoc)) {
|
||||
JsonArray pal = pDoc[F("palette")];
|
||||
if (!pal.isNull() && pal.size()>4) { // not an empty palette (at least 2 entries)
|
||||
if (!pal.isNull() && pal.size()>3) { // not an empty palette (at least 2 entries)
|
||||
if (pal[0].is<int>() && pal[1].is<const char *>()) {
|
||||
// we have an array of index & hex strings
|
||||
size_t palSize = MIN(pal.size(), 36);
|
||||
|
@ -1802,7 +1755,7 @@ void WS2812FX::loadCustomPalettes() {
|
|||
uint8_t rgbw[] = {0,0,0,0};
|
||||
tcp[ j ] = (uint8_t) pal[ i ].as<int>(); // index
|
||||
colorFromHexString(rgbw, pal[i+1].as<const char *>()); // will catch non-string entires
|
||||
for (size_t c=0; c<3; c++) tcp[j+1+c] = rgbw[c]; // only use RGB component
|
||||
for (size_t c=0; c<3; c++) tcp[j+1+c] = gamma8(rgbw[c]); // only use RGB component
|
||||
DEBUG_PRINTF("%d(%d) : %d %d %d\n", i, int(tcp[j]), int(tcp[j+1]), int(tcp[j+2]), int(tcp[j+3]));
|
||||
}
|
||||
} else {
|
||||
|
@ -1810,13 +1763,15 @@ void WS2812FX::loadCustomPalettes() {
|
|||
palSize -= palSize % 4; // make sure size is multiple of 4
|
||||
for (size_t i=0; i<palSize && pal[i].as<int>()<256; i+=4) {
|
||||
tcp[ i ] = (uint8_t) pal[ i ].as<int>(); // index
|
||||
tcp[i+1] = (uint8_t) pal[i+1].as<int>(); // R
|
||||
tcp[i+2] = (uint8_t) pal[i+2].as<int>(); // G
|
||||
tcp[i+3] = (uint8_t) pal[i+3].as<int>(); // B
|
||||
tcp[i+1] = gamma8((uint8_t) pal[i+1].as<int>()); // R
|
||||
tcp[i+2] = gamma8((uint8_t) pal[i+2].as<int>()); // G
|
||||
tcp[i+3] = gamma8((uint8_t) pal[i+3].as<int>()); // B
|
||||
DEBUG_PRINTF("%d(%d) : %d %d %d\n", i, int(tcp[i]), int(tcp[i+1]), int(tcp[i+2]), int(tcp[i+3]));
|
||||
}
|
||||
}
|
||||
customPalettes.push_back(targetPalette.loadDynamicGradientPalette(tcp));
|
||||
} else {
|
||||
DEBUG_PRINTLN(F("Wrong palette format."));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1832,7 +1787,7 @@ bool WS2812FX::deserializeMap(uint8_t n) {
|
|||
char fileName[32];
|
||||
strcpy_P(fileName, PSTR("/ledmap"));
|
||||
if (n) sprintf(fileName +7, "%d", n);
|
||||
strcat(fileName, ".json");
|
||||
strcat_P(fileName, PSTR(".json"));
|
||||
bool isFile = WLED_FS.exists(fileName);
|
||||
|
||||
if (!isFile) {
|
||||
|
@ -1866,7 +1821,7 @@ bool WS2812FX::deserializeMap(uint8_t n) {
|
|||
if (!map.isNull() && map.size()) { // not an empty map
|
||||
customMappingSize = map.size();
|
||||
customMappingTable = new uint16_t[customMappingSize];
|
||||
for (uint16_t i=0; i<customMappingSize; i++) {
|
||||
for (unsigned i=0; i<customMappingSize; i++) {
|
||||
customMappingTable[i] = (uint16_t) (map[i]<0 ? 0xFFFFU : map[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -216,7 +216,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||
if (((buttonType[s] == BTN_TYPE_ANALOG) || (buttonType[s] == BTN_TYPE_ANALOG_INVERTED)) && (digitalPinToAnalogChannel(btnPin[s]) < 0))
|
||||
{
|
||||
// not an ADC analog pin
|
||||
DEBUG_PRINTF("PIN ALLOC error: GPIO%d for analog button #%d is not an analog pin!\n", btnPin[s], s);
|
||||
DEBUG_PRINT(F("PIN ALLOC error: GPIO")); DEBUG_PRINT(btnPin[s]);
|
||||
DEBUG_PRINT(F("for analog button #")); DEBUG_PRINT(s);
|
||||
DEBUG_PRINTLN(F(" is not an analog pin!"));
|
||||
btnPin[s] = -1;
|
||||
pinManager.deallocatePin(pin,PinOwner::Button);
|
||||
}
|
||||
|
@ -357,6 +359,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||
|
||||
JsonObject light_tr = light["tr"];
|
||||
CJSON(fadeTransition, light_tr["mode"]);
|
||||
CJSON(modeBlending, light_tr["fx"]);
|
||||
int tdd = light_tr["dur"] | -1;
|
||||
if (tdd >= 0) transitionDelay = transitionDelayDefault = tdd * 100;
|
||||
CJSON(strip.paletteFade, light_tr["pal"]);
|
||||
|
@ -827,6 +830,7 @@ void serializeConfig() {
|
|||
|
||||
JsonObject light_tr = light.createNestedObject("tr");
|
||||
light_tr["mode"] = fadeTransition;
|
||||
light_tr["fx"] = modeBlending;
|
||||
light_tr["dur"] = transitionDelayDefault / 100;
|
||||
light_tr["pal"] = strip.paletteFade;
|
||||
light_tr[F("rpc")] = randomPaletteChangeTime;
|
||||
|
@ -888,6 +892,7 @@ void serializeConfig() {
|
|||
if_live[F("no-gc")] = arlsDisableGammaCorrection;
|
||||
if_live[F("offset")] = arlsOffset;
|
||||
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
JsonObject if_va = interfaces.createNestedObject("va");
|
||||
if_va[F("alexa")] = alexaEnabled;
|
||||
|
||||
|
@ -896,6 +901,7 @@ void serializeConfig() {
|
|||
if_va_macros.add(macroAlexaOff);
|
||||
|
||||
if_va["p"] = alexaNumPresets;
|
||||
#endif
|
||||
|
||||
#ifdef WLED_ENABLE_MQTT
|
||||
JsonObject if_mqtt = interfaces.createNestedObject("mqtt");
|
||||
|
@ -1033,7 +1039,7 @@ bool deserializeConfigSec() {
|
|||
JsonObject ap = doc["ap"];
|
||||
getStringFromJson(apPass, ap["psk"] , 65);
|
||||
|
||||
JsonObject interfaces = doc["if"];
|
||||
[[maybe_unused]] JsonObject interfaces = doc["if"];
|
||||
|
||||
#ifdef WLED_ENABLE_MQTT
|
||||
JsonObject if_mqtt = interfaces["mqtt"];
|
||||
|
@ -1072,7 +1078,7 @@ void serializeConfigSec() {
|
|||
JsonObject ap = doc.createNestedObject("ap");
|
||||
ap["psk"] = apPass;
|
||||
|
||||
JsonObject interfaces = doc.createNestedObject("if");
|
||||
[[maybe_unused]] JsonObject interfaces = doc.createNestedObject("if");
|
||||
#ifdef WLED_ENABLE_MQTT
|
||||
JsonObject if_mqtt = interfaces.createNestedObject("mqtt");
|
||||
if_mqtt["psk"] = mqttPass;
|
||||
|
|
|
@ -35,23 +35,59 @@ uint32_t color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16)
|
|||
* color add function that preserves ratio
|
||||
* idea: https://github.com/Aircoookie/WLED/pull/2465 by https://github.com/Proto-molecule
|
||||
*/
|
||||
uint32_t color_add(uint32_t c1, uint32_t c2)
|
||||
uint32_t color_add(uint32_t c1, uint32_t c2, bool fast)
|
||||
{
|
||||
uint32_t r = R(c1) + R(c2);
|
||||
uint32_t g = G(c1) + G(c2);
|
||||
uint32_t b = B(c1) + B(c2);
|
||||
uint32_t w = W(c1) + W(c2);
|
||||
uint16_t max = r;
|
||||
if (g > max) max = g;
|
||||
if (b > max) max = b;
|
||||
if (w > max) max = w;
|
||||
if (max < 256) return RGBW32(r, g, b, w);
|
||||
else return RGBW32(r * 255 / max, g * 255 / max, b * 255 / max, w * 255 / max);
|
||||
if (fast) {
|
||||
uint8_t r = R(c1);
|
||||
uint8_t g = G(c1);
|
||||
uint8_t b = B(c1);
|
||||
uint8_t w = W(c1);
|
||||
r = qadd8(r, R(c2));
|
||||
g = qadd8(g, G(c2));
|
||||
b = qadd8(b, B(c2));
|
||||
w = qadd8(w, W(c2));
|
||||
return RGBW32(r,g,b,w);
|
||||
} else {
|
||||
uint32_t r = R(c1) + R(c2);
|
||||
uint32_t g = G(c1) + G(c2);
|
||||
uint32_t b = B(c1) + B(c2);
|
||||
uint32_t w = W(c1) + W(c2);
|
||||
uint16_t max = r;
|
||||
if (g > max) max = g;
|
||||
if (b > max) max = b;
|
||||
if (w > max) max = w;
|
||||
if (max < 256) return RGBW32(r, g, b, w);
|
||||
else return RGBW32(r * 255 / max, g * 255 / max, b * 255 / max, w * 255 / max);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fades color toward black
|
||||
* if using "video" method the resulting color will never become black unless it is already black
|
||||
*/
|
||||
uint32_t color_fade(uint32_t c1, uint8_t amount, bool video)
|
||||
{
|
||||
uint8_t r = R(c1);
|
||||
uint8_t g = G(c1);
|
||||
uint8_t b = B(c1);
|
||||
uint8_t w = W(c1);
|
||||
if (video) {
|
||||
r = scale8_video(r, amount);
|
||||
g = scale8_video(g, amount);
|
||||
b = scale8_video(b, amount);
|
||||
w = scale8_video(w, amount);
|
||||
} else {
|
||||
r = scale8(r, amount);
|
||||
g = scale8(g, amount);
|
||||
b = scale8(b, amount);
|
||||
w = scale8(w, amount);
|
||||
}
|
||||
return RGBW32(r, g, b, w);
|
||||
}
|
||||
|
||||
void setRandomColor(byte* rgb)
|
||||
{
|
||||
lastRandomIndex = strip.getMainSegment().get_random_wheel_index(lastRandomIndex);
|
||||
lastRandomIndex = get_random_wheel_index(lastRandomIndex);
|
||||
colorHStoRGB(lastRandomIndex*256,255,rgb);
|
||||
}
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@
|
|||
#define CALL_MODE_NO_NOTIFY 5
|
||||
#define CALL_MODE_FX_CHANGED 6 //no longer used
|
||||
#define CALL_MODE_HUE 7
|
||||
#define CALL_MODE_PRESET_CYCLE 8
|
||||
#define CALL_MODE_PRESET_CYCLE 8 //no longer used
|
||||
#define CALL_MODE_BLYNK 9 //no longer used
|
||||
#define CALL_MODE_ALEXA 10
|
||||
#define CALL_MODE_WS_SEND 11 //special call mode, not for notifier, updates websocket only
|
||||
|
@ -313,10 +313,9 @@
|
|||
#define SEG_OPTION_MIRROR 3 //Indicates that the effect will be mirrored within the segment
|
||||
#define SEG_OPTION_FREEZE 4 //Segment contents will not be refreshed
|
||||
#define SEG_OPTION_RESET 5 //Segment runtime requires reset
|
||||
#define SEG_OPTION_TRANSITIONAL 6
|
||||
#define SEG_OPTION_REVERSED_Y 7
|
||||
#define SEG_OPTION_MIRROR_Y 8
|
||||
#define SEG_OPTION_TRANSPOSED 9
|
||||
#define SEG_OPTION_REVERSED_Y 6
|
||||
#define SEG_OPTION_MIRROR_Y 7
|
||||
#define SEG_OPTION_TRANSPOSED 8
|
||||
|
||||
//Segment differs return byte
|
||||
#define SEG_DIFFERS_BRI 0x01 // opacity
|
||||
|
@ -345,6 +344,7 @@
|
|||
#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached
|
||||
#define ERR_FS_PLOAD 12 // It was attempted to load a preset that does not exist
|
||||
#define ERR_FS_IRLOAD 13 // It was attempted to load an IR JSON cmd, but the "ir.json" file does not exist
|
||||
#define ERR_FS_RMLOAD 14 // It was attempted to load an remote JSON cmd, but the "remote.json" file does not exist
|
||||
#define ERR_FS_GENERAL 19 // A general unspecified filesystem error occured
|
||||
#define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented)
|
||||
#define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented)
|
||||
|
|
|
@ -198,10 +198,11 @@
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding-bottom: 10px;">
|
||||
<button class="btn btn-xs" type="button" onclick="window.location.href=getURL('/cpal.htm')"><i class="icons btn-icon"></i></button>
|
||||
<button class="btn btn-xs" type="button" onclick="palettesData=null;localStorage.removeItem('wledPalx');requestJson({rmcpal:true});setTimeout(loadPalettes,250,loadPalettesData);"><i class="icons btn-icon"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding-block: 10px;">
|
||||
<button class="btn btn-xs" type="button" onclick="togglePixelMagicTool()"><i class="icons btn-icon"></i></button>
|
||||
<button class="btn btn-xs" type="button" onclick="window.location.href=getURL('/cpal.htm')"><i class="icons btn-icon"></i></button>
|
||||
<button class="btn btn-xs" type="button" onclick="palettesData=null;localStorage.removeItem('wledPalx');requestJson({rmcpal:true});setTimeout(loadPalettes,250,loadPalettesData);"><i class="icons btn-icon"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -392,6 +393,7 @@
|
|||
<button class="btn" onclick="setLor(2)">Override until reboot</button><br>
|
||||
<span class="h">For best performance, it is recommended to turn off the streaming source when not in use.</span>
|
||||
</div>
|
||||
|
||||
<i id="roverstar" class="icons huge" onclick="setLor(0)"></i><br>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -33,10 +33,9 @@ var hol = [
|
|||
[0,11,24,4,"https://aircoookie.github.io/xmas.png"], // christmas
|
||||
[0,2,17,1,"https://images.alphacoders.com/491/491123.jpg"], // st. Patrick's day
|
||||
[2025,3,20,2,"https://aircoookie.github.io/easter.png"],
|
||||
[2023,3,9,2,"https://aircoookie.github.io/easter.png"],
|
||||
[2024,2,31,2,"https://aircoookie.github.io/easter.png"],
|
||||
[0,6,4,1,"https://initiate.alphacoders.com/download/wallpaper/516792/images/jpg/510921363292536"], // 4th of July
|
||||
[0,0,1,1,"https://initiate.alphacoders.com/download/wallpaper/1198800/images/jpg/2522807481585600"] // new year
|
||||
[0,6,4,1,"https://images.alphacoders.com/516/516792.jpg"], // 4th of July
|
||||
[0,0,1,1,"https://images.alphacoders.com/119/1198800.jpg"] // new year
|
||||
];
|
||||
|
||||
function handleVisibilityChange() {if (!d.hidden && new Date () - lastUpdate > 3000) requestJson();}
|
||||
|
@ -1209,7 +1208,7 @@ function updateUI()
|
|||
if (hasRGB) {
|
||||
updateTrail(gId('sliderR'));
|
||||
updateTrail(gId('sliderG'));
|
||||
updateTrail(gId('sliderB'));
|
||||
updateTrail(gId('sliderB'));
|
||||
}
|
||||
if (hasWhite) updateTrail(gId('sliderW'));
|
||||
|
||||
|
@ -1514,12 +1513,15 @@ function setEffectParameters(idx)
|
|||
}
|
||||
|
||||
// set the bottom position of selected effect (sticky) as the top of sliders div
|
||||
setInterval(()=>{
|
||||
function setSelectedEffectPosition() {
|
||||
let top = parseInt(getComputedStyle(gId("sliders")).height);
|
||||
top += 5;
|
||||
let sel = d.querySelector('#fxlist .selected');
|
||||
if (sel) sel.style.bottom = top + "px"; // we will need to remove this when unselected (in setFX())
|
||||
},750);
|
||||
}
|
||||
|
||||
setSelectedEffectPosition();
|
||||
setInterval(setSelectedEffectPosition,750);
|
||||
// set html color items on/off
|
||||
var cslLabel = '';
|
||||
var sep = '';
|
||||
|
@ -1700,7 +1702,7 @@ function toggleLiveview()
|
|||
let wsOn = ws && ws.readyState === WebSocket.OPEN;
|
||||
|
||||
var lvID = "liveview";
|
||||
if (isM && wsOn) {
|
||||
if (isM && wsOn) {
|
||||
lvID += "2D";
|
||||
if (isLv) gId('klv2D').innerHTML = `<iframe id="${lvID}" src="about:blank"></iframe>`;
|
||||
gId('mlv2D').style.transform = (isLv) ? "translateY(0px)":"translateY(100%)";
|
||||
|
@ -1887,7 +1889,7 @@ function makeP(i,pl)
|
|||
end: 0
|
||||
};
|
||||
var rep = plJson[i].repeat ? plJson[i].repeat : 0;
|
||||
content =
|
||||
content =
|
||||
`<div id="ple${i}" style="margin-top:10px;"></div><label class="check revchkl">Shuffle
|
||||
<input type="checkbox" id="pl${i}rtgl" onchange="plR(${i})" ${plJson[i].r||rep<0?"checked":""}>
|
||||
<span class="checkmark"></span>
|
||||
|
|
|
@ -7,13 +7,10 @@
|
|||
|
||||
<title>Pixel Magic Tool</title>
|
||||
|
||||
<!-- <link
|
||||
rel="shortcut icon"
|
||||
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAK9JREFUeNqUUssNwyAMJZWVUw4dhRHakZA6RqWMFEbwKDnk1FNBekEWxOBYQggL/D68yXXq+M7PtHkcefn89vrOw/UrP96w/NUFGiDLRz71GyY0QJa1Yn+nFa0ShqUNYCAF0QvoceOB4naEZif6UTNRapYaTyauRi4DEspr4Hbs5YKsbmtMyeJ0LxeESV4gB+hlSy4oO2txWysyus0a0+lO6vBjxcTMlG4mt2H6F2AAhU5NWu4dorQAAAAASUVORK5CYII=
|
||||
" /> -->
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--s-thumb: #0006;
|
||||
--s-background: #0003;
|
||||
--overlay: rgba(0, 0, 0, 0.5);
|
||||
--background: #111;
|
||||
--text: #bbb;
|
||||
|
@ -34,6 +31,24 @@
|
|||
--warning-light: #f48c06;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--s-thumb);
|
||||
opacity: 0.2;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--s-background);
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: var(--blue-light);
|
||||
}
|
||||
|
@ -65,7 +80,7 @@
|
|||
display: block;
|
||||
font-weight: 400;
|
||||
margin: 2px 0 5px;
|
||||
color: var(--text);
|
||||
color: var(--gray-light);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
@ -83,10 +98,19 @@
|
|||
font-weight: 600;
|
||||
}
|
||||
|
||||
:is(a:hover, a:focus, a:active) {
|
||||
a:is(:hover, :focus, :active) {
|
||||
color: var(--blue-medium);
|
||||
}
|
||||
|
||||
#wledEdit {
|
||||
padding: 4px 8px;
|
||||
background: var(--blue-light);
|
||||
margin-left: 6px;
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
color: var(--gray-light);
|
||||
}
|
||||
|
||||
.m-zero {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
@ -108,8 +132,7 @@
|
|||
}
|
||||
|
||||
.content {
|
||||
width: calc(100% - 40px);
|
||||
max-width: 768px;
|
||||
width: min(768px, calc(100% - 40px));
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
|
@ -117,26 +140,43 @@
|
|||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
margin: 20px 0 0;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.column {
|
||||
flex-basis: calc(50% - 10px);
|
||||
position: relative;
|
||||
padding: 0 5px;
|
||||
padding-inline: 5px;
|
||||
}
|
||||
|
||||
.column-full {
|
||||
flex-basis: 100%;
|
||||
position: relative;
|
||||
padding: 0 5px;
|
||||
padding-inline: 5px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.header .brand {
|
||||
width: 100%;
|
||||
max-width: 200px;
|
||||
height: 100%;
|
||||
display: block;
|
||||
outline: none;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
display: flex;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
color: var(--text);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
|
@ -157,7 +197,7 @@
|
|||
width: 32px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
padding: 0px 1px;
|
||||
padding-inline: 1px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
|
@ -172,18 +212,19 @@
|
|||
}
|
||||
|
||||
.input-group .input-description {
|
||||
width: 38px;
|
||||
width: 100%;
|
||||
max-width: 38px;
|
||||
height: 38px;
|
||||
padding: 10px 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: var(--gray-dark);
|
||||
background: var(--gray-light);
|
||||
border-radius: 0px 5px 5px 0;
|
||||
border-radius: 0px 8px 8px 0;
|
||||
border: 1px solid var(--gray-light);
|
||||
border-left: 0;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.input-group .square {
|
||||
|
@ -191,10 +232,19 @@
|
|||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.input-group .square input {
|
||||
text-align: center;
|
||||
background: none;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
color: var(--gray-dark);
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
resize: none;
|
||||
min-height: 200px;
|
||||
border-radius: 8px;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.custom-select {
|
||||
|
@ -231,7 +281,7 @@
|
|||
text-align: center;
|
||||
padding: 40px 10px;
|
||||
border-radius: 8px;
|
||||
margin: 20px 0 0;
|
||||
margin-top: 20px;
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
|
@ -253,14 +303,15 @@
|
|||
width: 100%;
|
||||
border-radius: 10px;
|
||||
outline: none;
|
||||
margin: 16px 0;
|
||||
margin-block: 15px;
|
||||
}
|
||||
|
||||
.range-slider::-webkit-slider-thumb {
|
||||
.range-slider::-webkit-slider-thumb,
|
||||
.range-slider::-moz-range-thumb {
|
||||
appearance: none;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
background-color: var(--gray-dark);
|
||||
background-color: var(--blue-light);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
|
@ -326,7 +377,7 @@
|
|||
align-items: center;
|
||||
width: auto;
|
||||
padding: 6px 12px;
|
||||
margin: 10px 0 0;
|
||||
margin-top: 10px;
|
||||
border-radius: 8px;
|
||||
transform: translateY(30px);
|
||||
opacity: 0;
|
||||
|
@ -334,7 +385,7 @@
|
|||
}
|
||||
|
||||
.toast .toast-body {
|
||||
padding: 8px 0;
|
||||
padding-block: 8px;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
letter-spacing: 0.5px;
|
||||
|
@ -360,7 +411,7 @@
|
|||
height: 3px;
|
||||
transform: scaleX(0);
|
||||
transform-origin: left;
|
||||
border-radius: inherit;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.toast.success .toast-progress {
|
||||
|
@ -387,22 +438,6 @@
|
|||
);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 0 0 20px;
|
||||
}
|
||||
|
||||
.header .brand {
|
||||
width: 100%;
|
||||
max-width: 200px;
|
||||
height: 100%;
|
||||
display: block;
|
||||
outline: none;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.carousel {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
@ -410,18 +445,6 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.carousel img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-right: 20px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.carousel img:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
|
@ -429,7 +452,7 @@
|
|||
border-radius: 50px;
|
||||
color: var(--text);
|
||||
cursor: pointer;
|
||||
margin: 0 0 10px;
|
||||
margin-bottom: 10px;
|
||||
background: var(--gray-medium);
|
||||
border: 1px solid var(--gray-dark);
|
||||
transition: all 0.5s ease-in-out;
|
||||
|
@ -477,7 +500,7 @@
|
|||
}
|
||||
|
||||
#recreatedImage {
|
||||
margin: 20px 0;
|
||||
margin-block: 20px;
|
||||
}
|
||||
|
||||
.invalid {
|
||||
|
@ -487,16 +510,12 @@
|
|||
.error-message {
|
||||
display: block;
|
||||
color: var(--error-dark);
|
||||
padding: 4px 0;
|
||||
padding-block: 4px;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.header {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.row {
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
|
@ -506,7 +525,7 @@
|
|||
.column,
|
||||
.column-full {
|
||||
flex-basis: 100%;
|
||||
margin: 20px 0 0;
|
||||
margin-top: 20px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
@ -542,68 +561,7 @@
|
|||
<div class="content">
|
||||
<form id="formGenerate" novalidate>
|
||||
<div class="header">
|
||||
<svg
|
||||
class="brand"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="200px"
|
||||
height="130px"
|
||||
viewBox="0 0 200 130"
|
||||
enable-background="new 0 0 200 130"
|
||||
xml:space="preserve">
|
||||
<image
|
||||
width="200"
|
||||
height="130"
|
||||
x="0"
|
||||
y="0"
|
||||
href="data:image/png;base64,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
|
||||
ZVJlYWR5ccllPAAAAABJRU5ErkJggg==" />
|
||||
</svg>
|
||||
<img src=" data:image/png;base64,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" alt="Pixel Magic Tool" class="brand">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="column" validate>
|
||||
|
@ -626,11 +584,11 @@
|
|||
<label for="pattern">Pattern</label>
|
||||
<select name="pattern" id="pattern" required>
|
||||
<option value="">Select a choice</option>
|
||||
<option value="1" title="['ffffff']" selected>
|
||||
Individual
|
||||
</option>
|
||||
<option value="1" title="['ffffff']">Individual</option>
|
||||
<option value="2" title="[0, 'ffffff']">Index</option>
|
||||
<option value="3" title="[0, 5, 'ffffff']">Range</option>
|
||||
<option value="3" title="[0, 5, 'ffffff']" selected>
|
||||
Range
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -686,11 +644,13 @@
|
|||
max="255"
|
||||
value="128"
|
||||
class="range-slider" />
|
||||
<input
|
||||
type="text"
|
||||
id="brightnessValue"
|
||||
class="input-description square"
|
||||
value="128" />
|
||||
<div class="input-description square">
|
||||
<input
|
||||
type="text"
|
||||
name="brightnessValue"
|
||||
id="brightnessValue"
|
||||
value="128" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -698,7 +658,11 @@
|
|||
<div class="column" validate>
|
||||
<label for="animation">Animation</label>
|
||||
<label class="switch">
|
||||
<input type="checkbox" name="animation" id="animation" />
|
||||
<input
|
||||
type="checkbox"
|
||||
name="animation"
|
||||
id="animation"
|
||||
data-parent="animation" />
|
||||
<span class="switch-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -708,19 +672,25 @@
|
|||
<input
|
||||
type="checkbox"
|
||||
name="transparentImage"
|
||||
id="transparentImage" />
|
||||
id="transparentImage"
|
||||
data-parent="transparentImage" />
|
||||
<span class="switch-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="column" validate>
|
||||
<label for="resizeImage">Resize Image</label>
|
||||
<label class="switch">
|
||||
<input type="checkbox" name="resizeImage" id="resizeImage" />
|
||||
<input
|
||||
type="checkbox"
|
||||
name="resizeImage"
|
||||
id="resizeImage"
|
||||
data-parent="resizeImage"
|
||||
checked />
|
||||
<span class="switch-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row resizeImage" style="display: none">
|
||||
<div class="row resizeImage">
|
||||
<div class="column" validate>
|
||||
<label for="width">Width</label>
|
||||
<input type="number" name="width" id="width" value="16" />
|
||||
|
@ -747,7 +717,9 @@
|
|||
min="0"
|
||||
step="0.1"
|
||||
inputmode="numeric" />
|
||||
<div class="input-description">sec</div>
|
||||
<div class="input-description">
|
||||
<span>sec</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column" validate>
|
||||
|
@ -762,7 +734,9 @@
|
|||
min="0"
|
||||
step="0.1"
|
||||
inputmode="numeric" />
|
||||
<div class="input-description">sec</div>
|
||||
<div class="input-description">
|
||||
<span>sec</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -773,30 +747,27 @@
|
|||
Color that will replace the
|
||||
<strong>transparent pixels</strong> in the image
|
||||
</small>
|
||||
<input type="color" name="color" id="color" value="#eeeeee" />
|
||||
<input type="color" name="color" id="color" value="#00BFFF" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="column-full" validate>
|
||||
<div class="custom-select">
|
||||
<label for="images">Images</label>
|
||||
<select name="images" id="images" required>
|
||||
<option value="">Select a choice</option>
|
||||
<option value="upload">Upload</option>
|
||||
<label for="images">
|
||||
<span>Images upload to WLED</span>
|
||||
<a id="wledEdit" href="http://[wled-ip]/edit" target="_blank">
|
||||
upload
|
||||
</a>
|
||||
</label>
|
||||
<select name="images" id="images">
|
||||
<option value="">Select image</option>
|
||||
</select>
|
||||
</div>
|
||||
<small>
|
||||
Images uploaded to
|
||||
<a id="wledEdit" href="http://[wled-ip]/edit" target="_blank">
|
||||
<strong>WLED</strong>
|
||||
</a>
|
||||
or upload image
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dropzone" class="dropzone" validate style="display: none">
|
||||
<div id="dropzone" class="dropzone" validate>
|
||||
<p id="dropzoneLabel">
|
||||
Drag and drop a file here or click to select a file
|
||||
Drag and drop a file here or click to select a local file
|
||||
</p>
|
||||
<input
|
||||
type="file"
|
||||
|
@ -868,7 +839,7 @@
|
|||
const hostname = element("hostname");
|
||||
hostname.value = host;
|
||||
|
||||
hostname.addEventListener("change", async () => {
|
||||
hostname.addEventListener("blur", async () => {
|
||||
WLED_URL = `${protocol}//${hostname.value}`;
|
||||
|
||||
await segments();
|
||||
|
@ -893,7 +864,7 @@
|
|||
|
||||
function hostnameLabel() {
|
||||
const link = element("wledEdit");
|
||||
link.href = link.href.replace("[wled-ip]", hostname.value);
|
||||
link.href = WLED_URL + "/edit";
|
||||
}
|
||||
|
||||
async function playlist() {
|
||||
|
@ -999,6 +970,7 @@
|
|||
|
||||
if (success) {
|
||||
toast(`Preset "${item.n}" save successfully`);
|
||||
window.parent.postMessage("loadPresets", WLED_URL);
|
||||
}
|
||||
} catch (error) {
|
||||
toast(`Error saving preset: ${error}`, "error");
|
||||
|
@ -1047,12 +1019,9 @@
|
|||
return mimeTypes.includes(mimetype);
|
||||
});
|
||||
|
||||
const options = [
|
||||
{ text: "Select a choice", value: "" },
|
||||
{ text: "Upload", value: "upload" },
|
||||
];
|
||||
const options = [{ text: "Select image", value: "" }];
|
||||
|
||||
if (images) {
|
||||
if (images.length > 0) {
|
||||
options.push(
|
||||
...images.map(({ name }) => ({
|
||||
text: name,
|
||||
|
@ -1064,6 +1033,11 @@
|
|||
|
||||
options.forEach(({ text, value }) => {
|
||||
const option = new Option(text, value);
|
||||
|
||||
if (index === 0) {
|
||||
option.selected = true;
|
||||
}
|
||||
|
||||
select.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
@ -1076,7 +1050,6 @@
|
|||
|
||||
async function segments() {
|
||||
const select = element("segments");
|
||||
const pattern = element("pattern");
|
||||
const width = element("width");
|
||||
const height = element("height");
|
||||
|
||||
|
@ -1114,7 +1087,6 @@
|
|||
option.selected = true;
|
||||
width.value = w;
|
||||
height.value = h;
|
||||
pattern.value = w * h > 512 ? 3 : 1;
|
||||
}
|
||||
|
||||
select.add(option);
|
||||
|
@ -1278,12 +1250,12 @@
|
|||
const dropzone = element("dropzone");
|
||||
const { value } = e.target.selectedOptions[0];
|
||||
|
||||
if (value === "upload") {
|
||||
if (!value) {
|
||||
const dropzoneLabel = element("dropzoneLabel");
|
||||
const source = element("source");
|
||||
|
||||
dropzoneLabel.textContent =
|
||||
"Drag and drop a file here or click to select a file";
|
||||
"Drag and drop a file here or click to select a local file";
|
||||
source.value = "";
|
||||
|
||||
dropzone.style.display = "block";
|
||||
|
@ -1293,62 +1265,51 @@
|
|||
});
|
||||
|
||||
element("transparentImage").addEventListener("change", (e) => {
|
||||
const transparentImage = d.getElementsByClassName("transparentImage");
|
||||
const transparentImage = d.getElementsByClassName("transparentImage")[0];
|
||||
const { checked } = e.target;
|
||||
|
||||
Array.from(transparentImage).forEach(function (element) {
|
||||
if (checked) {
|
||||
element.style.display = "flex";
|
||||
} else {
|
||||
element.style.display = "none";
|
||||
}
|
||||
});
|
||||
if (checked) {
|
||||
transparentImage.style.display = "flex";
|
||||
} else {
|
||||
transparentImage.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
element("resizeImage").addEventListener("change", (e) => {
|
||||
const resizeImage = d.getElementsByClassName("resizeImage");
|
||||
const resizeImage = d.getElementsByClassName("resizeImage")[0];
|
||||
const pattern = element("pattern");
|
||||
const { checked } = e.target;
|
||||
|
||||
Array.from(resizeImage).forEach(function (element) {
|
||||
if (checked) {
|
||||
pattern.value = 3;
|
||||
element.style.display = "flex";
|
||||
} else {
|
||||
pattern.value = 1;
|
||||
element.style.display = "none";
|
||||
}
|
||||
});
|
||||
if (checked) {
|
||||
resizeImage.style.display = "flex";
|
||||
} else {
|
||||
resizeImage.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
element("animation").addEventListener("change", (e) => {
|
||||
const animation = d.getElementsByClassName("animation");
|
||||
|
||||
const animation = d.getElementsByClassName("animation")[0];
|
||||
const pattern = element("pattern");
|
||||
const source = element("source");
|
||||
|
||||
const { checked } = e.target;
|
||||
|
||||
Array.from(animation).forEach(function (element) {
|
||||
if (checked) {
|
||||
toast(
|
||||
'If you want all frames in the image, set it to "0"',
|
||||
"warning",
|
||||
5000
|
||||
);
|
||||
if (checked) {
|
||||
toast(
|
||||
'If you want all frames in the image, set it to "0"',
|
||||
"warning",
|
||||
5000
|
||||
);
|
||||
|
||||
source.setAttribute("accept", "image/gif");
|
||||
element.style.display = "flex";
|
||||
pattern.value = 3;
|
||||
} else {
|
||||
source.setAttribute(
|
||||
"accept",
|
||||
"image/jpg,image/jpeg,image/png,image/gif"
|
||||
);
|
||||
element.style.display = "none";
|
||||
pattern.value = 1;
|
||||
}
|
||||
});
|
||||
source.setAttribute("accept", "image/gif");
|
||||
animation.style.display = "flex";
|
||||
} else {
|
||||
source.setAttribute(
|
||||
"accept",
|
||||
"image/jpg,image/jpeg,image/png,image/gif"
|
||||
);
|
||||
animation.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
element("btnGenerate").addEventListener("click", async (event) => {
|
||||
|
@ -1402,8 +1363,7 @@
|
|||
const response = element("response");
|
||||
const recreatedImage = element("recreatedImage");
|
||||
|
||||
const urlImage =
|
||||
images === "upload" ? URL.createObjectURL(file) : images;
|
||||
const urlImage = !images ? URL.createObjectURL(file) : images;
|
||||
|
||||
const image = await loadImage(urlImage);
|
||||
const { canvas, bri, id, i } = recreate(image);
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
<button type=submit id="b" onclick="window.location=getURL('/')">Back</button>
|
||||
<button type="submit" onclick="window.location=getURL('/settings/wifi')">WiFi Setup</button>
|
||||
<button type="submit" onclick="window.location=getURL('/settings/leds')">LED Preferences</button>
|
||||
<button id="2dbtn" style="display:none;" type="submit" onclick="window.location=getURL('/settings/2D')">2D Configuration</button>
|
||||
<button id="2dbtn" type="submit" onclick="window.location=getURL('/settings/2D')">2D Configuration</button>
|
||||
<button type="submit" onclick="window.location=getURL('/settings/ui')">User Interface</button>
|
||||
<button id="dmxbtn" style="display:none;" type="submit" onclick="window.location=getURL('/settings/dmx')">DMX Output</button>
|
||||
<button type="submit" onclick="window.location=getURL('/settings/sync')">Sync Interfaces</button>
|
||||
|
|
|
@ -773,6 +773,7 @@ Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65
|
|||
Brightness factor: <input name="BF" type="number" class="m" min="1" max="255" required> %
|
||||
<h3>Transitions</h3>
|
||||
Crossfade: <input type="checkbox" name="TF"><br>
|
||||
Effect blending: <input type="checkbox" name="EB"><br>
|
||||
Transition Time: <input name="TD" type="number" class="xl" min="0" max="65500"> ms<br>
|
||||
Enable Palette transitions: <input type="checkbox" name="PF"><br>
|
||||
<i>Random Cycle</i> Palette Time: <input name="TP" type="number" class="m" min="1" max="255"> s<br>
|
||||
|
|
|
@ -63,7 +63,8 @@ class NeoGammaWLEDMethod {
|
|||
#define gamma32(c) NeoGammaWLEDMethod::Correct32(c)
|
||||
#define gamma8(c) NeoGammaWLEDMethod::rawGamma8(c)
|
||||
uint32_t color_blend(uint32_t,uint32_t,uint16_t,bool b16=false);
|
||||
uint32_t color_add(uint32_t,uint32_t);
|
||||
uint32_t color_add(uint32_t,uint32_t, bool fast=false);
|
||||
uint32_t color_fade(uint32_t c1, uint8_t amount, bool video=false);
|
||||
inline uint32_t colorFromRgbw(byte* rgbw) { return uint32_t((byte(rgbw[3]) << 24) | (byte(rgbw[0]) << 16) | (byte(rgbw[1]) << 8) | (byte(rgbw[2]))); }
|
||||
void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb
|
||||
void colorKtoRGB(uint16_t kelvin, byte* rgb);
|
||||
|
@ -353,6 +354,7 @@ void checkSettingsPIN(const char *pin);
|
|||
uint16_t crc16(const unsigned char* data_p, size_t length);
|
||||
um_data_t* simulateSound(uint8_t simulationId);
|
||||
void enumerateLedmaps();
|
||||
uint8_t get_random_wheel_index(uint8_t pos);
|
||||
|
||||
#ifdef WLED_ADD_EEPROM_SUPPORT
|
||||
//wled_eeprom.cpp
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// Autogenerated from wled00/data/cpal/cpal.htm, do not edit!!
|
||||
const uint16_t PAGE_cpal_L = 4721;
|
||||
const uint8_t PAGE_cpal[] PROGMEM = {
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xbd, 0x3b, 0x7f, 0x73, 0xdb, 0xb6,
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xbd, 0x3b, 0x7f, 0x73, 0xdb, 0xb6,
|
||||
0x92, 0xff, 0xe7, 0x53, 0x20, 0x4c, 0x5f, 0x42, 0xd6, 0x14, 0x45, 0xd2, 0xb6, 0x64, 0x4b, 0xa2,
|
||||
0x3b, 0xa9, 0x93, 0x77, 0xce, 0x8d, 0xdd, 0x64, 0x5e, 0x7c, 0x6e, 0x7b, 0x3e, 0xbf, 0x31, 0x4d,
|
||||
0x42, 0x12, 0x1b, 0x8a, 0xe0, 0x03, 0x21, 0xd9, 0xae, 0xac, 0xef, 0x7e, 0xbb, 0x00, 0x48, 0x91,
|
||||
|
|
1564
wled00/html_other.h
1564
wled00/html_other.h
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
2262
wled00/html_simple.h
2262
wled00/html_simple.h
Plik diff jest za duży
Load Diff
3999
wled00/html_ui.h
3999
wled00/html_ui.h
Plik diff jest za duży
Load Diff
|
@ -210,7 +210,7 @@ void sendImprovInfoResponse() {
|
|||
//Use serverDescription if it has been changed from the default "WLED", else mDNS name
|
||||
bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0);
|
||||
char vString[20];
|
||||
sprintf_P(vString, PSTR("0.14.0/%i"), VERSION);
|
||||
sprintf_P(vString, PSTR("0.14.1-a1/%i"), VERSION);
|
||||
const char *str[4] = {"WLED", vString, bString, useMdnsName ? cmDNS : serverDescription};
|
||||
|
||||
sendImprovRPCResult(ImprovRPCType::Request_Info, 4, str);
|
||||
|
|
|
@ -165,6 +165,8 @@ void updateInterfaces(uint8_t callMode)
|
|||
|
||||
sendDataWs();
|
||||
lastInterfaceUpdate = millis();
|
||||
interfaceUpdateCallMode = 0; //disable
|
||||
|
||||
if (callMode == CALL_MODE_WS_SEND) return;
|
||||
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
|
@ -174,7 +176,6 @@ void updateInterfaces(uint8_t callMode)
|
|||
}
|
||||
#endif
|
||||
doPublishMqtt = true;
|
||||
interfaceUpdateCallMode = 0; //disable
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -247,6 +247,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||
}
|
||||
|
||||
fadeTransition = request->hasArg(F("TF"));
|
||||
modeBlending = request->hasArg(F("EB"));
|
||||
t = request->arg(F("TD")).toInt();
|
||||
if (t >= 0) transitionDelayDefault = t;
|
||||
strip.paletteFade = request->hasArg(F("PF"));
|
||||
|
|
|
@ -382,8 +382,9 @@ void handleNotifications()
|
|||
}
|
||||
if (version > 11) {
|
||||
// when applying synced options ignore selected as it may be used as indicator of which segments to sync
|
||||
// freeze, reset & transitional should never be synced
|
||||
selseg.options = (selseg.options & 0x0071U) | (udpIn[28+ofs]<<8) | (udpIn[9 +ofs] & 0x8E); // ignore selected, freeze, reset & transitional
|
||||
// freeze, reset should never be synced
|
||||
// LSB to MSB: select, reverse, on, mirror, freeze, reset, reverse_y, mirror_y, transpose, map1d2d (3), ssim (2), set (2)
|
||||
selseg.options = (selseg.options & 0b0000000000110001U) | (udpIn[28+ofs]<<8) | (udpIn[9 +ofs] & 0b11001110U); // ignore selected, freeze, reset
|
||||
if (applyEffects) {
|
||||
selseg.custom1 = udpIn[29+ofs];
|
||||
selseg.custom2 = udpIn[30+ofs];
|
||||
|
|
|
@ -416,9 +416,9 @@ uint16_t crc16(const unsigned char* data_p, size_t length) {
|
|||
// (only 2 used as stored in 1 bit in segment options, consider switching to a single global simulation type)
|
||||
typedef enum UM_SoundSimulations {
|
||||
UMS_BeatSin = 0,
|
||||
UMS_WeWillRockYou
|
||||
//UMS_10_13,
|
||||
//UMS_14_3
|
||||
UMS_WeWillRockYou,
|
||||
UMS_10_13,
|
||||
UMS_14_3
|
||||
} um_soundSimulations_t;
|
||||
|
||||
um_data_t* simulateSound(uint8_t simulationId)
|
||||
|
@ -503,7 +503,7 @@ um_data_t* simulateSound(uint8_t simulationId)
|
|||
fftResult[i] = 0;
|
||||
}
|
||||
break;
|
||||
/*case UMS_10_3:
|
||||
case UMS_10_13:
|
||||
for (int i = 0; i<16; i++)
|
||||
fftResult[i] = inoise8(beatsin8(90 / (i+1), 0, 200)*15 + (ms>>10), ms>>3);
|
||||
volumeSmth = fftResult[8];
|
||||
|
@ -512,7 +512,7 @@ um_data_t* simulateSound(uint8_t simulationId)
|
|||
for (int i = 0; i<16; i++)
|
||||
fftResult[i] = inoise8(beatsin8(120 / (i+1), 10, 30)*10 + (ms>>14), ms>>3);
|
||||
volumeSmth = fftResult[8];
|
||||
break;*/
|
||||
break;
|
||||
}
|
||||
|
||||
samplePeak = random8() > 250;
|
||||
|
@ -573,3 +573,17 @@ void enumerateLedmaps() {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a new, random color wheel index with a minimum distance of 42 from pos.
|
||||
*/
|
||||
uint8_t get_random_wheel_index(uint8_t pos) {
|
||||
uint8_t r = 0, x = 0, y = 0, d = 0;
|
||||
while (d < 42) {
|
||||
r = random8();
|
||||
x = abs(pos - r);
|
||||
y = 255 - x;
|
||||
d = MIN(x, y);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -351,6 +351,7 @@ WLED_GLOBAL byte nightlightTargetBri _INIT(0); // brightness after nightlig
|
|||
WLED_GLOBAL byte nightlightDelayMins _INIT(60);
|
||||
WLED_GLOBAL byte nightlightMode _INIT(NL_MODE_FADE); // See const.h for available modes. Was nightlightFade
|
||||
WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading color transition
|
||||
WLED_GLOBAL bool modeBlending _INIT(true); // enable effect blending
|
||||
WLED_GLOBAL uint16_t transitionDelay _INIT(750); // default crossfade duration in ms
|
||||
|
||||
WLED_GLOBAL byte briMultiplier _INIT(100); // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127)
|
||||
|
|
|
@ -40,7 +40,7 @@ bool isIp(String str) {
|
|||
|
||||
void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
if (!correctPIN) {
|
||||
if (final) request->send(500, "text/plain", FPSTR(s_unlock_cfg));
|
||||
if (final) request->send(401, "text/plain", FPSTR(s_unlock_cfg));
|
||||
return;
|
||||
}
|
||||
if (!index) {
|
||||
|
@ -86,7 +86,7 @@ void createEditHandler(bool enable) {
|
|||
#endif
|
||||
} else {
|
||||
editHandler = &server.on("/edit", HTTP_ANY, [](AsyncWebServerRequest *request){
|
||||
serveMessage(request, 500, "Access Denied", FPSTR(s_unlock_cfg), 254);
|
||||
serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_cfg), 254);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ void initServer()
|
|||
verboseResponse = deserializeState(root);
|
||||
} else {
|
||||
if (!correctPIN && strlen(settingsPIN)>0) {
|
||||
request->send(403, "application/json", F("{\"error\":1}")); // ERR_DENIED
|
||||
request->send(401, "application/json", F("{\"error\":1}")); // ERR_DENIED
|
||||
releaseJSONBufferLock();
|
||||
return;
|
||||
}
|
||||
|
@ -211,6 +211,8 @@ void initServer()
|
|||
|
||||
if (verboseResponse) {
|
||||
if (!isConfig) {
|
||||
lastInterfaceUpdate = millis(); // prevent WS update until cooldown
|
||||
interfaceUpdateCallMode = CALL_MODE_WS_SEND; // schedule WS update
|
||||
serveJson(request); return; //if JSON contains "v"
|
||||
} else {
|
||||
doSerializeConfig = true; //serializeConfig(); //Save new settings to FS
|
||||
|
@ -282,7 +284,7 @@ void initServer()
|
|||
//init ota page
|
||||
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if (otaLock) {
|
||||
serveMessage(request, 500, "Access Denied", FPSTR(s_unlock_ota), 254);
|
||||
serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_ota), 254);
|
||||
} else
|
||||
serveSettings(request); // checks for "upd" in URL and handles PIN
|
||||
});
|
||||
|
@ -292,7 +294,11 @@ void initServer()
|
|||
serveSettings(request, true); // handle PIN page POST request
|
||||
return;
|
||||
}
|
||||
if (Update.hasError() || otaLock) {
|
||||
if (otaLock) {
|
||||
serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_ota), 254);
|
||||
return;
|
||||
}
|
||||
if (Update.hasError()) {
|
||||
serveMessage(request, 500, F("Update failed!"), F("Please check your file and retry!"), 254);
|
||||
} else {
|
||||
serveMessage(request, 200, F("Update successful!"), F("Rebooting..."), 131);
|
||||
|
@ -533,7 +539,7 @@ void serveSettingsJS(AsyncWebServerRequest* request)
|
|||
}
|
||||
if (subPage > 0 && !correctPIN && strlen(settingsPIN)>0) {
|
||||
strcpy_P(buf, PSTR("alert('PIN incorrect.');"));
|
||||
request->send(403, "application/javascript", buf);
|
||||
request->send(401, "application/javascript", buf);
|
||||
return;
|
||||
}
|
||||
strcat_P(buf,PSTR("function GetV(){var d=document;"));
|
||||
|
@ -575,7 +581,7 @@ void serveSettings(AsyncWebServerRequest* request, bool post)
|
|||
// if OTA locked or too frequent PIN entry requests fail hard
|
||||
if ((subPage == SUBPAGE_WIFI && wifiLock && otaLock) || (post && !correctPIN && millis()-lastEditTime < PIN_RETRY_COOLDOWN))
|
||||
{
|
||||
serveMessage(request, 500, "Access Denied", FPSTR(s_unlock_ota), 254); return;
|
||||
serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_ota), 254); return;
|
||||
}
|
||||
|
||||
if (post) { //settings/set POST request, saving
|
||||
|
@ -605,7 +611,7 @@ void serveSettings(AsyncWebServerRequest* request, bool post)
|
|||
if (!s2[0]) strcpy_P(s2, s_redirecting);
|
||||
|
||||
bool redirectAfter9s = (subPage == SUBPAGE_WIFI || ((subPage == SUBPAGE_SEC || subPage == SUBPAGE_UM) && doReboot));
|
||||
serveMessage(request, 200, s, s2, redirectAfter9s ? 129 : (correctPIN ? 1 : 3));
|
||||
serveMessage(request, (correctPIN ? 200 : 401), s, s2, redirectAfter9s ? 129 : (correctPIN ? 1 : 3));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -633,7 +639,7 @@ void serveSettings(AsyncWebServerRequest* request, bool post)
|
|||
serveMessage(request, 200, strlen(settingsPIN) > 0 ? PSTR("Settings locked") : PSTR("No PIN set"), FPSTR(s_redirecting), 1);
|
||||
return;
|
||||
}
|
||||
case SUBPAGE_PINREQ : response = request->beginResponse_P(200, "text/html", PAGE_settings_pin, PAGE_settings_pin_length); break;
|
||||
case SUBPAGE_PINREQ : response = request->beginResponse_P(401, "text/html", PAGE_settings_pin, PAGE_settings_pin_length); break;
|
||||
case SUBPAGE_CSS : response = request->beginResponse_P(200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length); break;
|
||||
case SUBPAGE_JS : serveSettingsJS(request); return;
|
||||
case SUBPAGE_WELCOME : response = request->beginResponse_P(200, "text/html", PAGE_welcome, PAGE_welcome_length); break;
|
||||
|
|
|
@ -238,8 +238,8 @@ void getSettingsJS(byte subPage, char* dest)
|
|||
|
||||
if (subPage == SUBPAGE_MENU)
|
||||
{
|
||||
#ifndef WLED_DISABLE_2D // include only if 2D is compiled in
|
||||
oappend(PSTR("gId('2dbtn').style.display='';"));
|
||||
#ifdef WLED_DISABLE_2D // include only if 2D is not compiled in
|
||||
oappend(PSTR("gId('2dbtn').style.display='none';"));
|
||||
#endif
|
||||
#ifdef WLED_ENABLE_DMX // include only if DMX is enabled
|
||||
oappend(PSTR("gId('dmxbtn').style.display='';"));
|
||||
|
@ -441,6 +441,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||
sappend('c',SET_F("GC"),gammaCorrectCol);
|
||||
dtostrf(gammaCorrectVal,3,1,nS); sappends('s',SET_F("GV"),nS);
|
||||
sappend('c',SET_F("TF"),fadeTransition);
|
||||
sappend('c',SET_F("EB"),modeBlending);
|
||||
sappend('v',SET_F("TD"),transitionDelayDefault);
|
||||
sappend('c',SET_F("PF"),strip.paletteFade);
|
||||
sappend('v',SET_F("TP"),randomPaletteChangeTime);
|
||||
|
@ -478,7 +479,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||
|
||||
if (subPage == SUBPAGE_SYNC)
|
||||
{
|
||||
char nS[32];
|
||||
[[maybe_unused]] char nS[32];
|
||||
sappend('v',SET_F("UP"),udpPort);
|
||||
sappend('v',SET_F("U2"),udpPort2);
|
||||
sappend('v',SET_F("GS"),syncGroups);
|
||||
|
|
Ładowanie…
Reference in New Issue