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>
This commit is contained in:
23
basic1.cpp
23
basic1.cpp
@@ -58,6 +58,7 @@ extern "C" {
|
||||
#include "demo_game.h"
|
||||
#include "monopoly_game.h"
|
||||
#include "lua_game_loader.h"
|
||||
#include "serial_uploader.h"
|
||||
|
||||
|
||||
// Binary info for RP2350 - ensures proper boot image structure
|
||||
@@ -436,7 +437,11 @@ int main()
|
||||
|
||||
// Create GameLauncher
|
||||
GameLauncher launcher(V_WIDTH, V_HEIGHT, &renderer, &gui, &input_manager);
|
||||
|
||||
|
||||
// Create SerialUploader for rapid game iteration
|
||||
SerialUploader serial_uploader(&launcher);
|
||||
printf("Serial uploader initialized\n");
|
||||
|
||||
// Register available games
|
||||
launcher.register_game("Tic-Tac-Toe", "Classic 2-player game",
|
||||
[](uint16_t w, uint16_t h, LowLevelRenderer* r, LowLevelGUI* g, InputManager* im) -> Game* {
|
||||
@@ -563,11 +568,22 @@ int main()
|
||||
const uint32_t TARGET_FRAME_TIME_MS = 33; // 1000ms / 30fps ≈ 33ms
|
||||
uint32_t last_frame_time = 0;
|
||||
|
||||
bool needs_refresh = false; // Track if screen needs redraw
|
||||
|
||||
while (1) {
|
||||
// 0. Process serial uploads (for rapid game iteration)
|
||||
bool game_launched_via_serial = serial_uploader.process();
|
||||
if (game_launched_via_serial) {
|
||||
// A new game was uploaded and launched - trigger redraw
|
||||
needs_refresh = true;
|
||||
current_game = launcher.get_selected_game();
|
||||
// Note: game is already initialized by select_game_by_name()
|
||||
}
|
||||
|
||||
// Determine if we should sleep or stay awake for updates
|
||||
bool stay_awake = false;
|
||||
if (pending_refresh) stay_awake = true;
|
||||
|
||||
|
||||
if (launcher.is_game_selected()) {
|
||||
Game* g = launcher.get_selected_game();
|
||||
if (g && g->wants_frame_updates()) {
|
||||
@@ -579,9 +595,8 @@ int main()
|
||||
// Sleep until interrupt wakes us up (very power efficient!)
|
||||
__wfi(); // Wait For Interrupt - CPU sleeps until any interrupt occurs
|
||||
}
|
||||
|
||||
|
||||
InputEvent input = {INPUT_NONE, 0, 0, 0, 0, 0, false};
|
||||
bool needs_refresh = false;
|
||||
|
||||
// 1. Process button input first (higher priority)
|
||||
input = input_manager.process_button_input();
|
||||
|
||||
Reference in New Issue
Block a user