Skip to content

Commit

Permalink
Adding Pal Mode effects and 2 Byte Mapping - WIP
Browse files Browse the repository at this point in the history
In this commit both modes (pal/non pal) is supported to allow for testing, eventually only Pal mode supported

LedEffects:
- change some effects to Pal / 2 byte mapping mode: rainbow, lissajous and noise2D
- remove default values in argumnnet list for ColorFromPalette

LedFixture: projectAndMap
-  checkPalColorEffect: temp method until all effects have been converted to Palette / 2 byte mapping mode

LedLeds
- extend PhysMap with 2 byte Pal mode
- add addIndexP2
- add 2D vector leds.mappingTableIndexes
- add and use checkPalColorEffect
- add setPixelColorPal
- optimize fTb, fS, fR

LedModEffects
- fx.onChange: check on Pal / non pal effect change (and redo mapping)
  • Loading branch information
ewoudwijma committed Jul 15, 2024
1 parent 0413f4c commit c31c550
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 53 deletions.
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ lib_deps =
build_flags =
; -D APP=StarBase
-D PIOENV=$PIOENV
-D VERSION=24071207 ; Date and time (GMT!), update at every commit!!
-D VERSION=24071508 ; Date and time (GMT!), update at every commit!!
-D LFS_THREADSAFE ; enables use of semaphores in LittleFS driver
-D STARBASE_DEVMODE
${ESPAsyncWebServer.build_flags} ;alternatively PsychicHttp
Expand Down
37 changes: 20 additions & 17 deletions src/App/LedEffects.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ class RainbowEffect: public Effect {

for (forUnsigned16 i = 0; i < leds.nrOfLeds; i++) {
uint8_t index = (i * (16 << (scale / 29)) / leds.nrOfLeds) + counter;
leds.setPixelColor(i, ColorFromPalette(leds.palette, index, 255));
// leds.setPixelColor(i, ColorFromPalette(leds.palette, index));
leds.setPixelColorPal(i, index);
}
}

