Initial game launcher

This commit is contained in:
Adolfo Reyna
2026-01-30 21:39:09 -05:00
parent 2a6861fdf5
commit e3445b545d
7 changed files with 392 additions and 14 deletions

View File

@@ -49,7 +49,9 @@
#include "display/low_level_touch.h"
#include "input_manager.h"
#include "game.h"
#include "game_launcher.h"
#include "tic_tac_toe.h"
#include "demo_game.h"
// Binary info for RP2350 - ensures proper boot image structure
@@ -318,16 +320,24 @@ int main()
// Create InputManager for processing inputs
InputManager input_manager(touch, &config);
// Create game instance (polymorphic - can swap for other games later)
Game* current_game = new TicTacToeGame(V_WIDTH, V_HEIGHT, &renderer, &gui);
// Create GameLauncher
GameLauncher launcher(V_WIDTH, V_HEIGHT, &renderer, &gui);
// Initialize game
current_game->init();
// Register available games
launcher.register_game("Tic-Tac-Toe", "Classic 2-player game",
[](uint16_t w, uint16_t h, LowLevelRenderer* r, LowLevelGUI* g) -> Game* {
return new TicTacToeGame(w, h, r, g);
});
// Draw initial game graphics
current_game->draw();
launcher.register_game("Demo Game", "Simple test game",
[](uint16_t w, uint16_t h, LowLevelRenderer* r, LowLevelGUI* g) -> Game* {
return new DemoGame(w, h, r, g);
});
// Refresh the screen with the rendered GUI (async on Core 1)
// Draw launcher menu
launcher.draw();
// Refresh the screen with the launcher menu (async on Core 1)
refresh_screen_async(bit_buffer, display);
printf("Initial screen refresh queued on Core 1\n");
@@ -408,6 +418,9 @@ int main()
printf("\nEntering reactive game loop (Core 0 - input & logic)\n");
printf("Display refreshes handled by Core 1\n\n");
Game* current_game = nullptr;
uint32_t game_start_time = 0;
while (1) {
// Sleep until interrupt wakes us up (very power efficient!)
__wfi(); // Wait For Interrupt - CPU sleeps until any interrupt occurs
@@ -417,23 +430,58 @@ int main()
// 1. Process button input first (higher priority)
input = input_manager.process_button_input();
if (input.valid) {
needs_refresh = current_game->update(input);
}
// 2. Process touch input (if no button was pressed)
if (!input.valid) {
input = input_manager.process_touch_input(&last_touch_time);
if (input.valid) {
}
// 3. Process input based on current state
if (input.valid) {
if (launcher.is_game_selected()) {
// In game mode - process game input
current_game = launcher.get_selected_game();
needs_refresh = current_game->update(input);
// Check if player wants to exit (hold for 2+ seconds or special gesture)
// For now, we'll add a simple long-press detection
if (input.type == INPUT_TOUCH_DOWN) {
// Record start time on first touch
if (game_start_time == 0) {
game_start_time = to_ms_since_boot(get_absolute_time());
}
} else if (input.type == INPUT_TOUCH_UP) {
uint32_t now = to_ms_since_boot(get_absolute_time());
if (game_start_time > 0 && (now - game_start_time) > 2000) {
// Long press detected - return to menu
printf("Long press detected - returning to launcher\n");
launcher.reset();
needs_refresh = true;
}
game_start_time = 0;
}
} else {
// In launcher mode - process menu input
bool game_selected = launcher.update(input);
if (game_selected) {
printf("Game launched successfully\n");
game_start_time = 0;
}
needs_refresh = true;
}
}
// 3. Redraw and queue async refresh on Core 1
// 4. Redraw and queue async refresh on Core 1
if (needs_refresh || pending_refresh) {
// Clear buffer and redraw entire UI with updated state
memset(bit_buffer, 0, V_WIDTH * V_HEIGHT / 8);
current_game->draw();
if (launcher.is_game_selected()) {
current_game = launcher.get_selected_game();
current_game->draw();
} else {
launcher.draw();
}
// Request async refresh (non-blocking - handled by Core 1)
bool refresh_started = refresh_screen_async(bit_buffer, display);