Merge pull request #255 from Laupetin/feature/controller-bind-menus
Make keybind fields in menus work with controller keys
This commit is contained in:
commit
c99b6b058f
@ -1033,6 +1033,13 @@ namespace Components
|
|||||||
|
|
||||||
void Gamepad::UI_GamepadKeyEvent(const int gamePadIndex, const int key, const bool down)
|
void Gamepad::UI_GamepadKeyEvent(const int gamePadIndex, const int key, const bool down)
|
||||||
{
|
{
|
||||||
|
// If we are currently capturing a key for menu bind inputs then do not map keys and pass to game
|
||||||
|
if (*Game::g_waitingForKey)
|
||||||
|
{
|
||||||
|
Game::UI_KeyEvent(gamePadIndex, key, down);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& mapping : controllerMenuKeyMappings)
|
for (const auto& mapping : controllerMenuKeyMappings)
|
||||||
{
|
{
|
||||||
if (mapping.controllerKey == key)
|
if (mapping.controllerKey == key)
|
||||||
@ -1777,19 +1784,19 @@ namespace Components
|
|||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Gamepad::Key_GetCommandAssignmentInternal_Hk(const char* cmd, int (*keys)[2])
|
int Gamepad::Key_GetCommandAssignmentInternal([[maybe_unused]] int localClientNum, const char* cmd, int (*keys)[2])
|
||||||
{
|
{
|
||||||
auto keyCount = 0;
|
auto keyCount = 0;
|
||||||
|
|
||||||
if (gamePads[0].inUse)
|
if (gamePads[0].inUse)
|
||||||
{
|
{
|
||||||
cmd = GetGamePadCommand(cmd);
|
const auto gamePadCmd = GetGamePadCommand(cmd);
|
||||||
for (auto keyNum = 0; keyNum < Game::K_LAST_KEY; keyNum++)
|
for (auto keyNum = 0; keyNum < Game::K_LAST_KEY; keyNum++)
|
||||||
{
|
{
|
||||||
if (!Key_IsValidGamePadChar(keyNum))
|
if (!Key_IsValidGamePadChar(keyNum))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (Game::playerKeys[0].keys[keyNum].binding && strcmp(Game::playerKeys[0].keys[keyNum].binding, cmd) == 0)
|
if (Game::playerKeys[0].keys[keyNum].binding && strcmp(Game::playerKeys[0].keys[keyNum].binding, gamePadCmd) == 0)
|
||||||
{
|
{
|
||||||
(*keys)[keyCount++] = keyNum;
|
(*keys)[keyCount++] = keyNum;
|
||||||
|
|
||||||
@ -1818,6 +1825,35 @@ namespace Components
|
|||||||
return keyCount;
|
return keyCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __declspec(naked) Gamepad::Key_GetCommandAssignmentInternal_Stub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push eax
|
||||||
|
pushad
|
||||||
|
|
||||||
|
push [esp + 0x20 + 0x4 + 0x8] // keyNums
|
||||||
|
push [esp + 0x20 + 0x4 + 0x8] // command
|
||||||
|
push eax // localClientNum
|
||||||
|
call Key_GetCommandAssignmentInternal
|
||||||
|
add esp, 0xC
|
||||||
|
|
||||||
|
mov[esp + 0x20], eax
|
||||||
|
|
||||||
|
popad
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gamepad::Key_SetBinding_Hk(const int localClientNum, const int keyNum, const char* binding)
|
||||||
|
{
|
||||||
|
if(Key_IsValidGamePadChar(keyNum))
|
||||||
|
gpad_buttonConfig.set("custom");
|
||||||
|
|
||||||
|
Game::Key_SetBinding(localClientNum, keyNum, binding);
|
||||||
|
}
|
||||||
|
|
||||||
void Gamepad::CL_KeyEvent_Hk(const int localClientNum, const int key, const int down, const unsigned time)
|
void Gamepad::CL_KeyEvent_Hk(const int localClientNum, const int key, const int down, const unsigned time)
|
||||||
{
|
{
|
||||||
// A keyboard key has been pressed. Mark controller as unused.
|
// A keyboard key has been pressed. Mark controller as unused.
|
||||||
@ -1954,7 +1990,12 @@ namespace Components
|
|||||||
Utils::Hook(0x48E527, UI_RefreshViewport_Hk, HOOK_CALL).install()->quick();
|
Utils::Hook(0x48E527, UI_RefreshViewport_Hk, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
// Only return gamepad keys when gamepad enabled and only non gamepad keys when not
|
// Only return gamepad keys when gamepad enabled and only non gamepad keys when not
|
||||||
Utils::Hook(0x5A7A23, Key_GetCommandAssignmentInternal_Hk, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5A7890, Key_GetCommandAssignmentInternal_Stub, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
// Whenever a key binding for a gamepad key is replaced update the button config
|
||||||
|
Utils::Hook(0x47D473, Key_SetBinding_Hk, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x47D485, Key_SetBinding_Hk, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x47D49D, Key_SetBinding_Hk, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
// Add gamepad inputs to remote control (eg predator) handling
|
// Add gamepad inputs to remote control (eg predator) handling
|
||||||
Utils::Hook(0x5A6D4E, CL_RemoteControlMove_Stub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5A6D4E, CL_RemoteControlMove_Stub, HOOK_CALL).install()->quick();
|
||||||
|
@ -192,7 +192,9 @@ namespace Components
|
|||||||
static void CG_RegisterDvars_Hk();
|
static void CG_RegisterDvars_Hk();
|
||||||
|
|
||||||
static const char* GetGamePadCommand(const char* command);
|
static const char* GetGamePadCommand(const char* command);
|
||||||
static int Key_GetCommandAssignmentInternal_Hk(const char* cmd, int(*keys)[2]);
|
static int Key_GetCommandAssignmentInternal(int localClientNum, const char* cmd, int (*keys)[2]);
|
||||||
|
static void Key_GetCommandAssignmentInternal_Stub();
|
||||||
|
static void Key_SetBinding_Hk(int localClientNum, int keyNum, const char* binding);
|
||||||
static bool IsGamePadInUse();
|
static bool IsGamePadInUse();
|
||||||
static void CL_KeyEvent_Hk(int localClientNum, int key, int down, unsigned int time);
|
static void CL_KeyEvent_Hk(int localClientNum, int key, int down, unsigned int time);
|
||||||
static int CL_MouseEvent_Hk(int x, int y, int dx, int dy);
|
static int CL_MouseEvent_Hk(int x, int y, int dx, int dy);
|
||||||
|
@ -171,6 +171,7 @@ namespace Game
|
|||||||
Key_SetCatcher_t Key_SetCatcher = Key_SetCatcher_t(0x43BD00);
|
Key_SetCatcher_t Key_SetCatcher = Key_SetCatcher_t(0x43BD00);
|
||||||
Key_RemoveCatcher_t Key_RemoveCatcher = Key_RemoveCatcher_t(0x408260);
|
Key_RemoveCatcher_t Key_RemoveCatcher = Key_RemoveCatcher_t(0x408260);
|
||||||
Key_IsKeyCatcherActive_t Key_IsKeyCatcherActive = Key_IsKeyCatcherActive_t(0x4DA010);
|
Key_IsKeyCatcherActive_t Key_IsKeyCatcherActive = Key_IsKeyCatcherActive_t(0x4DA010);
|
||||||
|
Key_SetBinding_t Key_SetBinding = Key_SetBinding_t(0x494C90);
|
||||||
|
|
||||||
LargeLocalInit_t LargeLocalInit = LargeLocalInit_t(0x4A62A0);
|
LargeLocalInit_t LargeLocalInit = LargeLocalInit_t(0x4A62A0);
|
||||||
|
|
||||||
@ -558,6 +559,8 @@ namespace Game
|
|||||||
int* window_center_x = reinterpret_cast<int*>(0x649D638);
|
int* window_center_x = reinterpret_cast<int*>(0x649D638);
|
||||||
int* window_center_y = reinterpret_cast<int*>(0x649D630);
|
int* window_center_y = reinterpret_cast<int*>(0x649D630);
|
||||||
|
|
||||||
|
int* g_waitingForKey = reinterpret_cast<int*>(0x63A50FC);
|
||||||
|
|
||||||
void Sys_LockRead(FastCriticalSection* critSect)
|
void Sys_LockRead(FastCriticalSection* critSect)
|
||||||
{
|
{
|
||||||
InterlockedIncrement(&critSect->readCount);
|
InterlockedIncrement(&critSect->readCount);
|
||||||
|
@ -420,6 +420,9 @@ namespace Game
|
|||||||
typedef bool(__cdecl * Key_IsKeyCatcherActive_t)(int localClientNum, int catcher);
|
typedef bool(__cdecl * Key_IsKeyCatcherActive_t)(int localClientNum, int catcher);
|
||||||
extern Key_IsKeyCatcherActive_t Key_IsKeyCatcherActive;
|
extern Key_IsKeyCatcherActive_t Key_IsKeyCatcherActive;
|
||||||
|
|
||||||
|
typedef void(__cdecl * Key_SetBinding_t)(int localClientNum, int keyNum, const char* binding);
|
||||||
|
extern Key_SetBinding_t Key_SetBinding;
|
||||||
|
|
||||||
typedef void(__cdecl * LargeLocalInit_t)();
|
typedef void(__cdecl * LargeLocalInit_t)();
|
||||||
extern LargeLocalInit_t LargeLocalInit;
|
extern LargeLocalInit_t LargeLocalInit;
|
||||||
|
|
||||||
@ -1158,6 +1161,8 @@ namespace Game
|
|||||||
extern int* window_center_x;
|
extern int* window_center_x;
|
||||||
extern int* window_center_y;
|
extern int* window_center_y;
|
||||||
|
|
||||||
|
extern int* g_waitingForKey;
|
||||||
|
|
||||||
void Sys_LockRead(FastCriticalSection* critSect);
|
void Sys_LockRead(FastCriticalSection* critSect);
|
||||||
void Sys_UnlockRead(FastCriticalSection* critSect);
|
void Sys_UnlockRead(FastCriticalSection* critSect);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user