From 3260f465434518b515ff771059dce20d39b6281a Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Mon, 18 Sep 2023 14:57:15 +0200 Subject: [PATCH] bugfix for #3375 * improves robustness of the Matrix effect, by dynamically adjusting the "reference color" used to identify "falling code" head pixels. * a bit faster, as I've removed the need to scan all pixels a second time for "black screen" detection. Its still not perfect, and the main loop could be simplified a lot by leveraging on the fact that all changes actually happen in the top row, and "falling" is actually just moving everything down by one pixel. --- wled00/FX.cpp | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 2a1f9f27..1abca885 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5169,7 +5169,7 @@ static const char _data_FX_MODE_2DLISSAJOUS[] PROGMEM = "Lissajous@X frequency,F /////////////////////// // 2D Matrix // /////////////////////// -uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi. +uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi, and softhack007. if (!strip.isMatrix) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); @@ -5177,6 +5177,8 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. if (SEGENV.call == 0) { SEGMENT.fill(BLACK); + SEGENV.aux0 = SEGENV.aux1 = UINT16_MAX; + SEGENV.step = 0; } uint8_t fade = map(SEGMENT.custom1, 0, 255, 50, 250); // equals trail size @@ -5194,10 +5196,23 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. if (strip.now - SEGENV.step >= speed) { SEGENV.step = strip.now; + // find out what color value is returned by gPC for a "falling code" example pixel + // the color values returned may differ from the previously set values, due to + // - auto brightness limiter (dimming) + // - lossy color buffer (when not using global buffer) + // - color balance correction + // - segment opacity + CRGB oldSpawnColor = spawnColor; + if ((SEGENV.aux0 < cols) && (SEGENV.aux1 < rows)) { // we have a hint from last run + oldSpawnColor = SEGMENT.getPixelColorXY(SEGENV.aux0, SEGENV.aux1); // find color of previous spawns + SEGENV.aux1 ++; // our sample pixel will be one row down the next time + } + + // move pixels one row down. Falling codes keep color and add trail pixels; all others pixels are faded for (int row=rows-1; row>=0; row--) { for (int col=0; col= rows); // empty screen means that the last falling code has moved out of screen area // spawn new falling code - if (random8() < SEGMENT.intensity || emptyScreen) { + if (random8() <= SEGMENT.intensity || emptyScreen) { uint8_t spawnX = random8(cols); SEGMENT.setPixelColorXY(spawnX, 0, spawnColor); + // update hint for next run + SEGENV.aux0 = spawnX; + SEGENV.aux1 = 0; } } // if millis