diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 7ad7e893f..dd2725673 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -536,7 +536,8 @@ consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, consvar_t cv_gravity = CVAR_INIT ("gravity", "0.8", CV_RESTRICT|CV_FLOAT|CV_CALL, NULL, Gravity_OnChange); // change DEFAULT_GRAVITY if you change this -consvar_t cv_soundtest = CVAR_INIT ("soundtest", "0", CV_CALL, NULL, SoundTest_OnChange); +static CV_PossibleValue_t soundtest_cons_t[] = {{0, "MIN"}, {NUMSFX, "MAX"}}; +consvar_t cv_soundtest = CVAR_INIT ("soundtest", "0", CV_CALL, soundtest_cons_t, SoundTest_OnChange); static CV_PossibleValue_t minitimelimit_cons_t[] = {{15, "MIN"}, {9999, "MAX"}, {0, NULL}}; consvar_t cv_countdowntime = CVAR_INIT ("countdowntime", "30", CV_NETVAR|CV_CHEAT, minitimelimit_cons_t, NULL); diff --git a/src/deh_soc.c b/src/deh_soc.c index f5425e369..9ecb1cd7d 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -1972,13 +1972,9 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) } else if (fastncmp(word, "CVAR", 4)) { - UINT16 flags = IT_CVAR; + UINT16 flags = IT_INTERACT; if (fastcmp(word+4, "SLIDER")) - flags |= IT_CV_SLIDER; - else if (fastcmp(word+4, "STRING")) - flags |= IT_CV_STRING; - //else if (fastcmp(word+4, "INTEGER")) - //flags |= IT_CV_INTEGERSTEP; + flags |= IT_SLIDER; else if (word[4]) { WARN("unknown word '%s'", word); @@ -2009,17 +2005,14 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem) WARN("unknown menu '%s'", word2); continue; } + status |= IT_INTERACT; menuitem->submenu = mn; } else if (fastcmp(word, "CALL") || fastcmp(word, "ARROWS")) { - UINT16 flags; - if (word[0] == 'C') - flags = IT_CALL; - else if (word[0] == 'A') - flags = IT_ARROWS; - else - I_Error("bruh"); // i should probably just make "CALL" the stem for all of these + UINT16 flags = IT_INTERACT; + if (word[0] == 'A') + flags |= IT_ARROWS; menufunc_f *routine = get_menuroutine(word2); if (!routine) diff --git a/src/m_menu.c b/src/m_menu.c index fdc819d93..47a208b98 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -282,7 +282,7 @@ static void M_ChangeItemStatus(menutype_t type, const char *name, UINT16 flag, b static boolean M_ItemSelectable(menuitem_t *item) { - return !(item->status & (IT_HIDDEN|IT_GRAYEDOUT|IT_SECRET)) && (item->submenu || item->routine || item->cvar); + return (item->status & IT_INTERACT) && !(item->status & (IT_HIDDEN|IT_GRAYEDOUT|IT_SECRET)); } // bruh... @@ -806,57 +806,57 @@ void M_InitMenuPresTables(void) static UINT8 multi_spr2; static void M_GetFollowerState(void); -static INT32 M_ChangeCvar(INT32 choice) +static void M_ResetCvar(menuitem_t *item) { - consvar_t *cv = currentMenu->menuitems[itemOn].cvar; + consvar_t *cv = item->cvar; - if (choice == -1) + if (cv == &cv_playercolor[0] || cv == &cv_playercolor[1] || cv == &cv_playercolor[2] || cv == &cv_playercolor[3] || cv == &cv_dummycolor) { - if (cv == &cv_playercolor[0] || cv == &cv_playercolor[1] || cv == &cv_playercolor[2] || cv == &cv_playercolor[3] || cv == &cv_dummycolor) - { - INT32 skinno = R_SkinAvailable(skins[cv_chooseskin.value].name); - if (skinno != -1 && skincolors[skins[skinno].prefcolor].accessible) - CV_SetValue(cv,skins[skinno].prefcolor); - return true; - } - CV_Set(cv,cv->defaultvalue); - return true; - } - - choice = (choice<<1) - 1; - - if ((currentMenu->menuitems[itemOn].status & IT_ACTION) == IT_CV_SLIDER) - { - CV_SetValue(cv,cv->value+choice); - } - else if (cv->flags & CV_FLOAT) - { - /*if (!(currentMenu->menuitems[itemOn].status & IT_CV_INTEGERSTEP)) - { - char s[20]; - float n = FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f); - sprintf(s,"%ld%s",(long)n,M_Ftrim(n)); - CV_Set(cv,s); - } - else*/ - CV_SetValue(cv,FIXED_TO_FLOAT(cv->value)+(choice)); + INT32 skinno = R_SkinAvailable(skins[cv_chooseskin.value].name); + if (skinno != -1 && skincolors[skins[skinno].prefcolor].accessible) + CV_SetValue(cv, skins[skinno].prefcolor); } else - CV_AddValue(cv,choice); + CV_Set(cv, cv->defaultvalue); +} + +static void M_ChangeCvar(menuitem_t *item, SINT8 direction) +{ + consvar_t *cv = item->cvar; + INT32 amount = item->argument ? item->argument : cv->flags & CV_FLOAT ? FRACUNIT/16 : 1; + amount *= direction; + + if (cv->flags & CV_FLOAT) + { + char s[20]; + float n = FIXED_TO_FLOAT(cv->value + amount); + sprintf(s, "%ld%s", (long)n, M_Ftrim(n)); + CV_Set(cv, s); + } + else + CV_AddValue(cv, amount); if (cv == &cv_chooseskin) multi_spr2 = P_GetSkinSprite2(&skins[cv->value], SPR2_FSTN, NULL); else if (cv == &cv_dummyfollower) M_GetFollowerState(); // update follower state +} - return true; +static UINT32 M_StringCvarLength(consvar_t *cv) +{ + if (cv == &cv_dummyip) + return MAXIPADDRESSLEN; + else if (cv == &cv_dummyname || cv == &cv_playername[0] || cv == &cv_playername[1] || cv == &cv_playername[2] || cv == &cv_playername[3]) + return MAXPLAYERNAME + 1; + else + return MAXSTRINGLENGTH; } static boolean M_ChangeStringCvar(INT32 choice) { consvar_t *cv = currentMenu->menuitems[itemOn].cvar; char buf[MAXSTRINGLENGTH]; - size_t len; + size_t len = strlen(cv->string); if (shiftdown && choice >= 32 && choice <= 127) choice = shiftxform[choice]; @@ -864,7 +864,6 @@ static boolean M_ChangeStringCvar(INT32 choice) switch (choice) { case KEY_BACKSPACE: - len = strlen(cv->string); if (len > 0) { S_StartSound(NULL,sfx_menu1); // Tails @@ -880,33 +879,35 @@ static boolean M_ChangeStringCvar(INT32 choice) CV_Set(cv, ""); } return true; + case KEY_LEFTARROW: + case KEY_RIGHTARROW: + // TODO: navigation + return true; default: if (cv == &cv_dummyip) { // Rudimentary number and period enforcing - also allows letters so hostnames can be used instead if (!((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z')) && !(choice >= KEY_KEYPAD7 && choice <= KEY_KPADDEL && choice != KEY_MINUSPAD && choice != KEY_PLUSPAD)) //numpad too! - return false; + break; if (choice >= KEY_KEYPAD7) // sir, have you been golfing tonight? choice = "789-456+1230."[choice - KEY_KEYPAD7]; } - if (choice >= 32 && choice <= 127) + if (choice < 32 || choice > 127) + break; + + if (len < M_StringCvarLength(cv) - 1) { - len = strlen(cv->string); - if (len < (cv == &cv_dummyip ? MAXIPADDRESSLEN : MAXSTRINGLENGTH) - 1) - { - S_StartSound(NULL,sfx_menu1); // Tails - M_Memcpy(buf, cv->string, len); - buf[len++] = (char)choice; - buf[len] = 0; - CV_Set(cv, buf); - } - return true; + S_StartSound(NULL, sfx_menu1); // Tails + M_Memcpy(buf, cv->string, len); + buf[len++] = (char)choice; + buf[len] = 0; + CV_Set(cv, buf); } - break; + return true; } return false; } @@ -991,7 +992,6 @@ boolean M_Responder(event_t *ev) static tic_t joywait = 0, mousewait = 0; static INT32 pmousex = 0, pmousey = 0; static INT32 lastx = 0, lasty = 0; - menufunc_f *routine = NULL; // for some casting problem INT32 deviceplayer = G_GetDevicePlayer(ev->device); if (dedicated || (demo.playback && demo.title) @@ -1246,19 +1246,10 @@ boolean M_Responder(event_t *ev) // BP: one of the more big hack i have never made // G: not so hacky anymore...? // G: nevermind we have combi menuitems now - UINT16 itemtype = 0; - if (currentMenu->numitems) - { - itemtype = currentMenu->menuitems[itemOn].status; - routine = currentMenu->menuitems[itemOn].routine; - } - if ((itemtype & (IT_CVAR|IT_CV_STRING)) == (IT_CVAR|IT_CV_STRING)) - { - if (shiftdown && ch >= 32 && ch <= 127) - ch = shiftxform[ch]; - if (M_ChangeStringCvar(ch)) - return true; - } + menuitem_t *item = currentMenu->numitems ? ¤tMenu->menuitems[itemOn] : NULL; + + if (item && item->cvar && !item->cvar->PossibleValue && M_ChangeStringCvar(ch)) + return true; if (menustack[0] == MN_PLAYBACK && !con_destlines) { @@ -1283,7 +1274,7 @@ boolean M_Responder(event_t *ev) switch (ch) { case KEY_DOWNARROW: - if (!currentMenu->numitems) + if (!item) return true; do if (++itemOn >= currentMenu->numitems) @@ -1294,7 +1285,7 @@ boolean M_Responder(event_t *ev) return true; case KEY_UPARROW: - if (!currentMenu->numitems) + if (!item) return true; do if (--itemOn < 0) @@ -1305,24 +1296,24 @@ boolean M_Responder(event_t *ev) return true; case KEY_LEFTARROW: - if (itemtype & (IT_ARROWS|IT_CVAR) && !(itemtype & IT_CV_STRING)) - { - if (menustack[0] != MN_OP_SOUND || itemOn > 3) - S_StartSound(NULL, sfx_menu1); - (itemtype & IT_ARROWS ? routine : M_ChangeCvar)(0); - } - return true; - case KEY_RIGHTARROW: - if (itemtype & (IT_ARROWS|IT_CVAR) && !(itemtype & IT_CV_STRING)) - { - if (menustack[0] != MN_OP_SOUND || itemOn > 3) - S_StartSound(NULL, sfx_menu1); - (itemtype & IT_ARROWS ? routine : M_ChangeCvar)(1); - } + if (!item || !(item->cvar || item->status & IT_ARROWS)) + return true; + + if (menustack[0] != MN_OP_SOUND || itemOn > 3) + S_StartSound(NULL, sfx_menu1); + + if (item->cvar) + M_ChangeCvar(item, ch == KEY_RIGHTARROW ? 1 : -1); + else + item->routine(ch == KEY_RIGHTARROW ? 1 : 0); + return true; case KEY_ENTER: + if (!item) + return true; + noFurtherInput = true; currentMenu->lastOn = itemOn; @@ -1334,24 +1325,24 @@ boolean M_Responder(event_t *ev) playback_enterheld = 3; } - INT32 argument = currentMenu->menuitems[itemOn].argument; - if (currentMenu->menuitems[itemOn].cvar) - argument = currentMenu->menuitems[itemOn].cvar->value; + INT32 argument = item->argument; + if (item->cvar) + argument = item->cvar->value; - if (currentMenu->menuitems[itemOn].submenu) + if (item->submenu) { S_StartSound(NULL, sfx_menu1); - M_EnterMenu(currentMenu->menuitems[itemOn].submenu, true, argument); + M_EnterMenu(item->submenu, true, argument); } - else if (currentMenu->menuitems[itemOn].routine) + else if (item->routine) { S_StartSound(NULL, sfx_menu1); - routine(argument); + item->routine(argument); } - else if (currentMenu->menuitems[itemOn].cvar && !(itemtype & IT_CV_STRING)) + else if (item->cvar && item->cvar->PossibleValue) // not for string cvars! { S_StartSound(NULL, sfx_menu1); - M_ChangeCvar(1); // right arrow + M_ChangeCvar(item, 1); // right arrow } return true; @@ -1371,23 +1362,17 @@ boolean M_Responder(event_t *ev) return true; case KEY_BACKSPACE: - if (itemtype & IT_CVAR) - { - consvar_t *cv = currentMenu->menuitems[itemOn].cvar; - - if (cv == &cv_chooseskin - || cv == &cv_dummystaff - || cv == &cv_nextmap - || cv == &cv_newgametype - || cv == &cv_dummymultiplayer) - return true; - - if (menustack[0] != MN_OP_SOUND || itemOn > 3) - S_StartSound(NULL, sfx_menu1); - M_ChangeCvar(-1); + if (!item || !item->cvar + || item->cvar == &cv_chooseskin + || item->cvar == &cv_dummystaff + || item->cvar == &cv_nextmap + || item->cvar == &cv_newgametype + || item->cvar == &cv_dummymultiplayer) return true; - } + if (menustack[0] != MN_OP_SOUND || itemOn > 3) + S_StartSound(NULL, sfx_menu1); + M_ResetCvar(item); return true; default: @@ -2119,22 +2104,18 @@ static INT16 M_DrawMenuItem(menuitem_t *item, INT16 x, INT16 y, INT32 vflags, bo (BASEVIDWIDTH-currentMenu->x, y, vflags|highlightflags, name); } - if (item->status & IT_CVAR) + if (item->cvar) { consvar_t *cv = item->cvar; - switch(item->status & IT_ACTION) + if (!cv->PossibleValue) // string cvar? { - case IT_CV_SLIDER: - M_DrawSlider(x, y, cv, selected); - break; - case IT_CV_STRING: if (currentMenu->scrollheight && y + 12 > currentMenu->y + currentMenu->scrollheight) break; boolean side = vflags & MDF_TIMEATTACK || cv == &cv_dummyname; INT32 xofs = side ? 32 : 0; INT32 yofs = side ? -8 : 4; - w = side ? MAXPLAYERNAME : cv == &cv_dummyip ? MAXIPADDRESSLEN : MAXSTRINGLENGTH; + w = M_StringCvarLength(cv); M_DrawTextBox(x + xofs, y + yofs, w, 1); V_DrawString(x + xofs + 8, y + yofs + 8, vflags|V_ALLOWLOWERCASE, cv->string); @@ -2144,8 +2125,12 @@ static INT16 M_DrawMenuItem(menuitem_t *item, INT16 x, INT16 y, INT32 vflags, bo if (!side) y += 16; - break; - default: + } + else if (item->status & IT_SLIDER) + { + M_DrawSlider(x, y, cv, selected); + } + else { const char *str = cv->string; INT32 soffset = vflags & MDF_TIMEATTACK && cv != &cv_nextmap ? 40 : 0; @@ -2191,12 +2176,10 @@ static INT16 M_DrawMenuItem(menuitem_t *item, INT16 x, INT16 y, INT32 vflags, bo V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y, '\x1D' | highlightflags | strvf, false); // right arrow } - break; - } } break; } - else if (item->status & IT_CALL) + else if (item->routine) { char tmp[32*MAXINPUTMAPPING]; // should be enough :^) INT32 key; diff --git a/src/m_menu.h b/src/m_menu.h index c532542e1..c52388cc2 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -155,37 +155,29 @@ void M_QuitResponse(INT32 ch); // Determines whether to show a level in the list (platter version does not need to be exposed) boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); -// flags for items in the menu -// menu handle (what we do when key is pressed -#define IT_CALL 1 // call the function -#define IT_ARROWS 2 // call function with 0 for left arrow and 1 for right arrow in param -//#define IT_SUBMENU 4 // go to sub menu -#define IT_CVAR 8192 // handle as a cvar +typedef enum +{ + IT_INTERACT = 1<<0, // item can be interacted with + IT_HIDDEN = 1<<1, // item is invisible and cannot be interacted with (has priority over IT_INTERACT) + IT_GRAYEDOUT = 1<<2, // item is grayed out and non-interactible + IT_SECRET = 1<<3, // item text is displayed with question marks and non-interactible -// display flags -#define IT_DISPLAY (8+16+32) -#define IT_PATCH 8 // a patch or a string with big font -#define IT_STRING 16 // little string (spaced with 10) -#define IT_WHITESTRING 32 // little string in white -#define IT_HEADERTEXT (8+32) // Non-selectable header option, displays in yellow offset to the left a little + IT_ARROWS = 1<<4, // call-type items use arrow keys instead of enter + IT_SLIDER = 1<<5, // cvar-type items display a slider -// flags specific to each item action type -#define IT_ACTION (64+128+256) + IT_PATCH = 1<<6, // display a patch + IT_STRING = 1<<7, // display a string + IT_WHITESTRING = 1<<8, // displays a string with highlighted text + IT_HEADERTEXT = IT_PATCH|IT_WHITESTRING, + IT_DISPLAY = IT_PATCH|IT_STRING|IT_WHITESTRING, -//consvar specific -#define IT_CV_SLIDER 64 -#define IT_CV_STRING 128 -//#define IT_CV_INTEGERSTEP 256 // if cvar is CV_FLOAT, modify it by 1 instead of 0.0625 + IT_OFSX = 1<<9, // X coordinate is relative to current position + IT_OFSY = 1<<10, // ditto + IT_TEMPORARY = 1<<11, // with IT_OFS*, offset applies only to this item + IT_OVERLAY = 1<<12, // item is drawn at absolute coordinates, without scrolling -// extra flags -#define IT_CENTER 512 // if IT_PATCH, center it on screen -#define IT_HIDDEN 1024 // invisible, unselectable -#define IT_GRAYEDOUT 2048 // grayed out, unselectable -#define IT_SECRET 4096 // ??????? ???????????? -#define IT_OFSX 16384 // x coordinate is relative -#define IT_OFSY 32768 // ditto -#define IT_TEMPORARY 4 // offset is only applied temporarily -#define IT_OVERLAY 256 // no scrolling, draw at absolute coordinates + IT_CENTER = 1<<13, // centered text/patch +} menuitemflags_t; // carefully chosen to not conflict with V_ flags #define MDF_CENTERED 0x20 diff --git a/src/p_user.c b/src/p_user.c index eef6483a2..dc9b55e50 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2618,17 +2618,17 @@ static CV_PossibleValue_t CV_CamSpeed[] = {{0, "MIN"}, {1*FRACUNIT, "MAX"}, {0, static CV_PossibleValue_t CV_CamRotate[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}}; consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("cam_dist", "190", CV_FLOAT|CV_SAVE, NULL, NULL), - CVAR_INIT ("cam2_dist", "190", CV_FLOAT|CV_SAVE, NULL, NULL), - CVAR_INIT ("cam3_dist", "190", CV_FLOAT|CV_SAVE, NULL, NULL), - CVAR_INIT ("cam4_dist", "190", CV_FLOAT|CV_SAVE, NULL, NULL) + CVAR_INIT ("cam_dist", "190", CV_FLOAT|CV_SAVE, CV_Signed, NULL), + CVAR_INIT ("cam2_dist", "190", CV_FLOAT|CV_SAVE, CV_Signed, NULL), + CVAR_INIT ("cam3_dist", "190", CV_FLOAT|CV_SAVE, CV_Signed, NULL), + CVAR_INIT ("cam4_dist", "190", CV_FLOAT|CV_SAVE, CV_Signed, NULL) }; consvar_t cv_cam_height[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("cam_height", "75", CV_FLOAT|CV_SAVE, NULL, NULL), - CVAR_INIT ("cam2_height", "75", CV_FLOAT|CV_SAVE, NULL, NULL), - CVAR_INIT ("cam3_height", "75", CV_FLOAT|CV_SAVE, NULL, NULL), - CVAR_INIT ("cam4_height", "75", CV_FLOAT|CV_SAVE, NULL, NULL) + CVAR_INIT ("cam_height", "75", CV_FLOAT|CV_SAVE, CV_Signed, NULL), + CVAR_INIT ("cam2_height", "75", CV_FLOAT|CV_SAVE, CV_Signed, NULL), + CVAR_INIT ("cam3_height", "75", CV_FLOAT|CV_SAVE, CV_Signed, NULL), + CVAR_INIT ("cam4_height", "75", CV_FLOAT|CV_SAVE, CV_Signed, NULL) }; consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS] = {