2020-01-23 11:34:48 +13:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "XInputManager.h"
|
|
|
|
#include <XInput.h>
|
|
|
|
|
2021-03-10 07:43:47 +13:00
|
|
|
XInputManager::XInputManager(uint8_t** base_controller_input_address_ptr, const float vibrationStrengthFactor)
|
2020-01-23 11:34:48 +13:00
|
|
|
{
|
2021-03-10 07:43:47 +13:00
|
|
|
this->vibrationStrengthFactor = vibrationStrengthFactor;
|
2020-01-23 11:34:48 +13:00
|
|
|
xinputThread = std::thread(&XInputManager::Run, this, base_controller_input_address_ptr);
|
|
|
|
}
|
|
|
|
|
2020-02-02 09:03:46 +13:00
|
|
|
void XInputManager::Run(uint8_t** base_controller_input_address_ptr)
|
2020-01-23 11:34:48 +13:00
|
|
|
{
|
|
|
|
bool hasConnected = false;
|
|
|
|
for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
|
|
|
|
XINPUT_STATE state;
|
|
|
|
ZeroMemory(&state, sizeof(XINPUT_STATE));
|
|
|
|
|
2020-02-02 09:03:46 +13:00
|
|
|
const DWORD controllerState = XInputGetState(i, &state);
|
2020-01-23 11:34:48 +13:00
|
|
|
if (controllerState == ERROR_SUCCESS) {
|
|
|
|
controllerId = i;
|
|
|
|
hasConnected = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (hasConnected) {
|
|
|
|
WaitAndSetVibrationAddress(base_controller_input_address_ptr);
|
|
|
|
VibrationLoop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-02 09:03:46 +13:00
|
|
|
void XInputManager::WaitAndSetVibrationAddress(uint8_t** base_controller_input_address_ptr)
|
2020-01-23 11:34:48 +13:00
|
|
|
{
|
|
|
|
do {
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(4));
|
|
|
|
if (base_controller_input_address_ptr && *base_controller_input_address_ptr) {
|
|
|
|
vibration_address_low_frequency = (float*)(*base_controller_input_address_ptr + 0x40 + 0x60 - 0x4);
|
|
|
|
vibration_address_high_frequency = vibration_address_low_frequency + 1;
|
|
|
|
}
|
|
|
|
} while (vibration_address_low_frequency == NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void XInputManager::VibrationLoop()
|
|
|
|
{
|
|
|
|
const WORD maxVibrationStrength = 65535;
|
|
|
|
bool wasVibrating = false;
|
|
|
|
SetControllerVibration(0, 0);
|
|
|
|
while (true) {
|
|
|
|
const float vibrationStrengthLowFrequency = *vibration_address_low_frequency;
|
|
|
|
const float vibrationStrengthHighFrequency = *vibration_address_high_frequency;
|
2021-03-10 07:43:47 +13:00
|
|
|
if (vibrationStrengthLowFrequency > 0.01f || vibrationStrengthHighFrequency > 0.01f) {
|
2021-03-10 10:11:22 +13:00
|
|
|
const WORD leftMotorVibration = (WORD) (std::min(vibrationStrengthFactor * vibrationStrengthLowFrequency, 1.0f) * maxVibrationStrength);
|
|
|
|
const WORD rightMotorVibration = (WORD) (std::min(vibrationStrengthFactor * vibrationStrengthHighFrequency, 1.0f) * maxVibrationStrength);
|
2021-03-10 07:43:47 +13:00
|
|
|
SetControllerVibration(leftMotorVibration, rightMotorVibration);
|
2020-01-23 11:34:48 +13:00
|
|
|
wasVibrating = true;
|
|
|
|
}
|
2021-03-10 07:43:47 +13:00
|
|
|
else if (wasVibrating) {
|
2020-01-23 11:34:48 +13:00
|
|
|
SetControllerVibration(0, 0);
|
|
|
|
wasVibrating = false;
|
|
|
|
}
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(4));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void XInputManager::SetControllerVibration(const WORD& leftMotorVibration, const WORD& rightMotorVibration)
|
|
|
|
{
|
|
|
|
XINPUT_VIBRATION vibration;
|
|
|
|
ZeroMemory(&vibration, sizeof(XINPUT_VIBRATION));
|
|
|
|
vibration.wLeftMotorSpeed = leftMotorVibration;
|
|
|
|
vibration.wRightMotorSpeed = rightMotorVibration;
|
|
|
|
XInputSetState(controllerId, &vibration);
|
|
|
|
}
|