From 4b0b1d81ed7c59eed4b156a49012123a98dcb924 Mon Sep 17 00:00:00 2001 From: Zizin13 <162662805+Zizin13@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:18:38 -0700 Subject: [PATCH 1/4] fixing mouse select in name edit page --- PROJECTS/ROLLER/frontend_config.c | 61 ++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/PROJECTS/ROLLER/frontend_config.c b/PROJECTS/ROLLER/frontend_config.c index bd199a1..6019168 100644 --- a/PROJECTS/ROLLER/frontend_config.c +++ b/PROJECTS/ROLLER/frontend_config.c @@ -471,6 +471,55 @@ static int frontend_config_apply_volume_wheel(int iWheelY) //------------------------------------------------------------------------------------------------- +static void frontend_config_commit_name_edit(void) +{ + int iNameChar; + int iDefaultNameIdx; + + szFrontendConfigNewNameBuf[iFrontendConfigNameLength] = 0; + iFrontendConfigEditingName = 0; + + if (!iFrontendConfigSelectedCar) { + iFrontendConfigState = 0; + return; + } + + if ((unsigned int)iFrontendConfigSelectedCar <= 1) { + for (iNameChar = 0; iNameChar < 9; ++iNameChar) + player_names[player1_car][iNameChar] = + szFrontendConfigNewNameBuf[iNameChar]; + + frontend_config_begin_broadcast_wait( + -669, FRONTEND_CONFIG_BROADCAST_WAIT_CHECK_PLAYER1_NAME_AND_CARS); + return; + } + + if (iFrontendConfigSelectedCar == 2) { + for (iNameChar = 0; iNameChar < 9; ++iNameChar) + player_names[player2_car][iNameChar] = + szFrontendConfigNewNameBuf[iNameChar]; + + waste = CheckNames(player_names[player2_car], player2_car); + check_cars(); + return; + } + + iDefaultNameIdx = (iFrontendConfigSelectedCar - 3) ^ 1; + for (iNameChar = 0; iNameChar < 9; ++iNameChar) + default_names[iDefaultNameIdx][iNameChar] = + szFrontendConfigNewNameBuf[iNameChar]; + + if (!default_names[iDefaultNameIdx][0]) { + sprintf(buffer, "comp %i", iFrontendConfigSelectedCar - 2); + name_copy(default_names[iDefaultNameIdx], buffer); + } + + frontend_config_begin_broadcast_wait( + -1, FRONTEND_CONFIG_BROADCAST_WAIT_NONE); +} + +//------------------------------------------------------------------------------------------------- + static void frontend_config_handle_mouse(void) { int iHovered; @@ -499,7 +548,7 @@ static void frontend_config_handle_mouse(void) if (iFrontendConfigEditingName) { frontend_mouse_take_wheel_y(); if (frontend_mouse_consume_click_anywhere()) - frontend_mouse_press_accept(); + frontend_config_commit_name_edit(); return; } @@ -519,12 +568,12 @@ static void frontend_config_handle_mouse(void) return; iClicked = frontend_mouse_peek_clicked_id(); - iSubItem = frontend_config_submenu_item_from_mouse_id(iClicked); - if (iSubItem >= 0) - (void)frontend_config_set_submenu_item(iSubItem); - - if (frontend_mouse_consume_click_anywhere()) + if (frontend_mouse_consume_click_anywhere()) { + iSubItem = frontend_config_submenu_item_from_mouse_id(iClicked); + if (iSubItem >= 0) + (void)frontend_config_set_submenu_item(iSubItem); frontend_mouse_press_accept(); + } return; } From faefd68c163b16b55d70708790b1ed14c3f91234 Mon Sep 17 00:00:00 2001 From: Zizin13 <162662805+Zizin13@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:29:35 -0700 Subject: [PATCH 2/4] extend left menu hitboxes all the way left --- PROJECTS/ROLLER/frontend.h | 1 + PROJECTS/ROLLER/frontend_config.c | 7 +++++++ PROJECTS/ROLLER/frontend_screens.c | 1 + PROJECTS/ROLLER/frontend_select_car.c | 1 + PROJECTS/ROLLER/frontend_select_disk.c | 2 ++ PROJECTS/ROLLER/frontend_select_track.c | 3 +++ PROJECTS/ROLLER/frontend_select_type.c | 7 +++++++ PROJECTS/ROLLER/frontend_util.c | 10 ++++++++++ 8 files changed, 32 insertions(+) diff --git a/PROJECTS/ROLLER/frontend.h b/PROJECTS/ROLLER/frontend.h index 722b74f..8707cd6 100644 --- a/PROJECTS/ROLLER/frontend.h +++ b/PROJECTS/ROLLER/frontend.h @@ -268,6 +268,7 @@ int CheckNames(char *szPlayerName, int iPlayerIdx); void frontend_mouse_handle_event(const SDL_Event *pEvent); void frontend_mouse_begin_frame(int iVirtualWidth, int iVirtualHeight); void frontend_mouse_register_rect(int iId, int iX, int iY, int iWidth, int iHeight); +void frontend_mouse_register_left_menu_row(int iId, int iY); void frontend_mouse_register_text(int iId, tBlockHeader *pFont, const char *szText, const char *szMappingTable, int *pCharVOffsets, int iX, int iY, int iAlignment); diff --git a/PROJECTS/ROLLER/frontend_config.c b/PROJECTS/ROLLER/frontend_config.c index 6019168..9ed0b55 100644 --- a/PROJECTS/ROLLER/frontend_config.c +++ b/PROJECTS/ROLLER/frontend_config.c @@ -899,27 +899,34 @@ void frontend_config_update(void) font2_ascii, font2_offsets, sel_posns[0].x + 132, sel_posns[0].y + 7, 2); + frontend_mouse_register_left_menu_row(0, sel_posns[0].y); frontend_mouse_register_text(1, front_vga[2], &config_buffer[256], font2_ascii, font2_offsets, sel_posns[1].x + 132, sel_posns[1].y + 7, 2); + frontend_mouse_register_left_menu_row(1, sel_posns[1].y); frontend_mouse_register_text(3, front_vga[2], &config_buffer[4032], font2_ascii, font2_offsets, sel_posns[2].x + 132, sel_posns[2].y + 7, 2); + frontend_mouse_register_left_menu_row(3, sel_posns[2].y); frontend_mouse_register_text(4, front_vga[2], &config_buffer[4096], font2_ascii, font2_offsets, sel_posns[3].x + 132, sel_posns[3].y + 7, 2); + frontend_mouse_register_left_menu_row(4, sel_posns[3].y); frontend_mouse_register_text(5, front_vga[2], &config_buffer[4160], font2_ascii, font2_offsets, sel_posns[4].x + 132, sel_posns[4].y + 7, 2); + frontend_mouse_register_left_menu_row(5, sel_posns[4].y); if (network_on) frontend_mouse_register_text(6, front_vga[2], &config_buffer[5568], font2_ascii, font2_offsets, sel_posns[5].x + 132, sel_posns[5].y + 7, 2); + if (network_on) + frontend_mouse_register_left_menu_row(6, sel_posns[5].y); if (front_vga[6]) frontend_mouse_register_rect(7, 62, 336, front_vga[6][4].iWidth, front_vga[6][4].iHeight); diff --git a/PROJECTS/ROLLER/frontend_screens.c b/PROJECTS/ROLLER/frontend_screens.c index d22a77e..becd2c3 100644 --- a/PROJECTS/ROLLER/frontend_screens.c +++ b/PROJECTS/ROLLER/frontend_screens.c @@ -1305,6 +1305,7 @@ static void frontend_main_menu_register_text_item(int iItem, const char *szText) frontend_mouse_register_text(iItem, front_vga[2], szText, font2_ascii, font2_offsets, sel_posns[iItem].x + 132, sel_posns[iItem].y + 7, 2); + frontend_mouse_register_left_menu_row(iItem, sel_posns[iItem].y); } //------------------------------------------------------------------------------------------------- diff --git a/PROJECTS/ROLLER/frontend_select_car.c b/PROJECTS/ROLLER/frontend_select_car.c index 7cde305..024a3db 100644 --- a/PROJECTS/ROLLER/frontend_select_car.c +++ b/PROJECTS/ROLLER/frontend_select_car.c @@ -136,6 +136,7 @@ static void frontend_car_select_register_mouse_items(void) font2_ascii, font2_offsets, sel_posns[i].x + 132, sel_posns[i].y + 7, 2); + frontend_mouse_register_left_menu_row(i, sel_posns[i].y); } if (front_vga[6]) diff --git a/PROJECTS/ROLLER/frontend_select_disk.c b/PROJECTS/ROLLER/frontend_select_disk.c index 08ff247..15b2b00 100644 --- a/PROJECTS/ROLLER/frontend_select_disk.c +++ b/PROJECTS/ROLLER/frontend_select_disk.c @@ -364,10 +364,12 @@ static void frontend_disk_select_draw(void) font2_ascii, font2_offsets, sel_posns[0].x + 132, sel_posns[0].y + 7, 2); + frontend_mouse_register_left_menu_row(0, sel_posns[0].y); frontend_mouse_register_text(1, front_vga[2], &language_buffer[640], font2_ascii, font2_offsets, sel_posns[1].x + 132, sel_posns[1].y + 7, 2); + frontend_mouse_register_left_menu_row(1, sel_posns[1].y); if (front_vga[6]) frontend_mouse_register_rect(2, 62, 336, front_vga[6][4].iWidth, front_vga[6][4].iHeight); diff --git a/PROJECTS/ROLLER/frontend_select_track.c b/PROJECTS/ROLLER/frontend_select_track.c index a27af97..f6c5446 100644 --- a/PROJECTS/ROLLER/frontend_select_track.c +++ b/PROJECTS/ROLLER/frontend_select_track.c @@ -467,6 +467,7 @@ static void frontend_track_select_draw(int *piBlockIdx, int *piStartedFadeIn) FRONTEND_TRACK_COMMUNITY_LIST_RIGHT, sel_posns[iRow].y + 7, 2u, FRONTEND_TRACK_COMMUNITY_LIST_LEFT, FRONTEND_TRACK_COMMUNITY_LIST_RIGHT); + frontend_mouse_register_left_menu_row(iRow, sel_posns[iRow].y); } } menu_render_sprite(mr, FRONTEND_TRACK_ARROW_SLOT, iUpArrowBlock, @@ -485,6 +486,8 @@ static void frontend_track_select_draw(int *piBlockIdx, int *piStartedFadeIn) font2_ascii, font2_offsets, sel_posns[iRow].x + 132, sel_posns[iRow].y + 7, 2); + if (game_type != 1 && !iStockSelectionDisabled) + frontend_mouse_register_left_menu_row(iRow, sel_posns[iRow].y); } } diff --git a/PROJECTS/ROLLER/frontend_select_type.c b/PROJECTS/ROLLER/frontend_select_type.c index fcee069..e27e9c7 100644 --- a/PROJECTS/ROLLER/frontend_select_type.c +++ b/PROJECTS/ROLLER/frontend_select_type.c @@ -519,6 +519,7 @@ static void frontend_type_select_draw(void) font2_ascii, font2_offsets, sel_posns[0].x + 132, sel_posns[0].y + 7, 2); + frontend_mouse_register_left_menu_row(0, sel_posns[0].y); } else { menu_render_text(mr, 2, &language_buffer[384], font2_ascii, font2_offsets, sel_posns[0].x + 132, @@ -541,23 +542,29 @@ static void frontend_type_select_draw(void) font2_ascii, font2_offsets, sel_posns[0].x + 132, sel_posns[0].y + 7, 2); + frontend_mouse_register_left_menu_row(0, sel_posns[0].y); frontend_mouse_register_text(1, front_vga[2], &language_buffer[3200], font2_ascii, font2_offsets, sel_posns[1].x + 132, sel_posns[1].y + 7, 2); + frontend_mouse_register_left_menu_row(1, sel_posns[1].y); frontend_mouse_register_text(2, front_vga[2], &language_buffer[3264], font2_ascii, font2_offsets, sel_posns[2].x + 132, sel_posns[2].y + 7, 2); + frontend_mouse_register_left_menu_row(2, sel_posns[2].y); frontend_mouse_register_text(3, front_vga[2], &language_buffer[3328], font2_ascii, font2_offsets, sel_posns[3].x + 132, sel_posns[3].y + 7, 2); + frontend_mouse_register_left_menu_row(3, sel_posns[3].y); if (iFrontendTypeCheatModesAvailable) frontend_mouse_register_text(4, front_vga[2], &language_buffer[4288], font2_ascii, font2_offsets, sel_posns[4].x + 132, sel_posns[4].y + 7, 2); + if (iFrontendTypeCheatModesAvailable) + frontend_mouse_register_left_menu_row(4, sel_posns[4].y); } if (front_vga[6]) diff --git a/PROJECTS/ROLLER/frontend_util.c b/PROJECTS/ROLLER/frontend_util.c index 73b8fd2..bcd89f6 100644 --- a/PROJECTS/ROLLER/frontend_util.c +++ b/PROJECTS/ROLLER/frontend_util.c @@ -289,6 +289,8 @@ int CheckNames(char *szPlayerName, int iPlayerIdx) //------------------------------------------------------------------------------------------------- #define FRONTEND_MOUSE_MAX_HITBOXES 128 +#define FRONTEND_MOUSE_LEFT_MENU_RIGHT 176 +#define FRONTEND_MOUSE_LEFT_MENU_ROW_HEIGHT 22 typedef struct { @@ -503,6 +505,14 @@ void frontend_mouse_register_rect(int iId, int iX, int iY, int iWidth, int iHeig //------------------------------------------------------------------------------------------------- +void frontend_mouse_register_left_menu_row(int iId, int iY) +{ + frontend_mouse_register_rect(iId, 0, iY, FRONTEND_MOUSE_LEFT_MENU_RIGHT, + FRONTEND_MOUSE_LEFT_MENU_ROW_HEIGHT); +} + +//------------------------------------------------------------------------------------------------- + static int frontend_mouse_text_width(tBlockHeader *pFont, const char *szText, const char *szMappingTable) From 5d0566d0ac648f170f4889b47cf8f3921be166e0 Mon Sep 17 00:00:00 2001 From: Zizin13 <162662805+Zizin13@users.noreply.github.com> Date: Tue, 16 Jun 2026 22:08:01 -0700 Subject: [PATCH 3/4] draw mouse hover boxes on items with no normal highlighting --- PROJECTS/ROLLER/3d.c | 6 +- PROJECTS/ROLLER/frontend.h | 6 ++ PROJECTS/ROLLER/frontend_pause.c | 2 +- PROJECTS/ROLLER/frontend_screens.c | 2 + PROJECTS/ROLLER/frontend_select_track.c | 5 +- PROJECTS/ROLLER/frontend_select_type.c | 7 +- PROJECTS/ROLLER/frontend_util.c | 109 +++++++++++++++++++++++- PROJECTS/ROLLER/graphics.c | 50 +++++++++++ PROJECTS/ROLLER/graphics.h | 3 +- PROJECTS/ROLLER/menu_render.c | 11 +++ PROJECTS/ROLLER/menu_render.h | 2 + PROJECTS/ROLLER/menu_render_gpu.c | 75 ++++++++++++++++ PROJECTS/ROLLER/menu_render_gpu.h | 2 + PROJECTS/ROLLER/menu_render_software.c | 19 +++++ PROJECTS/ROLLER/menu_render_software.h | 2 + 15 files changed, 294 insertions(+), 7 deletions(-) diff --git a/PROJECTS/ROLLER/3d.c b/PROJECTS/ROLLER/3d.c index 38f360c..d7401d5 100644 --- a/PROJECTS/ROLLER/3d.c +++ b/PROJECTS/ROLLER/3d.c @@ -4624,8 +4624,11 @@ void game_copypic(uint8 *pSrc, uint8 *pDest, int iCarIdx) if (draw_type != 2) { display_paused(); if (trying_to_exit) { - if ((frames & 0xFu) < 8) + if ((frames & 0xFu) < 8) { prt_centrecol(rev_vga[1], &language_buffer[6592], 160, 100, 171); + frontend_mouse_draw_hover_box(FRONTEND_PAUSE_MOUSE_QUIT_PROMPT_ID, + 0, 0); + } } } } @@ -4659,6 +4662,7 @@ void game_copypic(uint8 *pSrc, uint8 *pDest, int iCarIdx) pQuitMessage = szF10ToQuitGame; mini_prt_centre(rev_vga[0], pQuitMessage, winw / 2, winh / 2); mini_prt_centre(rev_vga[0], "ESC TO CANCEL", winw / 2, winh / 2 + 14); + frontend_mouse_draw_hover_box(RACE_MOUSE_QUIT_PROMPT, 0, 0); scr_size = iSavedScrSize3; } } diff --git a/PROJECTS/ROLLER/frontend.h b/PROJECTS/ROLLER/frontend.h index 8707cd6..126e59a 100644 --- a/PROJECTS/ROLLER/frontend.h +++ b/PROJECTS/ROLLER/frontend.h @@ -11,6 +11,9 @@ #define PREVIEW_H 330 #define CAR_PREVIEW_Y 57 #define TRACK_PREVIEW_Y 5 +#define FRONTEND_PAUSE_MOUSE_QUIT_PROMPT_ID 100 + +typedef struct MenuRenderer MenuRenderer; typedef struct { @@ -281,6 +284,9 @@ void frontend_mouse_register_scaled_text(int iId, tBlockHeader *pFont, int frontend_mouse_take_hovered_id(void); int frontend_mouse_peek_hovered_id(void); int frontend_mouse_peek_clicked_id(void); +void frontend_mouse_draw_hover_box(int iId, int iVirtualWidth, + int iVirtualHeight); +void frontend_mouse_draw_menu_hover_box(MenuRenderer *pRenderer, int iId); int frontend_mouse_consume_click(void); int frontend_mouse_consume_click_anywhere(void); int frontend_mouse_take_wheel_y(void); diff --git a/PROJECTS/ROLLER/frontend_pause.c b/PROJECTS/ROLLER/frontend_pause.c index a20693a..db07c7f 100644 --- a/PROJECTS/ROLLER/frontend_pause.c +++ b/PROJECTS/ROLLER/frontend_pause.c @@ -10,7 +10,7 @@ //------------------------------------------------------------------------------------------------- enum { - FRONTEND_PAUSE_MOUSE_QUIT_PROMPT = 100 + FRONTEND_PAUSE_MOUSE_QUIT_PROMPT = FRONTEND_PAUSE_MOUSE_QUIT_PROMPT_ID }; static int frontend_pause_mouse_scale(int iValue) diff --git a/PROJECTS/ROLLER/frontend_screens.c b/PROJECTS/ROLLER/frontend_screens.c index becd2c3..e411710 100644 --- a/PROJECTS/ROLLER/frontend_screens.c +++ b/PROJECTS/ROLLER/frontend_screens.c @@ -1005,6 +1005,8 @@ static void frontend_main_menu_emit_draw(MenuRenderer *mr) frontend_mouse_register_text(FRONTEND_MAIN_MENU_MOUSE_QUIT_PROMPT, front_vga[15], &language_buffer[3456], font1_ascii, font1_offsets, 400, 250, 1); + frontend_mouse_draw_menu_hover_box(mr, + FRONTEND_MAIN_MENU_MOUSE_QUIT_PROMPT); } if (g_iNetworkTrackFileCRCMismatch) { menu_render_text(mr, 15, "TRACK FILE CRC MISMATCH", font1_ascii, diff --git a/PROJECTS/ROLLER/frontend_select_track.c b/PROJECTS/ROLLER/frontend_select_track.c index f6c5446..7094fa1 100644 --- a/PROJECTS/ROLLER/frontend_select_track.c +++ b/PROJECTS/ROLLER/frontend_select_track.c @@ -560,12 +560,13 @@ static void frontend_track_select_draw(int *piBlockIdx, int *piStartedFadeIn) "TRACKS", font3_ascii, font3_offsets, 540, 360, 0x8Fu, 1u, 450, 635, pal_addr); frontend_mouse_register_rect(FRONTEND_TRACK_MOUSE_CUP, 450, 316, - 185, 62); + 640 - 450, 400 - 316); } else { menu_render_sprite(mr, 14, iBlockIdx, 500, 300, 0, pal_addr); frontend_mouse_register_rect(FRONTEND_TRACK_MOUSE_CUP, 470, 280, - 160, 100); + 640 - 470, 400 - 280); } + frontend_mouse_draw_menu_hover_box(mr, FRONTEND_TRACK_MOUSE_CUP); if (frontend_track_select_is_community()) { if (g_iCommunityTrackSel >= 0 && g_iCommunityTrackSel < g_iCommunityTrackCount) { diff --git a/PROJECTS/ROLLER/frontend_select_type.c b/PROJECTS/ROLLER/frontend_select_type.c index e27e9c7..e18a403 100644 --- a/PROJECTS/ROLLER/frontend_select_type.c +++ b/PROJECTS/ROLLER/frontend_select_type.c @@ -574,7 +574,9 @@ static void frontend_type_select_draw(void) menu_render_sprite(mr, 14, iFrontendTypeBlockIdx, 500, 300, 0, pal_addr); if (!iFrontendTypeSkipColor) frontend_mouse_register_rect(FRONTEND_TYPE_MOUSE_CUP, 470, 280, - 160, 100); + 640 - 470, 400 - 280); + frontend_mouse_draw_menu_hover_box(mr, FRONTEND_TYPE_MOUSE_CUP); + frontend_type_select_register_submenu_mouse_items(); if (iFrontendTypeSkipColor) { menu_render_scaled_text(mr, 15, &language_buffer[3392], font1_ascii, font1_offsets, 400, 75, 143, 1u, 200, 640, @@ -825,6 +827,9 @@ static void frontend_type_select_draw(void) font1_offsets, 400, iTextYPosition, byFinalTextColor, 1u, 200, 640, pal_addr); + if (iFrontendTypeSkipColor && iFrontendTypeMenuSelection == 6) + frontend_mouse_draw_menu_hover_box(mr, FRONTEND_TYPE_MOUSE_SUB_BASE); + show_received_mesage(); menu_render_end_frame(mr); } diff --git a/PROJECTS/ROLLER/frontend_util.c b/PROJECTS/ROLLER/frontend_util.c index bcd89f6..32d6daa 100644 --- a/PROJECTS/ROLLER/frontend_util.c +++ b/PROJECTS/ROLLER/frontend_util.c @@ -291,6 +291,7 @@ int CheckNames(char *szPlayerName, int iPlayerIdx) #define FRONTEND_MOUSE_MAX_HITBOXES 128 #define FRONTEND_MOUSE_LEFT_MENU_RIGHT 176 #define FRONTEND_MOUSE_LEFT_MENU_ROW_HEIGHT 22 +#define FRONTEND_MOUSE_HOVER_BOX_COLOR 0xE7u typedef struct { @@ -302,6 +303,7 @@ typedef struct } tFrontendMouseHitbox; static tFrontendMouseHitbox s_frontendMouseHitboxes[FRONTEND_MOUSE_MAX_HITBOXES]; +static tFrontendMouseHitbox s_frontendMouseHoveredHitbox; static int s_iFrontendMouseHitboxCount = 0; static int s_iFrontendMouseVirtualWidth = 640; static int s_iFrontendMouseVirtualHeight = 400; @@ -313,6 +315,7 @@ static int s_iFrontendMouseClickVirtualY = 0; static int s_iFrontendMouseClickValid = 0; static int s_iFrontendMouseHoveredId = -1; static int s_iFrontendMouseClickedId = -1; +static int s_iFrontendMouseHoveredHitboxValid = 0; static int s_iFrontendMouseLeftDown = 0; static float s_fFrontendMouseWindowX = 0.0f; static float s_fFrontendMouseWindowY = 0.0f; @@ -460,6 +463,7 @@ void frontend_mouse_begin_frame(int iVirtualWidth, int iVirtualHeight) s_iFrontendMouseHitboxCount = 0; s_iFrontendMouseHoveredId = -1; s_iFrontendMouseClickedId = -1; + s_iFrontendMouseHoveredHitboxValid = 0; } //------------------------------------------------------------------------------------------------- @@ -492,8 +496,15 @@ void frontend_mouse_register_rect(int iId, int iX, int iY, int iWidth, int iHeig s_iFrontendMouseVirtualX >= iX && s_iFrontendMouseVirtualY >= iY && s_iFrontendMouseVirtualX < iX + iWidth && - s_iFrontendMouseVirtualY < iY + iHeight) + s_iFrontendMouseVirtualY < iY + iHeight) { s_iFrontendMouseHoveredId = iId; + s_frontendMouseHoveredHitbox.iId = iId; + s_frontendMouseHoveredHitbox.iX = iX; + s_frontendMouseHoveredHitbox.iY = iY; + s_frontendMouseHoveredHitbox.iWidth = iWidth; + s_frontendMouseHoveredHitbox.iHeight = iHeight; + s_iFrontendMouseHoveredHitboxValid = -1; + } if (s_iFrontendMouseClickValid && s_iFrontendMouseClickVirtualX >= iX && @@ -681,6 +692,102 @@ void frontend_mouse_register_scaled_text(int iId, tBlockHeader *pFont, //------------------------------------------------------------------------------------------------- +void frontend_mouse_draw_hover_box(int iId, int iVirtualWidth, int iVirtualHeight) +{ + int iSavedWinW; + int iSavedWinH; + int iDrawWidth; + int iDrawHeight; + int iX; + int iY; + int iWidth; + int iHeight; + + if (!s_iFrontendMouseHoveredHitboxValid || + s_iFrontendMouseHoveredId != iId) + return; + + iDrawWidth = iVirtualWidth > 0 ? iVirtualWidth : s_iFrontendMouseVirtualWidth; + iDrawHeight = iVirtualHeight > 0 ? iVirtualHeight : s_iFrontendMouseVirtualHeight; + if (iDrawWidth <= 0 || iDrawHeight <= 0) + return; + + iX = s_frontendMouseHoveredHitbox.iX; + iY = s_frontendMouseHoveredHitbox.iY; + iWidth = s_frontendMouseHoveredHitbox.iWidth; + iHeight = s_frontendMouseHoveredHitbox.iHeight; + + if (iX < 0) { + iWidth += iX; + iX = 0; + } + if (iY < 0) { + iHeight += iY; + iY = 0; + } + if (iX + iWidth > iDrawWidth) + iWidth = iDrawWidth - iX; + if (iY + iHeight > iDrawHeight) + iHeight = iDrawHeight - iY; + if (iWidth <= 1 || iHeight <= 1) + return; + + iSavedWinW = winw; + iSavedWinH = winh; + winw = iDrawWidth; + winh = iDrawHeight; + box_screen(iX, iY, iWidth, iHeight, FRONTEND_MOUSE_HOVER_BOX_COLOR); + winh = iSavedWinH; + winw = iSavedWinW; +} + +//------------------------------------------------------------------------------------------------- + +void frontend_mouse_draw_menu_hover_box(MenuRenderer *pRenderer, int iId) +{ + int iDrawWidth; + int iDrawHeight; + int iX; + int iY; + int iWidth; + int iHeight; + + if (!pRenderer || + !s_iFrontendMouseHoveredHitboxValid || + s_iFrontendMouseHoveredId != iId) + return; + + iDrawWidth = s_iFrontendMouseVirtualWidth; + iDrawHeight = s_iFrontendMouseVirtualHeight; + if (iDrawWidth <= 0 || iDrawHeight <= 0) + return; + + iX = s_frontendMouseHoveredHitbox.iX; + iY = s_frontendMouseHoveredHitbox.iY; + iWidth = s_frontendMouseHoveredHitbox.iWidth; + iHeight = s_frontendMouseHoveredHitbox.iHeight; + + if (iX < 0) { + iWidth += iX; + iX = 0; + } + if (iY < 0) { + iHeight += iY; + iY = 0; + } + if (iX + iWidth > iDrawWidth) + iWidth = iDrawWidth - iX; + if (iY + iHeight > iDrawHeight) + iHeight = iDrawHeight - iY; + if (iWidth <= 1 || iHeight <= 1) + return; + + menu_render_box(pRenderer, iX, iY, iWidth, iHeight, + FRONTEND_MOUSE_HOVER_BOX_COLOR, pal_addr); +} + +//------------------------------------------------------------------------------------------------- + int frontend_mouse_take_hovered_id(void) { if (s_uiFrontendMouseMotionSeq == s_uiFrontendMouseConsumedMotionSeq) diff --git a/PROJECTS/ROLLER/graphics.c b/PROJECTS/ROLLER/graphics.c index 165d69c..a59d1a2 100644 --- a/PROJECTS/ROLLER/graphics.c +++ b/PROJECTS/ROLLER/graphics.c @@ -1399,3 +1399,53 @@ void box(int iX, int iY, int iWidth, int iHeight, uint8 byBorderColor) } //------------------------------------------------------------------------------------------------- + +void box_screen(int iX, int iY, int iWidth, int iHeight, uint8 byBorderColor) +{ + int iX2; + int iY2; + int i; + int iStride; + uint8 *pTopRow; + uint8 *pBottomRow; + uint8 *pLeftEdge; + uint8 *pRightEdge; + + if (!scrbuf || winw <= 0 || winh <= 0 || iWidth <= 1 || iHeight <= 1) + return; + + iX2 = iX + iWidth - 1; + iY2 = iY + iHeight - 1; + if (iX2 < 0 || iY2 < 0 || iX >= winw || iY >= winh) + return; + + if (iX < 0) + iX = 0; + if (iY < 0) + iY = 0; + if (iX2 >= winw) + iX2 = winw - 1; + if (iY2 >= winh) + iY2 = winh - 1; + if (iX2 <= iX || iY2 <= iY) + return; + + iStride = winw; + pTopRow = &scrbuf[iX + iStride * iY]; + pBottomRow = &scrbuf[iX + iStride * iY2]; + for (i = iX; i <= iX2; ++i) { + *pTopRow++ = byBorderColor; + *pBottomRow++ = byBorderColor; + } + + pLeftEdge = &scrbuf[iX + iStride * iY]; + pRightEdge = &scrbuf[iX2 + iStride * iY]; + for (i = iY; i <= iY2; ++i) { + *pLeftEdge = byBorderColor; + *pRightEdge = byBorderColor; + pLeftEdge += iStride; + pRightEdge += iStride; + } +} + +//------------------------------------------------------------------------------------------------- diff --git a/PROJECTS/ROLLER/graphics.h b/PROJECTS/ROLLER/graphics.h index 1baefc6..90c6ccf 100644 --- a/PROJECTS/ROLLER/graphics.h +++ b/PROJECTS/ROLLER/graphics.h @@ -33,6 +33,7 @@ void sort_small_texture(uint8 *pDest, uint8 *pSrc, int iNumBlocks); void sort_texture(uint8 *pTexData, int iNumTextures); void sort_mini_texture(uint8 *pTexData, int iNumTextures); void box(int iX, int iY, int iWidth, int iHeight, uint8 byBorderColor); +void box_screen(int iX, int iY, int iWidth, int iHeight, uint8 byBorderColor); //------------------------------------------------------------------------------------------------- -#endif \ No newline at end of file +#endif diff --git a/PROJECTS/ROLLER/menu_render.c b/PROJECTS/ROLLER/menu_render.c index 73d2651..4bc45f7 100644 --- a/PROJECTS/ROLLER/menu_render.c +++ b/PROJECTS/ROLLER/menu_render.c @@ -173,6 +173,17 @@ void menu_render_sprite(MenuRenderer *renderer, int slot, int blockIdx, transparentColorIndex, palette); } +void menu_render_box(MenuRenderer *renderer, int x, int y, int width, + int height, uint8 colorIndex, const tColor *palette) { + if (!renderer) return; + if (renderer->mode == MENU_RENDER_GPU && renderer->gpu) + menu_render_gpu_box(renderer->gpu, x, y, width, height, + colorIndex, palette); + else + menu_render_sw_box(renderer->sw, x, y, width, height, + colorIndex, palette); +} + void menu_render_begin_fade(MenuRenderer *renderer, int direction, int durationFrames) { if (!renderer) return; diff --git a/PROJECTS/ROLLER/menu_render.h b/PROJECTS/ROLLER/menu_render.h index b347d74..0639c90 100644 --- a/PROJECTS/ROLLER/menu_render.h +++ b/PROJECTS/ROLLER/menu_render.h @@ -43,6 +43,8 @@ void menu_render_background(MenuRenderer *renderer, int slot); void menu_render_sprite(MenuRenderer *renderer, int slot, int blockIdx, int x, int y, int transparentColorIndex, const tColor *palette); +void menu_render_box(MenuRenderer *renderer, int x, int y, int width, + int height, uint8 colorIndex, const tColor *palette); // Fade system void menu_render_begin_fade(MenuRenderer *renderer, int direction, int durationFrames); diff --git a/PROJECTS/ROLLER/menu_render_gpu.c b/PROJECTS/ROLLER/menu_render_gpu.c index 2feb639..2d489fb 100644 --- a/PROJECTS/ROLLER/menu_render_gpu.c +++ b/PROJECTS/ROLLER/menu_render_gpu.c @@ -275,6 +275,37 @@ static void RecordDrawWithColorReplace(MenuRendererGPU *r, SDL_GPUTexture *textu } } +static void RecordDrawSolidColor(MenuRendererGPU *r, SDL_GPUTexture *texture, + uint8 colorIdx, const tColor *pal) +{ + if (r->vertexCount == 0 || r->drawCommandCount >= MAX_DRAW_COMMANDS) return; + + DrawCommand *cmd = &r->drawCommands[r->drawCommandCount++]; + cmd->texture = texture; + cmd->vertexOffset = r->vertexCount - 6; + cmd->vertexCount = 6; + cmd->layer = r->currentLayer; + memset(&cmd->uniforms, 0, sizeof(cmd->uniforms)); + cmd->uniforms.alphaMul = 1.0f; + cmd->uniforms.transparentR = -1.0f; + cmd->uniforms.transparentG = -1.0f; + cmd->uniforms.transparentB = -1.0f; + cmd->uniforms.replaceFromR = 1.0f; + cmd->uniforms.replaceFromG = 1.0f; + cmd->uniforms.replaceFromB = 1.0f; + + if (pal) { + const tColor *tc = &pal[colorIdx]; + cmd->uniforms.replaceToR = ColorToFloat(tc->byR); + cmd->uniforms.replaceToG = ColorToFloat(tc->byG); + cmd->uniforms.replaceToB = ColorToFloat(tc->byB); + } else { + cmd->uniforms.replaceToR = 1.0f; + cmd->uniforms.replaceToG = 0.0f; + cmd->uniforms.replaceToB = 0.0f; + } +} + static void ReplayDrawsLayer(MenuRendererGPU *r, SDL_GPURenderPass *renderPass, MenuDrawLayer minLayer, MenuDrawLayer maxLayer) { @@ -862,6 +893,50 @@ void menu_render_gpu_sprite(MenuRendererGPU *r, int slot, int blockIdx, int x, i RecordDraw(r, mt->texture, 1.0f, transparentIdx, pal); } +static void menu_render_gpu_solid_quad(MenuRendererGPU *r, int x, int y, + int width, int height, uint8 colorIdx, + const tColor *pal) +{ + if (!r->whiteTexture || width <= 0 || height <= 0) return; + EmitQuad(r, (float)x, (float)y, (float)width, (float)height, 0, 0, 1, 1); + RecordDrawSolidColor(r, r->whiteTexture, colorIdx, pal); +} + +void menu_render_gpu_box(MenuRendererGPU *r, int x, int y, int width, + int height, uint8 colorIdx, const tColor *pal) +{ + int x2; + int y2; + + if (!r || width <= 1 || height <= 1) + return; + + x2 = x + width - 1; + y2 = y + height - 1; + if (x2 < 0 || y2 < 0 || x >= MENU_WIDTH || y >= MENU_HEIGHT) + return; + + if (x < 0) + x = 0; + if (y < 0) + y = 0; + if (x2 >= MENU_WIDTH) + x2 = MENU_WIDTH - 1; + if (y2 >= MENU_HEIGHT) + y2 = MENU_HEIGHT - 1; + if (x2 <= x || y2 <= y) + return; + + width = x2 - x + 1; + height = y2 - y + 1; + menu_render_gpu_solid_quad(r, x, y, width, 1, colorIdx, pal); + menu_render_gpu_solid_quad(r, x, y2, width, 1, colorIdx, pal); + if (height > 2) { + menu_render_gpu_solid_quad(r, x, y + 1, 1, height - 2, colorIdx, pal); + menu_render_gpu_solid_quad(r, x2, y + 1, 1, height - 2, colorIdx, pal); + } +} + //--------------------------------------------------------------------------- // Text rendering //--------------------------------------------------------------------------- diff --git a/PROJECTS/ROLLER/menu_render_gpu.h b/PROJECTS/ROLLER/menu_render_gpu.h index 282c82c..49c00ca 100644 --- a/PROJECTS/ROLLER/menu_render_gpu.h +++ b/PROJECTS/ROLLER/menu_render_gpu.h @@ -35,6 +35,8 @@ void menu_render_gpu_background(MenuRendererGPU *renderer, int slot); void menu_render_gpu_sprite(MenuRendererGPU *renderer, int slot, int blockIdx, int x, int y, int transparentColorIndex, const tColor *palette); +void menu_render_gpu_box(MenuRendererGPU *renderer, int x, int y, int width, + int height, uint8 colorIndex, const tColor *palette); // Fade system void menu_render_gpu_begin_fade(MenuRendererGPU *renderer, int direction, int durationFrames); diff --git a/PROJECTS/ROLLER/menu_render_software.c b/PROJECTS/ROLLER/menu_render_software.c index 41e84f1..b4f68a0 100644 --- a/PROJECTS/ROLLER/menu_render_software.c +++ b/PROJECTS/ROLLER/menu_render_software.c @@ -25,6 +25,8 @@ struct MenuRendererSoftware { // explicit at the scene seam instead of smuggling it as a destination pointer. #define MENU_SW_CAR_PREVIEW_X 80 #define MENU_SW_CAR_PREVIEW_Y 54 +#define MENU_SW_WIDTH 640 +#define MENU_SW_HEIGHT 400 // --------------------------------------------------------------------------- // Lifecycle @@ -124,6 +126,23 @@ void menu_render_sw_sprite(MenuRendererSoftware *sw, int slot, int blockIdx, transparentColorIndex); } +void menu_render_sw_box(MenuRendererSoftware *sw, int x, int y, int width, + int height, uint8 colorIndex, const tColor *palette) { + int savedWinW; + int savedWinH; + + (void)sw; + (void)palette; + + savedWinW = winw; + savedWinH = winh; + winw = MENU_SW_WIDTH; + winh = MENU_SW_HEIGHT; + box_screen(x, y, width, height, colorIndex); + winh = savedWinH; + winw = savedWinW; +} + // --------------------------------------------------------------------------- // Fade system // --------------------------------------------------------------------------- diff --git a/PROJECTS/ROLLER/menu_render_software.h b/PROJECTS/ROLLER/menu_render_software.h index e82dad9..3c339fa 100644 --- a/PROJECTS/ROLLER/menu_render_software.h +++ b/PROJECTS/ROLLER/menu_render_software.h @@ -24,6 +24,8 @@ void menu_render_sw_background(MenuRendererSoftware *sw, int slot); void menu_render_sw_sprite(MenuRendererSoftware *sw, int slot, int blockIdx, int x, int y, int transparentColorIndex, const tColor *palette); +void menu_render_sw_box(MenuRendererSoftware *sw, int x, int y, int width, + int height, uint8 colorIndex, const tColor *palette); // Fade system void menu_render_sw_begin_fade(MenuRendererSoftware *sw, int direction, From 97bc8170ed1c9ca76e9b2cb8a1a111e035d35e7a Mon Sep 17 00:00:00 2001 From: Zizin13 <162662805+Zizin13@users.noreply.github.com> Date: Tue, 16 Jun 2026 22:35:49 -0700 Subject: [PATCH 4/4] network menu mouse select stuff, don't blink rectangles with press y to quit message --- PROJECTS/ROLLER/3d.c | 16 +- PROJECTS/ROLLER/frontend_lobby.c | 66 ++++++-- PROJECTS/ROLLER/frontend_select_players.c | 147 ++++++++++++++++- PROJECTS/ROLLER/func3.c | 186 ++++++++++++++++++++++ 4 files changed, 394 insertions(+), 21 deletions(-) diff --git a/PROJECTS/ROLLER/3d.c b/PROJECTS/ROLLER/3d.c index d7401d5..1c8a2b9 100644 --- a/PROJECTS/ROLLER/3d.c +++ b/PROJECTS/ROLLER/3d.c @@ -4624,11 +4624,19 @@ void game_copypic(uint8 *pSrc, uint8 *pDest, int iCarIdx) if (draw_type != 2) { display_paused(); if (trying_to_exit) { - if ((frames & 0xFu) < 8) { + int iPromptY = (scr_size * 96) >> 6; + int iPromptH = (scr_size * 14) >> 6; + + if (iPromptH <= 0) + iPromptH = 1; + frontend_mouse_register_rect(FRONTEND_PAUSE_MOUSE_QUIT_PROMPT_ID, + 0, iPromptY, + winw > 0 ? winw : XMAX, + iPromptH); + if ((frames & 0xFu) < 8) prt_centrecol(rev_vga[1], &language_buffer[6592], 160, 100, 171); - frontend_mouse_draw_hover_box(FRONTEND_PAUSE_MOUSE_QUIT_PROMPT_ID, - 0, 0); - } + frontend_mouse_draw_hover_box(FRONTEND_PAUSE_MOUSE_QUIT_PROMPT_ID, + 0, 0); } } } diff --git a/PROJECTS/ROLLER/frontend_lobby.c b/PROJECTS/ROLLER/frontend_lobby.c index 85be2f8..2575e1b 100644 --- a/PROJECTS/ROLLER/frontend_lobby.c +++ b/PROJECTS/ROLLER/frontend_lobby.c @@ -58,6 +58,10 @@ static eFrontendState eLobbyExitTarget; #define MENU_COLOR_RED 0xE7u +enum { + LOBBY_MOUSE_START = 1 +}; + static void lobby_draw_frame(void); static void lobby_begin_exit(eFrontendState eTarget); @@ -118,12 +122,22 @@ static void lobby_begin_broadcast_wait(eLobbyBroadcastAction eAction, //------------------------------------------------------------------------------------------------- +static void lobby_drain_mouse(void) +{ + frontend_mouse_take_wheel_y(); + (void)frontend_mouse_take_hovered_id(); + (void)frontend_mouse_consume_click_anywhere(); +} + +//------------------------------------------------------------------------------------------------- + static int lobby_update_broadcast_wait(void) { if (eLobbyBroadcastActionCurrent == eLOBBY_BROADCAST_NONE) return 0; lobby_draw_frame(); + lobby_drain_mouse(); if (!network_broadcast_wait_update()) return -1; @@ -278,9 +292,13 @@ static void lobby_emit_draw(MenuRenderer *mr) menu_render_text(mr, 1, buffer, font2_ascii, font2_offsets, 200, 4, 0x8Fu, 1u, pal_addr); if (players_waiting == network_on) { + frontend_mouse_register_text(LOBBY_MOUSE_START, front_vga[1], + &language_buffer[4800], font2_ascii, + font2_offsets, 200, 22, 1u); if ((frames & 0xFu) < 8) menu_render_text(mr, 1, &language_buffer[4800], font2_ascii, font2_offsets, 200, 22, 0x8Fu, 1u, pal_addr); + frontend_mouse_draw_menu_hover_box(mr, LOBBY_MOUSE_START); if (time_to_start) iLobbyActive = 0; } @@ -376,6 +394,7 @@ static void lobby_draw_frame(void) MenuRenderer *mr = GetMenuRenderer(); menu_render_begin_frame(mr); + frontend_mouse_begin_frame(640, 400); lobby_emit_draw(mr); if (iLobbyActive) { if (!front_fade) { @@ -389,6 +408,41 @@ static void lobby_draw_frame(void) //------------------------------------------------------------------------------------------------- +static int lobby_request_start_race(void) +{ + if (players_waiting != network_on || time_to_start) + return 0; + + if (g_iNetworkTrackFileCRCMismatch || + (TrackLoad == TRACK_LOAD_COMMUNITY && g_iCommunityTrackMissing) || + !community_track_available()) { + sfxsample(SOUND_SAMPLE_BUTTON, 0x8000); + return -1; + } + + lobby_begin_broadcast_wait(eLOBBY_BROADCAST_START_RACE, -671, 3); + return -1; +} + +//------------------------------------------------------------------------------------------------- + +static int lobby_handle_mouse(void) +{ + int iClicked; + + frontend_mouse_take_wheel_y(); + (void)frontend_mouse_take_hovered_id(); + + iClicked = frontend_mouse_peek_clicked_id(); + if (frontend_mouse_consume_click_anywhere() && + iClicked == LOBBY_MOUSE_START) + return lobby_request_start_race(); + + return 0; +} + +//------------------------------------------------------------------------------------------------- + static void lobby_handle_input(void) { unsigned int uiKeyPressed; @@ -399,16 +453,8 @@ static void lobby_handle_input(void) if (!uiKeyPressed) fatgetch(); } else if (uiKeyPressed <= 0xD) { - if (players_waiting == network_on && !time_to_start) { - if (g_iNetworkTrackFileCRCMismatch || - (TrackLoad == TRACK_LOAD_COMMUNITY && g_iCommunityTrackMissing) || - !community_track_available()) { - sfxsample(SOUND_SAMPLE_BUTTON, 0x8000); - return; - } - lobby_begin_broadcast_wait(eLOBBY_BROADCAST_START_RACE, -671, 3); + if (lobby_request_start_race()) return; - } } else if (uiKeyPressed == 27 && !time_to_start && !restart_net) { StartPressed = 0; time_to_start = 0; @@ -470,6 +516,8 @@ void frontend_lobby_update(void) check_cars(); lobby_draw_frame(); + if (lobby_handle_mouse()) + return; lobby_handle_input(); if (!iLobbyActive) { diff --git a/PROJECTS/ROLLER/frontend_select_players.c b/PROJECTS/ROLLER/frontend_select_players.c index 5def6ac..e11f10e 100644 --- a/PROJECTS/ROLLER/frontend_select_players.c +++ b/PROJECTS/ROLLER/frontend_select_players.c @@ -50,6 +50,15 @@ enum { ePLAYERS_NET_SLOT_SETUP_WAIT }; +enum { + FRONTEND_PLAYERS_NET_SLOT_MOUSE_BASE = 100 +}; + +enum { + FRONTEND_PLAYERS_NETWORK_MOUSE_MESSAGE = 110, + FRONTEND_PLAYERS_NETWORK_MOUSE_QUIT +}; + enum { ePLAYERS_BROADCAST_WAIT_NONE = 0, ePLAYERS_BROADCAST_WAIT_NETWORK_SETUP, @@ -60,6 +69,8 @@ enum { //------------------------------------------------------------------------------------------------- static void frontend_players_select_run_snapshot(void); +static void frontend_players_select_begin_broadcast_wait(int iBroadcastMode, + int iAction); //------------------------------------------------------------------------------------------------- @@ -71,8 +82,18 @@ static void frontend_players_select_handle_mouse(void) frontend_mouse_take_wheel_y(); if (iFrontendPlayersNetworkMode) { + iClicked = frontend_mouse_peek_clicked_id(); + if (frontend_mouse_consume_click_anywhere()) { + if (iClicked == FRONTEND_PLAYERS_NETWORK_MOUSE_MESSAGE) { + if (network_on) + select_messages(); + } else if (iClicked == FRONTEND_PLAYERS_NETWORK_MOUSE_QUIT) { + if (network_on) + frontend_players_select_begin_broadcast_wait( + -666, ePLAYERS_BROADCAST_WAIT_CLOSE_NETWORK); + } + } (void)frontend_mouse_take_hovered_id(); - (void)frontend_mouse_consume_click_anywhere(); return; } @@ -243,6 +264,58 @@ static uint8 frontend_players_net_slot_color(int iSlot) //------------------------------------------------------------------------------------------------- +static int frontend_players_net_slot_selectable(int iSlot) +{ + return iSlot >= 0 && iSlot < 4 && + (unsigned int)gamers_playing[iSlot] < 16; +} + +//------------------------------------------------------------------------------------------------- + +static int frontend_players_net_slot_from_mouse_id(int iId) +{ + int iSlot = iId - FRONTEND_PLAYERS_NET_SLOT_MOUSE_BASE; + + if (iSlot < 0 || iSlot >= 4) + return -1; + + return iSlot; +} + +//------------------------------------------------------------------------------------------------- + +static void frontend_players_net_slot_register_slot(int iSlot, + int iClipLeft, + int iClipRight) +{ + frontend_mouse_register_rect(FRONTEND_PLAYERS_NET_SLOT_MOUSE_BASE + iSlot, + iClipLeft, 88, iClipRight - iClipLeft + 1, + 300); +} + +//------------------------------------------------------------------------------------------------- + +static void frontend_players_net_slot_register_mouse_items(void) +{ + frontend_players_net_slot_register_slot(0, 200, 320); + frontend_players_net_slot_register_slot(1, 321, 419); + frontend_players_net_slot_register_slot(2, 421, 519); + frontend_players_net_slot_register_slot(3, 521, 639); +} + +//------------------------------------------------------------------------------------------------- + +static void frontend_players_net_slot_apply_hover(void) +{ + int iHovered = frontend_players_net_slot_from_mouse_id( + frontend_mouse_take_hovered_id()); + + if (frontend_players_net_slot_selectable(iHovered)) + iFrontendPlayersNetSlotCurrent = iHovered; +} + +//------------------------------------------------------------------------------------------------- + static void frontend_players_net_slot_draw_slot(MenuRenderer *mr, int iSlot, int x, @@ -292,6 +365,12 @@ static void frontend_players_net_slot_draw(void) { MenuRenderer *mr = GetMenuRenderer(); + frontend_mouse_begin_frame(640, 400); + if (iFrontendPlayersNetSlotPhase == ePLAYERS_NET_SLOT_SELECT) { + frontend_players_net_slot_register_mouse_items(); + frontend_players_net_slot_apply_hover(); + } + menu_render_begin_frame(mr); if (!front_fade) { front_fade = -1; @@ -352,6 +431,45 @@ static int frontend_players_net_slot_move_right(int iSlot) //------------------------------------------------------------------------------------------------- +static void frontend_players_net_slot_join_current(void) +{ + if (!frontend_players_net_slot_selectable(iFrontendPlayersNetSlotCurrent)) + return; + + frontend_players_select_add_cached_slot_nodes(iFrontendPlayersNetSlotCurrent); + network_slot = iFrontendPlayersNetSlotCurrent + 1; + network_broadcast_wait_start(-1, 1); + iFrontendPlayersNetSlotPhase = ePLAYERS_NET_SLOT_JOIN_WAIT; +} + +//------------------------------------------------------------------------------------------------- + +static void frontend_players_net_slot_handle_mouse(void) +{ + int iClickedSlot; + + frontend_mouse_take_wheel_y(); + + iClickedSlot = frontend_players_net_slot_from_mouse_id( + frontend_mouse_peek_clicked_id()); + if (frontend_mouse_consume_click_anywhere() && + frontend_players_net_slot_selectable(iClickedSlot)) { + iFrontendPlayersNetSlotCurrent = iClickedSlot; + frontend_players_net_slot_join_current(); + } +} + +//------------------------------------------------------------------------------------------------- + +static void frontend_players_net_slot_drain_mouse(void) +{ + frontend_mouse_take_wheel_y(); + (void)frontend_mouse_take_hovered_id(); + (void)frontend_mouse_consume_click_anywhere(); +} + +//------------------------------------------------------------------------------------------------- + static void frontend_players_net_slot_handle_input(void) { while (fatkbhit()) { @@ -369,12 +487,7 @@ static void frontend_players_net_slot_handle_input(void) } } } else if (uiKeyCode <= 0xD) { - if ((unsigned int)gamers_playing[iFrontendPlayersNetSlotCurrent] < 16) { - frontend_players_select_add_cached_slot_nodes(iFrontendPlayersNetSlotCurrent); - network_slot = iFrontendPlayersNetSlotCurrent + 1; - network_broadcast_wait_start(-1, 1); - iFrontendPlayersNetSlotPhase = ePLAYERS_NET_SLOT_JOIN_WAIT; - } + frontend_players_net_slot_join_current(); } else if (uiKeyCode == 27) { network_broadcast_wait_start(-666, 1); iFrontendPlayersNetSlotPhase = ePLAYERS_NET_SLOT_LEAVE_WAIT; @@ -391,6 +504,7 @@ static int frontend_players_net_slot_update(void) if (iFrontendPlayersNetSlotPhase == ePLAYERS_NET_SLOT_INIT) { frontend_players_net_slot_draw(); + frontend_players_net_slot_drain_mouse(); if (!network_initialise_update()) return -1; if (network_on) { @@ -404,6 +518,7 @@ static int frontend_players_net_slot_update(void) if (iFrontendPlayersNetSlotPhase == ePLAYERS_NET_SLOT_JOIN_WAIT) { frontend_players_net_slot_draw(); + frontend_players_net_slot_drain_mouse(); if (!network_broadcast_wait_update()) return -1; network_broadcast_wait_start(-667, 1); @@ -413,6 +528,7 @@ static int frontend_players_net_slot_update(void) if (iFrontendPlayersNetSlotPhase == ePLAYERS_NET_SLOT_SETUP_WAIT) { frontend_players_net_slot_draw(); + frontend_players_net_slot_drain_mouse(); if (!network_broadcast_wait_update()) return -1; frontend_players_select_finish_network_setup(); @@ -421,6 +537,7 @@ static int frontend_players_net_slot_update(void) if (iFrontendPlayersNetSlotPhase == ePLAYERS_NET_SLOT_LEAVE_WAIT) { frontend_players_net_slot_draw(); + frontend_players_net_slot_drain_mouse(); if (!network_broadcast_wait_update()) return -1; close_network(); @@ -436,8 +553,10 @@ static int frontend_players_net_slot_update(void) ROLLERCommsPumpSendQueue(); } frontend_players_net_slot_draw(); - if (!SnapshotShouldStop()) + if (!SnapshotShouldStop()) { + frontend_players_net_slot_handle_mouse(); frontend_players_net_slot_handle_input(); + } return -1; } @@ -585,6 +704,18 @@ void frontend_players_select_update(void) } menu_render_scaled_text(mr, 15, &language_buffer[4224], font1_ascii, font1_offsets, 400, 380, 231, 1u, 200, 640, pal_addr); menu_render_scaled_text(mr, 15, &language_buffer[7104], font1_ascii, font1_offsets, 400, 360, 231, 1u, 200, 640, pal_addr); + frontend_mouse_register_scaled_text( + FRONTEND_PLAYERS_NETWORK_MOUSE_QUIT, front_vga[15], + &language_buffer[4224], font1_ascii, font1_offsets, 400, 380, + 1u, 200, 640); + frontend_mouse_register_scaled_text( + FRONTEND_PLAYERS_NETWORK_MOUSE_MESSAGE, front_vga[15], + &language_buffer[7104], font1_ascii, font1_offsets, 400, 360, + 1u, 200, 640); + frontend_mouse_draw_menu_hover_box( + mr, FRONTEND_PLAYERS_NETWORK_MOUSE_QUIT); + frontend_mouse_draw_menu_hover_box( + mr, FRONTEND_PLAYERS_NETWORK_MOUSE_MESSAGE); } else { menu_render_scaled_text(mr, 15, &language_buffer[2944], font1_ascii, font1_offsets, 400, 75, 143, 1u, 200, 640, pal_addr); // MENU MODE UI: Show player selection options with highlighting menu_render_scaled_text(mr, 15, &language_buffer[3008], font1_ascii, font1_offsets, 400, 93, 143, 1u, 200, 640, pal_addr); diff --git a/PROJECTS/ROLLER/func3.c b/PROJECTS/ROLLER/func3.c index 827688e..9f15dc3 100644 --- a/PROJECTS/ROLLER/func3.c +++ b/PROJECTS/ROLLER/func3.c @@ -6196,11 +6196,193 @@ typedef struct static tSelectMessagesState s_SelectMessages; +enum { + SELECT_MESSAGES_MOUSE_EXIT = 3, + SELECT_MESSAGES_MOUSE_PLAYER_BASE = 100, + SELECT_MESSAGES_MOUSE_CONFIRM = 200 +}; + int select_messages_active(void) { return s_SelectMessages.iActive; } +static void select_messages_update_message_length(void) +{ + s_SelectMessages.iMessageLength = 0; + while (send_buffer[s_SelectMessages.iMessageLength]) + ++s_SelectMessages.iMessageLength; +} + +static void select_messages_send_current(void) +{ + s_SelectMessages.iSendConfirmation = -1; + send_message_to = s_SelectMessages.iSelectedPlayer; + + for (int i = 0; i < 32; ++i) + send_mes_buf[i] = send_buffer[i]; + + s_SelectMessages.uiCurrentMenu = 0; +} + +static int select_messages_left_item_from_mouse_id(int iId) +{ + if (iId < 0 || iId > SELECT_MESSAGES_MOUSE_EXIT) + return -1; + + return iId; +} + +static int select_messages_player_from_mouse_id(int iId) +{ + int iPlayer = iId - SELECT_MESSAGES_MOUSE_PLAYER_BASE; + + if (iPlayer < 0 || iPlayer >= network_on) + return -1; + + return iPlayer; +} + +static void select_messages_register_left_mouse_items(void) +{ + frontend_mouse_register_left_menu_row(0, sel_posns[0].y); + frontend_mouse_register_left_menu_row(1, sel_posns[2].y); + frontend_mouse_register_left_menu_row(2, sel_posns[4].y); + frontend_mouse_register_left_menu_row(SELECT_MESSAGES_MOUSE_EXIT, + sel_posns[11].y); +} + +static void select_messages_register_player_mouse_items(void) +{ + frontend_mouse_register_rect(SELECT_MESSAGES_MOUSE_PLAYER_BASE, + 200, 94, 440, 18); + + for (int iPlayer = 1; iPlayer < network_on; ++iPlayer) { + frontend_mouse_register_rect( + SELECT_MESSAGES_MOUSE_PLAYER_BASE + iPlayer, + 200, 112 + (iPlayer - 1) * 18, 440, 18); + } +} + +static void select_messages_register_mouse_items(unsigned int uiMenu) +{ + frontend_mouse_begin_frame(640, 400); + select_messages_register_left_mouse_items(); + + if (uiMenu == 1) + select_messages_register_player_mouse_items(); + else if (uiMenu == 3 && !s_SelectMessages.iSendConfirmation) + frontend_mouse_register_scaled_text( + SELECT_MESSAGES_MOUSE_CONFIRM, front_vga[15], + &language_buffer[7552], font2_ascii, font2_offsets, 400, 150, + 1u, 200, 640); +} + +static void select_messages_apply_mouse_hover(unsigned int uiMenu) +{ + int iHovered = frontend_mouse_take_hovered_id(); + + if (!uiMenu) { + int iMenuItem = select_messages_left_item_from_mouse_id(iHovered); + + if (iMenuItem >= 0) + s_SelectMessages.iMenuSelection = iMenuItem; + return; + } + + if (uiMenu == 1) { + int iPlayer = select_messages_player_from_mouse_id(iHovered); + + if (iPlayer >= 0) + s_SelectMessages.iMenuSelection = iPlayer; + } +} + +static void select_messages_activate_left_item(int iMenuItem) +{ + switch (iMenuItem) { + case 0: + s_SelectMessages.uiCurrentMenu = 1; + s_SelectMessages.iMenuSelection = s_SelectMessages.iSelectedPlayer; + break; + case 1: + s_SelectMessages.uiCurrentMenu = 2; + select_messages_update_message_length(); + break; + case 2: + select_messages_send_current(); + break; + case SELECT_MESSAGES_MOUSE_EXIT: + s_SelectMessages.iExitFlag = -1; + break; + default: + break; + } +} + +static void select_messages_activate_current_mouse_target(void) +{ + switch (s_SelectMessages.uiCurrentMenu) { + case 0: + select_messages_activate_left_item(s_SelectMessages.iMenuSelection); + break; + case 1: + if (s_SelectMessages.iMenuSelection >= 0 && + s_SelectMessages.iMenuSelection < network_on) { + s_SelectMessages.uiCurrentMenu = 0; + s_SelectMessages.iSelectedPlayer = s_SelectMessages.iMenuSelection; + s_SelectMessages.iMenuSelection = 0; + } + break; + case 2: + s_SelectMessages.uiCurrentMenu = 0; + s_SelectMessages.iMenuSelection = 2; + break; + case 3: + if (!s_SelectMessages.iSendConfirmation) { + s_SelectMessages.uiCurrentMenu = 0; + s_SelectMessages.iMenuSelection = 2; + } + break; + default: + break; + } +} + +static void select_messages_handle_mouse_click(void) +{ + int iClicked = frontend_mouse_peek_clicked_id(); + int iMenuItem; + int iPlayer; + + frontend_mouse_take_wheel_y(); + if (!frontend_mouse_consume_click_anywhere()) + return; + + iMenuItem = select_messages_left_item_from_mouse_id(iClicked); + if (iMenuItem >= 0) { + select_messages_activate_left_item(iMenuItem); + return; + } + + iPlayer = select_messages_player_from_mouse_id(iClicked); + if (iPlayer >= 0 && s_SelectMessages.uiCurrentMenu == 1) { + s_SelectMessages.uiCurrentMenu = 0; + s_SelectMessages.iSelectedPlayer = iPlayer; + s_SelectMessages.iMenuSelection = 0; + return; + } + + if (iClicked == SELECT_MESSAGES_MOUSE_CONFIRM && + s_SelectMessages.uiCurrentMenu == 3 && + !s_SelectMessages.iSendConfirmation) { + select_messages_send_current(); + return; + } + + select_messages_activate_current_mouse_target(); +} + //0005E300 void select_messages() { @@ -6249,6 +6431,9 @@ void select_messages() if (iSelectedPlayer < 0 || iSelectedPlayer >= network_on) iSelectedPlayer = 0; + select_messages_register_mouse_items(uiCurrentMenu); + select_messages_apply_mouse_hover(uiCurrentMenu); + // Setup screen buffer and copy VGA frame buffer pScreenBuffer = scrbuf; pBlockHeader = front_vga[0]; @@ -6369,6 +6554,7 @@ void select_messages() UPDATE_DISPLAY: show_received_mesage(); // UPDATE_DISPLAY: Show received messages and copy screen buffer copypic(scrbuf, screen); + select_messages_handle_mouse_click(); while (1) { // Main input processing loop if (!fatkbhit()) {