diff --git a/usermods/EleksTube_IPS/TFTs.h b/usermods/EleksTube_IPS/TFTs.h index 4c6bd9cb..0d52d46e 100644 --- a/usermods/EleksTube_IPS/TFTs.h +++ b/usermods/EleksTube_IPS/TFTs.h @@ -75,7 +75,7 @@ private: uint8_t lineBuffer[w * 2]; - if (!realtimeMode || realtimeOverride) strip.service(); + if (!realtimeMode || realtimeOverride || (realtimeMode && useMainSegmentOnly)) strip.service(); // 0,0 coordinates are top left for (row = 0; row < h; row++) { @@ -169,7 +169,7 @@ private: uint32_t lineSize = ((bitDepth * w +31) >> 5) * 4; uint8_t lineBuffer[lineSize]; - uint8_t serviceStrip = (!realtimeMode || realtimeOverride) ? 7 : 0; + uint8_t serviceStrip = (!realtimeMode || realtimeOverride || (realtimeMode && useMainSegmentOnly)) ? 7 : 0; // row is decremented as the BMP image is drawn bottom up for (row = h-1; row >= 0; row--) { if ((row & 0b00000111) == serviceStrip) strip.service(); //still refresh backlight to mitigate stutter every few rows @@ -250,7 +250,7 @@ private: uint8_t lineBuffer[w * 2]; - if (!realtimeMode || realtimeOverride) strip.service(); + if (!realtimeMode || realtimeOverride || (realtimeMode && useMainSegmentOnly)) strip.service(); // 0,0 coordinates are top left for (row = 0; row < h; row++) { diff --git a/wled00/FX.h b/wled00/FX.h index 6f5167d3..cb42a611 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -46,6 +46,11 @@ #define MAX(a,b) ((a)>(b)?(a):(b)) #endif +//color mangling macros +#ifndef RGBW32 +#define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b)))) +#endif + /* Not used in all effects yet */ #define WLED_FPS 42 #define FRAMETIME_FIXED (1000/WLED_FPS) @@ -637,12 +642,13 @@ class WS2812FX { resetSegments(), makeAutoSegments(bool forceReset = false), fixInvalidSegments(), - setPixelColor(uint16_t n, uint32_t c), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), show(void), setTargetFps(uint8_t fps), deserializeMap(uint8_t n=0); + inline void setPixelColor(uint16_t n, uint32_t c) {setPixelColor(n, byte(c>>16), byte(c>>8), byte(c), byte(c>>24));} + bool gammaCorrectBri = false, gammaCorrectCol = true, @@ -909,7 +915,6 @@ class WS2812FX { friend class ColorTransition; uint16_t - realPixelIndex(uint16_t i), transitionProgress(uint8_t tNr); public: diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 9fd81dea..e61e22be 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -131,6 +131,8 @@ void WS2812FX::service() { for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++) { + if (realtimeMode && useMainSegmentOnly && i == getMainSegmentId()) continue; + _segment_index = i; // reset the segment runtime data if needed, called before isActive to ensure deleted @@ -180,34 +182,11 @@ void WS2812FX::service() { _triggered = false; } -void IRAM_ATTR WS2812FX::setPixelColor(uint16_t n, uint32_t c) { - setPixelColor(n, R(c), G(c), B(c), W(c)); -} - -//used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring -uint16_t IRAM_ATTR WS2812FX::realPixelIndex(uint16_t i) { - int16_t iGroup = i * SEGMENT.groupLength(); - - /* reverse just an individual segment */ - int16_t realIndex = iGroup; - if (IS_REVERSE) { - if (IS_MIRROR) { - realIndex = (SEGMENT.length() - 1) / 2 - iGroup; //only need to index half the pixels - } else { - realIndex = (SEGMENT.length() - 1) - iGroup; - } - } - - realIndex += SEGMENT.start; - return realIndex; -} - void IRAM_ATTR WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) { - if (SEGLEN) {//from segment - uint16_t realIndex = realPixelIndex(i); - uint16_t len = SEGMENT.length(); + uint8_t segIdx; + if (SEGLEN) { // SEGLEN!=0 -> from segment/FX //color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments) if (_bri_t < 255) { r = scale8(r, _bri_t); @@ -215,30 +194,48 @@ void IRAM_ATTR WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte b = scale8(b, _bri_t); w = scale8(w, _bri_t); } + segIdx = _segment_index; + } else // from live/realtime + segIdx = _mainSegment; + + if (SEGLEN || (realtimeMode && useMainSegmentOnly)) { uint32_t col = RGBW32(r, g, b, w); + uint16_t len = _segments[segIdx].length(); - /* Set all the pixels in the group */ - for (uint16_t j = 0; j < SEGMENT.grouping; j++) { - uint16_t indexSet = realIndex + (IS_REVERSE ? -j : j); - if (indexSet >= SEGMENT.start && indexSet < SEGMENT.stop) { - if (IS_MIRROR) { //set the corresponding mirrored pixel - uint16_t indexMir = SEGMENT.stop - indexSet + SEGMENT.start - 1; - /* offset/phase */ - indexMir += SEGMENT.offset; - if (indexMir >= SEGMENT.stop) indexMir -= len; + // get physical pixel address (taking into account start, grouping, spacing [and offset]) + i = i * _segments[segIdx].groupLength(); + if (_segments[segIdx].options & REVERSE) { // is segment reversed? + if (_segments[segIdx].options & MIRROR) { // is segment mirrored? + i = (len - 1) / 2 - i; //only need to index half the pixels + } else { + i = (len - 1) - i; + } + } + i += _segments[segIdx].start; + // set all the pixels in the group + for (uint16_t j = 0; j < _segments[segIdx].grouping; j++) { + uint16_t indexSet = i + ((_segments[segIdx].options & REVERSE) ? -j : j); + if (indexSet >= _segments[segIdx].start && indexSet < _segments[segIdx].stop) { + + if (_segments[segIdx].options & MIRROR) { //set the corresponding mirrored pixel + uint16_t indexMir = _segments[segIdx].stop - indexSet + _segments[segIdx].start - 1; + indexMir += _segments[segIdx].offset; // offset/phase + + if (indexMir >= _segments[segIdx].stop) indexMir -= len; if (indexMir < customMappingSize) indexMir = customMappingTable[indexMir]; + busses.setPixelColor(indexMir, col); } - /* offset/phase */ - indexSet += SEGMENT.offset; - if (indexSet >= SEGMENT.stop) indexSet -= len; + indexSet += _segments[segIdx].offset; // offset/phase + if (indexSet >= _segments[segIdx].stop) indexSet -= len; if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; + busses.setPixelColor(indexSet, col); } } - } else { //live data, etc. + } else { if (i < customMappingSize) i = customMappingTable[i]; busses.setPixelColor(i, RGBW32(r, g, b, w)); } @@ -503,7 +500,13 @@ uint8_t WS2812FX::getActiveSegmentsNum(void) { uint32_t WS2812FX::getPixelColor(uint16_t i) { - i = realPixelIndex(i); + // get physical pixel + i = i * SEGMENT.groupLength();; + if (IS_REVERSE) { + if (IS_MIRROR) i = (SEGMENT.length() - 1) / 2 - i; //only need to index half the pixels + else i = (SEGMENT.length() - 1) - i; + } + i += SEGMENT.start; if (SEGLEN) { /* offset/phase */ diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index e416dad3..acc0adf5 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -294,6 +294,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { JsonObject if_live = interfaces["live"]; CJSON(receiveDirect, if_live["en"]); + CJSON(useMainSegmentOnly, if_live[F("mso")]); CJSON(e131Port, if_live["port"]); // 5568 if (e131Port == DDP_DEFAULT_PORT) e131Port = E131_DEFAULT_PORT; // prevent double DDP port allocation CJSON(e131Multicast, if_live[F("mc")]); @@ -699,6 +700,7 @@ void serializeConfig() { JsonObject if_live = interfaces.createNestedObject("live"); if_live["en"] = receiveDirect; + if_live[F("mso")] = useMainSegmentOnly; if_live["port"] = e131Port; if_live[F("mc")] = e131Multicast; diff --git a/wled00/data/index.css b/wled00/data/index.css index fafe7ccd..ea0bb1c7 100644 --- a/wled00/data/index.css +++ b/wled00/data/index.css @@ -665,9 +665,12 @@ input[type=range]::-moz-range-thumb { border: 1px solid var(--c-3); background-color: var(--c-3); } +#segutil .btn-s:hover, +#segutil2 .btn-s:hover, +#putil .btn-s:hover, .btn:hover { - border: 1px solid var(--c-5) !important; - background-color: var(--c-5) !important; + border: 1px solid var(--c-5) /*!important*/; + background-color: var(--c-5) /*!important*/; } .btn-s { width: 100%; @@ -917,7 +920,7 @@ textarea { .pwr { color: var(--c-6); - transform: translate(2px, 2px); + transform: translate(1px, 1px); cursor: pointer; } @@ -1041,7 +1044,7 @@ textarea { .seg .schkl { position: absolute; - top: 7px; + top: 8px; left: 9px; } diff --git a/wled00/data/index.js b/wled00/data/index.js index ea71eb99..41ed9c11 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -1941,6 +1941,8 @@ function setIntensity() function setLor(i) { var obj = {"lor": i}; + // allow canceling live mode (if sender crashes) + if (i===0 && lastinfo.live && ["","Hyperion","UDP"].includes(lastinfo.lm)) { obj.live = false; obj.v = true; } requestJson(obj); } diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm index 9315c28f..b634d6b3 100644 --- a/wled00/data/settings_sync.htm +++ b/wled00/data/settings_sync.htm @@ -104,7 +104,8 @@ Send notifications twice:
Enable instance list:
Make this instance discoverable:

Realtime

-Receive UDP realtime:

+Receive UDP realtime:
+Use main segment only:

Network DMX input
Type: -
🗓
`; - ih+=`