* Snake!

* Add spiLock to snake score saving

* Check fixes

* More careful locking

* WIP: Big Display Node

* Update src/graphics/HUB75Display.cpp

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Add HUB75 Native

* Add Tetris game module with core logic and UI integration

- 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.

* feat(snake): add snake graphics and update display logic in SnakeModule

* Prompt for Initials for Tetris, too

* refactor games module

* Games refactor

* hub75 native double buffer

* Games tuning

* Make joystick repeat events on held button

* Add clouds and colors

* Fix breakout and more color

* difficulty tuning

* trunk

* refactor game announcements, etc

* Scale chirpy gravity as game speed increases

* Portduino, check for hub75 display before reading in hub75 options

* Final(?) games tuning

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Properly ignore input when games screen not shown

* Fail gracefully when HUB75 is selected but not supported.

---------

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Ixitxachitl <kramerfm@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Jonathan Bennett
2026-07-16 18:35:33 -05:00
committed by GitHub
co-authored by GitHub Thomas Göttgens coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Ixitxachitl Copilot Autofix powered by AI
parent d3d02af817
commit 8d1fbbf55f
41 changed files with 4106 additions and 34 deletions
+33
View File
@@ -1017,6 +1017,39 @@ bool loadConfig(const char *configPath)
}
}
}
#if !defined(HAS_HUB75_NATIVE)
if (portduino_config.displayPanel == hub75) {
std::cerr << "HUB75 display panel selected, but this build does not support HUB75" << std::endl;
exit(EXIT_FAILURE);
}
#endif
// HUB75 RGB matrix (Raspberry Pi). Options map onto rgb_matrix::RGBMatrix::Options +
// RuntimeOptions; the library owns its GPIO pins so nothing is read via readGPIOFromYaml.
if (portduino_config.displayPanel == hub75 && yamlConfig["Display"]["HUB75"]) {
YAML::Node hub75 = yamlConfig["Display"]["HUB75"];
portduino_config.hub75_hardware_mapping = hub75["HardwareMapping"].as<std::string>("regular");
portduino_config.hub75_rows = hub75["Rows"].as<int>(64);
portduino_config.hub75_cols = hub75["Cols"].as<int>(64);
portduino_config.hub75_chain_length = hub75["ChainLength"].as<int>(1);
portduino_config.hub75_parallel = hub75["Parallel"].as<int>(1);
portduino_config.hub75_pwm_bits = hub75["PWMBits"].as<int>(11);
portduino_config.hub75_pwm_lsb_nanoseconds = hub75["PWMLSBNanoseconds"].as<int>(130);
portduino_config.hub75_brightness = hub75["Brightness"].as<int>(100);
portduino_config.hub75_scan_mode = hub75["ScanMode"].as<int>(0);
portduino_config.hub75_row_address_type = hub75["RowAddressType"].as<int>(0);
portduino_config.hub75_multiplexing = hub75["Multiplexing"].as<int>(0);
portduino_config.hub75_disable_hardware_pulsing = hub75["DisableHardwarePulsing"].as<bool>(false);
portduino_config.hub75_show_refresh_rate = hub75["ShowRefreshRate"].as<bool>(false);
portduino_config.hub75_inverse_colors = hub75["InverseColors"].as<bool>(false);
portduino_config.hub75_led_rgb_sequence = hub75["RGBSequence"].as<std::string>("RGB");
portduino_config.hub75_pixel_mapper_config = hub75["PixelMapper"].as<std::string>("");
portduino_config.hub75_panel_type = hub75["PanelType"].as<std::string>("");
portduino_config.hub75_limit_refresh_rate_hz = hub75["LimitRefreshRateHz"].as<int>(0);
portduino_config.hub75_gpio_slowdown = hub75["GPIOSlowdown"].as<int>(1);
// The BaseUI framebuffer geometry is the full panel size in pixels.
portduino_config.displayWidth = portduino_config.hub75_cols * portduino_config.hub75_chain_length;
portduino_config.displayHeight = portduino_config.hub75_rows * portduino_config.hub75_parallel;
}
}
if (yamlConfig["Touchscreen"]) {
if (yamlConfig["Touchscreen"]["Module"].as<std::string>("") == "XPT2046")