Skip to content

Add games (Tetris, Snake), 5 new animations, and multiple bugfixes#6

Open
Dcomp-commits wants to merge 10 commits into
psykokwak-com:masterfrom
Dcomp-commits:improvements-2026
Open

Add games (Tetris, Snake), 5 new animations, and multiple bugfixes#6
Dcomp-commits wants to merge 10 commits into
psykokwak-com:masterfrom
Dcomp-commits:improvements-2026

Conversation

@Dcomp-commits
Copy link
Copy Markdown

@Dcomp-commits Dcomp-commits commented May 16, 2026


🇬🇧 English

New features

Tetris & Snake games (web interface)

  • Page_tetris.h — Tetris playable from any browser hosted on the ESP8266.
    Supports touch controls on smartphone/tablet screens, and Bluetooth game
    controllers (PS4, PS5, Xbox, etc.) connected to the visiting device.
    Score/level/lines display, next-piece preview, runs on the LED matrix
  • Page_snake.h — Snake playable from any browser hosted on the ESP8266.
    Same dual control support: touchscreen or Bluetooth gamepad.
    Runs on the LED matrix
  • Accessible via /tetris.html and /snake.html
  • Links added in the sidebar navigation of the dashboard

5 new animations + improvements to existing ones (LedStrip.h)

Animation controls in the dashboard (Page_index.h)

  • Animation speed slider (1–20)
  • Animation min brightness slider (0–100%)
  • Animation max brightness slider (0–100%)

Custom inline color picker (Page_index.h)

  • Replaces native <input type="color"> which showed broken HSV sliders (defaulting to 0,0,0) in Android Chrome's "Personnalisé" mode
  • Click the color swatch to open an inline picker: 2D saturation/brightness square + hue rainbow slider
  • Works identically on all browsers and platforms (Android, iOS, desktop)
  • Hex text input retained for direct entry

Bug fixes

global.h

  • ResetEEPROM: only erased 511 bytes — MQTT zone was never cleared. Now uses EEPROM_SIZE (1024)
  • ReadStringFromEEPROM: off-by-one error corrected (read past buffer end)
  • WriteStringToEEPROM: added maxLen parameter with truncation to prevent overflow
  • printConfig: passwords now masked (***) in Serial output
  • Added AP_DEFAULT_PASSWORD and EEPROM_SIZE constants
  • Added APPassword field (EEPROM 712), brightnessMax, and animSpeed/Min/Max fields
  • Added sanity check on timeZone in ReadConfig
  • Animation index now bounds-checked on read — prevents silent fallback to Normal mode on first boot when EEPROM contains an out-of-range value

LedStrip.h

  • Matrix animation: trail fade used absolute Darken(35) — tail disappeared completely at low animBrightnessMax values. Fixed with proportional fade (brightness scales linearly with distance from head)
  • Lightning animation: FLASH phase set all pixels to white without calling copyForeground(), briefly erasing the time words. Fixed by adding copyForeground() at the end of the FLASH case

WiFiMgr.h

  • Timers unsigned int → unsigned long — overflow caused AP fallback failure after ~65s

WiFiMgr.cpp

  • Static IP now applied before WiFi.begin() (was after — caused DHCP conflict)
  • WiFi password removed from Serial logs
  • AP address corrected: 192.168.1.1 → 192.168.4.1 (standard ESP8266 AP address)
  • Added WiFi.setAutoReconnect(false) before switching to AP mode (two conflicting mechanisms)
  • STA timeout increased: 10s → 30s (WiFi 6 routers are slower to associate)
  • AP key validation: length() == 0 → length() < 8 (WPA2 requires minimum 8 characters)

NTP.h

  • Integer overflow fix in timezone calculation: timeZone * 360 could overflow int for UTC+9 and above (32767 limit). Fixed with (long) cast: (long)timeZone * 360. The select uses 1/10th-hour units (GMT+1 =
    value 10, 10 × 360s = 3600s = 1h), so the multiplier 360 is correct and unchanged

TexTime.ino

  • Use EEPROM_SIZE constant instead of hardcoded 1024
  • Default config now initializes all new fields and calls WriteConfig()
  • setAPssid now passes APPassword
  • tryToConnect uses const String& (avoids unnecessary heap copies)
  • setTimeout cast to unsigned long to prevent overflow
  • Added routes for Tetris and Snake

Page_network.h

  • Passwords (WiFi + AP) no longer sent back to the browser on page load
  • APPassword field added: only saved if length ≥ 8 (WPA2 requirement)

