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_scale_view_axis;
Dvar::Var Gamepad::cl_bypassMouseInput;
Dvar::Var Gamepad::cg_mapLocationSelectionCursorSpeed;
Dvar::Var Gamepad::xpadSensitivity;
Dvar::Var Gamepad::xpadEarlyTime;
@ -487,6 +488,77 @@ namespace Components
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)
{
return !Game::Key_IsKeyCatcherActive(localClientNum, Game::KEYCATCH_MASK_ANY) || Game::UI_GetActiveMenu(localClientNum) == Game::UIMENU_SCOREBOARD;
@ -1345,6 +1417,7 @@ namespace Components
aim_input_graph_index = Dvar::Var("aim_input_graph_index");
aim_scale_view_axis = Dvar::Var("aim_scale_view_axis");
cl_bypassMouseInput = Dvar::Var("cl_bypassMouseInput");
cg_mapLocationSelectionCursorSpeed = Dvar::Var("cg_mapLocationSelectionCursorSpeed");
}
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
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
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_scale_view_axis;
static Dvar::Var cl_bypassMouseInput;
static Dvar::Var cg_mapLocationSelectionCursorSpeed;
static Dvar::Var xpadSensitivity;
static Dvar::Var xpadEarlyTime;
@ -294,6 +295,8 @@ namespace Components
static void AimAssist_ApplyTurnRates(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 float CL_GamepadAxisValue(int gamePadIndex, Game::GamepadVirtualAxis virtualAxis);
static char ClampChar(int value);

View File

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

View File

@ -801,6 +801,12 @@ namespace Game
typedef void (__cdecl * Vec3UnpackUnitVec_t)(PackedUnitVec, vec3_t *);
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);
extern unzClose_t unzClose;
@ -903,6 +909,8 @@ namespace Game
extern clientStatic_t* cls;
extern cg_s* cgArray;
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize);
void Menu_FreeItemMemory(Game::itemDef_s* item);
void Menu_SetNextCursorItem(Game::UiContext* ctx, Game::menuDef_t* currentMenu, int unk = 1);

View File

@ -6141,6 +6141,24 @@ namespace Game
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
#ifndef IDA