Bit of cleanup + horizontal gamepad view acceleration
This commit is contained in:
parent
332232b88f
commit
784c4c8372
@ -3,8 +3,51 @@
|
||||
namespace Components
|
||||
{
|
||||
XINPUT_STATE XInput::xiStates[XUSER_MAX_COUNT];
|
||||
XINPUT_STATE XInput::lastxiState = { 0 };
|
||||
XINPUT_STATE XInput::lastXiState = { 0 };
|
||||
int XInput::xiPlayerNum = -1;
|
||||
std::chrono::milliseconds XInput::timeAtFirstHeldMaxLookX = 0ms; // "For how much time in miliseconds has the player been holding a horizontal direction on their stick, fully" (-1.0 or 1.0)
|
||||
bool XInput::isHoldingMaxLookX = false;
|
||||
|
||||
float XInput::lockedSensitivityMultiplier = 0.6f;
|
||||
float XInput::unlockedSensitivityMultiplier = 1.2f;
|
||||
float XInput::generalSensitivityMultiplier = 1.3f;
|
||||
|
||||
std::chrono::milliseconds XInput::msBeforeUnlockingSensitivity = 250ms;
|
||||
|
||||
std::vector<XInput::ActionMapping> mappings = {
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_A, "gostand"),
|
||||
//XInput::ActionMapping(XINPUT_GAMEPAD_B, "stance", true, true),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_X, "usereload"),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_Y, "weapnext", false),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_LEFT_SHOULDER, "smoke"),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_RIGHT_SHOULDER, "frag"),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_LEFT_THUMB, "breath_sprint"),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_RIGHT_THUMB, "melee"),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_START, "togglemenu", false),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_BACK, "scores"),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_DPAD_RIGHT, "actionslot 3"),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_DPAD_LEFT, "actionslot 2"),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_DPAD_UP, "actionslot 1"),
|
||||
XInput::ActionMapping(XINPUT_GAMEPAD_DPAD_DOWN, "actionslot 4"),
|
||||
};
|
||||
|
||||
|
||||
void XInput::Vibrate(int leftVal, int rightVal)
|
||||
{
|
||||
// Create a Vibraton State
|
||||
XINPUT_VIBRATION Vibration;
|
||||
|
||||
// Zeroise the Vibration
|
||||
ZeroMemory(&Vibration, sizeof(XINPUT_VIBRATION));
|
||||
|
||||
// Set the Vibration Values
|
||||
Vibration.wLeftMotorSpeed = leftVal;
|
||||
Vibration.wRightMotorSpeed = rightVal;
|
||||
|
||||
// Vibrate the controller
|
||||
XInputSetState(xiPlayerNum, &Vibration);
|
||||
}
|
||||
|
||||
|
||||
void XInput::PollXInputDevices()
|
||||
{
|
||||
@ -42,14 +85,48 @@ namespace Components
|
||||
{
|
||||
XINPUT_STATE* xiState = &xiStates[xiPlayerNum];
|
||||
|
||||
cmd->rightmove = static_cast<BYTE>(xiState->Gamepad.sThumbLX / 256);
|
||||
cmd->forwardmove = static_cast<BYTE>(xiState->Gamepad.sThumbLY / 256);
|
||||
// Deadzones
|
||||
float moveStickX = abs(xiState->Gamepad.sThumbLX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ? xiState->Gamepad.sThumbLX / (float)std::numeric_limits<SHORT>().max() : .0f;
|
||||
float moveStickY = abs(xiState->Gamepad.sThumbLY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE ? xiState->Gamepad.sThumbLY / (float)std::numeric_limits<SHORT>().max() : .0f;
|
||||
|
||||
Game::cl_angles[0] -= (xiState->Gamepad.sThumbRY / 32767.0f);
|
||||
Game::cl_angles[1] -= (xiState->Gamepad.sThumbRX / 32767.0f);
|
||||
float viewStickX = abs(xiState->Gamepad.sThumbRX) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ? xiState->Gamepad.sThumbRX / (float)std::numeric_limits<SHORT>().max() : .0f;
|
||||
float viewStickY = abs(xiState->Gamepad.sThumbRY) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE ? xiState->Gamepad.sThumbRY / (float)std::numeric_limits<SHORT>().max() : .0f;
|
||||
|
||||
bool pressingLeftTrigger = xiState->Gamepad.bLeftTrigger / 255.f > 0.5;
|
||||
if (pressingLeftTrigger != XInput::lastxiState.Gamepad.bLeftTrigger / 255.f > 0.5)
|
||||
cmd->rightmove = moveStickX * std::numeric_limits<char>().max();
|
||||
cmd->forwardmove = moveStickY * std::numeric_limits<char>().max();
|
||||
|
||||
// Gamepad horizontal acceleration on view
|
||||
if (abs(viewStickX) > 0.9f) {
|
||||
if (!XInput::isHoldingMaxLookX) {
|
||||
XInput::isHoldingMaxLookX = true;
|
||||
XInput::timeAtFirstHeldMaxLookX = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
|
||||
}
|
||||
else {
|
||||
std::chrono::milliseconds hasBeenHoldingLeftXForMs = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()) - XInput::timeAtFirstHeldMaxLookX;
|
||||
#ifdef STEP_SENSITIVITY
|
||||
if (hasBeenHoldingLeftXForMs < XInput::msBeforeUnlockingSensitivity) {
|
||||
viewStickX *= XInput::lockedSensitivityMultiplier;
|
||||
}
|
||||
else {
|
||||
viewStickX *= XInput::unlockedSensitivityMultiplier;
|
||||
}
|
||||
#else
|
||||
float coeff = std::clamp(hasBeenHoldingLeftXForMs.count()/(float)XInput::msBeforeUnlockingSensitivity.count(), 0.0F, 1.0F);
|
||||
viewStickX *= std::lerp(XInput::lockedSensitivityMultiplier, XInput::unlockedSensitivityMultiplier, coeff);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else{
|
||||
XInput::isHoldingMaxLookX = false;
|
||||
XInput::timeAtFirstHeldMaxLookX = 0ms;
|
||||
}
|
||||
|
||||
|
||||
Game::cl_angles[0] -= viewStickY;
|
||||
Game::cl_angles[1] -= viewStickX * generalSensitivityMultiplier;
|
||||
|
||||
bool pressingLeftTrigger = xiState->Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD ? true : false;
|
||||
if (pressingLeftTrigger != XInput::lastXiState.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
|
||||
{
|
||||
if (pressingLeftTrigger)
|
||||
Command::Execute("+speed");
|
||||
@ -57,8 +134,8 @@ namespace Components
|
||||
Command::Execute("-speed");
|
||||
}
|
||||
|
||||
bool pressingRightTrigger = xiState->Gamepad.bRightTrigger / 255.f > 0.5;
|
||||
if (pressingRightTrigger != XInput::lastxiState.Gamepad.bRightTrigger / 255.f > 0.5)
|
||||
bool pressingRightTrigger = xiState->Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD ? true : false;
|
||||
if (pressingRightTrigger != XInput::lastXiState.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
|
||||
{
|
||||
if (pressingRightTrigger)
|
||||
Command::Execute("+attack");
|
||||
@ -66,51 +143,43 @@ namespace Components
|
||||
Command::Execute("-attack");
|
||||
}
|
||||
|
||||
bool pressingWeapChange = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_Y) != 0;
|
||||
if (pressingWeapChange != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_Y) != 0))
|
||||
// Buttons (on/off) mappings
|
||||
for (size_t i = 0; i < mappings.size(); i++)
|
||||
{
|
||||
if (pressingWeapChange)
|
||||
Command::Execute("weapnext");
|
||||
auto mapping = mappings[i];
|
||||
auto action = mapping.action;
|
||||
auto antiAction = mapping.action;
|
||||
|
||||
if (mapping.isReversible) {
|
||||
action = "+" + mapping.action;
|
||||
antiAction = "-" + mapping.action;
|
||||
}
|
||||
else if (mapping.wasPressed) {
|
||||
if (xiState->Gamepad.wButtons & mapping.input) {
|
||||
// Button still pressed, do not send info
|
||||
if (mapping.spamWhenHeld) {
|
||||
Command::Execute(action.c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
mappings[i].wasPressed = false;
|
||||
}
|
||||
|
||||
bool pressingReload = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_X) != 0;
|
||||
if (pressingReload != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_X) != 0))
|
||||
{
|
||||
if (pressingReload)
|
||||
Command::Execute("+usereload");
|
||||
else
|
||||
Command::Execute("-usereload");
|
||||
continue;
|
||||
}
|
||||
|
||||
bool pressingJump = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_A) != 0;
|
||||
if (pressingJump != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_A) != 0))
|
||||
{
|
||||
if (pressingJump)
|
||||
Command::Execute("+gostand");
|
||||
else
|
||||
Command::Execute("-gostand");
|
||||
if (xiState->Gamepad.wButtons & mapping.input) {
|
||||
Command::Execute(action.c_str());
|
||||
mappings[i].wasPressed = true;
|
||||
}
|
||||
else if (mapping.isReversible && mapping.wasPressed) {
|
||||
mappings[i].wasPressed = false;
|
||||
Command::Execute(antiAction.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool pressingKnife = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_B) != 0;
|
||||
if (pressingKnife != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_B) != 0))
|
||||
{
|
||||
if (pressingKnife)
|
||||
Command::Execute("+melee");
|
||||
else
|
||||
Command::Execute("-melee");
|
||||
}
|
||||
|
||||
bool pressingSprint = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0;
|
||||
if (pressingSprint != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0))
|
||||
{
|
||||
if (pressingSprint)
|
||||
Command::Execute("+breath_sprint");
|
||||
else
|
||||
Command::Execute("-breath_sprint");
|
||||
}
|
||||
|
||||
bool pressingStance = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0;
|
||||
if (pressingStance != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0))
|
||||
bool pressingStance = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_B) != 0;
|
||||
if (pressingStance != ((XInput::lastXiState.Gamepad.wButtons & XINPUT_GAMEPAD_B) != 0))
|
||||
{
|
||||
if (pressingStance)
|
||||
Command::Execute("+stance");
|
||||
@ -118,78 +187,8 @@ namespace Components
|
||||
Command::Execute("-stance");
|
||||
}
|
||||
|
||||
bool pressingSmoke = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0;
|
||||
if (pressingSmoke != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0))
|
||||
{
|
||||
if (pressingSmoke)
|
||||
Command::Execute("+smoke");
|
||||
else
|
||||
Command::Execute("-smoke");
|
||||
}
|
||||
|
||||
bool pressingFrag = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0;
|
||||
if (pressingFrag != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0))
|
||||
{
|
||||
if (pressingFrag)
|
||||
Command::Execute("+frag");
|
||||
else
|
||||
Command::Execute("-frag");
|
||||
}
|
||||
|
||||
bool pressingScore = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_BACK) != 0;
|
||||
if (pressingScore != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) != 0))
|
||||
{
|
||||
if (pressingScore)
|
||||
Command::Execute("+scores");
|
||||
else
|
||||
Command::Execute("-scores");
|
||||
}
|
||||
|
||||
bool pressingAlt = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) != 0;
|
||||
if (pressingAlt != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) != 0))
|
||||
{
|
||||
if (pressingAlt)
|
||||
Command::Execute("+actionslot 2");
|
||||
else
|
||||
Command::Execute("-actionslot 2");
|
||||
}
|
||||
|
||||
bool pressingKillstreak = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) != 0;
|
||||
if (pressingKillstreak != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) != 0))
|
||||
{
|
||||
if (pressingKillstreak)
|
||||
Command::Execute("+actionslot 3");
|
||||
else
|
||||
Command::Execute("-actionslot 3");
|
||||
}
|
||||
|
||||
bool pressingNight = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) != 0;
|
||||
if (pressingNight != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) != 0))
|
||||
{
|
||||
if (pressingNight)
|
||||
Command::Execute("+actionslot 4");
|
||||
else
|
||||
Command::Execute("-actionslot 4");
|
||||
}
|
||||
|
||||
bool pressingUp = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) != 0;
|
||||
if (pressingUp != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) != 0))
|
||||
{
|
||||
if (pressingUp)
|
||||
Command::Execute("+actionslot 1");
|
||||
else
|
||||
Command::Execute("-actionslot 1");
|
||||
}
|
||||
|
||||
bool pressingStart = (xiState->Gamepad.wButtons & XINPUT_GAMEPAD_START) != 0;
|
||||
if (pressingStart != ((XInput::lastxiState.Gamepad.wButtons & XINPUT_GAMEPAD_START) != 0))
|
||||
{
|
||||
if (pressingStart)
|
||||
Command::Execute("togglemenu");
|
||||
}
|
||||
|
||||
|
||||
memcpy(&XInput::lastxiState, xiState, sizeof XINPUT_STATE);
|
||||
memcpy(&XInput::lastXiState, xiState, sizeof XINPUT_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,15 +221,15 @@ namespace Components
|
||||
add esp, 0Ch
|
||||
|
||||
// put both forward move and rightmove values in the movement button
|
||||
mov dl, byte ptr [edi+1Ah] // to_forwardMove
|
||||
mov dh, byte ptr [edi+1Bh] // to_rightMove
|
||||
mov dl, byte ptr[edi + 1Ah] // to_forwardMove
|
||||
mov dh, byte ptr[edi + 1Bh] // to_rightMove
|
||||
|
||||
mov [esp+30h], dx // to_buttons
|
||||
mov[esp + 30h], dx // to_buttons
|
||||
|
||||
mov dl, byte ptr [ebp+1Ah] // from_forwardMove
|
||||
mov dh, byte ptr [ebp+1Bh] // from_rightMove
|
||||
mov dl, byte ptr[ebp + 1Ah] // from_forwardMove
|
||||
mov dh, byte ptr[ebp + 1Bh] // from_rightMove
|
||||
|
||||
mov [esp+2Ch], dx // from_buttons
|
||||
mov[esp + 2Ch], dx // from_buttons
|
||||
|
||||
// return back
|
||||
push 0x60E40E
|
||||
|
@ -7,10 +7,35 @@ namespace Components
|
||||
public:
|
||||
XInput();
|
||||
|
||||
struct ActionMapping {
|
||||
int input;
|
||||
std::string action;
|
||||
bool isReversible;
|
||||
bool wasPressed = false;
|
||||
bool spamWhenHeld = false;
|
||||
|
||||
ActionMapping(int input, std::string action, bool isReversible = true, bool spamWhenHeld = false)
|
||||
{
|
||||
this->action = action;
|
||||
this->isReversible = isReversible;
|
||||
this->input = input;
|
||||
this->spamWhenHeld = spamWhenHeld;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
static XINPUT_STATE xiStates[XUSER_MAX_COUNT];
|
||||
static int xiPlayerNum;
|
||||
static XINPUT_STATE lastxiState;
|
||||
static XINPUT_STATE lastXiState;
|
||||
|
||||
static bool isHoldingMaxLookX;
|
||||
static std::chrono::milliseconds timeAtFirstHeldMaxLookX;
|
||||
static std::chrono::milliseconds msBeforeUnlockingSensitivity;
|
||||
static float lockedSensitivityMultiplier;
|
||||
static float unlockedSensitivityMultiplier;
|
||||
static float generalSensitivityMultiplier;
|
||||
|
||||
static void Vibrate(int leftVal = 0, int rightVal = 0);
|
||||
|
||||
static void CL_FrameStub();
|
||||
static void PollXInputDevices();
|
||||
|
Loading…
Reference in New Issue
Block a user