32 Commits

Author SHA1 Message Date
Adolfo Reyna
fe6e403a98 Reduce touch overhead and cap frame rate at 24 FPS 2026-02-18 15:53:48 -05:00
Adolfo Reyna
3e54466752 Add Core1 refresh recovery and shared SPI arbitration 2026-02-18 15:43:35 -05:00
Adolfo Reyna
ebc58d7e4d Add scene stack menu flow and restore stable TFT sync refresh 2026-02-18 15:10:20 -05:00
Adolfo Reyna
a06e0d69fe Refactor main loop touch flow and update docs 2026-02-18 12:08:23 -05:00
Adolfo Reyna
be6a217b08 Fix touch event stability and WFI wake filtering 2026-02-18 11:51:29 -05:00
Adolfo Reyna
b0ca1f1a55 Fix emulator build script, UI rendering, and clean up repo 2026-02-17 21:49:49 -05:00
Adolfo Reyna
76e3d2435e Make game name search case-insensitive
Serial uploader searches for games by filename (e.g., "tetris") but
games are registered by their metadata NAME field (e.g., "Tetris").
This caused launch failures when case didn't match.

Changed select_game_by_name() to use case-insensitive matching:
- strcasecmp() for exact match
- tolower() both strings before strstr() for partial match

Now uploading "tetris.lua" will successfully match and launch "Tetris".

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-12 23:27:48 -05:00
Adolfo Reyna
518bc054c4 Fix SPI bus contention crash on serial game upload
Serial uploader was crashing the Pico when launching games because
it accessed SD card (SPI) while Core 1 was refreshing display (also SPI).
Display and SD card share the same SPI bus and cannot be accessed
simultaneously.

Split game launch into prepare and execute phases:
- prepare: Re-scan games directory (safe, SD access done immediately)
- execute: Load Lua script from SD (deferred until display is idle)

Main loop now checks !is_refresh_in_progress() before completing
launch, preventing SPI conflicts.

Also updated SD card best practices skill to document SPI bus
contention as the #1 most critical issue to avoid.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-12 23:25:31 -05:00
Adolfo Reyna
84b009c33e Add serial upload tool for rapid Lua game iteration
Implements a complete serial upload workflow that allows uploading and
immediately testing Lua games via USB serial connection.

New Components:
- SerialUploader: Receives files via serial, writes to SD card
- upload_game.py: Python tool for sending files from host computer
- Protocol: Text-based with base64 encoding for reliability

Key Features:
- Uploads file to /games folder on SD card
- Overwrites existing files (FA_CREATE_ALWAYS)
- Auto-launches uploaded game immediately
- Proper memory cleanup (prevents Lua state conflicts)

SD Card Fixes:
- Fixed SPI speed management (12.5MHz for SD, 32MHz for display)
- Fixed SD write protocol (poll for data response token)
- Added speed switching wrappers around all FatFS operations
- Cleaned up excessive debug output

Game Launcher Improvements:
- Added clear_games() to prevent duplicate registrations
- Added cleanup in select_game_by_name() to delete old instances
- Added exact match priority in game selection
- LuaGameLoader now has clear_factory_data() for memory cleanup

Integration:
- Added serial_uploader to CMakeLists.txt
- Integrated into main loop in basic1.cpp
- Re-scans games after upload to pick up new files

Documentation:
- UPLOAD_TOOL.md: Usage instructions
- sd_card_best_practices.md: Critical lessons learned

Known Issues:
- Game launch after upload occasionally causes freeze (needs investigation)
- Display may not refresh properly after upload

Usage:
  python upload_game.py games/lua_examples/2048.lua /dev/tty.usbmodem101

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-12 22:52:57 -05:00
Adolfo Reyna
b5e69abc83 Add virtual navigation buttons to game launcher
- Display < PREV and NEXT > buttons at bottom of screen when multiple pages exist
- Buttons are touchable and respond to taps
- Button dimensions: 150x40 at y=235
- PREV button: x=30, NEXT button: x=200
- Updated instructions to show 'Touch buttons or KEY0/KEY1'
- Both KEY0/KEY1 and touch button presses navigate pages
- Updated lib/ and emulator/ versions
2026-02-12 20:46:41 -05:00
Adolfo Reyna
38ffdac749 Add pagination to game launcher - 4 games per page
- GameLauncher now displays only 4 games per page to keep menu in bounds
- Added page navigation with page indicator (Page X/Y)
- KEY0 navigates between pages and within page
- KEY1 selects the highlighted game
- Touch selection works on current page only
- Helper methods: get_total_pages(), get_page_start_index(), get_page_end_index()
- Updated both lib/ and emulator/ versions for consistency
2026-02-12 20:39:38 -05:00
Adolfo Reyna
eacc03a38c Implement 4-quadrant dirty rectangle optimization and 30 FPS limiting for ST7796
Add intelligent partial screen update system using bitwise XOR change detection
and 4-quadrant tracking (top-left, top-right, bottom-left, bottom-right). Each
changed pixel is routed to its quadrant, with sophisticated merge logic that
combines adjacent rectangles when beneficial (<40% overhead). This dramatically
reduces SPI bandwidth for UIs with scattered updates (e.g., corners, sidebars).

