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
This commit is contained in:
Adolfo Reyna
2026-02-12 20:46:41 -05:00
parent b722b8b9c5
commit b5e69abc83
5 changed files with 96 additions and 28 deletions

9
.gitignore vendored
View File

@@ -1,3 +1,12 @@
build
!.vscode/*
build*/
*.o
*.o.d
*.a
*.so
*.dylib
CMakeFiles/
*.cmake
emulator/build/
.DS_Store

View File

@@ -39,26 +39,45 @@ void GameLauncher::draw() {
renderer->draw_string_scaled(50, y + 36, games[i].description, 1);
}
char nav_text[128];
if (total_pages > 1) {
snprintf(nav_text, sizeof(nav_text), "KEY0: Next Page | KEY1: Select");
} else {
snprintf(nav_text, sizeof(nav_text), "KEY0: Navigate | KEY1: Select");
}
const char* instructions;
if (input_manager->has_buttons()) {
instructions = nav_text;
} else {
instructions = "Touch game to play";
}
int button_y = height - 65;
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 - 35, instructions, 2);
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();
@@ -79,7 +98,6 @@ bool GameLauncher::update(const InputEvent& event) {
case INPUT_BUTTON_0: {
int page_start = get_page_start_index();
int page_end = get_page_end_index();
int total_pages = get_total_pages();
if (page_end - page_start > 1) {
int old_index = selected_index;

View File

@@ -43,6 +43,11 @@ private:
static const int MENU_ITEM_HEIGHT = 40;
static const int MENU_PADDING = 10;
static const int GAMES_PER_PAGE = 4;
static const int NAV_BUTTON_Y = 235;
static const int PREV_BUTTON_X = 30;
static const int NEXT_BUTTON_X = 200;
static const int BUTTON_WIDTH = 150;
static const int BUTTON_HEIGHT = 40;
int get_total_pages() const;
int get_page_start_index() const;

View File

@@ -57,32 +57,64 @@ void GameLauncher::draw() {
renderer->draw_string_scaled(50, y + 36, games[i].description, 1);
}
// Draw pagination controls at bottom
char nav_text[128];
// Draw navigation buttons at bottom (only if multiple pages)
if (total_pages > 1) {
snprintf(nav_text, sizeof(nav_text), "KEY0: Next Page | KEY1: Select");
} else {
snprintf(nav_text, sizeof(nav_text), "KEY0: Navigate | KEY1: Select");
}
int button_y = height - 65;
const char* instructions;
if (input_manager->has_buttons()) {
instructions = nav_text;
} else {
instructions = "Touch game to play";
}
// Previous page button
bool has_prev = (current_page > 0);
gui->draw_button(window, 30, button_y, "< PREV", false, true);
// Next page button
bool has_next = (current_page + 1 < total_pages);
gui->draw_button(window, 200, button_y, "NEXT >", false, true);
// Draw instructions
renderer->set_font(&font_5x5_obj);
renderer->draw_string_scaled(30, height - 35, instructions, 2);
renderer->draw_string_scaled(30, height - 25, "Touch buttons or KEY0/KEY1", 1);
} else {
// Single page - just show select instruction
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: {
printf("Touch at (%d,%d) in launcher\n", event.x, event.y);
// Check if touch is on navigation buttons (if multiple pages)
if (total_pages > 1) {
// Previous button: x [30-180], y [235-275]
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;
printf("Navigated to previous page: %d\n", current_page);
}
break;
}
// Next button: x [200-350], y [235-275]
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;
printf("Navigated to next page: %d\n", current_page);
}
break;
}
}
// Check if touch is on a game entry for current page
int page_start = get_page_start_index();
int page_end = get_page_end_index();
@@ -110,7 +142,6 @@ bool GameLauncher::update(const InputEvent& event) {
// Navigate within current page or switch pages
int page_start = get_page_start_index();
int page_end = get_page_end_index();
int total_pages = get_total_pages();
// If multiple games on current page, navigate within page first
if (page_end - page_start > 1) {

View File

@@ -102,6 +102,11 @@ private:
static const int MENU_ITEM_HEIGHT = 40;
static const int MENU_PADDING = 10;
static const int GAMES_PER_PAGE = 4;
static const int NAV_BUTTON_Y = 235; // Bottom navigation buttons
static const int PREV_BUTTON_X = 30;
static const int NEXT_BUTTON_X = 200;
static const int BUTTON_WIDTH = 150;
static const int BUTTON_HEIGHT = 40;
// Helper functions for pagination
int get_total_pages() const;