mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Profiles: control setup (wip but does what it needs to for now)
This commit is contained in:
parent
5601fa4c22
commit
ebc2156b7e
5 changed files with 377 additions and 7 deletions
26
src/k_menu.h
26
src/k_menu.h
|
|
@ -20,6 +20,7 @@
|
|||
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
|
||||
#include "g_demo.h" //menudemo_t
|
||||
#include "k_profiles.h" // profile data & functions
|
||||
#include "g_input.h" // gc_
|
||||
|
||||
// flags for items in the menu
|
||||
// menu handle (what we do when key is pressed
|
||||
|
|
@ -226,6 +227,9 @@ extern menu_t OPTIONS_ProfilesDef;
|
|||
extern menuitem_t OPTIONS_EditProfile[];
|
||||
extern menu_t OPTIONS_EditProfileDef;
|
||||
|
||||
extern menuitem_t OPTIONS_ProfileControls[];
|
||||
extern menu_t OPTIONS_ProfileControlsDef;
|
||||
|
||||
extern menuitem_t OPTIONS_Video[];
|
||||
extern menu_t OPTIONS_VideoDef;
|
||||
|
||||
|
|
@ -626,6 +630,17 @@ extern struct optionsmenu_s {
|
|||
boolean resetprofile; // After going back from the edit menu, this tells the profile select menu to kill the profile data after the transition.
|
||||
profile_t *profile; // Pointer to the profile we're editing
|
||||
|
||||
INT16 controlscroll; // scrolling for the control menu....
|
||||
UINT8 bindcontrol; // 0: not binding, 1: binding control #1, 2: binding control #2
|
||||
INT16 bindtimer; // Timer until binding is cancelled (5s)
|
||||
|
||||
// controller coords...
|
||||
// Works the same as (t)opt
|
||||
INT16 contx;
|
||||
INT16 conty;
|
||||
INT16 tcontx;
|
||||
INT16 tconty;
|
||||
|
||||
// for video mode testing:
|
||||
INT32 vidm_testingmode;
|
||||
INT32 vidm_previousmode;
|
||||
|
|
@ -643,6 +658,8 @@ extern struct optionsmenu_s {
|
|||
tic_t fade;
|
||||
} optionsmenu;
|
||||
|
||||
extern INT16 controlleroffsets[][2];
|
||||
|
||||
extern consvar_t cv_dummyprofilename;
|
||||
extern consvar_t cv_dummyprofileplayername;
|
||||
|
||||
|
|
@ -659,9 +676,17 @@ void M_EraseData(INT32 choice); // For data erasing
|
|||
void M_ProfileSelectInit(INT32 choice);
|
||||
void M_HandleProfileSelect(INT32 ch);
|
||||
|
||||
// profile edition
|
||||
void M_HandleProfileEdit(void);
|
||||
void M_ProfileDeviceSelect(INT32 choice);
|
||||
boolean M_ProfileEditInputs(INT32 ch);
|
||||
|
||||
void M_HandleProfileControls(void);
|
||||
boolean M_ProfileControlsInputs(INT32 ch);
|
||||
void M_ProfileSetControl(INT32 ch);
|
||||
|
||||
void M_MapProfileControl(event_t *ev);
|
||||
|
||||
// video modes menu (resolution)
|
||||
void M_VideoModeMenu(INT32 choice);
|
||||
void M_HandleVideoModes(INT32 ch);
|
||||
|
|
@ -802,6 +827,7 @@ void M_DrawOptions(void);
|
|||
void M_DrawGenericOptions(void);
|
||||
void M_DrawProfileSelect(void);
|
||||
void M_DrawEditProfile(void);
|
||||
void M_DrawProfileControls(void);
|
||||
void M_DrawVideoModes(void);
|
||||
void M_DrawItemToggles(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -441,8 +441,8 @@ menuitem_t OPTIONS_EditProfile[] = {
|
|||
{IT_STRING | IT_CALL, "Character", "Default character and color for this Profile.",
|
||||
NULL, M_CharacterSelect, 0, 0},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, "Controls", "Select the button mappings for this Profile.",
|
||||
NULL, NULL, 0, 0},
|
||||
{IT_STRING | IT_CALL, "Controls", "Select the button mappings for this Profile.",
|
||||
NULL, M_ProfileDeviceSelect, 0, 0},
|
||||
};
|
||||
|
||||
menu_t OPTIONS_EditProfileDef = {
|
||||
|
|
@ -460,6 +460,96 @@ menu_t OPTIONS_EditProfileDef = {
|
|||
M_ProfileEditInputs,
|
||||
};
|
||||
|
||||
menuitem_t OPTIONS_ProfileControls[] = {
|
||||
|
||||
{IT_HEADER, "MAIN CONTROLS", "That's the stuff on the controller!!",
|
||||
NULL, NULL, 0, 0},
|
||||
|
||||
{IT_CONTROL, "A", "Accelerate / Confirm",
|
||||
"PR_BTA", M_ProfileSetControl, gc_a, 0},
|
||||
|
||||
{IT_CONTROL, "B", "Look backwards / Back",
|
||||
"PR_BTB", M_ProfileSetControl, gc_b, 0},
|
||||
|
||||
{IT_CONTROL, "C", "Spindash",
|
||||
"PR_BTC", M_ProfileSetControl, gc_c, 0},
|
||||
|
||||
{IT_CONTROL, "X", "Brake",
|
||||
"PR_BTX", M_ProfileSetControl, gc_x, 0},
|
||||
|
||||
// @TODO What does this do???
|
||||
{IT_CONTROL, "Y", "We just don't know",
|
||||
"PR_BTY", M_ProfileSetControl, gc_y, 0},
|
||||
|
||||
{IT_CONTROL, "Z", "We just don't know",
|
||||
"PR_BTZ", M_ProfileSetControl, gc_z, 0},
|
||||
|
||||
{IT_CONTROL, "L", "Use item",
|
||||
"PR_BTL", M_ProfileSetControl, gc_l, 0},
|
||||
|
||||
{IT_CONTROL, "R", "Drift",
|
||||
"PR_BTR", M_ProfileSetControl, gc_r, 0},
|
||||
|
||||
{IT_CONTROL, "Turn Left", "Turn left",
|
||||
"PR_PADL", M_ProfileSetControl, gc_left, 0},
|
||||
|
||||
{IT_CONTROL, "Turn Right", "Turn right",
|
||||
"PR_PADR", M_ProfileSetControl, gc_right, 0},
|
||||
|
||||
{IT_CONTROL, "Aim Forward", "Aim forwards",
|
||||
"PR_PADU", M_ProfileSetControl, gc_up, 0},
|
||||
|
||||
{IT_CONTROL, "Aim Backwards", "Aim backwards",
|
||||
"PR_PADD", M_ProfileSetControl, gc_down, 0},
|
||||
|
||||
{IT_CONTROL, "Start", "Open pause menu",
|
||||
"PR_BTS", M_ProfileSetControl, gc_start, 0},
|
||||
|
||||
{IT_HEADER, "OPTIONAL CONTROLS", "Take a screenshot, chat...",
|
||||
NULL, NULL, 0, 0},
|
||||
|
||||
{IT_CONTROL, "SCREENSHOT", "Also usable with F8 on Keyboard.",
|
||||
NULL, M_ProfileSetControl, gc_screenshot, 0},
|
||||
|
||||
{IT_CONTROL, "GIF CAPTURE", "Also usable with F9 on Keyboard.",
|
||||
NULL, M_ProfileSetControl, gc_recordgif, 0},
|
||||
|
||||
{IT_CONTROL, "OPEN CHAT", "Opens chatbox in online games.",
|
||||
NULL, M_ProfileSetControl, gc_talk, 0},
|
||||
|
||||
{IT_CONTROL, "OPEN TEAM CHAT", "Do we even have team gamemodes?",
|
||||
NULL, M_ProfileSetControl, gc_teamtalk, 0},
|
||||
|
||||
{IT_CONTROL, "OPEN CONSOLE", "Also usable with ` on Keyboard.",
|
||||
NULL, M_ProfileSetControl, gc_console, 0},
|
||||
|
||||
{IT_CONTROL, "LUA/A", "May be used by add-ons.",
|
||||
NULL, M_ProfileSetControl, gc_luaa, 0},
|
||||
|
||||
{IT_CONTROL, "LUA/B", "May be used by add-ons.",
|
||||
NULL, M_ProfileSetControl, gc_luab, 0},
|
||||
|
||||
{IT_CONTROL, "LUA/C", "May be used by add-ons.",
|
||||
NULL, M_ProfileSetControl, gc_luac, 0},
|
||||
};
|
||||
|
||||
|
||||
|
||||
menu_t OPTIONS_ProfileControlsDef = {
|
||||
sizeof (OPTIONS_ProfileControls) / sizeof (menuitem_t),
|
||||
&OPTIONS_EditProfileDef,
|
||||
0,
|
||||
OPTIONS_ProfileControls,
|
||||
32, 80,
|
||||
SKINCOLOR_ULTRAMARINE, 0,
|
||||
3, 10,
|
||||
M_DrawProfileControls,
|
||||
M_HandleProfileControls,
|
||||
NULL,
|
||||
NULL,
|
||||
M_ProfileControlsInputs,
|
||||
};
|
||||
|
||||
// video options menu...
|
||||
// options menu
|
||||
menuitem_t OPTIONS_Video[] =
|
||||
|
|
|
|||
120
src/k_menudraw.c
120
src/k_menudraw.c
|
|
@ -2268,6 +2268,126 @@ void M_DrawEditProfile(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Controller offsets to center on each button.
|
||||
INT16 controlleroffsets[][2] = {
|
||||
{0, 0}, // gc_none
|
||||
{70, 112}, // gc_up
|
||||
{70, 112}, // gc_down
|
||||
{70, 112}, // gc_left
|
||||
{70, 112}, // gc_right
|
||||
{208, 200}, // gc_a
|
||||
{237, 181}, // gc_b
|
||||
{267, 166}, // gc_c
|
||||
{191, 164}, // gc_x
|
||||
{215, 149}, // gc_y
|
||||
{242, 137}, // gc_z
|
||||
{55, 102}, // gc_l
|
||||
{253, 102}, // gc_r
|
||||
{149, 187}, // gc_start
|
||||
};
|
||||
|
||||
// the control stuff.
|
||||
// Dear god.
|
||||
void M_DrawProfileControls(void)
|
||||
{
|
||||
const UINT8 spacing = 34;
|
||||
INT32 y = 16 - (optionsmenu.controlscroll*spacing);
|
||||
INT32 x = 8;
|
||||
INT32 i, j;
|
||||
|
||||
M_DrawOptionsCogs();
|
||||
|
||||
// @TODO: have it move around and shit.
|
||||
V_DrawScaledPatch(BASEVIDWIDTH*2/3 - optionsmenu.contx, BASEVIDHEIGHT/2 -optionsmenu.conty, 0, W_CachePatchName("PR_CONT", PU_CACHE));
|
||||
|
||||
// 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);
|
||||
if (currentMenu->menuitems[itemOn].tooltip != NULL)
|
||||
{
|
||||
V_DrawCenteredThinString(BASEVIDWIDTH*2/3, 12, V_ALLOWLOWERCASE|V_6WIDTHSPACE, currentMenu->menuitems[itemOn].tooltip);
|
||||
}
|
||||
|
||||
V_DrawFill(0, 0, 138, 200, 31); // Black border
|
||||
|
||||
// Draw the menu options...
|
||||
for (i = 0; i < currentMenu->numitems; i++)
|
||||
{
|
||||
char buf[256];
|
||||
INT32 keys[2];
|
||||
|
||||
// cursor
|
||||
if (i == itemOn)
|
||||
{
|
||||
for (j=0; j < 24; j++)
|
||||
V_DrawFill(0, (y)+j, 128+j, 1, 73);
|
||||
}
|
||||
|
||||
switch (currentMenu->menuitems[i].status & IT_DISPLAY)
|
||||
{
|
||||
case IT_HEADERTEXT:
|
||||
V_DrawFill(0, y+17, 124, 1, 0); // underline
|
||||
V_DrawString(x, y+8, 0, currentMenu->menuitems[i].text);
|
||||
y += spacing;
|
||||
break;
|
||||
|
||||
case IT_STRING2:
|
||||
|
||||
if (currentMenu->menuitems[i].patch)
|
||||
V_DrawScaledPatch(x+12, y+12, 0, W_CachePatchName(currentMenu->menuitems[i].patch, PU_CACHE));
|
||||
else
|
||||
V_DrawString(x, y+1, (i == itemOn ? highlightflags : 0), currentMenu->menuitems[i].text);
|
||||
|
||||
if (currentMenu->menuitems[i].status & IT_CONTROL)
|
||||
{
|
||||
// Draw what the controls are mapped to
|
||||
keys[0] = optionsmenu.profile->controls[currentMenu->menuitems[i].mvar1][0];
|
||||
keys[1] = optionsmenu.profile->controls[currentMenu->menuitems[i].mvar1][1];
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
if (keys[0] == KEY_NULL && keys[1] == KEY_NULL)
|
||||
strcpy(buf, "\x85NOT BOUND");
|
||||
else
|
||||
{
|
||||
if (keys[0] != KEY_NULL)
|
||||
strcat (buf, G_KeynumToString (keys[0]));
|
||||
|
||||
if (keys[0] != KEY_NULL && keys[1] != KEY_NULL)
|
||||
strcat(buf," / ");
|
||||
|
||||
if (keys[1] != KEY_NULL)
|
||||
strcat (buf, G_KeynumToString (keys[1]));
|
||||
}
|
||||
|
||||
V_DrawThinString(x+32, y+12, V_6WIDTHSPACE, buf);
|
||||
|
||||
// controller dest coords:
|
||||
if (itemOn == i && currentMenu->menuitems[i].mvar1 && currentMenu->menuitems[i].mvar1 <= gc_start)
|
||||
{
|
||||
optionsmenu.tcontx = controlleroffsets[currentMenu->menuitems[i].mvar1][0];
|
||||
optionsmenu.tconty = controlleroffsets[currentMenu->menuitems[i].mvar1][1];
|
||||
}
|
||||
}
|
||||
|
||||
y += spacing;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Overlay for control binding
|
||||
if (optionsmenu.bindcontrol)
|
||||
{
|
||||
V_DrawFadeScreen(31, 8);
|
||||
|
||||
M_DrawTextBox((BASEVIDWIDTH/2) - (120), (BASEVIDHEIGHT/2) - (16), 30, 4);
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), 0, va("Press key #%d for control", optionsmenu.bindcontrol));
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4) +10, 0, va("\"%s\"", currentMenu->menuitems[itemOn].text));
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4) +20, highlightflags, va("(WAIT %d SECONDS TO SKIP)", optionsmenu.bindtimer/TICRATE));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the video modes list, a-la-Quake
|
||||
void M_DrawVideoModes(void)
|
||||
{
|
||||
|
|
|
|||
142
src/k_menufunc.c
142
src/k_menufunc.c
|
|
@ -831,6 +831,14 @@ boolean M_Responder(event_t *ev)
|
|||
// update keys current state
|
||||
G_MapEventsToControls(ev);
|
||||
|
||||
// Profiles: Control mapping.
|
||||
// We take the WHOLE EVENT for convenience.
|
||||
if (optionsmenu.bindcontrol)
|
||||
{
|
||||
M_MapProfileControl(ev);
|
||||
return true; // eat events.
|
||||
}
|
||||
|
||||
// Handle menu handling in-game.
|
||||
if (menuactive == false)
|
||||
{
|
||||
|
|
@ -1399,13 +1407,14 @@ static void M_HandleMenuInput(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
#if 0 // this shit is crazy
|
||||
//#if 0 // this shit is crazy
|
||||
if (routine)
|
||||
{
|
||||
void (*otherroutine)(event_t *sev) = currentMenu->menuitems[itemOn].itemaction;
|
||||
otherroutine(ev); //Alam: what a hack
|
||||
//void (*otherroutine)(event_t *sev) = currentMenu->menuitems[itemOn].itemaction;
|
||||
//otherroutine(menuKey); //Alam: what a hack
|
||||
routine(menuKey);
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -3744,6 +3753,131 @@ void M_HandleVideoModes(INT32 ch)
|
|||
}
|
||||
}
|
||||
|
||||
static void M_ProfileDeviceSelectResponse(INT32 key)
|
||||
{
|
||||
UINT8 i;
|
||||
(void) key;
|
||||
|
||||
for (i=0; i < MAXDEVICES; i++)
|
||||
{
|
||||
if (deviceResponding[i])
|
||||
{
|
||||
CV_SetValue(&cv_usejoystick[0], i); // Force-set this joystick as the current joystick we're using for P1 (which is the only one controlling menus)
|
||||
CONS_Printf("Using device %d for mappings\n", i);
|
||||
M_SetupNextMenu(&OPTIONS_ProfileControlsDef, false); // with that set, send us to the control def
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prompt a device selection window (just tap any button on the device you want)
|
||||
void M_ProfileDeviceSelect(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
// While we're here, setup the incoming controls menu to reset the scroll & bind status:
|
||||
optionsmenu.controlscroll = 0;
|
||||
optionsmenu.bindcontrol = 0;
|
||||
optionsmenu.bindtimer = 0;
|
||||
|
||||
optionsmenu.contx = optionsmenu.tcontx = controlleroffsets[gc_a][0];
|
||||
optionsmenu.conty = optionsmenu.tconty = controlleroffsets[gc_a][1];
|
||||
|
||||
M_StartMessage(M_GetText("Press any key on the device\nyou would like to use"), M_ProfileDeviceSelectResponse, MM_EVENTHANDLER);
|
||||
}
|
||||
|
||||
void M_HandleProfileControls(void)
|
||||
{
|
||||
UINT8 maxscroll = currentMenu->numitems - 5;
|
||||
M_OptionsTick();
|
||||
|
||||
optionsmenu.contx += (optionsmenu.tcontx - optionsmenu.contx)/2;
|
||||
optionsmenu.conty += (optionsmenu.tconty - optionsmenu.conty)/2;
|
||||
|
||||
if (abs(optionsmenu.contx - optionsmenu.tcontx) < 2 && abs(optionsmenu.conty - optionsmenu.tconty) < 2)
|
||||
{
|
||||
optionsmenu.contx = optionsmenu.tcontx;
|
||||
optionsmenu.conty = optionsmenu.tconty; // Avoid awkward 1 px errors.
|
||||
}
|
||||
|
||||
optionsmenu.controlscroll = itemOn - 3; // very barebones scrolling, but it works just fine for our purpose.
|
||||
if (optionsmenu.controlscroll > maxscroll)
|
||||
optionsmenu.controlscroll = maxscroll;
|
||||
|
||||
if (optionsmenu.controlscroll < 0)
|
||||
optionsmenu.controlscroll = 0;
|
||||
|
||||
// bindings, cancel if timer is depleted.
|
||||
if (optionsmenu.bindcontrol)
|
||||
{
|
||||
optionsmenu.bindtimer--;
|
||||
if (!optionsmenu.bindtimer)
|
||||
{
|
||||
optionsmenu.bindcontrol++;
|
||||
if (optionsmenu.bindcontrol > 2)
|
||||
optionsmenu.bindcontrol = 0; // we've gone past the max, just stop.
|
||||
else
|
||||
optionsmenu.bindtimer = TICRATE*5; // skip control
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
boolean M_ProfileControlsInputs(INT32 ch)
|
||||
{
|
||||
(void)ch;
|
||||
|
||||
// By default, accept all inputs.
|
||||
if (optionsmenu.bindcontrol)
|
||||
return true; // Eat all inputs there. We'll use a stupid hack in M_Responder instead.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void M_ProfileSetControl(INT32 ch)
|
||||
{
|
||||
(void) ch;
|
||||
|
||||
optionsmenu.bindcontrol = 1;
|
||||
optionsmenu.bindtimer = TICRATE*5;
|
||||
}
|
||||
|
||||
// Map the event to the profile.
|
||||
void M_MapProfileControl(event_t *ev)
|
||||
{
|
||||
INT32 c = ev->data1;
|
||||
UINT8 n = optionsmenu.bindcontrol-1; // # of input to bind
|
||||
INT32 controln = currentMenu->menuitems[itemOn].mvar1; // gc_
|
||||
UINT8 where = n; // By default, we'll save the bind where we're supposed to map.
|
||||
|
||||
// Only consider keydown events to make sure we ignore ev_mouse and ev_joystick as well
|
||||
if (ev->type != ev_keydown)
|
||||
return;
|
||||
|
||||
// Check if this control is already assigned, it'd look silly to assign the same key twice on the same thing.
|
||||
if (n == 0 && optionsmenu.profile->controls[controln][1] == c)
|
||||
{
|
||||
optionsmenu.profile->controls[controln][1] = KEY_NULL; // unbind
|
||||
where = 0; // save control in slot 0
|
||||
}
|
||||
else if (n == 1 && optionsmenu.profile->controls[controln][0] == c)
|
||||
{
|
||||
// Do nothing and exit this menu.
|
||||
optionsmenu.bindcontrol = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
optionsmenu.profile->controls[controln][where] = c;
|
||||
|
||||
optionsmenu.bindcontrol++;
|
||||
optionsmenu.bindtimer = TICRATE*5;
|
||||
if (optionsmenu.bindcontrol > 2)
|
||||
{
|
||||
optionsmenu.bindtimer = 0;
|
||||
optionsmenu.bindcontrol = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void M_HandleItemToggles(INT32 choice)
|
||||
{
|
||||
const INT32 width = 9, height = 3;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ profile_t PR_MakeProfile(const char *prname, const char *pname, const char *snam
|
|||
new.version = PROFILEVER;
|
||||
|
||||
strcpy(new.profilename, prname);
|
||||
|
||||
|
||||
strcpy(new.skinname, sname);
|
||||
strcpy(new.playername, pname);
|
||||
new.color = col;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue