Add gamepad location selection support

This commit is contained in:
Jan 2021-08-24 17:20:52 +02:00
parent fea24a509a
commit 8adea24d67
5 changed files with 119 additions and 10 deletions

View File

@ -179,6 +179,7 @@ namespace Components
Dvar::Var Gamepad::aim_input_graph_index; Dvar::Var Gamepad::aim_input_graph_index;
Dvar::Var Gamepad::aim_scale_view_axis; Dvar::Var Gamepad::aim_scale_view_axis;
Dvar::Var Gamepad::cl_bypassMouseInput; Dvar::Var Gamepad::cl_bypassMouseInput;
Dvar::Var Gamepad::cg_mapLocationSelectionCursorSpeed;
Dvar::Var Gamepad::xpadSensitivity; Dvar::Var Gamepad::xpadSensitivity;
Dvar::Var Gamepad::xpadEarlyTime; Dvar::Var Gamepad::xpadEarlyTime;
@ -223,7 +224,7 @@ namespace Components
__declspec(naked) void Gamepad::MSG_WriteDeltaUsercmdKeyStub() __declspec(naked) void Gamepad::MSG_WriteDeltaUsercmdKeyStub()
{ {
__asm __asm
{ {
// fix stack pointer // fix stack pointer
add esp, 0Ch add esp, 0Ch
@ -241,7 +242,7 @@ namespace Components
// return back // return back
push 0x60E40E push 0x60E40E
retn retn
} }
} }
void Gamepad::ApplyMovement(Game::msg_t* msg, int key, Game::usercmd_s* from, Game::usercmd_s* to) void Gamepad::ApplyMovement(Game::msg_t* msg, int key, Game::usercmd_s* from, Game::usercmd_s* to)
@ -269,7 +270,7 @@ namespace Components
__declspec(naked) void Gamepad::MSG_ReadDeltaUsercmdKeyStub() __declspec(naked) void Gamepad::MSG_ReadDeltaUsercmdKeyStub()
{ {
__asm __asm
{ {
push ebx // to push ebx // to
push ebp // from push ebp // from
push edi // key push edi // key
@ -280,13 +281,13 @@ namespace Components
// return back // return back
push 0x4921BF push 0x4921BF
ret ret
} }
} }
__declspec(naked) void Gamepad::MSG_ReadDeltaUsercmdKeyStub2() __declspec(naked) void Gamepad::MSG_ReadDeltaUsercmdKeyStub2()
{ {
__asm __asm
{ {
push ebx // to push ebx // to
push ebp // from push ebp // from
push edi // key push edi // key
@ -299,7 +300,7 @@ namespace Components
push esi push esi
push 0x492085 push 0x492085
ret ret
} }
} }
bool Gamepad::GPad_Check(const int gamePadIndex, const int portIndex) bool Gamepad::GPad_Check(const int gamePadIndex, const int portIndex)
@ -487,6 +488,77 @@ namespace Components
aaGlob.prevButtons = input->buttons; aaGlob.prevButtons = input->buttons;
} }
bool Gamepad::CG_HandleLocationSelectionInput_GamePad(const int localClientNum, Game::usercmd_s* cmd)
{
const auto frameTime = static_cast<float>(Game::cgArray[0].frametime) * 0.001f;
const auto mapAspectRatio = Game::cgArray[0].compassMapWorldSize[0] / Game::cgArray[0].compassMapWorldSize[1];
const auto selectionRequiresAngle = (Game::cgArray[0].predictedPlayerState.locationSelectionInfo & 0x80) != 0;
auto up = CL_GamepadAxisValue(localClientNum, Game::GPAD_VIRTAXIS_FORWARD);
auto right = CL_GamepadAxisValue(localClientNum, Game::GPAD_VIRTAXIS_SIDE);
auto magnitude = up * up + right * right;
if(magnitude > 1.0f)
{
magnitude = std::sqrt(magnitude);
up /= magnitude;
right /= magnitude;
}
Game::cgArray[0].selectedLocation[0] += right * cg_mapLocationSelectionCursorSpeed.get<float>() * frameTime;
Game::cgArray[0].selectedLocation[1] -= up * mapAspectRatio * cg_mapLocationSelectionCursorSpeed.get<float>() * frameTime;
if(selectionRequiresAngle)
{
const auto yawUp = CL_GamepadAxisValue(localClientNum, Game::GPAD_VIRTAXIS_PITCH);
const auto yawRight = CL_GamepadAxisValue(localClientNum, Game::GPAD_VIRTAXIS_YAW);
if(std::fabs(yawUp) > 0.0f || std::fabs(yawRight) > 0.0f)
{
Game::vec2_t vec
{
yawUp,
-yawRight
};
Game::cgArray[0].selectedLocationAngle = Game::AngleNormalize360(Game::vectoyaw(&vec));
Game::cgArray[0].selectedAngleLocation[0] = Game::cgArray[0].selectedLocation[0];
Game::cgArray[0].selectedAngleLocation[1] = Game::cgArray[0].selectedLocation[1];
}
}
else
{
Game::cgArray[0].selectedAngleLocation[0] = Game::cgArray[0].selectedLocation[0];
Game::cgArray[0].selectedAngleLocation[1] = Game::cgArray[0].selectedLocation[1];
}
return true;
}
constexpr auto CG_HandleLocationSelectionInput = 0x5A67A0;
__declspec(naked) void Gamepad::CG_HandleLocationSelectionInput_Stub()
{
__asm
{
// Prepare args for our function call
push esi // usercmd
push eax // localClientNum
call CG_HandleLocationSelectionInput
test al,al
jz exit_handling
// Call our function, the args were already prepared earlier
call CG_HandleLocationSelectionInput_GamePad
exit_handling:
add esp, 0x8
ret
}
}
bool Gamepad::CG_ShouldUpdateViewAngles(const int localClientNum) bool Gamepad::CG_ShouldUpdateViewAngles(const int localClientNum)
{ {
return !Game::Key_IsKeyCatcherActive(localClientNum, Game::KEYCATCH_MASK_ANY) || Game::UI_GetActiveMenu(localClientNum) == Game::UIMENU_SCOREBOARD; return !Game::Key_IsKeyCatcherActive(localClientNum, Game::KEYCATCH_MASK_ANY) || Game::UI_GetActiveMenu(localClientNum) == Game::UIMENU_SCOREBOARD;
@ -589,7 +661,7 @@ namespace Components
__declspec(naked) void Gamepad::CL_MouseMove_Stub() __declspec(naked) void Gamepad::CL_MouseMove_Stub()
{ {
__asm __asm
{ {
// Prepare args for our function call // Prepare args for our function call
push [esp+0x4] // frametime_base push [esp+0x4] // frametime_base
push ebx // cmd push ebx // cmd
@ -604,7 +676,7 @@ namespace Components
add esp,0xC add esp,0xC
ret ret
} }
} }
bool Gamepad::Key_IsValidGamePadChar(const int key) bool Gamepad::Key_IsValidGamePadChar(const int key)
@ -1188,7 +1260,7 @@ namespace Components
void __declspec(naked) Gamepad::Com_WriteConfiguration_Modified_Stub() void __declspec(naked) Gamepad::Com_WriteConfiguration_Modified_Stub()
{ {
__asm __asm
{ {
mov eax, [ecx + 0x18] mov eax, [ecx + 0x18]
or eax, gamePadBindingsModifiedFlags // Also check for gamePadBindingsModifiedFlags or eax, gamePadBindingsModifiedFlags // Also check for gamePadBindingsModifiedFlags
test al, 1 test al, 1
@ -1202,7 +1274,7 @@ namespace Components
endMethod: endMethod:
push 0x60B298 push 0x60B298
retn retn
} }
} }
@ -1345,6 +1417,7 @@ namespace Components
aim_input_graph_index = Dvar::Var("aim_input_graph_index"); aim_input_graph_index = Dvar::Var("aim_input_graph_index");
aim_scale_view_axis = Dvar::Var("aim_scale_view_axis"); aim_scale_view_axis = Dvar::Var("aim_scale_view_axis");
cl_bypassMouseInput = Dvar::Var("cl_bypassMouseInput"); cl_bypassMouseInput = Dvar::Var("cl_bypassMouseInput");
cg_mapLocationSelectionCursorSpeed = Dvar::Var("cg_mapLocationSelectionCursorSpeed");
} }
void Gamepad::IN_Init_Hk() void Gamepad::IN_Init_Hk()
@ -1503,6 +1576,9 @@ namespace Components
// 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(0x5A7A23, Key_GetCommandAssignmentInternal_Hk, HOOK_CALL).install()->quick();
// Add gamepad inputs to location selection (eg airstrike location) handling
Utils::Hook(0x5A6D72, CG_HandleLocationSelectionInput_Stub, HOOK_CALL).install()->quick();
// Add gamepad inputs to usercmds // Add gamepad inputs to usercmds
Utils::Hook(0x5A6DAE, CL_MouseMove_Stub, HOOK_CALL).install()->quick(); Utils::Hook(0x5A6DAE, CL_MouseMove_Stub, HOOK_CALL).install()->quick();
} }