Expand Down Expand Up @@ -178,14 +179,14 @@ class FlowEffect: public Effect {
uint16_t zoneLen = leds.nrOfLeds / zones;
uint16_t offset = (leds.nrOfLeds - zones * zoneLen) >> 1;

leds.fill_solid(ColorFromPalette(leds.palette, -counter, 255));
leds.fill_solid(ColorFromPalette(leds.palette, -counter));

for (int z = 0; z < zones; z++) {
uint16_t pos = offset + z * zoneLen;
for (int i = 0; i < zoneLen; i++) {
uint8_t colorIndex = (i * 255 / zoneLen) - counter;
uint16_t led = (z & 0x01) ? i : (zoneLen -1) -i;
leds[pos + led] = ColorFromPalette(leds.palette, colorIndex, 255);
leds[pos + led] = ColorFromPalette(leds.palette, colorIndex);
}
}
}
Expand Down Expand Up @@ -395,7 +396,7 @@ class BouncingBalls: public Effect {

int pos = roundf(balls[i].height * (leds.nrOfLeds - 1));

CRGB color = ColorFromPalette(leds.palette, i*(256/max(numBalls, (uint8_t)8)), 255); //error: no matching function for call to 'max(uint8_t&, int)'
CRGB color = ColorFromPalette(leds.palette, i*(256/max(numBalls, (uint8_t)8))); //error: no matching function for call to 'max(uint8_t&, int)'

leds[pos] = color;
// if (leds.nrOfLeds<32) leds.setPixelColor(indexToVStrip(pos, stripNr), color); // encode virtual strip into index
Expand Down Expand Up @@ -789,7 +790,7 @@ class PopCorn: public Effect {
// uint32_t col = SEGMENT.color_wheel(popcorn[i].colIndex);
// if (!SEGMENT.palette && popcorn[i].colIndex < NUM_COLORS) col = SEGCOLOR(popcorn[i].colIndex);
uint16_t ledIndex = popcorn[i].pos;
CRGB col = ColorFromPalette(leds.palette, popcorn[i].colIndex*(256/maxNumPopcorn), 255);
CRGB col = ColorFromPalette(leds.palette, popcorn[i].colIndex*(256/maxNumPopcorn));
if (ledIndex < leds.nrOfLeds) leds.setPixelColor(ledIndex, col);
}
}
Expand Down Expand Up @@ -877,7 +878,7 @@ class AudioRings: public RingEffect {
void setRingFromFtt(Leds &leds, int index, int ring) {
byte val = wledAudioMod->fftResults[index];
// Visualize leds to the beat
CRGB color = ColorFromPalette(leds.palette, val, 255);
CRGB color = ColorFromPalette(leds.palette, val);
color.nscale8_video(val);
setRing(leds, ring, color);
}
Expand Down Expand Up @@ -1074,8 +1075,8 @@ class DNA: public Effect {
//32: 4 * i
//16: 8 * i
phase = i * 127 / (leds.size.x-1) * phases / 64;
leds.setPixelColor(leds.XY(i, beatsin8(speed, 0, leds.size.y-1, 0, phase )), ColorFromPalette(leds.palette, i*5+ sys->now /17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND));
leds.setPixelColor(leds.XY(i, beatsin8(speed, 0, leds.size.y-1, 0, phase+128)), ColorFromPalette(leds.palette, i*5+128+ sys->now /17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND));
leds.setPixelColor(leds.XY(i, beatsin8(speed, 0, leds.size.y-1, 0, phase )), ColorFromPalette(leds.palette, i*5+ sys->now /17, beatsin8(5, 55, 255, 0, i*10)));
leds.setPixelColor(leds.XY(i, beatsin8(speed, 0, leds.size.y-1, 0, phase+128)), ColorFromPalette(leds.palette, i*5+128+ sys->now /17, beatsin8(5, 55, 255, 0, i*10+128)));
}
leds.blur2d(blur);
}
Expand Down Expand Up @@ -1264,7 +1265,8 @@ class Lissajous: public Effect {
//leds.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(sys->now/100+i, false, PALETTE_SOLID_WRAP, 0)); // draw pixel with anti-aliasing
unsigned palIndex = (256*locn.y) + phase/2 + (i* freqX)/64;
// leds.setPixelColorXY(xlocn, ylocn, SEGMENT.color_from_palette(palIndex, false, PALETTE_SOLID_WRAP, 0)); // draw pixel with anti-aliasing - color follows rotation
leds[locn] = ColorFromPalette(leds.palette, palIndex);
// leds[locn] = ColorFromPalette(leds.palette, palIndex);
leds.setPixelColorPal(locn, palIndex);
}
} else
for (int i=0; i < 256; i ++) {
Expand All @@ -1274,7 +1276,8 @@ class Lissajous: public Effect {
locn.x = (leds.size.x < 2) ? 1 : (map(2*locn.x, 0,511, 0,2*(leds.size.x-1)) +1) /2; // softhack007: "*2 +1" for proper rounding
locn.y = (leds.size.y < 2) ? 1 : (map(2*locn.y, 0,511, 0,2*(leds.size.y-1)) +1) /2; // "leds.size.y > 2" is needed to avoid div/0 in map()
// leds.setPixelColorXY((uint8_t)xlocn, (uint8_t)ylocn, SEGMENT.color_from_palette(sys->now/100+i, false, PALETTE_SOLID_WRAP, 0));
leds[locn] = ColorFromPalette(leds.palette, sys->now/100+i);
// leds[locn] = ColorFromPalette(leds.palette, sys->now/100+i);
leds.setPixelColorPal(locn, sys->now/100+i);
}
}

