Menus/Virtual Keyboard: cache cvar string for duration of typing

This avoids calling cvar callbacks after every key press.
This commit is contained in:
James R 2023-12-28 05:53:59 -08:00
parent 172951410b
commit 0ef1abcf3a
4 changed files with 36 additions and 37 deletions

View file

@ -542,6 +542,8 @@ extern struct menutyping_s
boolean keyboardcapslock; boolean keyboardcapslock;
boolean keyboardshift; boolean keyboardshift;
char cache[MAXSTRINGLENGTH]; // cached string
} menutyping; } menutyping;
// While typing, we'll have a fade strongly darken the screen to overlay the typing menu instead // While typing, we'll have a fade strongly darken the screen to overlay the typing menu instead
@ -666,6 +668,7 @@ void M_Init(void);
void M_PlayMenuJam(void); void M_PlayMenuJam(void);
void M_OpenVirtualKeyboard(boolean gamepad);
void M_MenuTypingInput(INT32 key); void M_MenuTypingInput(INT32 key);
void M_QuitResponse(INT32 ch); void M_QuitResponse(INT32 ch);

View file

@ -430,8 +430,6 @@ static void M_DrawMenuTyping(void)
INT32 x, y; INT32 x, y;
consvar_t *cv = currentMenu->menuitems[itemOn].itemaction.cvar;
char buf[8]; // We write there to use drawstring for convenience. char buf[8]; // We write there to use drawstring for convenience.
V_DrawFadeScreen(31, (menutyping.menutypingfade+1)/2); V_DrawFadeScreen(31, (menutyping.menutypingfade+1)/2);
@ -462,12 +460,12 @@ static void M_DrawMenuTyping(void)
V_DrawFill(x + 4, y + 4 + 5, 1, 8+6, 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_DrawFill(x + 5 + boxwidth - 8, y + 4 + 5, 1, 8+6, 121);
V_DrawString(x + 8, y + 12, 0, cv->string); V_DrawString(x + 8, y + 12, 0, menutyping.cache);
if (skullAnimCounter < 4 if (skullAnimCounter < 4
&& menutyping.menutypingclose == false && menutyping.menutypingclose == false
&& menutyping.menutypingfade == (menutyping.keyboardtyping ? 9 : 18)) && menutyping.menutypingfade == (menutyping.keyboardtyping ? 9 : 18))
{ {
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12 + 1, '_', false); V_DrawCharacter(x + 8 + V_StringWidth(menutyping.cache, 0), y + 12 + 1, '_', false);
} }
const INT32 buttonwidth = ((boxwidth + 1)/NUMVIRTUALKEYSINROW); const INT32 buttonwidth = ((boxwidth + 1)/NUMVIRTUALKEYSINROW);

View file

@ -972,9 +972,7 @@ static void M_HandleMenuInput(void)
// If we're hovering over a IT_CV_STRING option, pressing A/X opens the typing submenu // If we're hovering over a IT_CV_STRING option, pressing A/X opens the typing submenu
if (M_MenuConfirmPressed(pid)) if (M_MenuConfirmPressed(pid))
{ {
menutyping.keyboardtyping = thisMenuKey != -1 ? true : false; // If we entered this menu by pressing a menu Key, default to keyboard typing, otherwise use controller. M_OpenVirtualKeyboard(thisMenuKey == -1); // If we entered this menu by pressing a menu Key, default to keyboard typing, otherwise use controller.
menutyping.active = true;
menutyping.menutypingclose = false;
return; return;
} }

View file