Page_general.h

  • send_general_configuration_values_html: exposes animSpeed, animBrightnessMin, animBrightnessMax
  • send_general_led: live update of animation parameters without page reload; animation speed now calls setAnimSpeed() so the frame rate changes immediately (no Save required)

🇫🇷 Français

Nouvelles fonctionnalités

Jeux Tetris & Snake (interface web)

  • Page_tetris.h — Tetris jouable depuis n'importe quel navigateur connecté
    à l'ESP8266. Contrôles tactiles sur écran de smartphone/tablette, ou via
    un contrôleur Bluetooth (PS4, PS5, Xbox, etc.) connecté à l'appareil visitant
    la page. Affichage score/niveau/lignes, aperçu de la pièce suivante,
    s'exécute sur la matrice LED
  • Page_snake.h — Snake jouable depuis n'importe quel navigateur connecté
    à l'ESP8266. Même double support : écran tactile ou manette Bluetooth.
    S'exécute sur la matrice LED
  • Accessible via /tetris.html et /snake.html
  • Liens ajoutés dans la navigation latérale du dashboard

5 nouvelles animations + améliorations des animations existantes (LedStrip.h)

Contrôles d'animation dans le dashboard (Page_index.h)

  • Slider de vitesse d'animation (1–20)
  • Slider de luminosité minimale des animations (0–100%)
  • Slider de luminosité maximale des animations (0–100%)

Sélecteur de couleur inline personnalisé (Page_index.h)

  • Remplace le <input type="color"> natif dont les sliders HSV affichaient 0,0,0 (noir) par défaut dans le mode « Personnalisé » d'Android Chrome
  • Cliquer sur le carré coloré ouvre un picker inline : carré saturation/luminosité 2D + slider teinte arc-en-ciel
  • Fonctionne à l'identique sur tous les navigateurs et plateformes (Android, iOS, desktop)
  • Champ texte hex conservé pour la saisie directe

Corrections de bugs

global.h

  • ResetEEPROM : n'effaçait que 511 octets — la zone MQTT n'était jamais effacée. Utilise maintenant EEPROM_SIZE (1024)
  • ReadStringFromEEPROM : débordement d'un octet corrigé (lecture au-delà du buffer)
  • WriteStringToEEPROM : ajout d'un paramètre maxLen avec troncature pour éviter les débordements
  • printConfig : les mots de passe sont maintenant masqués (***) dans la sortie Serial
  • Ajout des constantes AP_DEFAULT_PASSWORD et EEPROM_SIZE
  • Ajout des champs APPassword (EEPROM 712), brightnessMax, et animSpeed/Min/Max
  • Ajout d'une vérification de cohérence sur timeZone dans ReadConfig
  • Index d'animation borné à la lecture — évite un fallback silencieux vers le mode Normal au démarrage si l'EEPROM contient une valeur hors plage

LedStrip.h

  • Animation Matrix : le fondu de la traînée utilisait Darken(35) absolu — la queue disparaissait complètement pour les faibles valeurs d'animBrightnessMax. Corrigé avec un fondu proportionnel (luminosité
    décroît linéairement avec la distance à la tête)
  • Animation Lightning : la phase FLASH mettait tous les pixels en blanc sans appeler copyForeground(), effaçant brièvement les mots de l'heure. Corrigé par l'ajout de copyForeground() en fin de case FLASH

WiFiMgr.h

  • Timers unsigned int → unsigned long — l'overflow provoquait un échec du basculement en mode AP après ~65s

WiFiMgr.cpp

  • L'IP statique est maintenant appliquée avant WiFi.begin() (était après — conflit DHCP)
  • Le mot de passe WiFi supprimé des logs Serial
  • Adresse AP corrigée : 192.168.1.1 → 192.168.4.1 (adresse standard ESP8266 en mode AP)
  • Ajout de WiFi.setAutoReconnect(false) avant le passage en mode AP (deux mécanismes en conflit)
  • Timeout STA augmenté : 10s → 30s (les box WiFi 6 sont plus lentes à associer)
  • Validation de la clé AP : length() == 0 → length() < 8 (WPA2 exige 8 caractères minimum)

NTP.h

  • Correction d'un overflow entier dans le calcul du fuseau horaire : timeZone * 360 dépassait la limite int (32767) pour UTC+9 et au-delà. Corrigé avec un cast (long) : (long)timeZone * 360. Le select
    utilise des unités de 1/10ème d'heure (GMT+1 = valeur 10, 10 × 360s = 3600s = 1h), le multiplicateur 360 est donc correct et inchangé

