Skip to content

Commit

Permalink
Implement Live Mapping, Live Scripts IDs instead of pointers
Browse files Browse the repository at this point in the history
panel scripts: add map function for Live Fixture Mapping  (WIP)

pio.ini: add STARLIGHT_LIVE_MAPPING

UserModLive:
- change from executable pointer to exeID (index in scripts list)
- Use Execution as stack variable, not pointer

LedEffects.h
- Live Effect: kill script if new script loaded

LedModEffects
- add LiveFixtureProjection if Live Mapping

LedModFixture
- set i2s_mapping_mode if live mapping
- mapFunction: run only if projection is 0
- Live Fixture: kill script if new script loaded
  • Loading branch information
ewowi committed Nov 1, 2024
1 parent 654b6f9 commit 42cb1b8
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 108 deletions.
31 changes: 31 additions & 0 deletions misc/LiveScripts/F_panel080-048.sc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@
define horizontalPanels 5
define verticalPanels 3

//to be modified for 80x48
void map(int pos) {
int panelnumber = pos / 256;
int datainpanel = pos % 256;
int Xp = 7 - panelnumber % 8;

//fix for ewowi panels
Xp=Xp+1;
if (Xp==8) {Xp=0;}

int yp = panelnumber / 8;
int X = Xp; //panel on the x axis
int Y = yp; //panel on the y axis

int y = datainpanel % 16;
int x = datainpanel / 16;

if (x % 2 == 0) //serpentine
{
Y = Y * 16 + y;
X = X * 16 + x;
}
else
{
Y = Y * 16 + 16 -y-1;
X = X * 16 + x;
}

mapResult = (95-Y) * 16 * 8 + (127-X);
}

