From 2e1a80c9cadbc715391186f3343e3e222bdd909b Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 16 May 2023 22:21:09 +0100 Subject: [PATCH 01/21] M_DrawPause: Show Round number/event sigil when roundqueue/GP is in action --- src/k_menudraw.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index ecb85d279..5a5aa5024 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -4081,7 +4081,7 @@ void M_DrawPause(void) V_DrawCenteredLSTitleLowString(220 + offset*2, 103, 0, word2); } - if (gamestate != GS_INTERMISSION) + if (gamestate != GS_INTERMISSION && roundqueue.size > 0) { y_data_t standings; memset(&standings, 0, sizeof (standings)); @@ -4105,7 +4105,57 @@ void M_DrawPause(void) standings.showrank = true; } - // Returns early if there's no roundqueue entries to draw + patch_t *smallroundpatch = NULL; + + if (grandprixinfo.gp == true && grandprixinfo.eventmode != GPEVENT_NONE) + { + const char *append = NULL; + + switch (grandprixinfo.eventmode) + { + case GPEVENT_SPECIAL: + { + append = "SS"; + break; + } + + case GPEVENT_BONUS: + { + append = "B"; + break; + } + + default: + break; + } + + if (append) + { + smallroundpatch = + W_CachePatchName( + va("TT_RNS%s", append), + PU_PATCH + ); + } + } + else if (roundqueue.roundnum > 0 && roundqueue.roundnum <= 10) + { + smallroundpatch = + W_CachePatchName( + va("TT_RNS%d", roundqueue.roundnum), + PU_PATCH + ); + } + + if (smallroundpatch != NULL) + { + V_DrawMappedPatch( + 24, 152, + 0, + smallroundpatch, + NULL); + } + Y_RoundQueueDrawer(&standings, false, false); } } From eb167a77dda222110aedbeb408dc6fd2dd81bcbb Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 16 May 2023 22:30:54 +0100 Subject: [PATCH 02/21] Challenges menu: Change track to "Lost in Recollection", away from "Always Read the Manual" --- src/menus/extras-challenges.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menus/extras-challenges.c b/src/menus/extras-challenges.c index 93c0f3ffe..c7d6674e1 100644 --- a/src/menus/extras-challenges.c +++ b/src/menus/extras-challenges.c @@ -21,7 +21,7 @@ menu_t MISC_ChallengesDef = { BASEVIDWIDTH/2, 30, 0, 0, 0, - "EXTRAS", + "UNLOCK", 98, 0, M_DrawChallenges, M_ChallengesTick, From 569ec11624d283b311ee859734b08b0126899bbf Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 17 May 2023 15:40:08 +0100 Subject: [PATCH 03/21] Y_PlayerStandingsDrawer: Show the points increase(/decrease) Shows in the same position as ping. Also, pushes the results slightly closer together horizontally if ping/increase is visible. --- src/y_inter.c | 57 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index f35dc9419..70ae5e7fb 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -436,7 +436,7 @@ void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 xoffset) INT32 heightcount = (standings->numplayers - 1); INT32 x, y; - INT32 x2, returny; + INT32 x2, returny, inwardshim = 0; boolean verticalresults = (standings->numplayers < 4); boolean datarightofcolumn = false; @@ -446,23 +446,29 @@ void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 xoffset) patch_t *resbar = W_CachePatchName("R_RESBAR", PU_PATCH); // Results bars for players + if (drawping || data.rankingsmode != 0) + { + inwardshim = 8; + } + if (verticalresults) { x = (BASEVIDWIDTH/2) - 61; - - if (drawping) - { - x += 9; - } } else { x = 29; + inwardshim /= 2; heightcount /= 2; } - x += xoffset; - x2 = x - 9; + x += xoffset + inwardshim; + x2 = x; + + if (drawping) + { + x2 -= 9; + } if (standings->numplayers > 10) { @@ -595,6 +601,39 @@ void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 xoffset) ); } } + else if (data.rankingsmode != 0) + { + char *increasenum = NULL; + + if (data.increase[pnum] != INT16_MIN) + { + increasenum = va( + "(%d)", + data.increase[pnum] + ); + } + + if (increasenum) + { + if (datarightofcolumn) + { + V_DrawThinString( + x2, y-2, + V_ALLOWLOWERCASE|V_6WIDTHSPACE, + increasenum + ); + } + else + { + V_DrawRightAlignedThinString( + x2, y-2, + V_ALLOWLOWERCASE|V_6WIDTHSPACE, + increasenum + ); + } + } + + } // Reverse the jitter offset if (standings->jitter[pnum] > 0) @@ -605,7 +644,7 @@ void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 xoffset) if (verticalresults == false && i == (standings->numplayers-1)/2) { - x = 169 + xoffset; + x = 169 + xoffset - inwardshim; y = returny; datarightofcolumn = true; From 16649d07547a68f52d2f8a917bc0c786e8ca7495 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 May 2023 12:25:45 +0100 Subject: [PATCH 04/21] M_ChangeStringCvar: Support for Cut, Copy, and Paste - Ctrl codes - ctrl-c, ctrl ins (copy) - ctrl-x (cut) - ctrl-v (paste) - Shift codes - shift-ins (paste) - shift-del (cut) --- src/menus/transient/virtual-keyboard.c | 120 +++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 9 deletions(-) diff --git a/src/menus/transient/virtual-keyboard.c b/src/menus/transient/virtual-keyboard.c index 3211538a3..b5d2bee0c 100644 --- a/src/menus/transient/virtual-keyboard.c +++ b/src/menus/transient/virtual-keyboard.c @@ -4,6 +4,7 @@ #include "../../k_menu.h" #include "../../s_sound.h" #include "../../hu_stuff.h" // shiftxform +#include "../../i_system.h" // I_Clipboard funcs // Typing "sub"-menu struct menutyping_s menutyping; @@ -27,32 +28,128 @@ INT16 shift_virtualKeyboard[5][13] = { {KEY_SPACE, KEY_RSHIFT, KEY_BACKSPACE, KEY_CAPSLOCK, KEY_ENTER, 0, 0, 0, 0, 0, 0, 0, 0} }; +typedef enum +{ + CVCPM_NONE, + CVCPM_COPY, + CVCPM_CUT, + CVCPM_PASTE +} cvarcopypastemode_t; + boolean M_ChangeStringCvar(INT32 choice) { consvar_t *cv = currentMenu->menuitems[itemOn].itemaction.cvar; char buf[MAXSTRINGLENGTH]; size_t len; + cvarcopypastemode_t copypastemode = CVCPM_NONE; - if (shiftdown && choice >= 32 && choice <= 127) - choice = shiftxform[choice]; + if (menutyping.keyboardtyping == true) + { + // We can only use global modifiers in key mode. + + if (ctrldown) + { + if (choice == 'c' || choice == 'C' || choice == KEY_INS) + { + // ctrl+c, ctrl+insert, copying + copypastemode = CVCPM_COPY; + } + else if (choice == 'x' || choice == 'X') + { + // ctrl+x, cutting + copypastemode = CVCPM_CUT; + } + else if (choice == 'v' || choice == 'V') + { + // ctrl+v, pasting + copypastemode = CVCPM_PASTE; + } + else + { + // not a known ctrl code + return false; + } + } + else if (shiftdown) + { + if (choice == KEY_INS) + { + // shift+insert, pasting + copypastemode = CVCPM_PASTE; + } + else if (choice == KEY_DEL) + { + // shift+delete, cutting + copypastemode = CVCPM_CUT; + } + else if (choice >= 32 && choice <= 127) + { + // shift+printable, generally uppercase + choice = shiftxform[choice]; + } + } + + if (copypastemode != CVCPM_NONE) + { + len = strlen(cv->string); + + if (copypastemode == CVCPM_PASTE) + { + const char *paste = I_ClipboardPaste(); + if (paste == NULL || paste[0] == '\0') + ; + else if (len < MAXSTRINGLENGTH - 1) + { + M_Memcpy(buf, cv->string, len); + buf[len] = 0; + + strncat(buf, paste, (MAXSTRINGLENGTH - 1) - len); + + CV_Set(cv, buf); + + S_StartSound(NULL, sfx_s3k5b); // Tails + } + } + else if (len > 0 /*&& (copypastemode == CVCPM_COPY + || copypastemode == CVCPM_CUT)*/ + ) + { + I_ClipboardCopy(cv->string, len); + + if (copypastemode == CVCPM_CUT) + { + // A cut should wipe. + CV_Set(cv, ""); + } + + S_StartSound(NULL, sfx_s3k5b); // Tails + } + + return true; + } + } switch (choice) { case KEY_BACKSPACE: - len = strlen(cv->string); - if (len > 0) + if (cv->string[0]) { - S_StartSound(NULL, sfx_s3k5b); // Tails + len = strlen(cv->string); + M_Memcpy(buf, cv->string, len); buf[len-1] = 0; + CV_Set(cv, buf); + + S_StartSound(NULL, sfx_s3k5b); // Tails } return true; case KEY_DEL: if (cv->string[0]) { - S_StartSound(NULL, sfx_s3k5b); // Tails CV_Set(cv, ""); + + S_StartSound(NULL, sfx_s3k5b); // Tails } return true; default: @@ -61,11 +158,14 @@ boolean M_ChangeStringCvar(INT32 choice) len = strlen(cv->string); if (len < MAXSTRINGLENGTH - 1) { - S_StartSound(NULL, sfx_s3k5b); // Tails M_Memcpy(buf, cv->string, len); + buf[len++] = (char)choice; buf[len] = 0; + CV_Set(cv, buf); + + S_StartSound(NULL, sfx_s3k5b); // Tails } return true; } @@ -85,8 +185,10 @@ static void M_UpdateKeyboardX(void) static boolean M_IsTypingKey(INT32 key) { - return key == KEY_BACKSPACE || key == KEY_ENTER || - key == KEY_ESCAPE || key == KEY_DEL || isprint(key); + return key == KEY_BACKSPACE || key == KEY_ENTER + || key == KEY_ESCAPE || key == KEY_DEL + || key == KEY_LCTRL || key == KEY_RCTRL + || isprint(key); } void M_MenuTypingInput(INT32 key) From 03a7f33c55753d6969a941dc0fae2ca4786a843f Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 May 2023 12:51:40 +0100 Subject: [PATCH 05/21] M_DrawMenuTyping: Slightly more consistent spacing for single-char virtual keys The entire virtual keyboard needs a visual redesign, but this will make navigating it slightly easier for now. --- src/k_menudraw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 5a5aa5024..d9b7fc87a 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -425,7 +425,7 @@ static void M_DrawMenuTyping(void) V_DrawString(x, y, V_ALLOWLOWERCASE|tflag|mflag, buf); - x += V_StringWidth(buf, 0)+8; + x += (buf[1] ? V_StringWidth(buf, 0) : 8) + 8; } x = 60; y += 12; From 23378048e3f26d387b79776ad8c27818ddfb19da Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 May 2023 12:52:31 +0100 Subject: [PATCH 06/21] k_menudraw.c: For all IT_CV_STRING handling, use a selection arrow instead of a flashing underscore Makes it clear that you can't type directly into the field, but must select it first. --- src/k_menudraw.c | 67 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index d9b7fc87a..fffa43cb9 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -680,12 +680,20 @@ void M_DrawGenericMenu(void) break; #endif case IT_CV_STRING: - M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1); - V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); - if (skullAnimCounter < 4 && i == itemOn) - V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12, - '_' | 0x80, false); - y += 16; + { + M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1); + + INT32 xoffs = 0; + if (itemOn == i) + { + xoffs += 8; + V_DrawString(x + (skullAnimCounter/5) + 6, y + 12, highlightflags, "\x1D"); + } + + V_DrawString(x + xoffs + 8, y + 12, V_ALLOWLOWERCASE, cv->string); + + y += 16; + } break; default: w = V_StringWidth(cv->string, 0); @@ -2727,9 +2735,16 @@ void M_DrawMPHost(void) switch (currentMenu->menuitems[i].status & IT_CVARTYPE) { case IT_CV_STRING: - V_DrawThinString(xp + 96, yp, V_ALLOWLOWERCASE|V_6WIDTHSPACE, cv->string); - if (skullAnimCounter < 4 && i == itemOn) - V_DrawString(xp + 96 + V_ThinStringWidth(cv->string, V_ALLOWLOWERCASE|V_6WIDTHSPACE), yp+1, 0, "_"); + { + INT32 xoffs = 0; + if (itemOn == i) + { + xoffs += 8; + V_DrawString(xp + (skullAnimCounter/5) + 94, yp+1, highlightflags, "\x1D"); + } + + V_DrawThinString(xp + xoffs + 96, yp, V_ALLOWLOWERCASE|V_6WIDTHSPACE, cv->string); + } break; @@ -2837,9 +2852,17 @@ void M_DrawMPJoinIP(void) colormapc = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE); V_DrawFixedPatch((xp + 12)<string); - if (skullAnimCounter < 4 && i == itemOn) - V_DrawString(xp + 18 + V_ThinStringWidth(cv->string, V_ALLOWLOWERCASE|V_6WIDTHSPACE), yp+1, 0, "_"); + + { + INT32 xoffs = 0; + if (itemOn == i) + { + xoffs += 8; + V_DrawString(xp + (skullAnimCounter/5) + 17, yp+1, highlightflags, "\x1D"); + } + + V_DrawThinString(xp + xoffs + 18, yp, V_ALLOWLOWERCASE|V_6WIDTHSPACE, cv->string); + } /*// On this specific menu the only time we'll ever see this is for the connect by IP typefield. // Draw the small GO button here (and the text which is a separate graphic) @@ -3167,12 +3190,20 @@ void M_DrawGenericOptions(void) case IT_CV_INVISSLIDER: // monitor toggles use this break; case IT_CV_STRING: - M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1); - V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); - if (skullAnimCounter < 4 && i == itemOn) - V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12, - '_' | 0x80, false); - y += 16; + { + M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1); + + INT32 xoffs = 0; + if (itemOn == i) + { + xoffs += 8; + V_DrawString(x + (skullAnimCounter/5) + 6, y + 12, highlightflags, "\x1D"); + } + + V_DrawString(x + xoffs + 8, y + 12, V_ALLOWLOWERCASE, cv->string); + + y += 16; + } break; default: w = V_StringWidth(cv->string, 0); From 276bbebc6ff01f5e313d8e5d83b4e0f119bb6975 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 May 2023 17:33:08 +0100 Subject: [PATCH 07/21] Use 6widthspace for Virtual Keyboard bottom-of-screen message --- src/k_menudraw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index fffa43cb9..d3f74251a 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -380,9 +380,9 @@ static void M_DrawMenuTyping(void) // Some contextual stuff if (menutyping.keyboardtyping) - V_DrawThinString(10, 175, V_ALLOWLOWERCASE|tflag|V_GRAYMAP, "Type using your keyboard. Press Enter to confirm & exit.\nUse your controller or any directional input to use the Virtual Keyboard.\n"); + V_DrawThinString(10, 175, V_ALLOWLOWERCASE|V_6WIDTHSPACE|tflag|V_GRAYMAP, "Type using your keyboard. Press Enter to confirm & exit.\nUse your controller or any directional input to use the Virtual Keyboard.\n"); else - V_DrawThinString(10, 175, V_ALLOWLOWERCASE|tflag|V_GRAYMAP, "Type using the Virtual Keyboard. Use the \'OK\' button to confirm & exit.\nPress any keyboard key not bound to a control to use it."); + V_DrawThinString(10, 175, V_ALLOWLOWERCASE|V_6WIDTHSPACE|tflag|V_GRAYMAP, "Type using the Virtual Keyboard. Use the \'OK\' button to confirm & exit.\nPress any keyboard key not bound to a control to use it."); // Now the keyboard itself From 0845cf077558d69c8a866c888f25e475ba9e54c9 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 May 2023 17:38:33 +0100 Subject: [PATCH 08/21] M_ChangeStringVar: Fix Caps Lock by using CON_ShiftChar directly --- src/menus/transient/virtual-keyboard.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/menus/transient/virtual-keyboard.c b/src/menus/transient/virtual-keyboard.c index b5d2bee0c..a9183e67d 100644 --- a/src/menus/transient/virtual-keyboard.c +++ b/src/menus/transient/virtual-keyboard.c @@ -3,7 +3,7 @@ #include "../../k_menu.h" #include "../../s_sound.h" -#include "../../hu_stuff.h" // shiftxform +#include "../../console.h" // CON_ShiftChar #include "../../i_system.h" // I_Clipboard funcs // Typing "sub"-menu @@ -82,11 +82,6 @@ boolean M_ChangeStringCvar(INT32 choice) // shift+delete, cutting copypastemode = CVCPM_CUT; } - else if (choice >= 32 && choice <= 127) - { - // shift+printable, generally uppercase - choice = shiftxform[choice]; - } } if (copypastemode != CVCPM_NONE) @@ -127,6 +122,9 @@ boolean M_ChangeStringCvar(INT32 choice) return true; } + + // Okay, now we can auto-modify the character. + choice = CON_ShiftChar(choice); } switch (choice) From 8e4e2eb0a9bd3666e4154ad0a9cb87905be8159f Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 May 2023 17:42:16 +0100 Subject: [PATCH 09/21] CON_Responder: *also* use CON_ShiftChar directly rather than have two different implementations that could desync --- src/console.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/console.c b/src/console.c index 6571b9f2a..dbfbf5c31 100644 --- a/src/console.c +++ b/src/console.c @@ -1309,17 +1309,7 @@ boolean CON_Responder(event_t *ev) else if (key == KEY_KPADSLASH) key = '/'; - // same capslock code as hu_stuff.c's HU_responder. Check there for details. - if ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z')) - { - if (shiftdown ^ capslock) - key = shiftxform[key]; - } - else - { - if (shiftdown) - key = shiftxform[key]; - } + key = CON_ShiftChar(key); // enter a char into the command prompt if (key < 32 || key > 127) From c8f350aa70e8b2196e1094d91492c424ac3ad574 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 May 2023 17:48:42 +0100 Subject: [PATCH 10/21] CON_ShiftChar: Integrate numpad translation from CON_Responder, so both chat and menu input can take advantage The original written comment by Callum remarks that it was good for writing IP addresses, and this makes it apply to the IP address Online Menu field... Also adds better comments. --- src/console.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/console.c b/src/console.c index dbfbf5c31..42b2e85b4 100644 --- a/src/console.c +++ b/src/console.c @@ -648,11 +648,31 @@ INT32 CON_ShiftChar(INT32 ch) { if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { + // Standard Latin-script uppercase translation if (shiftdown ^ capslock) ch = shiftxform[ch]; } - else // if we're holding shift we should still shift non letter symbols + else if (ch >= KEY_KEYPAD7 && ch <= KEY_KPADDEL) { + // Numpad keycodes mapped to printable equivalent + const char keypad_translation[] = + { + '7','8','9','-', + '4','5','6','+', + '1','2','3', + '0','.' + }; + + ch = keypad_translation[ch - KEY_KEYPAD7]; + } + else if (ch == KEY_KPADSLASH) + { + // Ditto, but non-contiguous keycode + ch = '/'; + } + else + { + // QWERTY keycode translation if (shiftdown) ch = shiftxform[ch]; } @@ -1296,19 +1316,6 @@ boolean CON_Responder(event_t *ev) return true; } - // allow people to use keypad in console (good for typing IP addresses) - Calum - if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL) - { - char keypad_translation[] = {'7','8','9','-', - '4','5','6','+', - '1','2','3', - '0','.'}; - - key = keypad_translation[key - KEY_KEYPAD7]; - } - else if (key == KEY_KPADSLASH) - key = '/'; - key = CON_ShiftChar(key); // enter a char into the command prompt From af334f927f8e95d4a0ca5fa1e91ce705d227e894 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 May 2023 21:21:48 +0100 Subject: [PATCH 11/21] Cleanup of the Virtual Keyboard - Variable width key support - Rearrangement of keys to take advantage of this - Uses thin strings - Or arrow sigils for backspace/shift - Shift and caps lock have been visually combined to match other virtual keyboards - Press shift once to enable shift, press again to disable shift and enable caps lock - Indicator light on shift to show capslock state --- src/k_menu.h | 5 +- src/k_menudraw.c | 123 ++++++++++++++++++++----- src/menus/transient/virtual-keyboard.c | 120 +++++++++++++++--------- 3 files changed, 180 insertions(+), 68 deletions(-) diff --git a/src/k_menu.h b/src/k_menu.h index 8eaf787a8..24ba4372e 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -487,8 +487,9 @@ extern INT16 skullAnimCounter; // skull animation counter extern INT32 menuKey; // keyboard key pressed for menu -extern INT16 virtualKeyboard[5][13]; -extern INT16 shift_virtualKeyboard[5][13]; +#define NUMVIRTUALKEYSINROW (10+2) // 1-9, 0, and a right-side gutter of two keys' width +extern INT16 virtualKeyboard[5][NUMVIRTUALKEYSINROW]; +extern INT16 shift_virtualKeyboard[5][NUMVIRTUALKEYSINROW]; extern struct menutyping_s { diff --git a/src/k_menudraw.c b/src/k_menudraw.c index d3f74251a..0f9307f4e 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -363,7 +363,7 @@ static void M_DrawMenuTyping(void) INT32 i, j; - INT32 x = 60; + INT32 x; INT32 y = 100 + (9-menutyping.menutypingfade)*8; INT32 tflag = (9 - menutyping.menutypingfade)<string); + V_DrawString(60, y-48 + 12, V_ALLOWLOWERCASE|tflag, cv->string); if (skullAnimCounter < 4) - V_DrawCharacter(x + V_StringWidth(cv->string, 0), y - 35, '_' | 0x80, false); + V_DrawCharacter(60 + V_StringWidth(cv->string, 0), y - 35, '_' | 0x80, false); // Some contextual stuff if (menutyping.keyboardtyping) @@ -384,52 +384,133 @@ static void M_DrawMenuTyping(void) else V_DrawThinString(10, 175, V_ALLOWLOWERCASE|V_6WIDTHSPACE|tflag|V_GRAYMAP, "Type using the Virtual Keyboard. Use the \'OK\' button to confirm & exit.\nPress any keyboard key not bound to a control to use it."); +#define BUTTONWIDTH (14) +#define BUTTONHEIGHT (11) // Now the keyboard itself + INT32 returnx = (BASEVIDWIDTH - (((BUTTONWIDTH + 1)*NUMVIRTUALKEYSINROW)-1))/2; + INT32 tempkeyboardx = menutyping.keyboardx; + + while (virtualKeyboard[menutyping.keyboardy][tempkeyboardx] == 1 + && tempkeyboardx > 0) + tempkeyboardx--; + + x = returnx; + for (i=0; i < 5; i++) { - for (j=0; j < 13; j++) + j = 0; + while (j < NUMVIRTUALKEYSINROW) { - INT32 mflag = 0; + INT32 mflag = V_ALLOWLOWERCASE|V_6WIDTHSPACE; INT16 c = virtualKeyboard[i][j]; + + INT32 buttonspacing = 1; + + UINT8 col = 27; + + INT32 arrowoffset = 0; + + while (j + buttonspacing < NUMVIRTUALKEYSINROW + && virtualKeyboard[i][j + buttonspacing] == 1) + { + buttonspacing++; + } + if (menutyping.keyboardshift ^ menutyping.keyboardcapslock) c = shift_virtualKeyboard[i][j]; + if (i < 4 && j < NUMVIRTUALKEYSINROW-2) + { + col = 25; + } if (c == KEY_BACKSPACE) - strcpy(buf, "DEL"); - + { + arrowoffset = 1; + buf[0] = '\x1C'; // left arrow + buf[1] = '\0'; + } else if (c == KEY_RSHIFT) - strcpy(buf, "SHIFT"); - - else if (c == KEY_CAPSLOCK) - strcpy(buf, "CAPS"); + { + arrowoffset = 2; + buf[0] = '\x1A'; // up arrow + buf[1] = '\0'; + if (menutyping.keyboardcapslock || menutyping.keyboardshift) + { + col = 22; + } + } else if (c == KEY_ENTER) + { strcpy(buf, "OK"); - + } else if (c == KEY_SPACE) - strcpy(buf, "SPACE"); - + { + strcpy(buf, "Space"); + } else { buf[0] = c; buf[1] = '\0'; } + INT32 width = ((BUTTONWIDTH + 1) * buttonspacing) - 1; + // highlight: - if (menutyping.keyboardx == j && menutyping.keyboardy == i && !menutyping.keyboardtyping) - mflag |= highlightflags; - else if (menutyping.keyboardtyping) + if (menutyping.keyboardtyping) + { mflag |= V_TRANSLUCENT; // grey it out if we can't use it. + } + else + { + if (tempkeyboardx == j && menutyping.keyboardy == i) + { + V_DrawFill(x + 1, y + 1, width - 2, BUTTONHEIGHT - 2, col - 3); - V_DrawString(x, y, V_ALLOWLOWERCASE|tflag|mflag, buf); + V_DrawFill(x, y, width, 1, 121); + V_DrawFill(x, y + BUTTONHEIGHT - 1, width, 1, 121); - x += (buf[1] ? V_StringWidth(buf, 0) : 8) + 8; + V_DrawFill(x, y + 1, 1, BUTTONHEIGHT - 2, 121); + V_DrawFill(x + width - 1, y + 1, 1, BUTTONHEIGHT - 2, 121); + + mflag |= highlightflags; + } + else + { + V_DrawFill(x, y, width, BUTTONHEIGHT, col); + } + } + + if (arrowoffset != 0) + { + if (c == KEY_RSHIFT) + { + V_DrawFill(x + width - 5, y + 1, 4, 4, 31); + + if (menutyping.keyboardcapslock) + { + V_DrawFill(x + width - 4, y + 2, 2, 2, 121); + } + } + + V_DrawCenteredString(x + (width/2), y + 1 + arrowoffset, tflag|mflag, buf); + } + else + { + V_DrawCenteredThinString(x + (width/2), y + 1, tflag|mflag, buf); + } + + x += width + 1; + j += buttonspacing; } - x = 60; - y += 12; + x = returnx; + y += BUTTONHEIGHT + 1; } + +#undef BUTTONWIDTH + } // Draw the message popup submenu diff --git a/src/menus/transient/virtual-keyboard.c b/src/menus/transient/virtual-keyboard.c index a9183e67d..1eaac8a7b 100644 --- a/src/menus/transient/virtual-keyboard.c +++ b/src/menus/transient/virtual-keyboard.c @@ -10,22 +10,22 @@ struct menutyping_s menutyping; // keyboard layouts -INT16 virtualKeyboard[5][13] = { +INT16 virtualKeyboard[5][NUMVIRTUALKEYSINROW] = { - {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0}, - {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0}, - {'a', 's', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', ';', '\'', '\\'}, - {'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, 0, 0}, - {KEY_SPACE, KEY_RSHIFT, KEY_BACKSPACE, KEY_CAPSLOCK, KEY_ENTER, 0, 0, 0, 0, 0, 0, 0, 0} + {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEY_BACKSPACE, 1}, + {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', '='}, + {'a', 's', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', '[', ']'}, + {'z', 'x', 'c', 'v', 'b', 'n', 'm', 0, ',', '.', ';', '\''}, + {KEY_RSHIFT, 1, 1, KEY_SPACE, 1, 1, 1, 1, '/', '\\', KEY_ENTER, 1} }; -INT16 shift_virtualKeyboard[5][13] = { +INT16 shift_virtualKeyboard[5][NUMVIRTUALKEYSINROW] = { - {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0}, - {'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0}, - {'A', 'S', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', ':', '\"', '|'}, - {'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0, 0, 0}, - {KEY_SPACE, KEY_RSHIFT, KEY_BACKSPACE, KEY_CAPSLOCK, KEY_ENTER, 0, 0, 0, 0, 0, 0, 0, 0} + {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', KEY_BACKSPACE, 1}, + {'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '_', '+'}, + {'A', 'S', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', '{', '}'}, + {'Z', 'X', 'C', 'V', 'B', 'N', 'M', 0, '<', '>', ':', '\"'}, + {KEY_RSHIFT, 1, 1, KEY_SPACE, 1, 1, 1, 1, '?', '|', KEY_ENTER, 1} }; typedef enum @@ -173,14 +173,6 @@ boolean M_ChangeStringCvar(INT32 choice) return false; } -// Updates the x coordinate of the keybord so prevent it from going in weird places -static void M_UpdateKeyboardX(void) -{ - // 0s are only at the rightmost edges of the keyboard table, so just go backwards until we get something. - while (!virtualKeyboard[menutyping.keyboardy][menutyping.keyboardx]) - menutyping.keyboardx--; -} - static boolean M_IsTypingKey(INT32 key) { return key == KEY_BACKSPACE || key == KEY_ENTER @@ -263,7 +255,6 @@ void M_MenuTypingInput(INT32 key) if (menutyping.keyboardy > 4) menutyping.keyboardy = 0; - M_UpdateKeyboardX(); M_SetMenuDelay(pid); S_StartSound(NULL, sfx_s3k5b); } @@ -273,54 +264,93 @@ void M_MenuTypingInput(INT32 key) if (menutyping.keyboardy < 0) menutyping.keyboardy = 4; - M_UpdateKeyboardX(); M_SetMenuDelay(pid); S_StartSound(NULL, sfx_s3k5b); } else if (menucmd[pid].dpad_lr > 0) // right { - menutyping.keyboardx++; - if (!virtualKeyboard[menutyping.keyboardy][menutyping.keyboardx]) - menutyping.keyboardx = 0; + do + { + menutyping.keyboardx++; + if (menutyping.keyboardx > NUMVIRTUALKEYSINROW-1) + { + menutyping.keyboardx = 0; + break; + } + } + while (virtualKeyboard[menutyping.keyboardy][menutyping.keyboardx] == 1); M_SetMenuDelay(pid); S_StartSound(NULL, sfx_s3k5b); } else if (menucmd[pid].dpad_lr < 0) // left { + while (virtualKeyboard[menutyping.keyboardy][menutyping.keyboardx] == 1) + { + menutyping.keyboardx--; + if (menutyping.keyboardx < 0) + { + menutyping.keyboardx = NUMVIRTUALKEYSINROW-1; + break; + } + } + menutyping.keyboardx--; if (menutyping.keyboardx < 0) { - menutyping.keyboardx = 12; - M_UpdateKeyboardX(); + menutyping.keyboardx = NUMVIRTUALKEYSINROW-1; } + M_SetMenuDelay(pid); S_StartSound(NULL, sfx_s3k5b); } else if (M_MenuConfirmPressed(pid)) { // Add the character. First though, check what we're pressing.... - INT16 c = virtualKeyboard[menutyping.keyboardy][menutyping.keyboardx]; - if (menutyping.keyboardshift ^ menutyping.keyboardcapslock) - c = shift_virtualKeyboard[menutyping.keyboardy][menutyping.keyboardx]; + INT32 tempkeyboardx = menutyping.keyboardx; + INT16 c = 0; + while ((c = virtualKeyboard[menutyping.keyboardy][tempkeyboardx]) == 1 + && tempkeyboardx > 0) + tempkeyboardx--; - if (c == KEY_RSHIFT) - menutyping.keyboardshift = !menutyping.keyboardshift; - else if (c == KEY_CAPSLOCK) - menutyping.keyboardcapslock = !menutyping.keyboardcapslock; - else if (c == KEY_ENTER) + if (c > 1) { - menutyping.menutypingclose = true; // close menu. - return; - } - else - { - M_ChangeStringCvar((INT32)c); // Write! - menutyping.keyboardshift = false; // undo shift if it had been pressed - } + if (menutyping.keyboardshift ^ menutyping.keyboardcapslock) + c = shift_virtualKeyboard[menutyping.keyboardy][tempkeyboardx]; - M_SetMenuDelay(pid); - S_StartSound(NULL, sfx_s3k5b); + if (c == KEY_RSHIFT) + { + if (menutyping.keyboardcapslock == true) + { + menutyping.keyboardcapslock = false; + } + else + { + menutyping.keyboardshift ^= true; + if (menutyping.keyboardshift == false) + { + menutyping.keyboardcapslock = true; + } + } + } + /* + else if (c == KEY_CAPSLOCK) + menutyping.keyboardcapslock = !menutyping.keyboardcapslock; + */ + else if (c == KEY_ENTER) + { + menutyping.menutypingclose = true; // close menu. + return; + } + else + { + M_ChangeStringCvar((INT32)c); // Write! + menutyping.keyboardshift = false; // undo shift if it had been pressed + } + + M_SetMenuDelay(pid); + S_StartSound(NULL, sfx_s3k5b); + } } } } From f7107e2f66598a5a0f724ca98c86317d6bd7b5e8 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 May 2023 21:42:48 +0100 Subject: [PATCH 12/21] Rearranged again All that effort and I didn't notice there was two i's :face_holding_back_tears: --- src/menus/transient/virtual-keyboard.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/menus/transient/virtual-keyboard.c b/src/menus/transient/virtual-keyboard.c index 1eaac8a7b..1a37ba6ab 100644 --- a/src/menus/transient/virtual-keyboard.c +++ b/src/menus/transient/virtual-keyboard.c @@ -12,20 +12,20 @@ struct menutyping_s menutyping; // keyboard layouts INT16 virtualKeyboard[5][NUMVIRTUALKEYSINROW] = { - {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEY_BACKSPACE, 1}, - {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', '='}, - {'a', 's', 'd', 'f', 'g', 'h', 'i', 'j', 'k', 'l', '[', ']'}, - {'z', 'x', 'c', 'v', 'b', 'n', 'm', 0, ',', '.', ';', '\''}, - {KEY_RSHIFT, 1, 1, KEY_SPACE, 1, 1, 1, 1, '/', '\\', KEY_ENTER, 1} + {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', KEY_BACKSPACE, 1}, + {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', '='}, + {'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '/', '[', ']'}, + {'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '\\', ';', '\''}, + {KEY_RSHIFT, 1, 1, KEY_SPACE, 1, 1, 1, 1, KEY_ENTER, 1, 1, 1} }; INT16 shift_virtualKeyboard[5][NUMVIRTUALKEYSINROW] = { {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', KEY_BACKSPACE, 1}, {'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '_', '+'}, - {'A', 'S', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', '{', '}'}, - {'Z', 'X', 'C', 'V', 'B', 'N', 'M', 0, '<', '>', ':', '\"'}, - {KEY_RSHIFT, 1, 1, KEY_SPACE, 1, 1, 1, 1, '?', '|', KEY_ENTER, 1} + {'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '?', '{', '}'}, + {'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '|', ':', '\"'}, + {KEY_RSHIFT, 1, 1, KEY_SPACE, 1, 1, 1, 1, KEY_ENTER, 1, 1, 1} }; typedef enum From ca68fe630b0161d8b1680448774080158fc83493 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 May 2023 22:15:56 +0100 Subject: [PATCH 13/21] Show PAUSED image when the game is stopped by the pause command In addition, don't show the pause menu PAUSED in modeattacking/netgames This text is now snapto-affected, since we can't (or at least shouldn't) summon the widescreen border in regular pause instances. --- src/d_main.c | 19 ------------------- src/k_menudraw.c | 32 +++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 1d07c9298..1b562b238 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -659,25 +659,6 @@ static void D_Display(void) if (forcerefresh && G_GamestateUsesLevel() == false) V_SetPalette(0); - // draw pause pic - if (paused && cv_showhud.value && !demo.playback) - { -#if 0 - INT32 py; - patch_t *patch; - if (automapactive) - py = 4; - else - py = viewwindowy + 4; - patch = W_CachePatchName("M_PAUSE", PU_PATCH); - V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - patch->width)/2, py, 0, patch); -#else - INT32 y = ((automapactive) ? (32) : (BASEVIDHEIGHT/2)); - M_DrawTextBox((BASEVIDWIDTH/2) - (60), y - (16), 13, 2); - V_DrawCenteredString(BASEVIDWIDTH/2, y - (4), V_YELLOWMAP, "Game Paused"); -#endif - } - if (demo.rewinding) V_DrawFadeScreen(TC_RAINBOW, (leveltime & 0x20) ? SKINCOLOR_PASTEL : SKINCOLOR_MOONSET); diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 0f9307f4e..0762ad88e 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -578,6 +578,16 @@ void M_DrawMenuMessage(void) } } +// PAUSE +static void M_DrawPausedText(INT32 x) +{ + patch_t *pausebg = W_CachePatchName("M_STRIPU", PU_CACHE); + patch_t *pausetext = W_CachePatchName("M_PAUSET", PU_CACHE); + + V_DrawFixedPatch(x, 0, FRACUNIT, V_SNAPTOLEFT|V_SNAPTOTOP|V_ADD, pausebg, NULL); + V_DrawFixedPatch(x, 0, FRACUNIT, V_SNAPTOLEFT|V_SNAPTOTOP, pausetext, NULL); +} + // // M_Drawer // Called after the view has been rendered, @@ -637,14 +647,17 @@ void M_Drawer(void) menuwipe = false; } + // draw pause pic + if (paused && !demo.playback && (menuactive || cv_showhud.value)) + { + M_DrawPausedText(0); + } + // focus lost notification goes on top of everything, even the former everything if (window_notinfocus && cv_showfocuslost.value) { M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2); - if (gamestate == GS_LEVEL && (P_AutoPause() || paused)) - V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), highlightflags, "Game Paused"); - else - V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), highlightflags, "Focus Lost"); + V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), highlightflags, "Focus Lost"); } } @@ -4024,8 +4037,6 @@ void M_DrawExtras(void) // INGAME / PAUSE MENUS // -// PAUSE - // PAUSE MAIN MENU void M_DrawPause(void) { @@ -4046,18 +4057,17 @@ void M_DrawPause(void) INT16 word2len = 0; boolean sok = false; - patch_t *pausebg = W_CachePatchName("M_STRIPU", PU_CACHE); patch_t *vertbg = W_CachePatchName("M_STRIPV", PU_CACHE); - patch_t *pausetext = W_CachePatchName("M_PAUSET", PU_CACHE); - patch_t *arrstart = W_CachePatchName("M_PTIP", PU_CACHE); patch_t *arrfill = W_CachePatchName("M_PFILL", PU_CACHE); //V_DrawFadeScreen(0xFF00, 16); // "PAUSED" - V_DrawFixedPatch(-offset*FRACUNIT, 0, FRACUNIT, V_ADD, pausebg, NULL); - V_DrawFixedPatch(-offset*FRACUNIT, 0, FRACUNIT, 0, pausetext, NULL); + if (!paused && !demo.playback && !modeattacking && !netgame) // as close to possible as P_AutoPause, but not dependent on menuactive + { + M_DrawPausedText(-offset*FRACUNIT); + } // Vertical Strip: V_DrawFixedPatch((230 + offset)< Date: Fri, 19 May 2023 23:10:13 +0100 Subject: [PATCH 14/21] Profile selection music - `_OCEAN` on first launch without profile set, to avoid skipping between three different tracks in quick succession - 'FILE' if you create a new profile on first launch OR if you go into Options->Profiles --- src/k_menufunc.c | 7 +++++-- src/menus/main-profile-select.c | 2 +- src/menus/options-profiles-1.c | 2 +- src/menus/options-profiles-edit-1.c | 2 +- src/menus/options-profiles-edit-controls.c | 2 +- src/menus/play-char-select.c | 1 + 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/k_menufunc.c b/src/k_menufunc.c index e467ba3b4..bc8f99f06 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -564,6 +564,9 @@ void M_StartControlPanel(void) currentMenu->lastOn = 0; CV_StealthSetValue(&cv_currprofile, -1); // Make sure to reset that as it is set by PR_ApplyProfile which we kind of hack together to force it. + + // Ambient ocean sounds + S_ChangeMusicInternal("_OCEAN", true); } else { @@ -571,9 +574,9 @@ void M_StartControlPanel(void) restoreMenu = &MainDef; currentMenu = M_SpecificMenuRestore(M_InterruptMenuWithChallenges(restoreMenu)); restoreMenu = NULL; - } - M_PlayMenuJam(); + M_PlayMenuJam(); + } } else { diff --git a/src/menus/main-profile-select.c b/src/menus/main-profile-select.c index 13b840f9a..eb0fdee53 100644 --- a/src/menus/main-profile-select.c +++ b/src/menus/main-profile-select.c @@ -16,7 +16,7 @@ menu_t MAIN_ProfilesDef = { 32, 80, SKINCOLOR_ULTRAMARINE, 0, 0, - NULL, + "FILE", 2, 5, M_DrawProfileSelect, M_OptionsTick, diff --git a/src/menus/options-profiles-1.c b/src/menus/options-profiles-1.c index 311788bb1..c43aba4fc 100644 --- a/src/menus/options-profiles-1.c +++ b/src/menus/options-profiles-1.c @@ -18,7 +18,7 @@ menu_t OPTIONS_ProfilesDef = { 32, 80, SKINCOLOR_ULTRAMARINE, 0, 0, - NULL, + "FILE", 2, 5, M_DrawProfileSelect, M_OptionsTick, diff --git a/src/menus/options-profiles-edit-1.c b/src/menus/options-profiles-edit-1.c index b1ed78f98..22375da93 100644 --- a/src/menus/options-profiles-edit-1.c +++ b/src/menus/options-profiles-edit-1.c @@ -30,7 +30,7 @@ menu_t OPTIONS_EditProfileDef = { 32, 80, SKINCOLOR_ULTRAMARINE, 0, 0, - NULL, + "FILE", 2, 5, M_DrawEditProfile, M_HandleProfileEdit, diff --git a/src/menus/options-profiles-edit-controls.c b/src/menus/options-profiles-edit-controls.c index b97b7f5b7..0140a89d4 100644 --- a/src/menus/options-profiles-edit-controls.c +++ b/src/menus/options-profiles-edit-controls.c @@ -109,7 +109,7 @@ menu_t OPTIONS_ProfileControlsDef = { 32, 80, SKINCOLOR_ULTRAMARINE, 0, 0, - NULL, + "FILE", 3, 5, M_DrawProfileControls, M_HandleProfileControls, diff --git a/src/menus/play-char-select.c b/src/menus/play-char-select.c index 35e918a65..c21990ba4 100644 --- a/src/menus/play-char-select.c +++ b/src/menus/play-char-select.c @@ -497,6 +497,7 @@ void M_CharacterSelectInit(void) void M_CharacterSelect(INT32 choice) { (void)choice; + PLAY_CharSelectDef.music = currentMenu->music; PLAY_CharSelectDef.prevMenu = currentMenu; M_SetupNextMenu(&PLAY_CharSelectDef, false); } From 38ddfeeef84d65514010c99a8594ba5c94baba5d Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 20 May 2023 20:43:00 +0100 Subject: [PATCH 15/21] Make virtual keyboard even stronger - Show a textbox (with highlighted border) so the console font is more likely to be legible. - Increases the width of the virtual keys to match this. - Show menu entry name and tooltip on faded view (if they exist), for additional context for what you're writing - Make the text entry and the virtual keys slide seperately --- src/k_menudraw.c | 271 ++++++++++++++----------- src/menus/transient/virtual-keyboard.c | 27 ++- 2 files changed, 171 insertions(+), 127 deletions(-) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 0762ad88e..4669b9753 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -357,159 +357,204 @@ void M_DrawMenuForeground(void) } } +// +// M_DrawMenuTooltips +// +// Draw a banner across the top of the screen, with a description of the current option displayed +// +static void M_DrawMenuTooltips(void) +{ + if (currentMenu->menuitems[itemOn].tooltip != NULL) + { + V_DrawFixedPatch(0, 0, FRACUNIT, 0, W_CachePatchName("MENUHINT", PU_CACHE), NULL); + V_DrawCenteredThinString(BASEVIDWIDTH/2, 12, V_ALLOWLOWERCASE|V_6WIDTHSPACE, currentMenu->menuitems[itemOn].tooltip); + } +} + // Draws the typing submenu static void M_DrawMenuTyping(void) { - INT32 i, j; - INT32 x; - INT32 y = 100 + (9-menutyping.menutypingfade)*8; - INT32 tflag = (9 - menutyping.menutypingfade)<menuitems[itemOn].itemaction.cvar; char buf[8]; // We write there to use drawstring for convenience. - V_DrawFadeScreen(31, menutyping.menutypingfade); + V_DrawFadeScreen(31, (menutyping.menutypingfade+1)/2); // Draw the string we're editing at the top. - V_DrawString(60, y-48 + 12, V_ALLOWLOWERCASE|tflag, cv->string); - if (skullAnimCounter < 4) - V_DrawCharacter(60 + V_StringWidth(cv->string, 0), y - 35, '_' | 0x80, false); - // Some contextual stuff - if (menutyping.keyboardtyping) - V_DrawThinString(10, 175, V_ALLOWLOWERCASE|V_6WIDTHSPACE|tflag|V_GRAYMAP, "Type using your keyboard. Press Enter to confirm & exit.\nUse your controller or any directional input to use the Virtual Keyboard.\n"); + const INT32 boxwidth = (8*(MAXSTRINGLENGTH + 1)) + 7; + x = (BASEVIDWIDTH - boxwidth)/2; + y = 80; + if (menutyping.menutypingfade < 9) + y += (9-menutyping.menutypingfade)*10; else - V_DrawThinString(10, 175, V_ALLOWLOWERCASE|V_6WIDTHSPACE|tflag|V_GRAYMAP, "Type using the Virtual Keyboard. Use the \'OK\' button to confirm & exit.\nPress any keyboard key not bound to a control to use it."); + y += (9-menutyping.menutypingfade); -#define BUTTONWIDTH (14) + if (currentMenu->menuitems[itemOn].text) + { + V_DrawThinString(x + 5, y - 2, highlightflags|V_ALLOWLOWERCASE, currentMenu->menuitems[itemOn].text); + } + + M_DrawMenuTooltips(); + + //M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1); + V_DrawFill(x + 5, y + 4 + 5, boxwidth - 8, 8+6, 159); + + V_DrawFill(x + 4, y + 4 + 4, boxwidth - 6, 1, 121); + V_DrawFill(x + 4, y + 4 + 5 + 8 + 6, boxwidth - 6, 1, 121); + + V_DrawFill(x + 4, y + 4 + 5, 1, 8+6, 121); + V_DrawFill(x + 5 + boxwidth - 8, y + 4 + 5, 1, 8+6, 121); + + V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); + if (skullAnimCounter < 4) + V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12 + 1, '_' | 0x80, false); + + const INT32 buttonwidth = ((boxwidth + 1)/NUMVIRTUALKEYSINROW); #define BUTTONHEIGHT (11) // Now the keyboard itself - INT32 returnx = (BASEVIDWIDTH - (((BUTTONWIDTH + 1)*NUMVIRTUALKEYSINROW)-1))/2; - INT32 tempkeyboardx = menutyping.keyboardx; + x += 5; + INT32 returnx = x; - while (virtualKeyboard[menutyping.keyboardy][tempkeyboardx] == 1 - && tempkeyboardx > 0) - tempkeyboardx--; - - x = returnx; - - for (i=0; i < 5; i++) + if (menutyping.menutypingfade > 9) { - j = 0; - while (j < NUMVIRTUALKEYSINROW) + y += 36 + 80 + (9-menutyping.menutypingfade)*10; // double yoffs for animation + + INT32 tempkeyboardx = menutyping.keyboardx; + + while (virtualKeyboard[menutyping.keyboardy][tempkeyboardx] == 1 + && tempkeyboardx > 0) + tempkeyboardx--; + + for (i = 0; i < 5; i++) { - INT32 mflag = V_ALLOWLOWERCASE|V_6WIDTHSPACE; - INT16 c = virtualKeyboard[i][j]; - - INT32 buttonspacing = 1; - - UINT8 col = 27; - - INT32 arrowoffset = 0; - - while (j + buttonspacing < NUMVIRTUALKEYSINROW - && virtualKeyboard[i][j + buttonspacing] == 1) + j = 0; + while (j < NUMVIRTUALKEYSINROW) { - buttonspacing++; - } + INT32 mflag = V_ALLOWLOWERCASE|V_6WIDTHSPACE; + INT16 c = virtualKeyboard[i][j]; - if (menutyping.keyboardshift ^ menutyping.keyboardcapslock) - c = shift_virtualKeyboard[i][j]; + INT32 buttonspacing = 1; - if (i < 4 && j < NUMVIRTUALKEYSINROW-2) - { - col = 25; - } + UINT8 col = 27; - if (c == KEY_BACKSPACE) - { - arrowoffset = 1; - buf[0] = '\x1C'; // left arrow - buf[1] = '\0'; - } - else if (c == KEY_RSHIFT) - { - arrowoffset = 2; - buf[0] = '\x1A'; // up arrow - buf[1] = '\0'; + INT32 arrowoffset = 0; - if (menutyping.keyboardcapslock || menutyping.keyboardshift) + while (j + buttonspacing < NUMVIRTUALKEYSINROW + && virtualKeyboard[i][j + buttonspacing] == 1) { - col = 22; + buttonspacing++; } - } - else if (c == KEY_ENTER) - { - strcpy(buf, "OK"); - } - else if (c == KEY_SPACE) - { - strcpy(buf, "Space"); - } - else - { - buf[0] = c; - buf[1] = '\0'; - } - INT32 width = ((BUTTONWIDTH + 1) * buttonspacing) - 1; + if (menutyping.keyboardshift ^ menutyping.keyboardcapslock) + c = shift_virtualKeyboard[i][j]; - // highlight: - if (menutyping.keyboardtyping) - { - mflag |= V_TRANSLUCENT; // grey it out if we can't use it. - } - else - { - if (tempkeyboardx == j && menutyping.keyboardy == i) + if (i < 4 && j < NUMVIRTUALKEYSINROW-2) { - V_DrawFill(x + 1, y + 1, width - 2, BUTTONHEIGHT - 2, col - 3); + col = 25; + } - V_DrawFill(x, y, width, 1, 121); - V_DrawFill(x, y + BUTTONHEIGHT - 1, width, 1, 121); + if (c == KEY_BACKSPACE) + { + arrowoffset = 1; + buf[0] = '\x1C'; // left arrow + buf[1] = '\0'; + } + else if (c == KEY_RSHIFT) + { + arrowoffset = 2; + buf[0] = '\x1A'; // up arrow + buf[1] = '\0'; - V_DrawFill(x, y + 1, 1, BUTTONHEIGHT - 2, 121); - V_DrawFill(x + width - 1, y + 1, 1, BUTTONHEIGHT - 2, 121); - - mflag |= highlightflags; + if (menutyping.keyboardcapslock || menutyping.keyboardshift) + { + col = 22; + } + } + else if (c == KEY_ENTER) + { + strcpy(buf, "OK"); + } + else if (c == KEY_SPACE) + { + strcpy(buf, "Space"); } else { - V_DrawFill(x, y, width, BUTTONHEIGHT, col); + buf[0] = c; + buf[1] = '\0'; } - } - if (arrowoffset != 0) - { - if (c == KEY_RSHIFT) + INT32 width = (buttonwidth * buttonspacing) - 1; + + // highlight: + /*if (menutyping.keyboardtyping) { - V_DrawFill(x + width - 5, y + 1, 4, 4, 31); - - if (menutyping.keyboardcapslock) + mflag |= V_TRANSLUCENT; // grey it out if we can't use it. + } + else*/ + { + if (tempkeyboardx == j && menutyping.keyboardy == i) { - V_DrawFill(x + width - 4, y + 2, 2, 2, 121); + V_DrawFill(x + 1, y + 1, width - 2, BUTTONHEIGHT - 2, col - 3); + + V_DrawFill(x, y, width, 1, 121); + V_DrawFill(x, y + BUTTONHEIGHT - 1, width, 1, 121); + + V_DrawFill(x, y + 1, 1, BUTTONHEIGHT - 2, 121); + V_DrawFill(x + width - 1, y + 1, 1, BUTTONHEIGHT - 2, 121); + + mflag |= highlightflags; + } + else + { + V_DrawFill(x, y, width, BUTTONHEIGHT, col); } } - V_DrawCenteredString(x + (width/2), y + 1 + arrowoffset, tflag|mflag, buf); - } - else - { - V_DrawCenteredThinString(x + (width/2), y + 1, tflag|mflag, buf); - } + if (arrowoffset != 0) + { + if (c == KEY_RSHIFT) + { + V_DrawFill(x + width - 5, y + 1, 4, 4, 31); - x += width + 1; - j += buttonspacing; + if (menutyping.keyboardcapslock) + { + V_DrawFill(x + width - 4, y + 2, 2, 2, 121); + } + } + + V_DrawCenteredString(x + (width/2), y + 1 + arrowoffset, mflag, buf); + } + else + { + V_DrawCenteredThinString(x + (width/2), y + 1, mflag, buf); + } + + x += width + 1; + j += buttonspacing; + } + x = returnx; + y += BUTTONHEIGHT + 1; } - x = returnx; - y += BUTTONHEIGHT + 1; } -#undef BUTTONWIDTH +#undef BUTTONHEIGHT + + // Some contextual stuff + if (menutyping.keyboardtyping) + { + V_DrawThinString(returnx, 175, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_GRAYMAP, "Type using your keyboard. Press Enter to confirm & exit.\nUse your controller or any directional input to use the Virtual Keyboard.\n"); + } + else + { + V_DrawThinString(x, 175, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_GRAYMAP, "Type using the Virtual Keyboard. Use the \'OK\' button to confirm & exit.\nPress any keyboard key not bound to a control to use it."); + } } @@ -665,20 +710,6 @@ void M_Drawer(void) // GENERIC MENUS // ========================================================================== -// -// M_DrawMenuTooltips -// -// Draw a banner across the top of the screen, with a description of the current option displayed -// -static void M_DrawMenuTooltips(void) -{ - if (currentMenu->menuitems[itemOn].tooltip != NULL) - { - V_DrawFixedPatch(0, 0, FRACUNIT, 0, W_CachePatchName("MENUHINT", PU_CACHE), NULL); - V_DrawCenteredThinString(BASEVIDWIDTH/2, 12, V_ALLOWLOWERCASE|V_6WIDTHSPACE, currentMenu->menuitems[itemOn].tooltip); - } -} - // Converts a string into question marks. // Used for the secrets menu, to hide yet-to-be-unlocked stuff. static const char *M_CreateSecretMenuOption(const char *str) diff --git a/src/menus/transient/virtual-keyboard.c b/src/menus/transient/virtual-keyboard.c index 1a37ba6ab..ed40f6430 100644 --- a/src/menus/transient/virtual-keyboard.c +++ b/src/menus/transient/virtual-keyboard.c @@ -188,21 +188,34 @@ void M_MenuTypingInput(INT32 key) // Fade-in - if (menutyping.menutypingclose) // closing + if (menutyping.menutypingclose) { + // Closing menutyping.menutypingfade--; if (!menutyping.menutypingfade) menutyping.active = false; return; // prevent inputs while closing the menu. } - else // opening + else { - menutyping.menutypingfade++; - if (menutyping.menutypingfade > 9) // Don't fade all the way, but have it VERY strong to be readable - menutyping.menutypingfade = 9; - else if (menutyping.menutypingfade < 9) - return; // Don't allow typing until it's fully opened. + // Opening + const UINT8 destination = (menutyping.keyboardtyping ? 9 : 18); + + if (menutyping.menutypingfade > destination) + { + menutyping.menutypingfade--; + } + else if (menutyping.menutypingfade < destination) + { + menutyping.menutypingfade++; + } + + if (menutyping.menutypingfade != destination) + { + // Don't allow typing until it's fully opened. + return; + } } // Determine when to check for keyboard inputs or controller inputs using menuKey, which is the key passed here as argument. From fb578d7da250d9c14b3f320cdd32292821e59921 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 20 May 2023 20:43:41 +0100 Subject: [PATCH 16/21] Add-ons menu: Add name and tooltip for Search/filter field Now visible via Virtual Keyboard. --- src/menus/extras-addons.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menus/extras-addons.c b/src/menus/extras-addons.c index 868ba4cd4..e3cbf192b 100644 --- a/src/menus/extras-addons.c +++ b/src/menus/extras-addons.c @@ -10,7 +10,7 @@ menuitem_t MISC_AddonsMenu[] = { - {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, NULL, + {IT_STRING | IT_CVAR | IT_CV_STRING, "Search for add-ons", "Provide a full or partial name to filter available files by.", NULL, {.cvar = &cv_dummyaddonsearch}, 0, 0}, {IT_KEYHANDLER | IT_NOTHING, NULL, NULL, NULL, {.routine = M_HandleAddons}, 0, 0}, // dummy menuitem for the control func From df31f7cf3a86c33405a737af26e25c200d605da5 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 20 May 2023 21:03:23 +0100 Subject: [PATCH 17/21] M_HandleMenuInput: Fix incorrect menuKey comparison that was preventing the Virtual Keyboard from ever being activated on first opening --- src/k_menufunc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_menufunc.c b/src/k_menufunc.c index bc8f99f06..20f456278 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -887,7 +887,7 @@ static void M_HandleMenuInput(void) // If we're hovering over a IT_CV_STRING option, pressing A/X opens the typing submenu if (M_MenuConfirmPressed(pid)) { - menutyping.keyboardtyping = menuKey != 0 ? true : false; // If we entered this menu by pressing a menu Key, default to keyboard typing, otherwise use controller. + menutyping.keyboardtyping = menuKey != -1 ? true : false; // If we entered this menu by pressing a menu Key, default to keyboard typing, otherwise use controller. menutyping.active = true; menutyping.menutypingclose = false; return; From f24a640e0412f39d01bfb4d8b5913a5fcc5dae37 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 20 May 2023 22:37:31 +0100 Subject: [PATCH 18/21] Increase reliability of menuKey system The intersection between processed buttons and raw keyboard data is a messy one and will probably never be perfect, but it is now consistent. - Never overwrite a valid keyboard menuKey recieved this frame with a -1 if a different type of event is recieved as well. - Store previous state of dpad_lr and dpad_ud on menucmd struct. - Previously, if `a` was bound to Turn Left, it could produce a valid menuKey for one frame, then be considered a leftward input - switching from manual keyboard to Virtual Keyboard. - It still only produces a valid menuKey for one frame... but we simply filter out leftward inputs that are older than this frame to keep things (relatively) clean. --- src/k_menu.h | 8 +++++++- src/k_menufunc.c | 19 +++++++++++++------ src/menus/transient/virtual-keyboard.c | 19 +++++++++++++++++-- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/k_menu.h b/src/k_menu.h index 24ba4372e..d461973b4 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -552,10 +552,16 @@ typedef enum struct menucmd_t { + // Current frame's data SINT8 dpad_ud; // up / down dpad SINT8 dpad_lr; // left / right UINT32 buttons; // buttons - UINT32 buttonsHeld; // prev frame's buttons + + // Previous frame's data + SINT8 prev_dpad_ud; + SINT8 prev_dpad_lr; + UINT32 buttonsHeld; + UINT16 delay; // menu wait UINT32 delayCount; // num times ya did menu wait (to make the wait shorter each time) }; diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 20f456278..32c51d092 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -223,7 +223,7 @@ static boolean M_GamestateCanOpenMenu(void) // boolean M_Responder(event_t *ev) { - menuKey = -1; + boolean menuKeyJustChanged = false; if (dedicated || (demo.playback && demo.title) @@ -255,10 +255,11 @@ boolean M_Responder(event_t *ev) D_StartTitle(); } - if (ev->type == ev_keydown && ev->data1 < NUMKEYS) + if (ev->type == ev_keydown && ev->data1 > 0 && ev->data1 < NUMKEYS) { // Record keyboard presses menuKey = ev->data1; + menuKeyJustChanged = true; } // Profiles: Control mapping. @@ -354,7 +355,7 @@ boolean M_Responder(event_t *ev) } // Typing for CV_IT_STRING - if (menutyping.active && !menutyping.menutypingclose && menutyping.keyboardtyping) + if (menuKeyJustChanged && menutyping.active && !menutyping.menutypingclose && menutyping.keyboardtyping) { M_ChangeStringCvar(menuKey); } @@ -740,6 +741,9 @@ void M_UpdateMenuCMD(UINT8 i) { UINT8 mp = max(1, setup_numplayers); + menucmd[i].prev_dpad_ud = menucmd[i].dpad_ud; + menucmd[i].prev_dpad_lr = menucmd[i].dpad_lr; + menucmd[i].dpad_ud = 0; menucmd[i].dpad_lr = 0; @@ -833,6 +837,9 @@ static void M_HandleMenuInput(void) void (*routine)(INT32 choice); // for some casting problem UINT8 pid = 0; // todo: Add ability for any splitscreen player to bring up the menu. SINT8 lr = 0, ud = 0; + INT32 thisMenuKey = menuKey; + + menuKey = -1; if (menuactive == false) { @@ -849,7 +856,7 @@ static void M_HandleMenuInput(void) // Typing for CV_IT_STRING if (menutyping.active) { - M_MenuTypingInput(menuKey); + M_MenuTypingInput(thisMenuKey); return; } @@ -861,7 +868,7 @@ static void M_HandleMenuInput(void) // Handle menu-specific input handling. If this returns true, we skip regular input handling. if (currentMenu->inputroutine) { - if (currentMenu->inputroutine(menuKey)) + if (currentMenu->inputroutine(thisMenuKey)) { return; } @@ -887,7 +894,7 @@ static void M_HandleMenuInput(void) // If we're hovering over a IT_CV_STRING option, pressing A/X opens the typing submenu if (M_MenuConfirmPressed(pid)) { - menutyping.keyboardtyping = menuKey != -1 ? true : false; // If we entered this menu by pressing a menu Key, default to keyboard typing, otherwise use controller. + menutyping.keyboardtyping = thisMenuKey != -1 ? true : false; // If we entered this menu by pressing a menu Key, default to keyboard typing, otherwise use controller. menutyping.active = true; menutyping.menutypingclose = false; return; diff --git a/src/menus/transient/virtual-keyboard.c b/src/menus/transient/virtual-keyboard.c index ed40f6430..da5bb4d2d 100644 --- a/src/menus/transient/virtual-keyboard.c +++ b/src/menus/transient/virtual-keyboard.c @@ -243,10 +243,25 @@ void M_MenuTypingInput(INT32 key) || M_MenuButtonPressed(pid, MBT_X) || M_MenuButtonPressed(pid, MBT_Y) || M_MenuButtonPressed(pid, MBT_Z) - || menucmd[pid].dpad_lr != 0 - || menucmd[pid].dpad_ud != 0 + || (menucmd[pid].dpad_lr != 0 && menucmd[pid].prev_dpad_lr == 0) + || (menucmd[pid].dpad_ud != 0 && menucmd[pid].prev_dpad_ud != 0) )) { + /*CONS_Printf("key is %d, \ + %c%c%c-%c%c%c-%c-%c%c%c%c\n", + key, + M_MenuButtonPressed(pid, MBT_A) ? 'A' : ' ', + M_MenuButtonPressed(pid, MBT_B) ? 'B' : ' ', + M_MenuButtonPressed(pid, MBT_C) ? 'C' : ' ', + M_MenuButtonPressed(pid, MBT_X) ? 'X' : ' ', + M_MenuButtonPressed(pid, MBT_Y) ? 'Y' : ' ', + M_MenuButtonPressed(pid, MBT_Z) ? 'Z' : ' ', + M_MenuButtonPressed(pid, MBT_START) ? '+' : ' ', + menucmd[pid].dpad_lr < 0 ? '<' : ' ', + menucmd[pid].dpad_ud > 0 ? '^' : ' ', + menucmd[pid].dpad_ud < 0 ? 'v' : ' ', + menucmd[pid].dpad_lr > 0 ? '>' : ' ' + );*/ menutyping.keyboardtyping = false; return; } From 04d87bfb6c89f1ea4dab8fc332662d976017ed31 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 21 May 2023 00:04:45 +0100 Subject: [PATCH 19/21] M_MenuTypingInput: In Virtual Keyboard mode, assign some buttons as shortcuts - Start: closes the menu - B/X: backspace - C: Toggle shift/caps lock --- src/menus/transient/virtual-keyboard.c | 68 ++++++++++++++++++-------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/src/menus/transient/virtual-keyboard.c b/src/menus/transient/virtual-keyboard.c index da5bb4d2d..d09480014 100644 --- a/src/menus/transient/virtual-keyboard.c +++ b/src/menus/transient/virtual-keyboard.c @@ -173,6 +173,22 @@ boolean M_ChangeStringCvar(INT32 choice) return false; } +static void M_ToggleVirtualShift(void) +{ + if (menutyping.keyboardcapslock == true) + { + menutyping.keyboardcapslock = false; + } + else + { + menutyping.keyboardshift ^= true; + if (menutyping.keyboardshift == false) + { + menutyping.keyboardcapslock = true; + } + } +} + static boolean M_IsTypingKey(INT32 key) { return key == KEY_BACKSPACE || key == KEY_ENTER @@ -183,7 +199,6 @@ static boolean M_IsTypingKey(INT32 key) void M_MenuTypingInput(INT32 key) { - const UINT8 pid = 0; // Fade-in @@ -228,7 +243,8 @@ void M_MenuTypingInput(INT32 key) && !(menucmd[pid].buttons & MBT_C) && !(menucmd[pid].buttons & MBT_X) && !(menucmd[pid].buttons & MBT_Y) - && !(menucmd[pid].buttons & MBT_Z)) + && !(menucmd[pid].buttons & MBT_Z) + && !(menucmd[pid].buttons & MBT_START)) { menutyping.keyboardtyping = true; } @@ -243,6 +259,7 @@ void M_MenuTypingInput(INT32 key) || M_MenuButtonPressed(pid, MBT_X) || M_MenuButtonPressed(pid, MBT_Y) || M_MenuButtonPressed(pid, MBT_Z) + || M_MenuButtonPressed(pid, MBT_START) || (menucmd[pid].dpad_lr != 0 && menucmd[pid].prev_dpad_lr == 0) || (menucmd[pid].dpad_ud != 0 && menucmd[pid].prev_dpad_ud != 0) )) @@ -270,9 +287,12 @@ void M_MenuTypingInput(INT32 key) if (key == KEY_ENTER || key == KEY_ESCAPE) { menutyping.menutypingclose = true; // close menu. + + M_SetMenuDelay(pid); + S_StartSound(NULL, sfx_s3k5b); + return; } - } if (menucmd[pid].delay == 0 && !menutyping.keyboardtyping) // We must check for this here because we bypass the normal delay check to allow for normal keyboard inputs @@ -332,6 +352,30 @@ void M_MenuTypingInput(INT32 key) M_SetMenuDelay(pid); S_StartSound(NULL, sfx_s3k5b); } + else if (M_MenuButtonPressed(pid, MBT_START)) + { + // Shortcut for close menu. + menutyping.menutypingclose = true; + + M_SetMenuDelay(pid); + S_StartSound(NULL, sfx_s3k5b); + } + else if (M_MenuBackPressed(pid)) + { + // Shortcut for backspace. + M_ChangeStringCvar(KEY_BACKSPACE); + + M_SetMenuDelay(pid); + S_StartSound(NULL, sfx_s3k5b); + } + else if (M_MenuExtraPressed(pid)) + { + // Shortcut for shift/caps lock. + M_ToggleVirtualShift(); + + M_SetMenuDelay(pid); + S_StartSound(NULL, sfx_s3k5b); + } else if (M_MenuConfirmPressed(pid)) { // Add the character. First though, check what we're pressing.... @@ -348,27 +392,11 @@ void M_MenuTypingInput(INT32 key) if (c == KEY_RSHIFT) { - if (menutyping.keyboardcapslock == true) - { - menutyping.keyboardcapslock = false; - } - else - { - menutyping.keyboardshift ^= true; - if (menutyping.keyboardshift == false) - { - menutyping.keyboardcapslock = true; - } - } + M_ToggleVirtualShift(); } - /* - else if (c == KEY_CAPSLOCK) - menutyping.keyboardcapslock = !menutyping.keyboardcapslock; - */ else if (c == KEY_ENTER) { menutyping.menutypingclose = true; // close menu. - return; } else { From a0f0c83975d66d2819c6bdbdfb07a22f6ecdd1d5 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 21 May 2023 00:14:11 +0100 Subject: [PATCH 20/21] M_DrawMenuTyping: On Virtual Keyboard, highlight when system button presses occour - A - B/X - C - Start --- src/k_menudraw.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 4669b9753..8c99f5e31 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -374,6 +374,8 @@ static void M_DrawMenuTooltips(void) // Draws the typing submenu static void M_DrawMenuTyping(void) { + const UINT8 pid = 0; + INT32 i, j; INT32 x, y; @@ -459,11 +461,19 @@ static void M_DrawMenuTyping(void) col = 25; } + boolean canmodifycol = (menutyping.menutypingfade == 18); + if (c == KEY_BACKSPACE) { arrowoffset = 1; buf[0] = '\x1C'; // left arrow buf[1] = '\0'; + + if (canmodifycol && M_MenuBackHeld(pid)) + { + col -= 4; + canmodifycol = false; + } } else if (c == KEY_RSHIFT) { @@ -475,10 +485,22 @@ static void M_DrawMenuTyping(void) { col = 22; } + + if (canmodifycol && M_MenuExtraHeld(pid)) + { + col -= 4; + canmodifycol = false; + } } else if (c == KEY_ENTER) { strcpy(buf, "OK"); + + if (menutyping.menutypingclose) + { + col -= 4; + canmodifycol = false; + } } else if (c == KEY_SPACE) { @@ -501,6 +523,12 @@ static void M_DrawMenuTyping(void) { if (tempkeyboardx == j && menutyping.keyboardy == i) { + if (canmodifycol && M_MenuConfirmHeld(pid)) + { + col -= 4; + canmodifycol = false; + } + V_DrawFill(x + 1, y + 1, width - 2, BUTTONHEIGHT - 2, col - 3); V_DrawFill(x, y, width, 1, 121); From 8845f36a3dfa9021ec95aad521f7ead51652b96c Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 22 May 2023 15:32:07 +0100 Subject: [PATCH 21/21] HU_DrawRankings: Adjust slightly - Only show `Lap 0/Lap 1` if numlaps > 1, to match other circumstances where laps aren't real - Only show player roundscore if gametype supports roundscore - Otherwise accept a blank right side of the player bar in custom gametypes. (one day for Lua..?) --- src/hu_stuff.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index fa366bd36..48725247e 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2586,13 +2586,16 @@ static void HU_DrawRankings(void) #define strtime standings.strval[standings.numplayers] + standings.val[standings.numplayers] = 0; + strtime[0] = '\0'; + if (players[i].pflags & PF_NOCONTEST) { standings.val[standings.numplayers] = (UINT32_MAX-1); STRBUFCPY(strtime, "RETIRED."); } else if ((gametyperules & GTR_CIRCUIT)) - { + { standings.val[standings.numplayers] = players[i].laps; if (players[i].exiting) @@ -2600,12 +2603,12 @@ static void HU_DrawRankings(void) snprintf(strtime, sizeof strtime, "%i'%02i\"%02i", G_TicsToMinutes(players[i].realtime, true), G_TicsToSeconds(players[i].realtime), G_TicsToCentiseconds(players[i].realtime)); } - else + else if (numlaps > 1) { - snprintf(strtime, sizeof strtime, "Lap %d", standings.val[standings.numplayers]); + snprintf(strtime, sizeof strtime, "Lap %d", players[i].laps); } } - else + else if ((gametyperules & GTR_POINTLIMIT)) { standings.val[standings.numplayers] = players[i].roundscore; snprintf(strtime, sizeof strtime, "%d", standings.val[standings.numplayers]);