Expand Down Expand Up @@ -1311,7 +1314,7 @@ class Frizzles: public Effect {
Coord3D pos = {0,0,0};
pos.x = beatsin8(bpm/8 + i, 0, leds.size.x - 1);
pos.y = beatsin8(intensity/8 - i, 0, leds.size.y - 1);
CRGB color = ColorFromPalette(leds.palette, beatsin8(12, 0, 255), 255);
CRGB color = ColorFromPalette(leds.palette, beatsin8(12, 0, 255));
leds[pos] = color;
}
leds.blur2d(blur);
Expand Down Expand Up @@ -1376,7 +1379,8 @@ class Noise2D: public Effect {
for (int y = 0; y < leds.size.y; y++) {
for (int x = 0; x < leds.size.x; x++) {
uint8_t pixelHue8 = inoise8(x * scale, y * scale, sys->now / (16 - speed));
leds.setPixelColor(leds.XY(x, y), ColorFromPalette(leds.palette, pixelHue8));
// leds.setPixelColor(leds.XY(x, y), ColorFromPalette(leds.palette, pixelHue8));
leds.setPixelColorPal(leds.XY(x, y), pixelHue8);
}
}
}
Expand Down Expand Up @@ -2263,14 +2267,13 @@ class Waverly: public Effect {
uint16_t thisMax = min(map(thisVal, 0, 512, 0, leds.size.y), (long)leds.size.x);

for (pos.y = 0; pos.y < thisMax; pos.y++) {
CRGB color = ColorFromPalette(leds.palette, map(pos.y, 0, thisMax, 250, 0), 255, LINEARBLEND);
CRGB color = ColorFromPalette(leds.palette, map(pos.y, 0, thisMax, 250, 0));
if (!noClouds)
leds.addPixelColor(pos, color);
leds.addPixelColor(leds.XY((leds.size.x - 1) - pos.x, (leds.size.y - 1) - pos.y), color);
}
}
leds.blur2d(16);

}

void controls(Leds &leds, JsonObject parentVar) {
Expand Down Expand Up @@ -2615,7 +2618,7 @@ class RipplesEffect: public Effect {
uint32_t time_interval = sys->now/(100 - speed)/((256.0f-128.0f)/20.0f);
pos.y = floor(leds.size.y/2.0f + sinf(d/ripple_interval + time_interval) * leds.size.y/2.0f); //between 0 and leds.size.y

leds[pos] = CHSV( sys->now/50 + random8(64), 200, 255);// ColorFromPalette(leds.palette,call, bri, LINEARBLEND);
leds[pos] = CHSV( sys->now/50 + random8(64), 200, 255);// ColorFromPalette(leds.palette,call, bri);
}
}
}
Expand Down Expand Up @@ -2653,7 +2656,7 @@ class SphereMoveEffect: public Effect {
uint16_t d = distance(pos.x, pos.y, pos.z, origin.x, origin.y, origin.z);

if (d>diameter && d<diameter+1) {
leds[pos] = CHSV( sys->now/50 + random8(64), 200, 255);// ColorFromPalette(leds.palette,call, bri, LINEARBLEND);
leds[pos] = CHSV( sys->now/50 + random8(64), 200, 255);// ColorFromPalette(leds.palette,call, bri);
}
}
}
Expand All @@ -2679,7 +2682,7 @@ class PixelMapEffect: public Effect {
leds.fill_solid(CRGB::Black);

Coord3D pos = {x, y, z};
leds[pos] = CHSV( sys->now/50 + random8(64), 255, 255);// ColorFromPalette(leds.palette,call, bri, LINEARBLEND);
leds[pos] = CHSV( sys->now/50 + random8(64), 255, 255);// ColorFromPalette(leds.palette,call, bri);
}

