Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions wled00/FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -910,7 +916,6 @@ class WS2812FX {
friend class ColorTransition;

uint16_t
realPixelIndex(uint16_t i),
transitionProgress(uint8_t tNr);

public:
Expand Down
83 changes: 43 additions & 40 deletions wled00/FX_fcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -185,65 +187,60 @@ 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);
g = scale8(g, _bri_t);
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));
}
Expand Down Expand Up @@ -508,7 +505,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 */
Expand All @@ -523,7 +526,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
}

WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) {
if (id >= MAX_NUM_SEGMENTS) return _segments[0];
if (id >= MAX_NUM_SEGMENTS) return _segments[getMainSegmentId()];
return _segments[id];
}

Expand Down
2 changes: 2 additions & 0 deletions wled00/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,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")]);
Expand Down Expand Up @@ -704,6 +705,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;

Expand Down
13 changes: 13 additions & 0 deletions wled00/data/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,19 @@ input[type=number]::-webkit-outer-spin-button {
right: 8px;
}

.frz {
left: 36px;
position: absolute;
top: 0px;
cursor: pointer;
padding: 8px;
}

/* TODO expanded does not seem to apply to .frz, what is this for? */
.expanded .frz {
display: none;
}

.check, .radio {
display: inline-block;
position: relative;
Expand Down
2 changes: 1 addition & 1 deletion wled00/data/index.htm
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
<div id="Effects" class="tabcontent">
<p class="labels">Effect speed</p>
<div class="staytop">
<i class="icons slider-icon" style="cursor: pointer;" onclick="tglFreeze()">&#xe325;</i>
<i class="icons slider-icon" style="cursor: pointer;" title="Freeze" onclick="tglFreeze()">&#xe325;</i>
<div class="sliderwrap il">
<input id="sliderSpeed" class="noslide" onchange="setSpeed()" oninput="updateTrail(this)" max="255" min="0" type="range" value="128" />
<output class="sliderbubble hidden"></output>
Expand Down
10 changes: 8 additions & 2 deletions wled00/data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ function populateInfo(i)
function populateSegments(s)
{
var cn = "";
let li = lastinfo;
segCount = 0; lowestUnused = 0; lSeg = 0;

for (var y = 0; y < (s.seg||[]).length; y++)
Expand All @@ -584,6 +585,7 @@ function populateSegments(s)
<input type="checkbox" id="seg${i}sel" onchange="selSeg(${i})" ${inst.sel ? "checked":""}>
<span class="checkmark schk"></span>
</label>
<i class="icons e-icon frz" id="seg${i}frz" onclick="event.preventDefault();tglFreeze(${i});" style="display:${inst.frz?"inline":"none"}">&#x${li.live && li.liveseg==i?'e410':'e325'};</i>
<div class="segname">
<div class="segntxt" onclick="selSegEx(${i})">${inst.n ? inst.n : "Segment "+i}</div>
<i class="icons edit-icon ${expanded[i] ? "expanded":""}" id="seg${i}nedit" onclick="tglSegn(${i})">&#xe2c6;</i>
Expand Down Expand Up @@ -964,7 +966,7 @@ function updateUI()

function displayRover(i,s)
{
d.getElementById('rover').style.transform = (i.live && s.lor == 0) ? "translateY(0px)":"translateY(100%)";
d.getElementById('rover').style.transform = (i.live && s.lor == 0 && i.liveseg<0) ? "translateY(0px)":"translateY(100%)";
var sour = i.lip ? i.lip:""; if (sour.length > 2) sour = " from " + sour;
d.getElementById('lv').innerHTML = `WLED is receiving live ${i.lm} data${sour}`;
d.getElementById('roverstar').style.display = (i.live && s.lor) ? "block":"none";
Expand Down Expand Up @@ -1643,7 +1645,11 @@ function setSegBri(s){
function tglFreeze(s=null)
{
var obj = {"seg": {"frz": "t"}}; // toggle
if (s!==null) obj.id = s;
if (s!==null) {
obj.seg.id = s;
// if live segment, enter live override (which also unfreezes)
if (lastinfo && s==lastinfo.liveseg && lastinfo.live) obj = {"lor":1};
}
requestJson(obj);
}

Expand Down
3 changes: 2 additions & 1 deletion wled00/data/settings_sync.htm
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ <h3>Instance List</h3>
Enable instance list: <input type="checkbox" name="NL"><br>
Make this instance discoverable: <input type="checkbox" name="NB">
<h3>Realtime</h3>
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
Receive UDP realtime: <input type="checkbox" name="RD"><br>
Use main segment only: <input type="checkbox" name="MO"><br><br>
<i>Network DMX input</i><br>
Type:
<select name=DI onchange="SP(); adj();">
Expand Down
1 change: 1 addition & 0 deletions wled00/fcn_declare.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte
void notify(byte callMode, bool followUp=false);
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte *buffer, uint8_t bri=255, bool isRGBW=false);
void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
void exitRealtime();
void handleNotifications();
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
void refreshNodeList();
Expand Down
3 changes: 2 additions & 1 deletion wled00/html_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ Send notifications twice: <input type="checkbox" name="S2"><br><i>
Reboot required to apply changes.</i><h3>Instance List</h3>
Enable instance list: <input type="checkbox" name="NL"><br>
Make this instance discoverable: <input type="checkbox" name="NB"><h3>Realtime
</h3>Receive UDP realtime: <input type="checkbox" name="RD"><br><br><i>
</h3>Receive UDP realtime: <input type="checkbox" name="RD"><br>
Use main segment only: <input type="checkbox" name="MO"><br><br><i>
Network DMX input</i><br>Type: <select name="DI" onchange="SP(),adj()"><option
value="5568">E1.31 (sACN)</option><option value="6454">Art-Net</option><option
value="0" selected="selected">Custom port</option></select><br><div id="xp">
Expand Down
Loading