~/Projects/WLED
git clone https://code.lsong.org/WLED
Commit
- Commit
- 3260f465434518b515ff771059dce20d39b6281a
- Author
- Frank <91616163+[email protected]>
- Date
- 2023-09-18 14:57:15 +0200 +0200
- Diffstat
wled00/FX.cpp | 42 +++++++++++++++++++++++++++---------------
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.
diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 2a1f9f27b5764f7ba99062dc313520dbe3d9dd59..1abca885582de139248214dc87899a2025630484 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -5169,7 +5169,7 @@ /////////////////////// // 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 @@ const uint16_t rows = SEGMENT.virtualHeight(); 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 @@ } 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<cols; col++) { CRGB pix = SEGMENT.getPixelColorXY(col, row); - if (pix == spawnColor) { + if (pix == oldSpawnColor) { // this comparison may still fail due to overlays changing pixels, or due to gaps (2d-gaps.json) SEGMENT.setPixelColorXY(col, row, trailColor); // create trail if (row < rows-1) SEGMENT.setPixelColorXY(col, row+1, spawnColor); } else { @@ -5208,30 +5223,27 @@ } } // check for empty screen to ensure code spawn + bool emptyScreen = (SEGENV.aux1 >= rows); // empty screen means that the last falling code has moved out of screen area WS2812FX.cpp contains all effect methods - for (int i = ledstart; i < ledstart + ledlen; i++) + Harm Aldick - 2016 #define IBN 5100 - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal WS2812FX.cpp contains all effect methods - SEGENV.aux1--; - * Running lights in opposite directions. + * @param pulsewidth 0-127 /* + The MIT License (MIT) WS2812FX.cpp contains all effect methods - return sin8(in + 192); // correct phase shift of sine so that it starts and stops at 0 of this software and associated documentation files (the "Software"), to deal -#include "fcn_declare.h" of this software and associated documentation files (the "Software"), to deal - } - + www.aldick.org * Running lights in opposite directions. - WS2812FX.cpp contains all effect methods + LICENSE - if (random8() < SEGMENT.intensity || emptyScreen) { + // update hint for next run - * Running lights in opposite directions. + www.aldick.org www.aldick.org + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#define IBN 5100 + color1 = SEGMENT.color_wheel(SEGENV.aux1); of this software and associated documentation files (the "Software"), to deal - LICENSE } } // if millis