Key changes:
- 4-quadrant dirty rectangle tracking with automatic merging
- XOR-based change detection for fast byte-level comparison
- Expose st7796_set_window() for partial region updates
- 30 FPS frame rate limiter (33ms per frame) to prevent excessive refreshes
- Smart sleep timing when frame rate limit is active

Performance: Up to 99% reduction in SPI traffic for corner-based UIs
(e.g., 4 small regions vs full 480x320 screen updates).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-11 12:56:10 -05:00
Adolfo Reyna
b59d716965 Optimize ST7796 driver: Use bulk SPI transfers and blocking DMA for higher framerate 2026-02-11 11:40:26 -05:00
Adolfo Reyna
fe5d58b663 Refactor power saving logic into display drivers and add ST7789 support 2026-02-10 22:20:53 -05:00
Adolfo Reyna
8cbb95b181 Add auto-sleep/wake functionality with timer-based dimming
- Added PWM brightness control to ST7796 driver (0-100%)
- Implemented hardware sleep mode for ST7796 (saves ~150mA)
- Added sleep/wake functions preserving framebuffer and settings
- Implemented timer-based inactivity detection (checks every 10s)
- Auto-sleep after 5 minutes of no user input
- Touch controller remains active during TFT sleep for instant wake
- E-ink display also sleeps after timeout, requires re-init on wake
- Added hardware_pwm library dependency to CMakeLists.txt
- Brightness and sleep/wake methods exposed through display abstraction layer
2026-02-10 20:29:10 -05:00
Adolfo Reyna
b16211f148 Fix SD card integration and Lua game loading
- Fix SD card MISO pin (was using display MISO instead of SD MISO)
- Add FatFS mounting after SD card initialization
- Restore SPI baudrate on all SD init failure paths
- Add case-insensitive .lua file extension check
- Filter out hidden 8.3 filename entries
- Add SPI speed management functions for shared SPI bus
- Wrap all FatFS operations with SPI speed switching
- Restore display SPI speed (32 MHz) after SD operations
- Add debug output to Lua game loader

This fixes slow display refresh when SD card is present and enables
reliable Lua game loading from SD card /games directory.
2026-02-07 19:31:38 -05:00
Adolfo Reyna
2a472fc29f Add frame tick system for continuous animation
- Added INPUT_FRAME_TICK event type to input_event.h
- Added wants_frame_updates() virtual method to Game base class
- Implemented frame tick logic in main loop (basic1.cpp and emulator/main.cpp)
- Added Lua bindings: game.set_frame_updates(bool) and INPUT.FRAME_TICK
- Updated LuaGame to support frame updates via registry flag
- Updated ball.lua to use continuous frame updates for smooth animation
- Both hardware and emulator now support continuous animation for physics/games
2026-02-07 13:20:10 -05:00
Adolfo Reyna
e6e4eca188 Add Lua 5.4 scripting integration for dynamic game loading
- Integrated Lua 5.4 engine (32-bit mode for embedded ARM)
- Created LuaGame wrapper class implementing Game interface
- Added C++ bindings exposing renderer, game state, and input to Lua
- Implemented SD card loader for automatic .lua game discovery
- Updated GameLauncher to support std::function for lambda captures
- Made Game class members public for Lua bindings access
- Added example Lua games: counter, snake, bouncing ball
- Included comprehensive API documentation

Games can now be written as .lua text files on SD card and loaded
without recompilation. Build size: 747KB UF2, Lua VM uses ~50-80KB RAM.
2026-02-07 11:56:03 -05:00
Adolfo Reyna
64f61759d7 Fix emulator compilation and crash, and implement Monopoly payment modal 2026-02-06 23:13:32 -05:00
Adolfo Reyna
e2817262b0 Add virtual touch buttons for Monopoly game and centralize configuration in ModalButtonHelper 2026-02-06 22:11:24 -05:00
Adolfo Reyna
3bdbfb1811 Fix 1-bit bitmap rendering and add player turn modal 2026-02-02 23:14:11 -05:00
Adolfo Reyna
c6d7bd6c8c monopoly Main UI Changes 2026-01-31 22:46:26 -05:00
Adolfo Reyna
78b376ad5d fix rent calculation 2026-01-31 22:23:49 -05:00
Adolfo Reyna
76a74477a7 emulator working 2026-01-30 23:40:10 -05:00
Adolfo Reyna
f860d4f5e6 input manager provides ground of truth on device input choise 2026-01-30 22:07:31 -05:00
Adolfo Reyna
436245a7a2 Fix render issues with fonts 2026-01-30 22:02:15 -05:00
Adolfo Reyna
e3445b545d Initial game launcher 2026-01-30 21:39:09 -05:00
Adolfo Reyna
2a6861fdf5 refactored to multiple games implementation 2026-01-30 21:33:42 -05:00
Adolfo Reyna
8d0bca691a hardware button support 2026-01-29 15:23:03 -05:00
Adolfo Reyna
3a08cb5119 improve touch with pooling 2026-01-29 14:16:19 -05:00
Adolfo Reyna
d19a2ca639 touch with abtraction working, SD is not working 2026-01-28 23:23:49 -05:00
Adolfo Reyna
adfbef7228 abstracting display, touch and sd 2026-01-28 20:12:41 -05:00