Snake!#10936
Conversation
⚡ Try this PR in the Web FlasherWarning This is an automated, unreviewed CI test build. Back up your device configuration Supported boards built by this PR (27)
Build artifacts expire on 2026-08-13. Updated for |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds an opt-in Snake game to BaseUI displays and introduces HUB75 RGB-matrix display support across ESP32 and Portduino targets, including rendering backends, configuration, Screen/UI integration, high-score persistence, picker input, and tests. ChangesSnake Game Feature
HUB75 Display Support
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant Screen
participant SnakeModule
participant SnakeGame
participant NotificationRenderer
participant SafeFile
User->>Screen: Select games frame
Screen->>SnakeModule: launchGame()
SnakeModule->>SnakeModule: loadHighScores()
SnakeModule->>SnakeModule: startPlaying()
loop each tick
SnakeModule->>SnakeGame: step()
SnakeGame-->>SnakeModule: alive or won state
SnakeModule->>Screen: requestRedraw()
end
SnakeModule->>Screen: showAlphanumericPicker(callback)
Screen->>NotificationRenderer: drawAlphanumericPicker
NotificationRenderer-->>SnakeModule: initials callback
SnakeModule->>SafeFile: saveHighScores()
sequenceDiagram
participant YAMLConfig
participant PortduinoGlue
participant Screen
participant HUB75Native
participant RGBMatrix
YAMLConfig->>PortduinoGlue: load HUB75 settings
PortduinoGlue->>Screen: set display geometry and panel type
Screen->>HUB75Native: construct and connect backend
HUB75Native->>RGBMatrix: create matrix and render framebuffer
Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (6)
src/modules/SnakeModule.h (1)
13-15: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTrim multi-paragraph doc comments per coding guidelines.
The
SNAKE_ANNOUNCE_HIGH_SCOREdoc (Lines 13-15) and the class-level doc (Lines 28-37) exceed the guideline limit with multi-paragraph explanations. As per coding guidelines,**/*.{c,cc,cpp,cxx,h,hpp,hh}: "Keep code comments minimal: one or two lines maximum... and do not restate the next line."Also applies to: 28-37
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/modules/SnakeModule.h` around lines 13 - 15, Trim the doc comments in SnakeModule.h so they fit the coding guideline of one or two lines maximum and avoid multi-paragraph explanations. Shorten both the SNAKE_ANNOUNCE_HIGH_SCORE comment and the SnakeModule class-level doc, keeping only the essential summary and removing repeated details or restatements of nearby code.Source: Coding guidelines
src/modules/SnakeGame.h (2)
7-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTrim multi-line doc comments per coding guidelines.
The class-level doc (Lines 7-16) and the
setDirection/stepdocs (Lines 42-47, 50-54) run 3-4+ content lines with multi-paragraph explanations. As per coding guidelines,**/*.{c,cc,cpp,cxx,h,hpp,hh}: "Keep code comments minimal: one or two lines maximum, only when the reason is not obvious, and do not restate the next line."Also applies to: 42-47, 50-54
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/modules/SnakeGame.h` around lines 7 - 16, Trim the long multi-line comments in SnakeGame.h to meet the coding guideline by shortening the class-level doc and the setDirection/step docs to at most one or two lines each, keeping only essential context. Update the comments attached to SnakeGame, setDirection, and step so they are minimal and do not restate obvious code behavior or include multi-paragraph explanations.Source: Coding guidelines
72-76: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider an
assert()for the test-seam precondition.
placeFoodAtdocuments "Caller must pass an unoccupied cell" but doesn't verify it. As per coding guidelines, "Useassert()for invariants that should never fail," which would catch test misuse without adding runtime cost in production builds (NDEBUG).🛡️ Proposed fix
- void placeFoodAt(uint8_t x, uint8_t y) { foodCell = {x, y}; } + void placeFoodAt(uint8_t x, uint8_t y) { + assert(!occupied(x, y)); + foodCell = {x, y}; + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/modules/SnakeGame.h` around lines 72 - 76, The test-seam helper SnakeGame::placeFoodAt documents that the caller must pass an unoccupied cell, but it does not enforce that invariant. Add an assert() inside placeFoodAt to verify the requested x,y is not already occupied before assigning foodCell, so misuse is caught in debug/test builds without production overhead. Use the existing SnakeGame and placeFoodAt symbols to locate the change.Source: Coding guidelines
src/modules/SnakeModule.cpp (1)
22-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTrim comments exceeding the guideline's line limit.
The pixel-layout block comment (Lines 22-25, 4 lines) and the
exitToIdleexplanation (Lines 100-103, 3 lines) exceed the stated limit. As per coding guidelines, "Keep code comments minimal: use at most one or two lines, only when the reason is not obvious; do not add multi-paragraph explanatory comments."Also applies to: 100-103
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/modules/SnakeModule.cpp` around lines 22 - 25, Trim the oversized explanatory comments in SnakeModule so they fit the guideline of at most one or two lines. Shorten the pixel-layout block near the top of the file and the exitToIdle explanation to only the essential intent, removing multi-line detail while keeping a brief note if needed for non-obvious behavior.Source: Coding guidelines
src/graphics/draw/NotificationRenderer.cpp (1)
469-471: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueTrim the
drawAlphanumericPickerheader comment to ≤2 lines.This block is 3 lines; per repo guideline comments should be capped at 1-2 lines.
✏️ Suggested trim
-// Arcade-style initials entry. Mirrors drawHexPicker's cursor/confirm flow, but each position -// holds a character from ALPHANUMERIC_CHARS (cycled with UP/DOWN) instead of a packed digit, and -// the assembled string is returned through textInputCallback. +// Arcade-style initials entry, mirroring drawHexPicker's cursor/confirm flow but cycling +// each position through ALPHANUMERIC_CHARS instead of a packed digit.As per coding guidelines, "Keep code comments minimal: use at most one or two lines, only when the reason is not obvious; do not add multi-paragraph explanatory comments or restate what the next line does."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/graphics/draw/NotificationRenderer.cpp` around lines 469 - 471, The header comment for drawAlphanumericPicker is too long and should be trimmed to at most two lines. Shorten the explanatory comment above drawAlphanumericPicker so it stays minimal and still identifies the picker behavior, without restating implementation details; use the drawAlphanumericPicker symbol to locate the block.Source: Coding guidelines
src/graphics/Screen.cpp (1)
456-465: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueTrim the
drawSnakeFramecomment to ≤2 lines.This block is 3 lines; per repo guideline comments should be capped at 1-2 lines.
✏️ Suggested trim
`#if` BASEUI_HAS_GAMES -// The games frame is a dedicated, always-present frame (unlike generic module frames it is placed -// at a fixed position right after home), so it draws through its own trampoline rather than the -// moduleFrames lockstep used by drawModuleFrame. +// Dedicated always-present frame, so it uses its own trampoline instead of drawModuleFrame's lockstep. static void drawSnakeFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)As per coding guidelines, "Keep code comments minimal: use at most one or two lines, only when the reason is not obvious; do not add multi-paragraph explanatory comments or restate what the next line does."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/graphics/Screen.cpp` around lines 456 - 465, The comment above drawSnakeFrame in Screen.cpp is too long and should be reduced to at most 2 lines. Shorten the existing explanation while preserving the essential rationale for why this frame uses its own trampoline instead of moduleFrames, and keep the static drawSnakeFrame identifier easy to locate.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/modules/SnakeModule.cpp`:
- Around line 430-447: The saveHighScores() write path is not fully
synchronized, because SafeFile only protects open/close while FSCom.mkdir and
sf.write() can still race with other SPI users. Update
SnakeModule::saveHighScores() to take spiLock around the filesystem operations
that touch the bus, including the directory creation and the actual write call,
and keep sf.close() outside that lock to avoid nested locking.
- Around line 136-141: Replace the raw millis()-based wake-kick timing in
SnakeModule with Throttle-based rate limiting. In the SnakeModule logic around
the display-awake kick, avoid direct lastAwakeKickMs arithmetic and instead use
Throttle::isWithinTimespanMs() or a small non-lambda helper that can be passed
to Throttle::execute(), since execute only accepts a plain function pointer.
Keep the existing EVENT_PRESS trigger behavior, but route the timing check
through the Throttle utility.
---
Nitpick comments:
In `@src/graphics/draw/NotificationRenderer.cpp`:
- Around line 469-471: The header comment for drawAlphanumericPicker is too long
and should be trimmed to at most two lines. Shorten the explanatory comment
above drawAlphanumericPicker so it stays minimal and still identifies the picker
behavior, without restating implementation details; use the
drawAlphanumericPicker symbol to locate the block.
In `@src/graphics/Screen.cpp`:
- Around line 456-465: The comment above drawSnakeFrame in Screen.cpp is too
long and should be reduced to at most 2 lines. Shorten the existing explanation
while preserving the essential rationale for why this frame uses its own
trampoline instead of moduleFrames, and keep the static drawSnakeFrame
identifier easy to locate.
In `@src/modules/SnakeGame.h`:
- Around line 7-16: Trim the long multi-line comments in SnakeGame.h to meet the
coding guideline by shortening the class-level doc and the setDirection/step
docs to at most one or two lines each, keeping only essential context. Update
the comments attached to SnakeGame, setDirection, and step so they are minimal
and do not restate obvious code behavior or include multi-paragraph
explanations.
- Around line 72-76: The test-seam helper SnakeGame::placeFoodAt documents that
the caller must pass an unoccupied cell, but it does not enforce that invariant.
Add an assert() inside placeFoodAt to verify the requested x,y is not already
occupied before assigning foodCell, so misuse is caught in debug/test builds
without production overhead. Use the existing SnakeGame and placeFoodAt symbols
to locate the change.
In `@src/modules/SnakeModule.cpp`:
- Around line 22-25: Trim the oversized explanatory comments in SnakeModule so
they fit the guideline of at most one or two lines. Shorten the pixel-layout
block near the top of the file and the exitToIdle explanation to only the
essential intent, removing multi-line detail while keeping a brief note if
needed for non-obvious behavior.
In `@src/modules/SnakeModule.h`:
- Around line 13-15: Trim the doc comments in SnakeModule.h so they fit the
coding guideline of one or two lines maximum and avoid multi-paragraph
explanations. Shorten both the SNAKE_ANNOUNCE_HIGH_SCORE comment and the
SnakeModule class-level doc, keeping only the essential summary and removing
repeated details or restatements of nearby code.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: f5ae4f53-1fb2-4884-987c-c272be2e0701
📒 Files selected for processing (14)
src/configuration.hsrc/graphics/Screen.cppsrc/graphics/Screen.hsrc/graphics/draw/NotificationRenderer.cppsrc/graphics/draw/NotificationRenderer.hsrc/graphics/draw/UIRenderer.cppsrc/graphics/images.hsrc/modules/Modules.cppsrc/modules/SnakeGame.cppsrc/modules/SnakeGame.hsrc/modules/SnakeModule.cppsrc/modules/SnakeModule.htest/native-suite-counttest/test_snake/test_main.cpp
| // Keep the display awake through long straight runs that generate no key presses. | ||
| const uint32_t now = millis(); | ||
| if (now - lastAwakeKickMs > 1500) { | ||
| powerFSM.trigger(EVENT_PRESS); | ||
| lastAwakeKickMs = now; | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm Throttle's API surface before applying the diff
ast-grep outline src --items all --type class,function --match 'Throttle'
rg -n -A5 'class Throttle' srcRepository: meshtastic/firmware
Length of output: 613
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the relevant code around the reviewed lines and Throttle usage patterns.
sed -n '110,170p' src/modules/SnakeModule.cpp
printf '\n---\n'
sed -n '1,120p' src/mesh/Throttle.h
printf '\n---\n'
sed -n '1,220p' src/mesh/Throttle.cpp
printf '\n---\n'
rg -n "Throttle::execute\\(|Throttle::isWithinTimespanMs\\(" src | head -n 50Repository: meshtastic/firmware
Length of output: 9591
Use Throttle here instead of raw millis() arithmetic. Throttle::execute() only accepts a plain function pointer, so this needs a small helper or Throttle::isWithinTimespanMs() rather than the lambda shown in the diff.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/modules/SnakeModule.cpp` around lines 136 - 141, Replace the raw
millis()-based wake-kick timing in SnakeModule with Throttle-based rate
limiting. In the SnakeModule logic around the display-awake kick, avoid direct
lastAwakeKickMs arithmetic and instead use Throttle::isWithinTimespanMs() or a
small non-lambda helper that can be passed to Throttle::execute(), since execute
only accepts a plain function pointer. Keep the existing EVENT_PRESS trigger
behavior, but route the timing check through the Throttle utility.
Source: Coding guidelines
Firmware Size Report42 targets | vs
Show 37 more target(s)
Size budgets
Budgets live in Updated for 2bd1ee5 |
|
spiLock->lock() breaks saving on nRF52, scope the manual lock only around FSCom.mkdir() and let SafeFile handle its own locking? |
I didn't realize creating the safefile object took a lock internally. And for whatever reason, sf.write() does not lock internally. |
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
- Implement TetrisGame class for game logic, including piece movement, rotation, and line clearing. - Create TetrisModule class to manage game state, input handling, and rendering on OLED display. - Introduce high score tracking with persistence and optional mesh broadcasting. - Define UI states for title, playing, paused, game over, and high scores. - Implement input handling for game controls and state transitions. - Add rendering functions for the game board, high scores, and title screen.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (5)
src/platform/portduino/PortduinoGlue.cpp (1)
1073-1075: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueCast to
unsigned charbeforetolower().Passing a plain (possibly signed)
chartotolower()is undefined behavior for values with the high bit set. Low-risk here since action names are expected to be ASCII, but the fix is trivial.🛡️ Proposed fix
for (auto &c : action) - c = tolower(c); + c = tolower(static_cast<unsigned char>(c));🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/portduino/PortduinoGlue.cpp` around lines 1073 - 1075, Update the action normalization loop in the button handling code to cast each character to unsigned char before passing it to tolower(), while preserving the existing lowercase conversion behavior.src/platform/portduino/HUB75Native.cpp (2)
62-62: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
CreateMatrixFromOptionsis the legacy alias.Per rpi-rgb-led-matrix's
led-matrix.h,CreateMatrixFromOptions()is documented as the "Legacy version ofRGBMatrix::CreateFromOptions()". Functionally identical today, but consider callingRGBMatrix::CreateFromOptions(options, runtime)directly to avoid relying on a legacy shim.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/portduino/HUB75Native.cpp` at line 62, Update the matrix initialization in HUB75Native to call rgb_matrix::RGBMatrix::CreateFromOptions(options, runtime) instead of the legacy rgb_matrix::CreateMatrixFromOptions alias, preserving the existing options and runtime arguments.
11-18: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winConsider an
assert()on displayWidth/displayHeight.The comment documents an ordering invariant (
portduino_configfully populated before this constructor runs) but nothing enforces it; a broken initialization order would silently produce a 0x0 geometry. As per coding guidelines, "Use assert() for invariants that should never fail."🛡️ Proposed fix
setGeometry(GEOMETRY_RAWMODE, portduino_config.displayWidth, portduino_config.displayHeight); + assert(portduino_config.displayWidth > 0 && portduino_config.displayHeight > 0); LOG_DEBUG("HUB75Native %dx%d", portduino_config.displayWidth, portduino_config.displayHeight);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/portduino/HUB75Native.cpp` around lines 11 - 18, Add assertions in the HUB75Native constructor before setGeometry to enforce that portduino_config.displayWidth and portduino_config.displayHeight are positive. Keep the existing geometry setup and debug logging unchanged, ensuring invalid initialization fails immediately instead of configuring a 0x0 display.Source: Coding guidelines
variants/native/portduino/HUB75Native.h (1)
18-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTrim the multi-paragraph class comment.
This 11-line, multi-paragraph doc comment exceeds the project's comment guideline. As per coding guidelines, "Keep code comments minimal: use at most one or two lines... do not add multi-paragraph explanatory comments." Consider moving the design rationale to a design doc/PR description and leaving a 1-2 line summary here.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@variants/native/portduino/HUB75Native.h` around lines 18 - 28, Replace the multi-paragraph comment above the HUB75 native backend with a concise one- or two-line summary of its purpose. Remove the implementation details, design rationale, configuration explanation, and source-location note from the comment.Source: Coding guidelines
src/platform/portduino/architecture.h (1)
39-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMissing
#ifndefguard breaks the file's override convention.Every other flag in this file (
HAS_BUTTON,HAS_WIFI,HAS_RADIO, etc.) uses#ifndef X /#defineX 1 /#endif`` so a variant can pre-define the flag to override auto-detection. This new block skips that guard, so if anything ever pre-definesHAS_HUB75_NATIVEto a different value before this header, you'll get a macro-redefinition conflict instead of a clean override.♻️ Proposed fix
-#if defined(ARCH_PORTDUINO) && __has_include(<led-matrix.h>) -#define HAS_HUB75_NATIVE 1 +#ifndef HAS_HUB75_NATIVE +#if __has_include(<led-matrix.h>) +#define HAS_HUB75_NATIVE 1 +#endif `#endif`🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/portduino/architecture.h` around lines 39 - 41, Update the HAS_HUB75_NATIVE detection block in architecture.h to follow the file’s existing override convention: only define it when ARCH_PORTDUINO and led-matrix.h are available and HAS_HUB75_NATIVE is not already defined, preserving any pre-defined value without macro redefinition.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/platform/portduino/PortduinoGlue.cpp`:
- Around line 1012-1036: Update the HUB75 configuration block around
yamlConfig["Display"]["HUB75"] to require both the HUB75 YAML node and
displayPanel == hub75 before applying HUB75 settings or overwriting
displayWidth/displayHeight. Preserve the existing HUB75 configuration behavior
when hub75 is the selected panel, while ignoring stray HUB75 settings for other
panel types.
---
Nitpick comments:
In `@src/platform/portduino/architecture.h`:
- Around line 39-41: Update the HAS_HUB75_NATIVE detection block in
architecture.h to follow the file’s existing override convention: only define it
when ARCH_PORTDUINO and led-matrix.h are available and HAS_HUB75_NATIVE is not
already defined, preserving any pre-defined value without macro redefinition.
In `@src/platform/portduino/HUB75Native.cpp`:
- Line 62: Update the matrix initialization in HUB75Native to call
rgb_matrix::RGBMatrix::CreateFromOptions(options, runtime) instead of the legacy
rgb_matrix::CreateMatrixFromOptions alias, preserving the existing options and
runtime arguments.
- Around line 11-18: Add assertions in the HUB75Native constructor before
setGeometry to enforce that portduino_config.displayWidth and
portduino_config.displayHeight are positive. Keep the existing geometry setup
and debug logging unchanged, ensuring invalid initialization fails immediately
instead of configuring a 0x0 display.
In `@src/platform/portduino/PortduinoGlue.cpp`:
- Around line 1073-1075: Update the action normalization loop in the button
handling code to cast each character to unsigned char before passing it to
tolower(), while preserving the existing lowercase conversion behavior.
In `@variants/native/portduino/HUB75Native.h`:
- Around line 18-28: Replace the multi-paragraph comment above the HUB75 native
backend with a concise one- or two-line summary of its purpose. Remove the
implementation details, design rationale, configuration explanation, and
source-location note from the comment.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 163a134d-6a43-4a59-80c7-9ce74a402b7a
📒 Files selected for processing (14)
bin/config-dist.yamlbin/config.d/display-hub75-64x64.yamlsrc/graphics/HUB75Display.cppsrc/graphics/HUB75Display.hsrc/graphics/Screen.cppsrc/graphics/TFTColorRegions.hsrc/platform/portduino/HUB75Native.cppsrc/platform/portduino/PortduinoGlue.cppsrc/platform/portduino/PortduinoGlue.hsrc/platform/portduino/architecture.hvariants/esp32s3/visualizer-hub75/platformio.inivariants/esp32s3/visualizer-hub75/variant.hvariants/native/portduino/HUB75Native.hvariants/native/portduino/platformio.ini
🚧 Files skipped from review as they are similar to previous changes (1)
- src/graphics/Screen.cpp
Disabled by default. Initially intended for a conference display.
Made with help from Claude.
Summary by CodeRabbit