View File

@ -272,6 +272,7 @@ namespace Components
static Dvar::Var aim_input_graph_index; static Dvar::Var aim_input_graph_index;
static Dvar::Var aim_scale_view_axis; static Dvar::Var aim_scale_view_axis;
static Dvar::Var cl_bypassMouseInput; static Dvar::Var cl_bypassMouseInput;
static Dvar::Var cg_mapLocationSelectionCursorSpeed;
static Dvar::Var xpadSensitivity; static Dvar::Var xpadSensitivity;
static Dvar::Var xpadEarlyTime; static Dvar::Var xpadEarlyTime;
@ -294,6 +295,8 @@ namespace Components
static void AimAssist_ApplyTurnRates(const Game::AimInput* input, Game::AimOutput* output); static void AimAssist_ApplyTurnRates(const Game::AimInput* input, Game::AimOutput* output);
static void AimAssist_UpdateGamePadInput(const Game::AimInput* input, Game::AimOutput* output); static void AimAssist_UpdateGamePadInput(const Game::AimInput* input, Game::AimOutput* output);
static bool CG_HandleLocationSelectionInput_GamePad(int localClientNum, Game::usercmd_s* cmd);
static void CG_HandleLocationSelectionInput_Stub();
static bool CG_ShouldUpdateViewAngles(int localClientNum); static bool CG_ShouldUpdateViewAngles(int localClientNum);
static float CL_GamepadAxisValue(int gamePadIndex, Game::GamepadVirtualAxis virtualAxis); static float CL_GamepadAxisValue(int gamePadIndex, Game::GamepadVirtualAxis virtualAxis);
static char ClampChar(int value); static char ClampChar(int value);