TexTime.ino

  • Utilisation de la constante EEPROM_SIZE au lieu de 1024 en dur
  • La config par défaut initialise maintenant tous les nouveaux champs et appelle WriteConfig()
  • setAPssid transmet maintenant APPassword
  • tryToConnect utilise const String& (évite les copies inutiles sur le heap)
  • Cast unsigned long sur setTimeout pour éviter l'overflow
  • Ajout des routes pour Tetris et Snake

Page_network.h

  • Les mots de passe (WiFi + AP) ne sont plus renvoyés au navigateur à l'ouverture de la page
  • Champ APPassword ajouté : sauvegardé uniquement si longueur ≥ 8 (exigence WPA2)

Page_general.h

  • send_general_configuration_values_html : expose animSpeed, animBrightnessMin, animBrightnessMax
  • send_general_led : mise à jour live des paramètres d'animation sans rechargement de page ; la vitesse d'animation appelle maintenant setAnimSpeed() pour que la fréquence change immédiatement (sans
    nécessiter Save)

Dcomp-commits and others added 10 commits May 16, 2026 21:23
New features:
- Page_tetris.h: Tetris game playable via web interface on LED matrix
- Page_snake.h: Snake game playable via web interface on LED matrix
- LedStrip.h: 5 new animations + improvements to existing ones

Bug fixes:
- global.h: EEPROM reset now covers full 1024 bytes (was 511); off-by-one
  in ReadStringFromEEPROM; WriteStringToEEPROM truncates to maxLen; passwords
  masked in printConfig; add AP_DEFAULT_PASSWORD, EEPROM_SIZE constants;
  add brightnessMax, APPassword, animSpeed/Min/Max fields with EEPROM R/W;
  timezone sanity check on ReadConfig
- WiFiMgr.h: timers unsigned int -> unsigned long (overflow fix at ~65s)
- WiFiMgr.cpp: static IP applied before WiFi.begin (DHCP conflict fix);
  password removed from Serial logs; AP address 192.168.1.1 -> 192.168.4.1;
  setAutoReconnect(false) before AP mode; WPA2 key length check >= 8;
  STA timeout 10s -> 30s for WiFi 6 compatibility
- NTP.h: integer overflow fix in timezone calculation (cast to long)
- TexTime.ino: use EEPROM_SIZE constant; default config initializes all new
  fields and calls WriteConfig(); setAPssid passes APPassword; tryToConnect
  uses const String& signature; setTimeout overflow cast; add game routes
- Page_network.h: passwords not returned to browser on page load;
  APPassword field added (min 8 chars, only saved if valid length)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Page_index.h: add speed, min/max brightness sliders for animations;
  add Tetris and Snake links in sidebar navigation
- Page_general.h: expose animSpeed/animBrightnessMin/Max in config
  values endpoint and live LED update handler
- TexTime.ino: save animSpeed/animBrightnessMin/Max in /admin/save/general

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The timezone select uses 1/10th-hour units (GMT+1 = value 10).
Correct multiplier is 360 (10 * 360 = 3600s = 1h).
The (long) cast is kept to prevent int overflow for UTC+9 and above.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents setAnimation() from silently falling back to index 0 (Normal)
when EEPROM contains an out-of-range animation value (e.g. 0xFF on first
boot or after firmware downgrade).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use QTLed.setAnimSpeed() instead of directly writing _config.animSpeed,
so begin() is called on the current animation and the new FPS takes
effect in real-time without requiring Save.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace absolute Darken(35) with a distance-based proportional fade so
the tail remains visible at any brightness level. Previously, low
animBrightnessMax values caused the trail to reach black in 2-3 pixels,
making variable trail lengths invisible.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add copyForeground() at the end of the FLASH phase, consistent with
BUILD and FADE which already do this. Background pixels still flash
white but word pixels are restored on top.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
initializeColorPicker() now explicitly syncs colorText.value to
colorInput.value after setValues() loads server data. setValues()
sets colorText programmatically (no 'input' event fires), leaving
colorInput stuck at #000000.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces browser-native color picker with a custom inline picker:
- Colored swatch (click to open/close)
- 2D saturation/value square (drag to pick)
- Hue rainbow slider
- Hex text input stays for direct entry
- Works identically on Android and desktop
- CSS loaded with ?t=timestamp to prevent stale cache

Fixes Android Chrome "Personnalise" HSV sliders defaulting to 0,0,0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
setValues() sets element.value programmatically without firing oninput,
so animspeedt, animbrightmint and animbrightmaxt stayed at '--' after
loading stored settings. Sync them explicitly in the loadGeneralSettings
callback once all setValues() calls have resolved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant