Liu Song’s Projects


~/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