void controls(Leds &leds, JsonObject parentVar) {
Expand Down
62 changes: 45 additions & 17 deletions src/App/LedFixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@ void Fixture::projectAndMap() {
leds->size = Coord3D{0,0,0};
//vectors really gone now?
for (PhysMap &map:leds->mappingTable) {
if (map.getMapType() == m_morePixels) {
map.indexes->clear();
delete map.indexes;
if (leds->checkPalColorEffect()) { // checkPalColorEffect: temp method until all effects have been converted to Palette / 2 byte mapping mode
leds->mappingTableIndexes.clear();
}
else
if (map.getMapType() == m_morePixels) {
map.indexes->clear();
delete map.indexes;
}
}
leds->mappingTable.clear();
// leds->effectData.reset(); //do not reset as want to save settings.
Expand Down Expand Up @@ -138,11 +142,14 @@ void Fixture::projectAndMap() {
if (indexV >= leds->mappingTable.size()) {
for (size_t i = leds->mappingTable.size(); i <= indexV; i++) {
// ppf("mapping %d,%d,%d add physMap before %d %d\n", pixel.y, pixel.y, pixel.z, indexV, leds->mappingTable.size());
leds->mappingTable.push_back(PhysMap()); //abort() was called at PC 0x40191473 on core 1 std::allocator<unsigned short> >&&)
leds->mappingTable.push_back(PhysMap(leds->checkPalColorEffect())); // checkPalColorEffect: temp method until all effects have been converted to Palette / 2 byte mapping mode
}
}

leds->mappingTable[indexV].addIndexP(indexP);
if (leds->checkPalColorEffect()) // checkPalColorEffect: temp method until all effects have been converted to Palette / 2 byte mapping mode
leds->mappingTable[indexV].addIndexP2(*leds, indexP);
else
leds->mappingTable[indexV].addIndexP(indexP);
// ppf("mapping b:%d t:%d V:%d\n", indexV, indexP, leds->mappingTable.size());
} //indexV not too high
} //indexV
Expand Down Expand Up @@ -218,26 +225,47 @@ void Fixture::projectAndMap() {
if (leds->mappingTable.size() < leds->size.x * leds->size.y * leds->size.z)
ppf("mapping add extra physMap %d to %d size: %d,%d,%d\n", leds->mappingTable.size(), leds->size.x * leds->size.y * leds->size.z, leds->size.x, leds->size.y, leds->size.z);
for (size_t i = leds->mappingTable.size(); i < leds->size.x * leds->size.y * leds->size.z; i++) {
leds->mappingTable.push_back(PhysMap());
leds->mappingTable.push_back(PhysMap(leds->checkPalColorEffect())); // checkPalColorEffect: temp method until all effects have been converted to Palette / 2 byte mapping mode
}

leds->nrOfLeds = leds->mappingTable.size();

// ppf("post leds %d p:%d\n", leds->mappingTable.size(), leds->checkPalColorEffect());

//debug info + summary values
for (PhysMap &map:leds->mappingTable) {
switch (map.getMapType()) {
case m_onePixel:
nrOfPhysical++;
break;
case m_morePixels:
// ppf("ledV %d mapping: #ledsP (%d):", indexV, nrOfLogical);
for (uint16_t indexP:*map.indexes) {
// ppf(" %d", indexP);
if (leds->checkPalColorEffect()) { // checkPalColorEffect: temp method until all effects have been converted to Palette / 2 byte mapping mode
// ppf("i: %d t:%d\n", nrOfLogical, map.mapType);
switch (map.mapType) {
case m_onePixel:
// ppf("ledV %d mapping: #ledsP : %d\n", nrOfLogical, map.indexP1);
nrOfPhysical++;
}
// ppf("\n");
break;
break;
case m_morePixels:
// ppf("ledV %d mapping: #ledsP :", nrOfLogical);

for (uint16_t indexP: leds->mappingTableIndexes[map.indexes1]) {
// ppf(" %d", indexP);
nrOfPhysical++;
}
// ppf("\n");
break;
}
}
else
switch (map.getMapType()) {
case m_onePixel:
nrOfPhysical++;
break;
case m_morePixels:
// ppf("ledV %d mapping: #ledsP :", nrOfLogical);
for (uint16_t indexP:*map.indexes) {
ppf(" %d", indexP);
nrOfPhysical++;
}
// ppf("\n");
break;
}
nrOfLogical++;
// else
// ppf("ledV %d no mapping\n", x);
Expand Down
61 changes: 56 additions & 5 deletions src/App/LedLeds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ void fastled_fill_rainbow(struct CRGB * targetArray, int numToFill, unsigned8 in
}

void Leds::triggerMapping() {
doMap = true; //specify which leds to remapp
fixture->doMap = true; //fixtgure will also be remapped
doMap = true; //specify which leds to remap
fixture->doMap = true; //fixture will also be remapped
}

unsigned16 Leds::XYZ(Coord3D pixel) {
Expand Down Expand Up @@ -71,6 +71,32 @@ void Leds::setPixelColor(unsigned16 indexV, CRGB color, unsigned8 blendAmount) {
ppf(" dev sPC V:%d >= %d", indexV, NUM_LEDS_Max);
}

void Leds::setPixelColorPal(unsigned16 indexV, uint8_t palIndex, uint8_t palBri, unsigned8 blendAmount) {
if (indexV < mappingTable.size()) {
switch (mappingTable[indexV].mapType) {
case m_color:
mappingTable[indexV].palIndex = palIndex;
mappingTable[indexV].palBri = palBri;
case m_onePixel: {
uint16_t indexP = mappingTable[indexV].indexP1;
fixture->ledsP[indexP] = blend(ColorFromPalette(palette, palIndex, palBri), fixture->ledsP[indexP], blendAmount==UINT8_MAX?fixture->globalBlend:blendAmount);
break; }
case m_morePixels:
if (mappingTable[indexV].indexes1 < mappingTableIndexes.size())
for (forUnsigned16 indexP: mappingTableIndexes[mappingTable[indexV].indexes1]) {
fixture->ledsP[indexP] = blend(ColorFromPalette(palette, palIndex, palBri), fixture->ledsP[indexP], blendAmount==UINT8_MAX?fixture->globalBlend:blendAmount);
}
// else
// ppf("dev setPixelColorPal i:%d m:%d s:%d\n", indexV, mappingTable[indexV].indexes1, mappingTableIndexes.size());
break;
}
}
else if (indexV < NUM_LEDS_Max) //no projection
fixture->ledsP[(projectionNr == p_Random)?random(fixture->nrOfLeds):indexV] = ColorFromPalette(palette, palIndex, palBri);
else if (indexV != UINT16_MAX) //assuming UINT16_MAX is set explicitly (e.g. in XYZ)
ppf(" dev sPC V:%d >= %d", indexV, NUM_LEDS_Max);
}

CRGB Leds::getPixelColor(unsigned16 indexV) {
if (indexV < mappingTable.size()) {
switch (mappingTable[indexV].getMapType()) {
Expand All @@ -94,7 +120,7 @@ CRGB Leds::getPixelColor(unsigned16 indexV) {
}

void Leds::fadeToBlackBy(unsigned8 fadeBy) {
if (projectionNr == p_None || projectionNr == p_Random || (fixture->nrOfLeds == nrOfLeds)) {
if (projectionNr == p_None || projectionNr == p_Random || (fixture->listOfLeds.size() == 1)) {
fastled_fadeToBlackBy(fixture->ledsP, fixture->nrOfLeds, fadeBy);
} else {
for (PhysMap &map:mappingTable) {
Expand All @@ -118,7 +144,7 @@ void Leds::fadeToBlackBy(unsigned8 fadeBy) {
}

void Leds::fill_solid(const struct CRGB& color, bool noBlend) {
if (projectionNr == p_None || projectionNr == p_Random || (fixture->nrOfLeds == nrOfLeds)) {
if (projectionNr == p_None || projectionNr == p_Random || (fixture->listOfLeds.size() == 1)) {
fastled_fill_solid(fixture->ledsP, fixture->nrOfLeds, color);
} else {
for (PhysMap &map:mappingTable) {
Expand All @@ -138,7 +164,7 @@ void Leds::fill_solid(const struct CRGB& color, bool noBlend) {
}

void Leds::fill_rainbow(unsigned8 initialhue, unsigned8 deltahue) {
if (projectionNr == p_None || projectionNr == p_Random || (fixture->nrOfLeds == nrOfLeds)) {
if (projectionNr == p_None || projectionNr == p_Random || (fixture->listOfLeds.size() == 1)) {
fastled_fill_rainbow(fixture->ledsP, fixture->nrOfLeds, initialhue, deltahue);
} else {
CHSV hsv;
Expand All @@ -162,3 +188,28 @@ void Leds::fill_rainbow(unsigned8 initialhue, unsigned8 deltahue) {
}
}
}

void PhysMap::addIndexP2(Leds &leds, uint16_t indexP) {
// ppf("addIndexP2 i:%d t:%d", indexP, mapType);
switch (mapType) {
case m_color:
// case m_rgbColor:
indexP1 = indexP;
mapType = m_onePixel;
break;
case m_onePixel: {
uint16_t oldIndexP = indexP1;
std::vector<uint16_t> newVector;
newVector.push_back(oldIndexP);
newVector.push_back(indexP);
leds.mappingTableIndexes.push_back(newVector);
indexes1 = leds.mappingTableIndexes.size() - 1;
mapType = m_morePixels;
break; }
case m_morePixels:
leds.mappingTableIndexes[indexes1].push_back(indexP);
// ppf(" more %d", mappingTableIndexes.size());
break;
}
// ppf("\n");
}
Loading

0 comments on commit c31c550

Please sign in to comment.