void main() {
for (int panelY = 0; panelY < verticalPanels; panelY++) {
for (int panelX = horizontalPanels-1; panelX >=0; panelX--) {
Expand Down
30 changes: 30 additions & 0 deletions misc/LiveScripts/F_panel128-096.sc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,36 @@
define horizontalPanels 8
define verticalPanels 6

void map(int pos) {
int panelnumber = pos / 256;
int datainpanel = pos % 256;
int Xp = 7 - panelnumber % 8;

//fix for ewowi panels
Xp=Xp+1;
if (Xp==8) {Xp=0;}

int yp = panelnumber / 8;
int X = Xp; //panel on the x axis
int Y = yp; //panel on the y axis

int y = datainpanel % 16;
int x = datainpanel / 16;

if (x % 2 == 0) //serpentine
{
Y = Y * 16 + y;
X = X * 16 + x;
}
else
{
Y = Y * 16 + 16 -y-1;
X = X * 16 + x;
}

mapResult = (95-Y) * 16 * 8 + (127-X);
}

void main() {
for (int panelY = 0; panelY < verticalPanels; panelY++) {
for (int panelX = horizontalPanels-1; panelX >=0; panelX--) {
Expand Down
1 change: 1 addition & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ build_flags =
-D ARDUINO_USB_CDC_ON_BOOT=0 ; Make sure that the right HardwareSerial driver is picked in arduino-esp32 (needed on "classic ESP32")
-D STARLIGHT_MAXLEDS=12288 ;LEDs specific
${STARLIGHT_CLOCKLESS_VIRTUAL_LED_DRIVER.build_flags} ; temporary here, until there is one driver for s3 and non s3
; -D STARLIGHT_LIVE_MAPPING
lib_deps =
${env.lib_deps}
${STARLIGHT_CLOCKLESS_VIRTUAL_LED_DRIVER.lib_deps} ; temporary here, until there is one driver for s3 and non s3
Expand Down
16 changes: 10 additions & 6 deletions src/App/LedEffects.h
Original file line number Diff line number Diff line change
Expand Up @@ -2992,10 +2992,14 @@ class LiveEffect: public Effect {
if (strnstr(fileName, ".sc", sizeof(fileName)) != nullptr) {
ppf("script.onChange Live Fixture %s\n", fileName);

//to do kill the old one if changed
uint8_t newExeID = liveM->findExecutable(fileName);
if (newExeID == UINT8_MAX) {
ppf("kill old live effect script\n");
liveM->killAndDelete(leds.liveEffectID);
}
leds.liveEffectID = newExeID;

leds.liveEffectExecutable = liveM->findExecutable(fileName);
if (!leds.liveEffectExecutable) {
if (leds.liveEffectID == UINT8_MAX) {

liveM->scPreBaseScript = "";

Expand All @@ -3022,11 +3026,11 @@ class LiveEffect: public Effect {
liveM->scPreBaseScript += "define NUM_LEDS " + std::to_string(leds.nrOfLeds) + "\n";
liveM->scPreBaseScript += "define panel_width " + std::to_string(leds.size.x) + "\n"; //isn't panel_width always the same as width?

leds.liveEffectExecutable = liveM->compile(fileName, "void main(){resetStat();setup();while(2>1){loop();sync();}}");
leds.liveEffectID = liveM->compile(fileName, "void main(){resetStat();setup();while(2>1){loop();sync();}}");
}

if (leds.liveEffectExecutable)
liveM->executeBackgroundTask(leds.liveEffectExecutable);
if (leds.liveEffectID != UINT8_MAX)
liveM->executeBackgroundTask(leds.liveEffectID);
else
ppf("mapInitAlloc Live Effect not created (compilation error?) %s\n", fileName);
}
Expand Down
6 changes: 3 additions & 3 deletions src/App/LedLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ void LedsLayer::fill_rainbow(uint8_t initialhue, uint8_t deltahue) {
(projection->*addPixelCached)(*this, pixelAdjusted, indexV);
mdl->getValueRowNr = UINT8_MAX; // end of run projection functions in the right rowNr context

if (indexV != UINT16_MAX) {
if (indexV != UINT16_MAX) { //can be set to UINT16_MAX by projection
if (indexV >= nrOfLeds || indexV >= STARLIGHT_MAXLEDS)
ppf("dev addPixel leds[%d] indexV too high %d>=%d or %d (m:%d p:%d) p:%d,%d,%d s:%d,%d,%d\n", rowNr, indexV, nrOfLeds, STARLIGHT_MAXLEDS, mappingTableSizeUsed, fix->indexP, pixel.x, pixel.y, pixel.z, size.x, size.y, size.z);
else {
Expand All @@ -361,8 +361,8 @@ void LedsLayer::fill_rainbow(uint8_t initialhue, uint8_t deltahue) {
// ppf("mapping b:%d t:%d V:%d\n", indexV, indexP, mappingTableSizeUsed);
} //indexV not too high
} //indexV
else
ppf("dev check this case indexV != UINT16_MAX %d\n", indexV);
// else
// ppf("dev check this case indexV != UINT16_MAX %d\n", indexV);

} //if x,y,z between start and end
} //if projection && doMap
Expand Down
2 changes: 1 addition & 1 deletion src/App/LedLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ class LedsLayer {
CRGBPalette16 palette;

#ifdef STARBASE_USERMOD_LIVE
void *liveEffectExecutable = nullptr; //will be Executable * in the future
uint8_t liveEffectID = UINT8_MAX;
#endif

int XY(int x, int y) {
Expand Down
6 changes: 5 additions & 1 deletion src/App/LedModEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ inline uint16_t getRGBWsize(uint16_t nleds){
#endif

//load projections
projections.push_back(new NoneProjection);
#ifdef STARLIGHT_LIVE_MAPPING
projections.push_back(new LiveMappingProjection);
#else
projections.push_back(new NoneProjection);
#endif
projections.push_back(new DefaultProjection);
projections.push_back(new PinwheelProjection);
projections.push_back(new MirrorReverseTransposeProjection);
Expand Down
100 changes: 52 additions & 48 deletions src/App/LedModFixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,45 +309,49 @@
static void _addPin(uint8_t a1) {fix->addPin(a1);}
static void _addPixelsPost() {fix->addPixelsPost();}

#ifdef STARLIGHT_ICLD_MAPPING
#ifdef STARLIGHT_LIVE_MAPPING
uint16_t mapResult = UINT16_MAX;

uint16_t mapfunction(uint16_t pos)
{
if (fix->liveFixtureExecutable) {
mapResult = pos;
ppf("±"); // to see if it is invoked...
// liveM->executeTask(fix->liveFixtureExecutable, "map", pos); //if not existst then Impossible to execute @_map: not found and crash -> check existence before?

return mapResult; //set by this task
} else { // this is hardcoded and only for testing purposes
int datainpanel = pos % 256;
int Xp = 7 - panelnumber % 8;

//fix for ewowi panels
Xp=Xp+1;
if (Xp==8) {Xp=0;}

int yp = panelnumber / 8;
int X = Xp; //panel on the x axis
int Y = yp; //panel on the y axis

int y = datainpanel % 16;
int x = datainpanel / 16;
if (!fix->layers[0]->projection) { // projection 0
if (false && fix->liveFixtureID != UINT8_MAX) {
mapResult = pos;
if (pos == 0) ppf("±"); // to see if it is invoked...
liveM->executeTask(fix->liveFixtureID, "map", pos); //if not existst then Impossible to execute @_map: not found and crash -> check existence before?

return mapResult; //set by this task
} else { // this is hardcoded and only for testing purposes
int panelnumber = pos / 256;
int datainpanel = pos % 256;
int Xp = 7 - panelnumber % 8;

//fix for ewowi panels
Xp=Xp+1;
if (Xp==8) {Xp=0;}

int yp = panelnumber / 8;
int X = Xp; //panel on the x axis
int Y = yp; //panel on the y axis

int y = datainpanel % 16;
int x = datainpanel / 16;

if (x % 2 == 0) //serpentine
{
Y = Y * 16 + y;
X = X * 16 + x;
}
else
{
Y = Y * 16 + 16 -y-1;
X = X * 16 + x;
}

if (x % 2 == 0) //serpentine
{
Y = Y * 16 + y;
X = X * 16 + x;
return (95-Y) * 16 * 8 + (127-X);
}
else
{
Y = Y * 16 + 16 -y-1;
X = X * 16 + x;
}

return (95-Y) * 16 * 8 + (127-X);
}
} else
return pos;
}
#endif
#endif
Expand All @@ -369,15 +373,15 @@

ppf("mapInitAlloc Live Fixture %s\n", fileName);

void *newExecutable = liveM->findExecutable(fileName);
// ppf("mapInitAlloc Live Fixture %s o:%p n:%p =:%d\n", fileName, newExecutable, liveFixtureExecutable, newExecutable != liveFixtureExecutable);
// if (newExecutable && liveFixtureExecutable && newExecutable != liveFixtureExecutable) {
// ppf("kill old live fixture script\n");
// liveM->killAndDelete(liveFixtureExecutable);
// }
liveFixtureExecutable = newExecutable;
uint8_t newExeID = liveM->findExecutable(fileName);
ppf("mapInitAlloc Live Fixture %s n:%d o:%d =:%d\n", fileName, newExeID, liveFixtureID, newExeID != liveFixtureID);
if (newExeID == UINT8_MAX) {
ppf("kill old live fixture script\n");
liveM->killAndDelete(liveFixtureID);
}
liveFixtureID = newExeID;

if (!liveFixtureExecutable) {
if (liveFixtureID == UINT8_MAX) {
//if the file is already compiled, use it, otherwise compile new one

liveM->scPreBaseScript = "";
Expand All @@ -392,19 +396,19 @@
liveM->addExternalFun("void", "addPixel", "(uint16_t a1, uint16_t a2, uint16_t a3)", (void *)_addPixel);
liveM->addExternalFun("void", "addPin", "(uint8_t a1)", (void *)_addPin);
liveM->addExternalFun("void", "addPixelsPost", "()", (void *)_addPixelsPost);
#ifdef STARLIGHT_ICLD_MAPPING
#ifdef STARLIGHT_LIVE_MAPPING
liveM->addExternalVal("uint16_t", "mapResult", &mapResult); //used in map function
#endif

liveFixtureExecutable = liveM->compile(fileName, "void c(){addPixelsPre();main();addPixelsPost();}");
liveFixtureID = liveM->compile(fileName, "void c(){addPixelsPre();main();addPixelsPost();}");
}

if (liveFixtureExecutable) {
if (liveFixtureID != UINT8_MAX) {
start = millis();
pass = 1;
liveM->executeTask(liveFixtureExecutable, "c");
liveM->executeTask(liveFixtureID, "c");
pass = 2;
liveM->executeTask(liveFixtureExecutable, "c");
liveM->executeTask(liveFixtureID, "c");
}
else
ppf("mapInitAlloc Live Fixture not created (compilation error?) %s\n", fileName);
Expand Down Expand Up @@ -718,7 +722,7 @@
//void initled( uint8_t * leds, int * pins, int numstrip, int NUM_LED_PER_STRIP)
#else
driver.initled((uint8_t*) ledsP, pinAssignment, lengths, nb_pins, ORDER_GRB);
#ifdef STARLIGHT_ICLD_MAPPING
#if STARBASE_USERMOD_LIVE & STARLIGHT_LIVE_MAPPING
driver.setMapLed(&mapfunction);
#endif
//void initled(uint8_t *leds, int *Pinsq, int *sizes, int num_strips, colorarrangment cArr)
Expand All @@ -730,7 +734,7 @@
int pins[6] = { STARLIGHT_ICVLD_PINS };
driver.initled(ledsP, pins, STARLIGHT_ICVLD_CLOCK_PIN, STARLIGHT_ICVLD_LATCH_PIN);
// driver.enableShowPixelsOnCore(1);
#ifdef STARLIGHT_ICLD_MAPPING
#if STARBASE_USERMOD_LIVE & STARLIGHT_LIVE_MAPPING
driver.setMapLed(&mapfunction);
#endif
driver.setGamma(255.0/255.0, 176.0/255.0, 240.0/255.0);
Expand Down
7 changes: 3 additions & 4 deletions src/App/LedModFixture.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@
#define NBIS2SERIALPINS 6 //6 shift registers
#endif
// #include "esp_heap_caps.h"
#if STARBASE_USERMOD_LIVE & false //crashes at the moment
#if STARBASE_USERMOD_LIVE & STARLIGHT_LIVE_MAPPING
#define I2S_MAPPING_MODE (I2S_MAPPING_MODE_OPTION_MAPPING_SOFTWARE) //works no flickering anymore (due to __NB_DMA_BUFFER)!
// #define I2S_MAPPING_MODE (I2S_MAPPING_MODE_OPTION_MAPPING_IN_MEMORY) //not working: IllegalInstruction Backtrace: 0x5515d133:0x3ffb1fc0 |<-CORRUPTED
#define __NB_DMA_BUFFER 5 //or 10 ... underscore ! default 2 (2 causes flickering in case of mapping).
#define STARLIGHT_ICLD_MAPPING
#define __NB_DMA_BUFFER 10 //or 10 ... underscore ! default 2 (2 causes flickering in case of mapping).
#else
#define I2S_MAPPING_MODE (I2S_MAPPING_MODE_OPTION_NONE) //works but mapping using StarLight mappingTable needed
#endif
Expand Down Expand Up @@ -143,7 +142,7 @@ class LedModFixture: public SysModule {
void addPixelsPost();

#ifdef STARBASE_USERMOD_LIVE
void *liveFixtureExecutable = nullptr; //will be Executable * in the future
uint8_t liveFixtureID = UINT8_MAX;
#endif

#ifdef STARLIGHT_CLOCKLESS_LED_DRIVER
Expand Down
11 changes: 11 additions & 0 deletions src/App/LedProjections.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ class NoneProjection: public Projection {
}
}; //NoneProjection

#ifdef STARLIGHT_LIVE_MAPPING
class LiveMappingProjection: public Projection {
const char * name() {return "Live Fixture Mapping";}
//uint8_t dim() {return _1D;} // every projection should work for all D
const char * tags() {return "💫";}

void setup(LedsLayer &leds, JsonObject parentVar) {
}
}; //NoneProjection
#endif

class DefaultProjection: public Projection {
const char * name() {return "Default";}
const char * tags() {return "💫";}
Expand Down
Loading

0 comments on commit 42cb1b8

Please sign in to comment.