@ -38,8 +38,6 @@ typedef enum
boolean M_ChangeStringCvar(INT32 choice) boolean M_ChangeStringCvar(INT32 choice)
{ {
consvar_t *cv = currentMenu->menuitems[itemOn].itemaction.cvar;
char buf[MAXSTRINGLENGTH];
size_t len; size_t len;
cvarcopypastemode_t copypastemode = CVCPM_NONE; cvarcopypastemode_t copypastemode = CVCPM_NONE;
@ -86,7 +84,7 @@ boolean M_ChangeStringCvar(INT32 choice)
if (copypastemode != CVCPM_NONE) if (copypastemode != CVCPM_NONE)
{ {
len = strlen(cv->string); len = strlen(menutyping.cache);
if (copypastemode == CVCPM_PASTE) if (copypastemode == CVCPM_PASTE)
{ {
@ -95,12 +93,7 @@ boolean M_ChangeStringCvar(INT32 choice)
; ;
else if (len < MAXSTRINGLENGTH - 1) else if (len < MAXSTRINGLENGTH - 1)
{ {
M_Memcpy(buf, cv->string, len); strlcat(menutyping.cache, paste, MAXSTRINGLENGTH);
buf[len] = 0;
strncat(buf, paste, (MAXSTRINGLENGTH - 1) - len);
CV_Set(cv, buf);
S_StartSound(NULL, sfx_s3k5b); // Tails S_StartSound(NULL, sfx_s3k5b); // Tails
} }
@ -109,12 +102,12 @@ boolean M_ChangeStringCvar(INT32 choice)
|| copypastemode == CVCPM_CUT)*/ || copypastemode == CVCPM_CUT)*/
) )
{ {
I_ClipboardCopy(cv->string, len); I_ClipboardCopy(menutyping.cache, len);
if (copypastemode == CVCPM_CUT) if (copypastemode == CVCPM_CUT)
{ {
// A cut should wipe. // A cut should wipe.
CV_Set(cv, ""); strcpy(menutyping.cache, "");
} }
S_StartSound(NULL, sfx_s3k5b); // Tails S_StartSound(NULL, sfx_s3k5b); // Tails
@ -130,22 +123,18 @@ boolean M_ChangeStringCvar(INT32 choice)
switch (choice) switch (choice)
{ {
case KEY_BACKSPACE: case KEY_BACKSPACE:
if (cv->string[0]) if (menutyping.cache[0])
{ {
len = strlen(cv->string); len = strlen(menutyping.cache);
menutyping.cache[len - 1] = 0;
M_Memcpy(buf, cv->string, len);
buf[len-1] = 0;
CV_Set(cv, buf);
S_StartSound(NULL, sfx_s3k5b); // Tails S_StartSound(NULL, sfx_s3k5b); // Tails
} }
return true; return true;
case KEY_DEL: case KEY_DEL:
if (cv->string[0]) if (menutyping.cache[0])
{ {
CV_Set(cv, ""); strcpy(menutyping.cache, "");
S_StartSound(NULL, sfx_s3k5b); // Tails S_StartSound(NULL, sfx_s3k5b); // Tails
} }
@ -153,15 +142,11 @@ boolean M_ChangeStringCvar(INT32 choice)
default: default:
if (choice >= 32 && choice <= 127) if (choice >= 32 && choice <= 127)
{ {
len = strlen(cv->string); len = strlen(menutyping.cache);
if (len < MAXSTRINGLENGTH - 1) if (len < MAXSTRINGLENGTH - 1)
{ {
M_Memcpy(buf, cv->string, len); menutyping.cache[len++] = (char)choice;
menutyping.cache[len] = 0;
buf[len++] = (char)choice;
buf[len] = 0;
CV_Set(cv, buf);
S_StartSound(NULL, sfx_s3k5b); // Tails S_StartSound(NULL, sfx_s3k5b); // Tails
} }
@ -189,6 +174,12 @@ static void M_ToggleVirtualShift(void)
} }
} }
static void M_CloseVirtualKeyboard(void)
{
menutyping.menutypingclose = true; // close menu.
CV_Set(currentMenu->menuitems[itemOn].itemaction.cvar, menutyping.cache);
}
static boolean M_IsTypingKey(INT32 key) static boolean M_IsTypingKey(INT32 key)
{ {
return key == KEY_BACKSPACE || key == KEY_ENTER return key == KEY_BACKSPACE || key == KEY_ENTER
@ -286,7 +277,7 @@ void M_MenuTypingInput(INT32 key)
// OTHERWISE, process keyboard inputs for typing! // OTHERWISE, process keyboard inputs for typing!
if (key == KEY_ENTER || key == KEY_ESCAPE) if (key == KEY_ENTER || key == KEY_ESCAPE)
{ {
menutyping.menutypingclose = true; // close menu. M_CloseVirtualKeyboard();
M_SetMenuDelay(pid); M_SetMenuDelay(pid);
S_StartSound(NULL, sfx_s3k5b); S_StartSound(NULL, sfx_s3k5b);
@ -355,7 +346,7 @@ void M_MenuTypingInput(INT32 key)
else if (M_MenuButtonPressed(pid, MBT_START)) else if (M_MenuButtonPressed(pid, MBT_START))
{ {
// Shortcut for close menu. // Shortcut for close menu.
menutyping.menutypingclose = true; M_CloseVirtualKeyboard();
M_SetMenuDelay(pid); M_SetMenuDelay(pid);
S_StartSound(NULL, sfx_s3k5b); S_StartSound(NULL, sfx_s3k5b);
@ -396,7 +387,7 @@ void M_MenuTypingInput(INT32 key)
} }
else if (c == KEY_ENTER) else if (c == KEY_ENTER)
{ {
menutyping.menutypingclose = true; // close menu. M_CloseVirtualKeyboard();
} }
else else
{ {
@ -410,3 +401,12 @@ void M_MenuTypingInput(INT32 key)
} }
} }
} }
void M_OpenVirtualKeyboard(boolean gamepad)
{
menutyping.keyboardtyping = !gamepad;
menutyping.active = true;
menutyping.menutypingclose = false;
strlcpy(menutyping.cache, currentMenu->menuitems[itemOn].itemaction.cvar->string, MAXSTRINGLENGTH);
}