View File

@ -339,6 +339,8 @@ namespace Game
Win_GetLanguage_t Win_GetLanguage = Win_GetLanguage_t(0x45CBA0); Win_GetLanguage_t Win_GetLanguage = Win_GetLanguage_t(0x45CBA0);
Vec3UnpackUnitVec_t Vec3UnpackUnitVec = Vec3UnpackUnitVec_t(0x45CA90); Vec3UnpackUnitVec_t Vec3UnpackUnitVec = Vec3UnpackUnitVec_t(0x45CA90);
vectoyaw_t vectoyaw = vectoyaw_t(0x45AD10);
AngleNormalize360_t AngleNormalize360 = AngleNormalize360_t(0x438DC0);
unzClose_t unzClose = unzClose_t(0x41BF20); unzClose_t unzClose = unzClose_t(0x41BF20);
@ -441,6 +443,8 @@ namespace Game
clientStatic_t* cls = reinterpret_cast<clientStatic_t*>(0xA7FE90); clientStatic_t* cls = reinterpret_cast<clientStatic_t*>(0xA7FE90);
cg_s* cgArray = reinterpret_cast<cg_s*>(0x7F0F78);
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize) XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize)
{ {
int elSize = DB_GetXAssetSizeHandlers[type](); int elSize = DB_GetXAssetSizeHandlers[type]();

View File

@ -800,6 +800,12 @@ namespace Game
typedef void (__cdecl * Vec3UnpackUnitVec_t)(PackedUnitVec, vec3_t *); typedef void (__cdecl * Vec3UnpackUnitVec_t)(PackedUnitVec, vec3_t *);
extern Vec3UnpackUnitVec_t Vec3UnpackUnitVec; extern Vec3UnpackUnitVec_t Vec3UnpackUnitVec;
typedef float(__cdecl* vectoyaw_t)(vec2_t* vec);
extern vectoyaw_t vectoyaw;
typedef float(__cdecl* AngleNormalize360_t)(float val);
extern AngleNormalize360_t AngleNormalize360;
typedef void(__cdecl * unzClose_t)(void* handle); typedef void(__cdecl * unzClose_t)(void* handle);
extern unzClose_t unzClose; extern unzClose_t unzClose;
@ -903,6 +909,8 @@ namespace Game
extern clientStatic_t* cls; extern clientStatic_t* cls;
extern cg_s* cgArray;
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize); XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize);
void Menu_FreeItemMemory(Game::itemDef_s* item); void Menu_FreeItemMemory(Game::itemDef_s* item);
void Menu_SetNextCursorItem(Game::UiContext* ctx, Game::menuDef_t* currentMenu, int unk = 1); void Menu_SetNextCursorItem(Game::UiContext* ctx, Game::menuDef_t* currentMenu, int unk = 1);

View File

@ -6141,6 +6141,24 @@ namespace Game
float scale; float scale;
}; };
struct __declspec(align(8)) cg_s
{
playerState_s predictedPlayerState;
char _pad0[0x67638];
int frametime; // + 0x6A754
char _pad1[0x960C]; // + 0x6A758
float compassMapWorldSize[2]; // + 0x73D64
char _pad2[0x74]; // + 0x73D6C
float selectedLocation[2]; // + 0x73DE0
float selectedLocationAngle;
float selectedAngleLocation[2];
float selectedLocationPrev[2];
float selectedLocationAnglePrev;
char _pad3[0x89740];
};
constexpr auto aaaaaaa1 = sizeof(cg_s);
#pragma endregion #pragma endregion
#ifndef IDA #ifndef IDA