Add gamepad location selection support
This commit is contained in:
parent
fea24a509a
commit
8adea24d67
@ -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;
|
||||
@ -223,7 +224,7 @@ namespace Components
|
||||
__declspec(naked) void Gamepad::MSG_WriteDeltaUsercmdKeyStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
{
|
||||
// fix stack pointer
|
||||
add esp, 0Ch
|
||||
|
||||
@ -241,7 +242,7 @@ namespace Components
|
||||
// return back
|
||||
push 0x60E40E
|
||||
retn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
{
|
||||
push ebx // to
|
||||
push ebp // from
|
||||
push edi // key
|
||||
@ -280,13 +281,13 @@ namespace Components
|
||||
// return back
|
||||
push 0x4921BF
|
||||
ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__declspec(naked) void Gamepad::MSG_ReadDeltaUsercmdKeyStub2()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
{
|
||||
push ebx // to
|
||||
push ebp // from
|
||||
push edi // key
|
||||
@ -299,7 +300,7 @@ namespace Components
|
||||
push esi
|
||||
push 0x492085
|
||||
ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Gamepad::GPad_Check(const int gamePadIndex, const int portIndex)
|
||||
@ -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;
|
||||
@ -589,7 +661,7 @@ namespace Components
|
||||
__declspec(naked) void Gamepad::CL_MouseMove_Stub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
{
|
||||
// Prepare args for our function call
|
||||
push [esp+0x4] // frametime_base
|
||||
push ebx // cmd
|
||||
@ -604,7 +676,7 @@ namespace Components
|
||||
add esp,0xC
|
||||
|
||||
ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Gamepad::Key_IsValidGamePadChar(const int key)
|
||||
@ -1188,7 +1260,7 @@ namespace Components
|
||||
void __declspec(naked) Gamepad::Com_WriteConfiguration_Modified_Stub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
{
|
||||
mov eax, [ecx + 0x18]
|
||||
or eax, gamePadBindingsModifiedFlags // Also check for gamePadBindingsModifiedFlags
|
||||
test al, 1
|
||||
@ -1202,7 +1274,7 @@ namespace Components
|
||||
endMethod:
|
||||
push 0x60B298
|
||||
retn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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]();
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user