// Copy of game_launcher.cpp for emulator build #include "game_launcher.h" #include "../display/low_level_gui.h" #include "../display/low_level_render.h" #include "input_manager.h" #include extern Font font_5x5_obj; GameLauncher::GameLauncher(uint16_t width, uint16_t height, LowLevelRenderer *renderer, LowLevelGUI *gui, InputManager *input_manager) : width(width), height(height), renderer(renderer), gui(gui), input_manager(input_manager), selected_index(0), selected_game(nullptr), current_page(0) {} void GameLauncher::register_game( const char *name, const char *description, std::function factory) { GameEntry entry; entry.name = name; entry.description = description; entry.factory = factory; games.push_back(entry); printf("Registered game: %s - %s\n", name, description); } void GameLauncher::draw() { LowLevelWindow *window = gui->draw_new_window(10, 10, width - 20, height - 20, "Game Launcher"); renderer->set_font(&font_5x5_obj); int total_pages = get_total_pages(); char title[64]; snprintf(title, sizeof(title), "Select a Game: (Page %d/%d)", current_page + 1, total_pages); renderer->draw_string_scaled(30, 40, title, 2); int page_start = get_page_start_index(); int page_end = get_page_end_index(); for (int i = page_start; i < page_end && i < (int)games.size(); i++) { int item_index = i - page_start; int y = MENU_Y_START + (item_index * MENU_ITEM_HEIGHT); bool is_selected = (i == selected_index); gui->draw_button(window, 20, y, games[i].name, is_selected, true); renderer->set_font(&font_5x5_obj); renderer->set_text_color(true); renderer->draw_string_scaled(50, y + 36, games[i].description, 1); } if (total_pages > 1) { int button_y = height - 65; renderer->set_font(&font_5x5_obj); gui->draw_button(window, PREV_BUTTON_X, button_y, "PREV", false, true); gui->draw_button(window, NEXT_BUTTON_X, button_y, "NEXT", false, true); renderer->set_font(&font_5x5_obj); renderer->draw_string_scaled(30, height - 25, "Touch buttons or KEY0/KEY1", 1); } else { renderer->set_font(&font_5x5_obj); renderer->draw_string_scaled( 30, height - 35, "KEY0: Navigate | KEY1: Select | Touch to play", 1); } } bool GameLauncher::update(const InputEvent &event) { bool needs_refresh = false; int total_pages = get_total_pages(); switch (event.type) { case INPUT_TOUCH_DOWN: { // Check if touch is on navigation buttons (if multiple pages) if (total_pages > 1) { if (event.x >= PREV_BUTTON_X && event.x < PREV_BUTTON_X + BUTTON_WIDTH && event.y >= NAV_BUTTON_Y && event.y < NAV_BUTTON_Y + BUTTON_HEIGHT) { if (current_page > 0) { current_page--; selected_index = get_page_start_index(); needs_refresh = true; } break; } if (event.x >= NEXT_BUTTON_X && event.x < NEXT_BUTTON_X + BUTTON_WIDTH && event.y >= NAV_BUTTON_Y && event.y < NAV_BUTTON_Y + BUTTON_HEIGHT) { if (current_page + 1 < total_pages) { current_page++; selected_index = get_page_start_index(); needs_refresh = true; } break; } } int page_start = get_page_start_index(); int page_end = get_page_end_index(); for (int i = page_start; i < page_end && i < (int)games.size(); i++) { int item_index = i - page_start; int y = MENU_Y_START + (item_index * MENU_ITEM_HEIGHT); if (event.y >= y - 5 && event.y < y + MENU_ITEM_HEIGHT - 5) { selected_game = games[i].factory(width, height, renderer, gui, input_manager); if (selected_game) { selected_game->init(); return true; } break; } } break; } case INPUT_BUTTON_0: { int page_start = get_page_start_index(); int page_end = get_page_end_index(); if (page_end - page_start > 1) { int old_index = selected_index; selected_index++; if (selected_index >= page_end) { if (current_page + 1 < total_pages) { current_page++; selected_index = get_page_start_index(); } else { current_page = 0; selected_index = 0; } } else if (selected_index < page_start) { selected_index = page_start; } } else { if (current_page + 1 < total_pages) { current_page++; selected_index = get_page_start_index(); } else { current_page = 0; selected_index = 0; } } needs_refresh = true; break; } case INPUT_BUTTON_1: { if (selected_index >= 0 && selected_index < (int)games.size()) { selected_game = games[selected_index].factory(width, height, renderer, gui, input_manager); if (selected_game) { selected_game->init(); return true; } } break; } default: break; } return needs_refresh; } Game *GameLauncher::get_selected_game() { return selected_game; } void GameLauncher::reset() { if (selected_game) { delete selected_game; selected_game = nullptr; } selected_index = 0; current_page = 0; } int GameLauncher::get_total_pages() const { if (games.empty()) return 1; return (games.size() + GAMES_PER_PAGE - 1) / GAMES_PER_PAGE; } int GameLauncher::get_page_start_index() const { return current_page * GAMES_PER_PAGE; } int GameLauncher::get_page_end_index() const { return (current_page + 1) * GAMES_PER_PAGE; }