Update controls in real time in control setup, allow testing controller mappings

This commit is contained in:
SinnamonLat 2022-04-13 03:03:58 +02:00
parent 66c62b38da
commit 62b6b7ea8f
4 changed files with 84 additions and 14 deletions

View file

@ -674,6 +674,8 @@ extern struct optionsmenu_s {
UINT8 bindcontrol; // 0: not binding, 1: binding control #1, 2: binding control #2
INT16 bindtimer; // Timer until binding is cancelled (5s)
INT16 trycontroller; // Starts at 3*TICRATE, holding B lowers this, when at 0, cancel controller try mode.
// Used for horrible axis shenanigans
INT32 lastkey;
tic_t keyheldfor;
@ -731,6 +733,7 @@ boolean M_ProfileControlsInputs(INT32 ch);
void M_ProfileSetControl(INT32 ch);
void M_MapProfileControl(event_t *ev);
void M_ProfileTryController(INT32 choice);
// video modes menu (resolution)
void M_VideoModeMenu(INT32 choice);

View file

@ -538,6 +538,12 @@ menuitem_t OPTIONS_ProfileControls[] = {
{IT_CONTROL | IT_CVAR, "KICKSTART ACCEL", "Hold A to auto-accel. Tap it to cancel.",
NULL, {.cvar = &cv_dummyprofilekickstart}, 0, 0},
{IT_HEADER, "EXTRA", "",
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CALL, "TRY MAPPINGS", "Only display the controller for testing.",
NULL, {.routine = M_ProfileTryController}, 0, 0},
};

View file

@ -2723,6 +2723,29 @@ void M_DrawProfileControls(void)
}
}
if (optionsmenu.trycontroller)
{
optionsmenu.tcontx = BASEVIDWIDTH*2/3 - 10;
optionsmenu.tconty = BASEVIDHEIGHT/2 +70;
V_DrawCenteredString(160, 180, highlightflags, va("HOLD [X] FOR %d SECONDS TO BACK OUT", optionsmenu.trycontroller/TICRATE));
return; // Don't draw the rest if we're trying the controller.
}
// If we're past here, draw some text warnings.
if (gamestate == GS_MENU || PR_GetProfileNum(optionsmenu.profile) == cv_lastprofile[pid].value)
{
if (gamestate != GS_MENU) // If we're in a menu we'll always use the current profile to map controls from regardless.
V_DrawCenteredThinString(229, 180, highlightflags|V_ALLOWLOWERCASE|V_6WIDTHSPACE, "This is your last used profile,");
V_DrawCenteredThinString(229, 190, highlightflags|V_ALLOWLOWERCASE|V_6WIDTHSPACE, "Control changes will happen in real time");
}
else
{
V_DrawCenteredThinString(229, 180, highlightflags|V_ALLOWLOWERCASE|V_6WIDTHSPACE, "This isn't your last used profile,");
V_DrawCenteredThinString(229, 180, highlightflags|V_ALLOWLOWERCASE|V_6WIDTHSPACE, "Changes will apply on next profile selection.");
}
// Tooltip
// The text is slightly shifted hence why we don't just use M_DrawMenuTooltips()
V_DrawFixedPatch(0, 0, FRACUNIT, 0, W_CachePatchName("MENUHINT", PU_CACHE), NULL);
@ -2754,6 +2777,10 @@ void M_DrawProfileControls(void)
y += spacing;
break;
case IT_STRING:
V_DrawString(x, y+1, (i == itemOn ? highlightflags : 0), currentMenu->menuitems[i].text);
break;
case IT_STRING2:
{
boolean drawnpatch = false;

View file

@ -4249,12 +4249,36 @@ void M_HandleProfileControls(void)
}
}
void M_ProfileTryController(INT32 choice)
{
(void) choice;
// I managed to softlock myself during testing lol.
if (!optionsmenu.profile->controls[gc_x][0])
{
M_StartMessage(M_GetText("You need to bind a key to [X]\nto use this feature.\n"), NULL, MM_NOTHING);
return;
}
optionsmenu.trycontroller = TICRATE*3;
}
boolean M_ProfileControlsInputs(INT32 ch)
{
const UINT8 pid = 0;
(void)ch;
// By default, accept all inputs.
if (optionsmenu.trycontroller)
{
if (M_MenuButtonHeld(pid, MBT_X))
optionsmenu.trycontroller--;
else
optionsmenu.trycontroller = TICRATE*3;
return true;
}
if (optionsmenu.bindcontrol)
return true; // Eat all inputs there. We'll use a stupid hack in M_Responder instead.
@ -4278,22 +4302,10 @@ boolean M_ProfileControlsInputs(INT32 ch)
}
else if (M_MenuBackPressed(pid))
{
UINT8 i;
UINT8 pnum;
optionsmenu.profile->kickstartaccel = cv_dummyprofilekickstart.value; // Make sure to save kickstart accel.
pnum = PR_GetProfileNum(optionsmenu.profile);
// Check if this profile is one we have last used on any player:
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
if (cv_lastprofile[i].value == pnum)
{
PR_ApplyProfile(pnum, i);
break;
}
}
// Reapply player 1's real profile.
PR_ApplyProfile(cv_lastprofile[0].value, 0);
}
return false;
@ -4452,6 +4464,28 @@ void M_MapProfileControl(event_t *ev)
optionsmenu.profile->controls[controln][where] = c;
optionsmenu.bindcontrol = 0; // not binding anymore
// If possible, reapply the profile...
if (gamestate == GS_MENU) // In menu? Apply this to P1, no questions asked.
{
// Apply the profile's properties to player 1 but keep the last profile cv to p1's ACTUAL profile to revert once we exit.
UINT8 lastp = cv_lastprofile[0].value;
PR_ApplyProfile(PR_GetProfileNum(optionsmenu.profile), 0);
CV_StealthSetValue(&cv_lastprofile[0], lastp);
}
else // != GS_MENU
{
// ONLY apply the profile if it's in use by anything currently.
UINT8 pnum = PR_GetProfileNum(optionsmenu.profile);
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
if (cv_lastprofile[i].value == pnum)
{
PR_ApplyProfile(pnum, i);
break;
}
}
}
}
#undef KEYHOLDFOR