forked from Ports/perfect_dark
port: add keybind menu
This commit is contained in:
1 parent
cea9527936
commit
c8db5fa106
3 files changed
+378
-14
No files matched your search
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#define INPUT_MAX_CONTROLLERS MAXCONTROLLERS
|
#define INPUT_MAX_CONTROLLERS MAXCONTROLLERS
|
||||||
#define INPUT_MAX_CONTROLLER_BUTTONS 32
|
#define INPUT_MAX_CONTROLLER_BUTTONS 32
|
||||||
|
#define INPUT_MAX_BINDS 4
|
||||||
|
|
||||||
#define CONT_STICK_XNEG 0x10000
|
#define CONT_STICK_XNEG 0x10000
|
||||||
#define CONT_STICK_XPOS 0x20000
|
#define CONT_STICK_XPOS 0x20000
|
||||||
@@ -115,6 +116,8 @@ s32 inputButtonPressed(s32 idx, u32 contbtn);
|
|||||||
// if bind is -1, picks a bind slot automatically
|
// if bind is -1, picks a bind slot automatically
|
||||||
void inputKeyBind(s32 idx, u32 ck, s32 bind, u32 vk);
|
void inputKeyBind(s32 idx, u32 ck, s32 bind, u32 vk);
|
||||||
|
|
||||||
|
const u32 *inputKeyGetBinds(s32 idx, u32 ck);
|
||||||
|
|
||||||
// get VK_ value from human-readable name
|
// get VK_ value from human-readable name
|
||||||
s32 inputGetKeyByName(const char *name);
|
s32 inputGetKeyByName(const char *name);
|
||||||
|
|
||||||
@@ -165,4 +168,9 @@ void inputUpdate(void);
|
|||||||
// call this before configSave()
|
// call this before configSave()
|
||||||
void inputSaveConfig(void);
|
void inputSaveConfig(void);
|
||||||
|
|
||||||
|
void inputSetDefaultKeyBinds(void);
|
||||||
|
|
||||||
|
void inputClearLastKey(void);
|
||||||
|
s32 inputGetLastKey(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+82
-14
@@ -10,7 +10,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
#define MAX_BINDS 4
|
|
||||||
#define TRIG_THRESHOLD (30 * 256)
|
#define TRIG_THRESHOLD (30 * 256)
|
||||||
#define DEFAULT_DEADZONE 4096
|
#define DEFAULT_DEADZONE 4096
|
||||||
#define DEFAULT_DEADZONE_RY 6144
|
#define DEFAULT_DEADZONE_RY 6144
|
||||||
@@ -21,7 +20,7 @@
|
|||||||
static SDL_GameController *pads[INPUT_MAX_CONTROLLERS];
|
static SDL_GameController *pads[INPUT_MAX_CONTROLLERS];
|
||||||
static s32 rumbleSupported[INPUT_MAX_CONTROLLERS];
|
static s32 rumbleSupported[INPUT_MAX_CONTROLLERS];
|
||||||
|
|
||||||
static u32 binds[MAXCONTROLLERS][CK_TOTAL_COUNT][MAX_BINDS]; // [i][CK_][b] = [VK_]
|
static u32 binds[MAXCONTROLLERS][CK_TOTAL_COUNT][INPUT_MAX_BINDS]; // [i][CK_][b] = [VK_]
|
||||||
|
|
||||||
static s32 connectedMask = 0;
|
static s32 connectedMask = 0;
|
||||||
|
|
||||||
@@ -37,6 +36,8 @@ static f32 mouseSensY = 1.5f;
|
|||||||
|
|
||||||
static f32 rumbleScale = 0.5f;
|
static f32 rumbleScale = 0.5f;
|
||||||
|
|
||||||
|
static s32 lastKey = 0;
|
||||||
|
|
||||||
// NOTE: by default this gets inverted for 1.2: "right stick" here means left stick on your controller
|
// NOTE: by default this gets inverted for 1.2: "right stick" here means left stick on your controller
|
||||||
static u32 axisMap[2][2] = {
|
static u32 axisMap[2][2] = {
|
||||||
{ SDL_CONTROLLER_AXIS_LEFTX, SDL_CONTROLLER_AXIS_LEFTY },
|
{ SDL_CONTROLLER_AXIS_LEFTX, SDL_CONTROLLER_AXIS_LEFTY },
|
||||||
@@ -186,6 +187,8 @@ void inputSetDefaultKeyBinds(void)
|
|||||||
{ CK_8000, SDL_CONTROLLER_BUTTON_LEFTSTICK },
|
{ CK_8000, SDL_CONTROLLER_BUTTON_LEFTSTICK },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
memset(binds, 0, sizeof(binds));
|
||||||
|
|
||||||
for (u32 i = 0; i < sizeof(kbbinds) / sizeof(kbbinds[0]); ++i) {
|
for (u32 i = 0; i < sizeof(kbbinds) / sizeof(kbbinds[0]); ++i) {
|
||||||
for (s32 j = 1; j < 3; ++j) {
|
for (s32 j = 1; j < 3; ++j) {
|
||||||
if (kbbinds[i][j]) {
|
if (kbbinds[i][j]) {
|
||||||
@@ -233,6 +236,18 @@ static inline void inputCloseController(const s32 cidx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline s32 inputControllerGetIndex(SDL_GameController *ctrl) {
|
||||||
|
if (ctrl) {
|
||||||
|
for (s32 i = 0; i < INPUT_MAX_CONTROLLERS; ++i) {
|
||||||
|
if (pads[i] == ctrl) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int inputEventFilter(void *data, SDL_Event *event)
|
static int inputEventFilter(void *data, SDL_Event *event)
|
||||||
{
|
{
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
@@ -250,19 +265,54 @@ static int inputEventFilter(void *data, SDL_Event *event)
|
|||||||
|
|
||||||
case SDL_CONTROLLERDEVICEREMOVED: {
|
case SDL_CONTROLLERDEVICEREMOVED: {
|
||||||
SDL_GameController *ctrl = SDL_GameControllerFromInstanceID(event->cdevice.which);
|
SDL_GameController *ctrl = SDL_GameControllerFromInstanceID(event->cdevice.which);
|
||||||
if (ctrl) {
|
const s32 idx = inputControllerGetIndex(ctrl);
|
||||||
for (s32 i = 0; i < INPUT_MAX_CONTROLLERS; ++i) {
|
if (idx >= 0) {
|
||||||
if (pads[i] == ctrl) {
|
inputCloseController(idx);
|
||||||
inputCloseController(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDL_MOUSEWHEEL:
|
case SDL_MOUSEWHEEL:
|
||||||
mouseWheel = event->wheel.y;
|
mouseWheel = event->wheel.y;
|
||||||
|
if (!lastKey && mouseWheel) {
|
||||||
|
lastKey = (mouseWheel < 0) + VK_MOUSE_WHEEL_UP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
if (!lastKey) {
|
||||||
|
lastKey = VK_MOUSE_BEGIN - 1 + event->button.button;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
if (!lastKey) {
|
||||||
|
lastKey = VK_KEYBOARD_BEGIN + event->key.keysym.scancode;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_CONTROLLERBUTTONDOWN:
|
||||||
|
if (!lastKey) {
|
||||||
|
lastKey = VK_JOY1_BEGIN + event->cbutton.button;
|
||||||
|
SDL_GameController *ctrl = SDL_GameControllerFromInstanceID(event->cdevice.which);
|
||||||
|
const s32 idx = inputControllerGetIndex(ctrl);
|
||||||
|
if (idx >= 0) {
|
||||||
|
lastKey += idx * INPUT_MAX_CONTROLLER_BUTTONS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_CONTROLLERAXISMOTION:
|
||||||
|
if (!lastKey) {
|
||||||
|
if (event->caxis.axis >= SDL_CONTROLLER_AXIS_TRIGGERLEFT && event->caxis.value > TRIG_THRESHOLD) {
|
||||||
|
lastKey = VK_JOY1_LTRIG + (event->caxis.axis - SDL_CONTROLLER_AXIS_TRIGGERLEFT);
|
||||||
|
SDL_GameController *ctrl = SDL_GameControllerFromInstanceID(event->cdevice.which);
|
||||||
|
const s32 idx = inputControllerGetIndex(ctrl);
|
||||||
|
if (idx >= 0) {
|
||||||
|
lastKey += idx * INPUT_MAX_CONTROLLER_BUTTONS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -349,7 +399,7 @@ static inline void inputSaveBinds(void)
|
|||||||
for (u32 ck = 0; ck < CK_TOTAL_COUNT; ++ck) {
|
for (u32 ck = 0; ck < CK_TOTAL_COUNT; ++ck) {
|
||||||
snprintf(keyname, sizeof(keyname), "%s.%s", secname, inputGetContKeyName(ck));
|
snprintf(keyname, sizeof(keyname), "%s.%s", secname, inputGetContKeyName(ck));
|
||||||
bindstr[0] = '\0';
|
bindstr[0] = '\0';
|
||||||
for (s32 b = 0; b < MAX_BINDS; ++b) {
|
for (s32 b = 0; b < INPUT_MAX_BINDS; ++b) {
|
||||||
if (binds[i][ck][b]) {
|
if (binds[i][ck][b]) {
|
||||||
if (b) {
|
if (b) {
|
||||||
strncat(bindstr, ", ", sizeof(bindstr) - 1);
|
strncat(bindstr, ", ", sizeof(bindstr) - 1);
|
||||||
@@ -500,7 +550,7 @@ s32 inputInit(void)
|
|||||||
|
|
||||||
static inline s32 inputBindPressed(const s32 idx, const u32 ck)
|
static inline s32 inputBindPressed(const s32 idx, const u32 ck)
|
||||||
{
|
{
|
||||||
for (s32 i = 0; i < MAX_BINDS; ++i) {
|
for (s32 i = 0; i < INPUT_MAX_BINDS; ++i) {
|
||||||
if (binds[idx][ck][i]) {
|
if (binds[idx][ck][i]) {
|
||||||
if (inputKeyPressed(binds[idx][ck][i])) {
|
if (inputKeyPressed(binds[idx][ck][i])) {
|
||||||
return 1;
|
return 1;
|
||||||
@@ -733,26 +783,34 @@ void inputControllerSetAxisDeadzone(s32 stick, s32 axis, f32 value)
|
|||||||
|
|
||||||
void inputKeyBind(s32 idx, u32 ck, s32 bind, u32 vk)
|
void inputKeyBind(s32 idx, u32 ck, s32 bind, u32 vk)
|
||||||
{
|
{
|
||||||
if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS || bind >= MAX_BINDS || ck >= CK_TOTAL_COUNT) {
|
if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS || bind >= INPUT_MAX_BINDS || ck >= CK_TOTAL_COUNT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (bind < 0) {
|
if (bind < 0) {
|
||||||
for (s32 i = 0; i < MAX_BINDS; ++i) {
|
for (s32 i = 0; i < INPUT_MAX_BINDS; ++i) {
|
||||||
if (binds[idx][ck][i] == 0) {
|
if (binds[idx][ck][i] == 0) {
|
||||||
bind = i;
|
bind = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bind < 0) {
|
if (bind < 0) {
|
||||||
bind = MAX_BINDS - 1; // just overwrite last
|
bind = INPUT_MAX_BINDS - 1; // just overwrite last
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
binds[idx][ck][bind] = vk;
|
binds[idx][ck][bind] = vk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const u32 *inputKeyGetBinds(s32 idx, u32 ck)
|
||||||
|
{
|
||||||
|
if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS || ck >= CK_TOTAL_COUNT) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return binds[idx][ck];
|
||||||
|
}
|
||||||
|
|
||||||
s32 inputKeyPressed(u32 vk)
|
s32 inputKeyPressed(u32 vk)
|
||||||
{
|
{
|
||||||
if (vk >= VK_KEYBOARD_BEGIN && vk < VK_MOUSE_BEGIN) {
|
if (vk >= VK_KEYBOARD_BEGIN && vk < VK_MOUSE_BEGIN) {
|
||||||
@@ -935,3 +993,13 @@ s32 inputGetKeyByName(const char *name)
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void inputClearLastKey(void)
|
||||||
|
{
|
||||||
|
lastKey = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 inputGetLastKey(void)
|
||||||
|
{
|
||||||
|
return lastKey;
|
||||||
|
}
|
||||||
@@ -11,6 +11,11 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
static s32 g_BindsPlayer = 0;
|
||||||
|
static s32 g_BindIndex = 0;
|
||||||
|
static u32 g_BindContKey = 0;
|
||||||
|
static char g_BindsPlayerText[] = "Player 1 Bindings";
|
||||||
|
|
||||||
static MenuItemHandlerResult menuhandlerMouseEnabled(s32 operation, struct menuitem *item, union handlerdata *data)
|
static MenuItemHandlerResult menuhandlerMouseEnabled(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
@@ -691,6 +696,281 @@ struct menudialogdef g_ExtendedGameMenuDialog = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerDoBind(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||||
|
|
||||||
|
struct menuitem g_ExtendedBindKeyMenuItems[] = {
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_LABEL,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"\n",
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SEPARATOR,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SELECTABLE,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Press new key or button...\n",
|
||||||
|
0,
|
||||||
|
menuhandlerDoBind,
|
||||||
|
},
|
||||||
|
{ MENUITEMTYPE_END },
|
||||||
|
};
|
||||||
|
|
||||||
|
struct menudialogdef g_ExtendedBindKeyMenuDialog = {
|
||||||
|
MENUDIALOGTYPE_WHITE,
|
||||||
|
(uintptr_t)"Bind",
|
||||||
|
g_ExtendedBindKeyMenuItems,
|
||||||
|
NULL,
|
||||||
|
MENUDIALOGFLAG_LITERAL_TEXT | MENUDIALOGFLAG_IGNOREBACK | MENUDIALOGFLAG_STARTSELECTS,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct menubind {
|
||||||
|
u32 ck;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct menubind menuBinds[] = {
|
||||||
|
{ CK_ZTRIG, "Fire [ZT]\n" },
|
||||||
|
{ CK_LTRIG, "Fire Mode [LT]\n" },
|
||||||
|
{ CK_RTRIG, "Aim Mode [RT]\n" },
|
||||||
|
{ CK_A, "Use / Accept [A]\n" },
|
||||||
|
{ CK_B, "Use / Cancel [B]\n" },
|
||||||
|
{ CK_X, "Reload [X]\n" },
|
||||||
|
{ CK_Y, "Next Weapon [Y]\n" },
|
||||||
|
{ CK_DPAD_L, "Prev Weapon [DL]\n" },
|
||||||
|
{ CK_DPAD_L, "Radial Menu [DD]\n" },
|
||||||
|
{ CK_START, "Pause Menu [ST]\n" },
|
||||||
|
{ CK_8000, "Cycle Crouch [+]\n" },
|
||||||
|
{ CK_4000, "Half Crouch [+]\n" },
|
||||||
|
{ CK_2000, "Full Crouch [+]\n" },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *menutextBind(struct menuitem *item);
|
||||||
|
static MenuItemHandlerResult menuhandlerBind(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||||
|
static MenuItemHandlerResult menuhandlerResetBinds(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||||
|
|
||||||
|
#define DEFINE_MENU_BIND() \
|
||||||
|
{ \
|
||||||
|
MENUITEMTYPE_DROPDOWN, \
|
||||||
|
0, \
|
||||||
|
0, \
|
||||||
|
(uintptr_t)menutextBind, \
|
||||||
|
0, \
|
||||||
|
menuhandlerBind, \
|
||||||
|
}
|
||||||
|
|
||||||
|
struct menuitem g_ExtendedBindsMenuItems[] = {
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
DEFINE_MENU_BIND(),
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SEPARATOR,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SELECTABLE,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Reset to Defaults\n",
|
||||||
|
0,
|
||||||
|
menuhandlerResetBinds,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SEPARATOR,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SELECTABLE,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
||||||
|
L_OPTIONS_213, // "Back"
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{ MENUITEMTYPE_END },
|
||||||
|
};
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerDoBind(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
if (!menuIsDialogOpen(&g_ExtendedBindKeyMenuDialog)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputKeyPressed(VK_ESCAPE)) {
|
||||||
|
menuPopDialog();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const s32 key = inputGetLastKey();
|
||||||
|
if (key && key != VK_ESCAPE) {
|
||||||
|
inputKeyBind(g_BindsPlayer, g_BindContKey, g_BindIndex, key);
|
||||||
|
menuPopDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *menutextBind(struct menuitem *item)
|
||||||
|
{
|
||||||
|
return menuBinds[item - g_ExtendedBindsMenuItems].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerBind(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
const s32 idx = item - g_ExtendedBindsMenuItems;
|
||||||
|
const u32 *binds;
|
||||||
|
|
||||||
|
static char keyname[128];
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case MENUOP_GETOPTIONCOUNT:
|
||||||
|
data->dropdown.value = INPUT_MAX_BINDS;
|
||||||
|
break;
|
||||||
|
case MENUOP_GETOPTIONTEXT:
|
||||||
|
binds = inputKeyGetBinds(g_BindsPlayer, menuBinds[idx].ck);
|
||||||
|
if (binds && binds[data->dropdown.value]) {
|
||||||
|
strncpy(keyname, inputGetKeyName(binds[data->dropdown.value]), sizeof(keyname) - 1);
|
||||||
|
for (char *p = keyname; *p; ++p) {
|
||||||
|
if (*p == '_') *p = ' ';
|
||||||
|
}
|
||||||
|
return (intptr_t)keyname;
|
||||||
|
}
|
||||||
|
return (intptr_t)"NONE";
|
||||||
|
case MENUOP_SET:
|
||||||
|
g_ExtendedBindKeyMenuItems[0].param2 = (uintptr_t)menuBinds[idx].name;
|
||||||
|
g_BindIndex = data->dropdown.value;
|
||||||
|
g_BindContKey = menuBinds[idx].ck;
|
||||||
|
inputClearLastKey();
|
||||||
|
menuPushDialog(&g_ExtendedBindKeyMenuDialog);
|
||||||
|
break;
|
||||||
|
case MENUOP_GETSELECTEDINDEX:
|
||||||
|
data->dropdown.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerResetBinds(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
if (operation == MENUOP_SET) {
|
||||||
|
inputSetDefaultKeyBinds();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct menudialogdef g_ExtendedBindsMenuDialog = {
|
||||||
|
MENUDIALOGTYPE_DEFAULT,
|
||||||
|
(uintptr_t)g_BindsPlayerText,
|
||||||
|
g_ExtendedBindsMenuItems,
|
||||||
|
NULL,
|
||||||
|
MENUDIALOGFLAG_LITERAL_TEXT | MENUDIALOGFLAG_STARTSELECTS | MENUDIALOGFLAG_IGNOREBACK,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerOpenBinds(s32 operation, struct menuitem *item, union handlerdata *data);
|
||||||
|
|
||||||
|
struct menuitem g_ExtendedSelectBindsMenuItems[] = {
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SELECTABLE,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Player 1\n",
|
||||||
|
0,
|
||||||
|
menuhandlerOpenBinds,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SELECTABLE,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Player 2\n",
|
||||||
|
0,
|
||||||
|
menuhandlerOpenBinds,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SELECTABLE,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Player 3\n",
|
||||||
|
0,
|
||||||
|
menuhandlerOpenBinds,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SELECTABLE,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Player 4\n",
|
||||||
|
0,
|
||||||
|
menuhandlerOpenBinds,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SEPARATOR,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SELECTABLE,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_SELECTABLE_CLOSESDIALOG,
|
||||||
|
L_OPTIONS_213, // "Back"
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
|
{ MENUITEMTYPE_END },
|
||||||
|
};
|
||||||
|
|
||||||
|
static MenuItemHandlerResult menuhandlerOpenBinds(s32 operation, struct menuitem *item, union handlerdata *data)
|
||||||
|
{
|
||||||
|
if (operation == MENUOP_SET) {
|
||||||
|
g_BindsPlayer = item - g_ExtendedSelectBindsMenuItems;
|
||||||
|
g_BindsPlayerText[7] = g_BindsPlayer + '1';
|
||||||
|
menuPushDialog(&g_ExtendedBindsMenuDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct menudialogdef g_ExtendedSelectBindsMenuDialog = {
|
||||||
|
MENUDIALOGTYPE_DEFAULT,
|
||||||
|
(uintptr_t)"Key Bindings",
|
||||||
|
g_ExtendedSelectBindsMenuItems,
|
||||||
|
NULL,
|
||||||
|
MENUDIALOGFLAG_LITERAL_TEXT,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
struct menuitem g_ExtendedMenuItems[] = {
|
struct menuitem g_ExtendedMenuItems[] = {
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_SELECTABLE,
|
MENUITEMTYPE_SELECTABLE,
|
||||||
@@ -724,6 +1004,14 @@ struct menuitem g_ExtendedMenuItems[] = {
|
|||||||
0,
|
0,
|
||||||
(void *)&g_ExtendedGameMenuDialog,
|
(void *)&g_ExtendedGameMenuDialog,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MENUITEMTYPE_SELECTABLE,
|
||||||
|
0,
|
||||||
|
MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_LITERAL_TEXT,
|
||||||
|
(uintptr_t)"Key Bindings\n",
|
||||||
|
0,
|
||||||
|
(void *)&g_ExtendedSelectBindsMenuDialog,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MENUITEMTYPE_SEPARATOR,
|
MENUITEMTYPE_SEPARATOR,
|
||||||
0,
|
0,
|
||||||
|
|||||||
Reference in new issue
Block a user