Bindings and Controllers #106
|
@ -20,6 +20,10 @@ namespace SHADE
|
|||
/* Static defines */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
bool SHInputManager::controllerInUse = false;
|
||||
|
||||
std::map<std::string, SHInputManager::SHLogicalBindingData> SHInputManager::bindings;
|
||||
|
||||
unsigned SHInputManager::keyCount = 0;
|
||||
bool SHInputManager::keys[MAX_KEYS];
|
||||
bool SHInputManager::keysLast[MAX_KEYS];
|
||||
|
@ -41,6 +45,60 @@ namespace SHADE
|
|||
int SHInputManager::mouseWheelVerticalDelta = 0;
|
||||
int SHInputManager::mouseWheelVerticalDeltaPoll = 0;
|
||||
|
||||
unsigned char SHInputManager::controllersConnectedCount = 0;
|
||||
unsigned SHInputManager::controllersInputCount[XUSER_MAX_COUNT];
|
||||
unsigned SHInputManager::controllersButtonCount[XUSER_MAX_COUNT];
|
||||
short SHInputManager::controllers[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||
short SHInputManager::controllersLast[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||
double SHInputManager::controllersHeldTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||
double SHInputManager::controllersReleasedTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||
|
||||
//Internal helper function for splitting between inputs
|
||||
bool SHInputManager::controllerConsideredHeld(size_t inputIdx, short value) noexcept
|
||||
{
|
||||
if (inputIdx >= MAX_CONTROLLER_INPUT) return false; //Bounds check
|
||||
else
|
||||
{
|
||||
if (inputIdx < NUM_CONTROLLER_BUTTON)
|
||||
{
|
||||
return static_cast<bool>(value);
|
||||
}
|
||||
else if (inputIdx < NUM_CONTROLLER_BUTTON + NUM_CONTROLLER_TRIGGER)
|
||||
{
|
||||
return (value > XINPUT_GAMEPAD_TRIGGER_THRESHOLD);
|
||||
}
|
||||
else if (inputIdx < NUM_CONTROLLER_BUTTON + NUM_CONTROLLER_TRIGGER + NUM_CONTROLLER_TRIGGER)
|
||||
{
|
||||
return (std::abs(value) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (std::abs(value) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Internal helper function for getting normalised input value
|
||||
double SHInputManager::controllerNormalisedValue(size_t inputIdx, short value) noexcept
|
||||
{
|
||||
if (inputIdx >= MAX_CONTROLLER_INPUT) return 0.0; //Bounds check
|
||||
else
|
||||
{
|
||||
if (inputIdx < NUM_CONTROLLER_BUTTON)
|
||||
{
|
||||
return static_cast<double>(value);
|
||||
}
|
||||
else if (inputIdx < NUM_CONTROLLER_BUTTON + NUM_CONTROLLER_TRIGGER) //8-bit triggers, 0 to 255
|
||||
{
|
||||
return static_cast<double>(value) / static_cast<double>(UCHAR_MAX);
|
||||
}
|
||||
else //16-bit thumbsticks, -32768 to 32767
|
||||
{
|
||||
return static_cast<double>(value) / static_cast<double>(SHRT_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHInputManager::UpdateInput(double dt) noexcept
|
||||
{
|
||||
//Keyboard and Mouse Buttons////////////////////////////////////////////////
|
||||
|
@ -120,6 +178,273 @@ namespace SHADE
|
|||
mouseWheelVerticalDelta = 0;
|
||||
mouseWheelVerticalDelta = mouseWheelVerticalDeltaPoll;
|
||||
mouseWheelVerticalDeltaPoll = 0;
|
||||
|
||||
//Controllers//////////////////////////////////////////////////////////////
|
||||
|
||||
controllersConnectedCount = 0;
|
||||
|
||||
//Set last controller states
|
||||
memcpy(controllersLast, controllers, sizeof(controllers));
|
||||
|
||||
//Reset controller states
|
||||
SecureZeroMemory(&controllers, sizeof(controllers));
|
||||
|
||||
//https://learn.microsoft.com/en-us/windows/win32/xinput/getting-started-with-xinput#getting-controller-state
|
||||
for (DWORD c = 0; c < XUSER_MAX_COUNT; ++c)
|
||||
{
|
||||
controllersInputCount[c] = 0;
|
||||
controllersButtonCount[c] = 0;
|
||||
|
||||
XINPUT_STATE state;
|
||||
SecureZeroMemory(&state, sizeof(XINPUT_STATE));
|
||||
|
||||
//Get the state of controller from XInput
|
||||
DWORD result = XInputGetState(c, &state);
|
||||
|
||||
//Write gamepad data
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
++controllersConnectedCount;
|
||||
|
||||
//DIGITAL BUTTONS///////////////////////////////////////
|
||||
|
||||
//DPAD UP
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_UP)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_UP)] = 0;
|
||||
}
|
||||
|
||||
//DPAD DOWN
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_DOWN)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_DOWN)] = 0;
|
||||
}
|
||||
|
||||
//DPAD LEFT
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_LEFT)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_LEFT)] = 0;
|
||||
}
|
||||
|
||||
//DPAD RIGHT
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_RIGHT)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_RIGHT)] = 0;
|
||||
}
|
||||
|
||||
//START
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_START)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::START)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::START)] = 0;
|
||||
}
|
||||
|
||||
//BACK
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::BACK)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::BACK)] = 0;
|
||||
}
|
||||
|
||||
//LEFT THUMBSTICK BUTTON
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_THUMBSTICK)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_THUMBSTICK)] = 0;
|
||||
}
|
||||
|
||||
//RIGHT THUMBSTICK BUTTON
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_THUMBSTICK)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_THUMBSTICK)] = 0;
|
||||
}
|
||||
|
||||
//LEFT SHOULDER BUTTON
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_SHOULDER)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_SHOULDER)] = 0;
|
||||
}
|
||||
|
||||
//RIGHT SHOULDER BUTTON
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_SHOULDER)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_SHOULDER)] = 0;
|
||||
}
|
||||
|
||||
//A
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::A)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::A)] = 0;
|
||||
}
|
||||
|
||||
//B
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_B)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::B)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::B)] = 0;
|
||||
}
|
||||
|
||||
//X
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_X)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::X)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::X)] = 0;
|
||||
}
|
||||
|
||||
//Y
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y)
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::Y)] = 1;
|
||||
++controllersInputCount[c];
|
||||
++controllersButtonCount[c];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::Y)] = 0;
|
||||
}
|
||||
|
||||
//8 BIT VALUES (0 - 255)///////////////////////////////////
|
||||
|
||||
//LEFT TRIGGER
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_TRIGGER)] = state.Gamepad.bLeftTrigger;
|
||||
if (state.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
|
||||
{
|
||||
++controllersInputCount[c]; //Registered as held
|
||||
}
|
||||
|
||||
//RIGHT TRIGGER
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_TRIGGER)] = state.Gamepad.bRightTrigger;
|
||||
if (state.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
|
||||
{
|
||||
++controllersInputCount[c]; //Registered as held
|
||||
}
|
||||
|
||||
//16 BIT VALUES (0 - 65535)////////////////////////////////
|
||||
|
||||
//LEFT THUMBSTICK X
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_THUMBSTICK_X)] = state.Gamepad.sThumbLX;
|
||||
if (std::abs(state.Gamepad.sThumbLX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
|
||||
{
|
||||
++controllersInputCount[c];
|
||||
}
|
||||
|
||||
//LEFT THUMBSTICK Y
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_THUMBSTICK_Y)] = state.Gamepad.sThumbLY;
|
||||
if (std::abs(state.Gamepad.sThumbLY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
|
||||
{
|
||||
++controllersInputCount[c];
|
||||
}
|
||||
|
||||
//RIGHT THUMBSTICK X
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_THUMBSTICK_X)] = state.Gamepad.sThumbRX;
|
||||
if (std::abs(state.Gamepad.sThumbRX) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
|
||||
{
|
||||
++controllersInputCount[c];
|
||||
}
|
||||
|
||||
//RIGHT THUMBSTICK Y
|
||||
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_THUMBSTICK_Y)] = state.Gamepad.sThumbRY;
|
||||
if (std::abs(state.Gamepad.sThumbRY) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
|
||||
{
|
||||
++controllersInputCount[c];
|
||||
}
|
||||
}
|
||||
|
||||
//Timers and updating if controller is presently in use
|
||||
for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i)
|
||||
{
|
||||
if (controllerConsideredHeld(i, controllers[c][i])) //Considered on
|
||||
{
|
||||
controllerInUse = true;
|
||||
if (!controllerConsideredHeld(i, controllersLast[c][i])) //Just on
|
||||
{
|
||||
controllersHeldTime[c][i] = 0.0; //Reset timer
|
||||
}
|
||||
controllersHeldTime[c][i] += dt; //Tick up
|
||||
}
|
||||
else //Considered off
|
||||
{
|
||||
if (controllerConsideredHeld(i, controllersLast[c][i])) //Just off
|
||||
{
|
||||
controllersReleasedTime[c][i] = 0.0; //Reset timer
|
||||
}
|
||||
controllersReleasedTime[c][i] += dt; //Tick up
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SHInputManager::AnyKeyDown(SH_KEYCODE* firstDetected) noexcept
|
||||
|
@ -161,4 +486,336 @@ namespace SHADE
|
|||
return false;
|
||||
}
|
||||
|
||||
//Any controller input being held
|
||||
//For analog, this means going being deadzone values
|
||||
bool SHInputManager::AnyControllerInput(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i)
|
||||
{
|
||||
if (controllerConsideredHeld(i, controllers[cNum][i]))
|
||||
{
|
||||
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHInputManager::AnyControllerInputDown(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i)
|
||||
{
|
||||
if (controllerConsideredHeld(i, controllers[cNum][i]) && !controllerConsideredHeld(i, controllersLast[cNum][i]))
|
||||
{
|
||||
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHInputManager::AnyControllerInputUp(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i)
|
||||
{
|
||||
if (!controllerConsideredHeld(i, controllers[cNum][i]) && controllerConsideredHeld(i, controllersLast[cNum][i]))
|
||||
{
|
||||
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHInputManager::AnyControllerButton(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
for (size_t i = 0; i < NUM_CONTROLLER_BUTTON; ++i)
|
||||
{
|
||||
if (controllerConsideredHeld(i, controllers[cNum][i]))
|
||||
{
|
||||
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHInputManager::AnyControllerButtonDown(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
for (size_t i = 0; i < NUM_CONTROLLER_BUTTON; ++i)
|
||||
{
|
||||
if (controllerConsideredHeld(i, controllers[cNum][i]) && !controllerConsideredHeld(i, controllersLast[cNum][i]))
|
||||
{
|
||||
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHInputManager::AnyControllerButtonUp(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
for (size_t i = 0; i < NUM_CONTROLLER_BUTTON; ++i)
|
||||
{
|
||||
if (!controllerConsideredHeld(i, controllers[cNum][i]) && controllerConsideredHeld(i, controllersLast[cNum][i]))
|
||||
{
|
||||
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Only get of largest magnitude
|
||||
double SHInputManager::GetBindingAxis(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
//Over keycodes, prioritise positive
|
||||
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||
{
|
||||
if (GetKey(k)) return 1.0;
|
||||
}
|
||||
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||
{
|
||||
if (GetKey(k)) return -1.0;
|
||||
}
|
||||
|
||||
double largestMagnitude = 0.0;
|
||||
|
||||
//Over controllerCodes
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||
{
|
||||
double newValue = 0.0;
|
||||
if (GetControllerInput(c, &newValue, nullptr, nullptr, cNum))
|
||||
if (std::abs(newValue) > std::abs(largestMagnitude)) largestMagnitude = newValue;
|
||||
}
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||
{
|
||||
double newValue = 0.0;
|
||||
if (GetControllerInput(c, &newValue, nullptr, nullptr, cNum))
|
||||
if (std::abs(newValue) > std::abs(largestMagnitude)) largestMagnitude = -newValue;
|
||||
}
|
||||
|
||||
return largestMagnitude;
|
||||
}
|
||||
|
||||
bool SHInputManager::GetBindingPositiveButton(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
|
||||
//Over keycodes
|
||||
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||
{
|
||||
if (GetKey(k)) return true;
|
||||
}
|
||||
|
||||
//Over controller buttons
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||
{
|
||||
if (GetControllerInput(c, nullptr, nullptr, nullptr, cNum)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHInputManager::GetBindingNegativeButton(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
|
||||
//Over keycodes
|
||||
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||
{
|
||||
if (GetKey(k)) return true;
|
||||
}
|
||||
|
||||
//Over controller buttons
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||
{
|
||||
if (GetControllerInput(c, nullptr, nullptr, nullptr, cNum)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHInputManager::GetBindingPositiveButtonDown(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
|
||||
//Over keycodes
|
||||
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||
{
|
||||
if (GetKeyDown(k)) return true;
|
||||
}
|
||||
|
||||
//Over controller buttons
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||
{
|
||||
if (GetControllerInputDown(c, nullptr, cNum)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHInputManager::GetBindingNegativeButtonDown(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
|
||||
//Over keycodes
|
||||
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||
{
|
||||
if (GetKeyDown(k)) return true;
|
||||
}
|
||||
|
||||
//Over controller buttons
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||
{
|
||||
if (GetControllerInputDown(c, nullptr, cNum)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHInputManager::GetBindingPositiveButtonUp(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
|
||||
//Over keycodes
|
||||
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||
{
|
||||
if (GetKeyUp(k)) return true;
|
||||
}
|
||||
|
||||
//Over controller buttons
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||
{
|
||||
if (GetControllerInputUp(c, nullptr, cNum)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SHInputManager::GetBindingNegativeButtonUp(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||
|
||||
//Over keycodes
|
||||
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||
{
|
||||
if (GetKeyUp(k)) return true;
|
||||
}
|
||||
|
||||
//Over controller buttons
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||
{
|
||||
if (GetControllerInputUp(c, nullptr, cNum)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//Fetches longest hold time
|
||||
double SHInputManager::GetBindingPositiveHeldTime(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return 0.0;
|
||||
|
||||
double maxHeldTime = 0.0;
|
||||
|
||||
//Over keycodes
|
||||
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||
{
|
||||
if (GetKeyHeldTime(k) > maxHeldTime) maxHeldTime = GetKeyHeldTime(k);
|
||||
}
|
||||
|
||||
//Over controller buttons
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||
{
|
||||
if (GetControllerInputHeldTime(c, cNum) > maxHeldTime) maxHeldTime = GetControllerInputHeldTime(c);
|
||||
}
|
||||
|
||||
return maxHeldTime;
|
||||
}
|
||||
|
||||
double SHInputManager::GetBindingNegativeHeldTime(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return 0.0;
|
||||
|
||||
double maxHeldTime = 0.0;
|
||||
|
||||
//Over keycodes
|
||||
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||
{
|
||||
if (GetKeyHeldTime(k) > maxHeldTime) maxHeldTime = GetKeyHeldTime(k);
|
||||
}
|
||||
|
||||
//Over controller buttons
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||
{
|
||||
if (GetControllerInputHeldTime(c, cNum) > maxHeldTime) maxHeldTime = GetControllerInputHeldTime(c);
|
||||
}
|
||||
|
||||
return maxHeldTime;
|
||||
}
|
||||
|
||||
//Fetches shortest release time
|
||||
double SHInputManager::GetBindingPositiveReleasedTime(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return 0.0;
|
||||
|
||||
double minReleaseTime = _HUGE_ENUF;
|
||||
|
||||
//Over keycodes
|
||||
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||
{
|
||||
if (GetKeyReleasedTime(k) < minReleaseTime) minReleaseTime = GetKeyReleasedTime(k);
|
||||
}
|
||||
|
||||
//Over controller buttons
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||
{
|
||||
if (GetControllerInputReleasedTime(c, cNum) < minReleaseTime) minReleaseTime = GetControllerInputReleasedTime(c);
|
||||
}
|
||||
|
||||
return minReleaseTime;
|
||||
}
|
||||
|
||||
double SHInputManager::GetBindingNegativeReleasedTime(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return 0.0;
|
||||
|
||||
double minReleaseTime = _HUGE_ENUF;
|
||||
|
||||
//Over keycodes
|
||||
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||
{
|
||||
if (GetKeyReleasedTime(k) < minReleaseTime) minReleaseTime = GetKeyReleasedTime(k);
|
||||
}
|
||||
|
||||
//Over controller buttons
|
||||
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||
{
|
||||
if (GetControllerInputReleasedTime(c, cNum) < minReleaseTime) minReleaseTime = GetControllerInputReleasedTime(c);
|
||||
}
|
||||
|
||||
return minReleaseTime;
|
||||
}
|
||||
|
||||
//Only for mouse movement
|
||||
//Get largest delta
|
||||
double SHInputManager::GetBindingMouseVelocity(std::string bindingName, size_t cNum) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return 0.0;
|
||||
|
||||
//Mouse velocity
|
||||
double velX = 0.0;
|
||||
double velY = 0.0;
|
||||
GetMouseVelocity(&velX, &velY);
|
||||
|
||||
return bindings[bindingName].mouseXPositiveMultiplier * velX + bindings[bindingName].mouseYPositiveMultiplier * velY;
|
||||
}
|
||||
|
||||
} //namespace SHADE
|
|
@ -10,9 +10,12 @@
|
|||
*********************************************************************/
|
||||
|
||||
#pragma once
|
||||
//#include <Xinput.h>
|
||||
//#include "../../SHADE_Managed/src/SHpch.h"
|
||||
#include <Xinput.h>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "../../SHADE_Managed/src/SHpch.h"
|
||||
#include "SH_API.h"
|
||||
#pragma comment(lib, "xinput.lib")
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -268,6 +271,58 @@ namespace SHADE
|
|||
OEM_CLEAR
|
||||
};
|
||||
|
||||
enum class SH_CONTROLLERCODE
|
||||
{
|
||||
//Digital
|
||||
DPAD_UP,
|
||||
DPAD_DOWN,
|
||||
DPAD_LEFT,
|
||||
DPAD_RIGHT,
|
||||
START,
|
||||
BACK,
|
||||
LEFT_THUMBSTICK,
|
||||
RIGHT_THUMBSTICK,
|
||||
LEFT_SHOULDER,
|
||||
RIGHT_SHOULDER,
|
||||
A,
|
||||
B,
|
||||
X,
|
||||
Y,
|
||||
|
||||
//1 Byte Unsigned Analog
|
||||
LEFT_TRIGGER,
|
||||
RIGHT_TRIGGER,
|
||||
|
||||
//2 Byte Signed Analog
|
||||
LEFT_THUMBSTICK_X,
|
||||
LEFT_THUMBSTICK_Y,
|
||||
RIGHT_THUMBSTICK_X,
|
||||
RIGHT_THUMBSTICK_Y
|
||||
};
|
||||
|
||||
private:
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Struct for logical bindings */
|
||||
/*------------------------------------------------------------------------*/
|
||||
struct SH_API SHLogicalBindingData
|
||||
{
|
||||
//Key codes mapped to positive
|
||||
std::set<SH_KEYCODE> positiveKeyCodes;
|
||||
|
||||
//Key codes mapped to negative
|
||||
std::set<SH_KEYCODE> negativeKeyCodes;
|
||||
|
||||
//Controller Codes mapped to positive
|
||||
std::set<SH_CONTROLLERCODE> positiveControllerCodes;
|
||||
|
||||
//Controller Codes mapped to negative
|
||||
std::set<SH_CONTROLLERCODE> negativeControllerCodes;
|
||||
|
||||
//Mouse movement mapped to axes?
|
||||
double mouseXPositiveMultiplier;
|
||||
double mouseYPositiveMultiplier;
|
||||
};
|
||||
|
||||
public:
|
||||
//Updates current state of the input, with dt to be fetched from FRC
|
||||
//TODO should dt be fixed or variable?
|
||||
|
@ -392,7 +447,7 @@ namespace SHADE
|
|||
keysToggleLast[static_cast<int>(key)]);
|
||||
}
|
||||
|
||||
//Mouse/////////////
|
||||
//Mouse/////////////////////////////////////////////////////
|
||||
|
||||
//Get the mouse location with respect to the screen
|
||||
static inline void GetMouseScreenPosition (int* x = nullptr,
|
||||
|
@ -428,7 +483,95 @@ namespace SHADE
|
|||
return mouseWheelVerticalDelta;
|
||||
}
|
||||
|
||||
//GET INPUT TIMINGS///////////////////////////////////////////////////////////
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Input state accessors (KB & M) */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
//How many controller inputs of any kind are being used now
|
||||
static inline unsigned GetControllerInputCount(size_t cNum = 0) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return 0;
|
||||
return controllersInputCount[cNum];
|
||||
}
|
||||
|
||||
//How many controller buttons are being pressed now
|
||||
//Subtract from getControllerInputCount() for analog triggers / thumbsticks
|
||||
static inline unsigned GetControllerButtonCount(size_t cNum = 0) noexcept
|
||||
{
|
||||
if (cNum >= XUSER_MAX_COUNT) return 0;
|
||||
return controllersButtonCount[cNum];
|
||||
}
|
||||
|
||||
//Any controller input being held
|
||||
//For analog, this means going being deadzone values
|
||||
//controllerNum should be between 0 and 3
|
||||
static bool AnyControllerInput(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||
|
||||
//Any controller input activated in THIS FRAME ONLY
|
||||
//For analog, this means going being deadzone values
|
||||
//controllerNum should be between 0 and 3
|
||||
static bool AnyControllerInputDown(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||
|
||||
//Any controller input deactivated in THIS FRAME ONLY
|
||||
//For analog, this means going below deadzone values
|
||||
//controllerNum should be between 0 and 3
|
||||
static bool AnyControllerInputUp(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||
|
||||
//Any DIGITAL controller buttons being held
|
||||
//controllerNum should be between 0 and 3
|
||||
static bool AnyControllerButton(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||
|
||||
//Any DIGITAL controller button activated in THIS FRAME ONLY
|
||||
//controllerNum should be between 0 and 3
|
||||
static bool AnyControllerButtonDown(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||
|
||||
//Any DIGITAL controller button deactivated in THIS FRAME ONLY
|
||||
//controllerNum should be between 0 and 3
|
||||
static bool AnyControllerButtonUp(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||
|
||||
//If controller input is being held in the current frame
|
||||
//normalisedValue is the value of the input between 0 and 1, relevant for trigger and thumbstick data
|
||||
//controllerNum should be between 0 and 3
|
||||
static inline bool GetControllerInput(SH_CONTROLLERCODE input,
|
||||
double* normalisedValue = nullptr,
|
||||
double* heldTime = nullptr,
|
||||
double* releasedTime = nullptr,
|
||||
size_t controllerNum = 0) noexcept
|
||||
{
|
||||
if (controllerNum >= XUSER_MAX_COUNT) return false;
|
||||
if (normalisedValue) *normalisedValue = controllerNormalisedValue(static_cast<size_t>(input), controllers[controllerNum][static_cast<size_t>(input)]);
|
||||
if (heldTime) *heldTime = controllersHeldTime[controllerNum][static_cast<size_t>(input)];
|
||||
if (releasedTime) *releasedTime = controllersReleasedTime[controllerNum][static_cast<size_t>(input)];
|
||||
return controllerConsideredHeld(static_cast<size_t>(input), controllers[controllerNum][static_cast<size_t>(input)]);
|
||||
}
|
||||
|
||||
//If controller input was considered to be held down in THIS FRAME ONLY
|
||||
//controllerNum should be between 0 and 3
|
||||
static inline bool GetControllerInputDown(SH_CONTROLLERCODE input,
|
||||
double* releasedTime = nullptr,
|
||||
size_t controllerNum = 0) noexcept
|
||||
{
|
||||
if (controllerNum >= XUSER_MAX_COUNT) return false;
|
||||
if (releasedTime) *releasedTime = controllersReleasedTime[controllerNum][static_cast<size_t>(input)];
|
||||
return (controllerConsideredHeld(static_cast<size_t>(input), controllers[controllerNum][static_cast<size_t>(input)]) &&
|
||||
!controllerConsideredHeld(static_cast<size_t>(input), controllersLast[controllerNum][static_cast<size_t>(input)]));
|
||||
}
|
||||
|
||||
//If controller input was considered to be released in THIS FRAME ONLY
|
||||
//controllerNum should be between 0 and 3
|
||||
static inline bool GetControllerInputUp(SH_CONTROLLERCODE input,
|
||||
double* releasedTime = nullptr,
|
||||
size_t controllerNum = 0) noexcept
|
||||
{
|
||||
if (controllerNum >= XUSER_MAX_COUNT) return false;
|
||||
if (releasedTime) *releasedTime = controllersReleasedTime[controllerNum][static_cast<size_t>(input)];
|
||||
return (!controllerConsideredHeld(static_cast<size_t>(input), controllers[controllerNum][static_cast<size_t>(input)]) &&
|
||||
controllerConsideredHeld(static_cast<size_t>(input), controllersLast[controllerNum][static_cast<size_t>(input)]));
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Timing accessors */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
//Keyboard/////////////
|
||||
|
||||
|
@ -456,6 +599,191 @@ namespace SHADE
|
|||
return keysToggleOffTime[static_cast<int>(key)];
|
||||
}
|
||||
|
||||
//Controller//////////////////////
|
||||
|
||||
//How long has this controller input been considered to be held down for
|
||||
static inline double GetControllerInputHeldTime(SH_CONTROLLERCODE code,
|
||||
size_t controllerNum = 0) noexcept
|
||||
{
|
||||
if (controllerNum >= XUSER_MAX_COUNT) return 0.0;
|
||||
return controllersHeldTime[controllerNum][static_cast<size_t>(code)];
|
||||
}
|
||||
|
||||
//How long has this controller input been considered to be released for
|
||||
static inline double GetControllerInputReleasedTime(SH_CONTROLLERCODE code,
|
||||
size_t controllerNum = 0) noexcept
|
||||
{
|
||||
if (controllerNum >= XUSER_MAX_COUNT) return 0.0;
|
||||
return controllersReleasedTime[controllerNum][static_cast<size_t>(code)];
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Binding Functions */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
//Add a new binding to the map
|
||||
static inline void BindingsAdd(std::string newBindingName) noexcept
|
||||
{
|
||||
bindings.insert({ newBindingName, SHLogicalBindingData() });
|
||||
}
|
||||
|
||||
//Remove a binding from the map
|
||||
//Returns 1 if found and removed, 0 if not found
|
||||
static inline size_t BindingsRemove(std::string targetBindingName) noexcept
|
||||
{
|
||||
return bindings.erase(targetBindingName);
|
||||
}
|
||||
|
||||
//Clears all bindings from the list
|
||||
static inline void BindingsClear() noexcept
|
||||
{
|
||||
bindings.clear();
|
||||
}
|
||||
|
||||
//Get the number of bindings present
|
||||
static inline size_t BindingsCount() noexcept
|
||||
{
|
||||
return bindings.size();
|
||||
}
|
||||
|
||||
//Check positive keycodes to binding
|
||||
static inline std::set<SH_KEYCODE> const& BindingsGetPositiveKeyCodes(std::string bindingName) noexcept
|
||||
{
|
||||
return bindings[bindingName].positiveKeyCodes;
|
||||
}
|
||||
|
||||
//Add positive SH_KEYCODE to binding
|
||||
static inline void BindingsAddPositiveKeyCode(std::string targetBindingName,
|
||||
SH_KEYCODE toAdd) noexcept
|
||||
{
|
||||
bindings[targetBindingName].positiveKeyCodes.insert(toAdd);
|
||||
}
|
||||
|
||||
//Remove positive SH_KEYCODE from binding
|
||||
//If toRemove found and removed, returns 1. Otherwise, 0.
|
||||
static inline size_t BindingsRemovePositiveKeyCode(std::string targetBindingName,
|
||||
SH_KEYCODE toRemove) noexcept
|
||||
{
|
||||
return bindings[targetBindingName].positiveKeyCodes.erase(toRemove);
|
||||
}
|
||||
|
||||
//Check negative keycodes to binding
|
||||
static inline std::set<SH_KEYCODE> const& BindingsGetNegativeKeyCodes(std::string bindingName) noexcept
|
||||
{
|
||||
return bindings[bindingName].negativeKeyCodes;
|
||||
}
|
||||
|
||||
//Add negative SH_KEYCODE to binding
|
||||
static inline void BindingsAddNegativeKeyCode(std::string targetBindingName,
|
||||
SH_KEYCODE toAdd) noexcept
|
||||
{
|
||||
bindings[targetBindingName].negativeKeyCodes.insert(toAdd);
|
||||
}
|
||||
|
||||
//Remove negative SH_KEYCODE from binding
|
||||
//If toRemove found and removed, returns 1. Otherwise, 0.
|
||||
static inline size_t BindingsRemoveNegativeKeyCode(std::string targetBindingName,
|
||||
SH_KEYCODE toRemove) noexcept
|
||||
{
|
||||
return bindings[targetBindingName].negativeKeyCodes.erase(toRemove);
|
||||
}
|
||||
|
||||
//Check positive controllercodes to binding
|
||||
static inline std::set<SH_CONTROLLERCODE> const& BindingsGetPositiveControllerCodes(std::string bindingName) noexcept
|
||||
{
|
||||
return bindings[bindingName].positiveControllerCodes;
|
||||
}
|
||||
|
||||
//Add positive SH_CONTROLLERCODE to binding
|
||||
static inline void BindingsAddPositiveControllerCode(std::string targetBindingName,
|
||||
SH_CONTROLLERCODE toAdd) noexcept
|
||||
{
|
||||
bindings[targetBindingName].positiveControllerCodes.insert(toAdd);
|
||||
}
|
||||
|
||||
//Remove positive SH_CONTROLLERCODE from binding
|
||||
//If toRemove found and removed, returns 1. Otherwise, 0.
|
||||
static inline size_t BindingsRemovePositiveControllerCode(std::string targetBindingName,
|
||||
SH_CONTROLLERCODE toRemove) noexcept
|
||||
{
|
||||
return bindings[targetBindingName].positiveControllerCodes.erase(toRemove);
|
||||
}
|
||||
|
||||
//Check negative controllercodes to binding
|
||||
static inline std::set<SH_CONTROLLERCODE> const& BindingsGetNegativeControllerCodes(std::string bindingName) noexcept
|
||||
{
|
||||
return bindings[bindingName].negativeControllerCodes;
|
||||
}
|
||||
|
||||
//Add negative SH_CONTROLLERCODE to binding
|
||||
static inline void BindingsAddNegativeControllerCode(std::string targetBindingName,
|
||||
SH_CONTROLLERCODE toAdd) noexcept
|
||||
{
|
||||
bindings[targetBindingName].negativeControllerCodes.insert(toAdd);
|
||||
}
|
||||
|
||||
//Remove negative SH_CONTROLLERCODE from binding
|
||||
//If toRemove found and removed, returns 1. Otherwise, 0.
|
||||
static inline size_t BindingsRemoveNegativeControllerCode(std::string targetBindingName,
|
||||
SH_CONTROLLERCODE toRemove) noexcept
|
||||
{
|
||||
return bindings[targetBindingName].negativeControllerCodes.erase(toRemove);
|
||||
}
|
||||
|
||||
//Mouse movement bindings
|
||||
|
||||
static inline double const BindingsGetMouseXPositiveMultiplier(std::string bindingName) noexcept
|
||||
{
|
||||
return bindings[bindingName].mouseXPositiveMultiplier;
|
||||
}
|
||||
|
||||
static inline void BindingsSetMouseXPositiveMultiplier(std::string bindingName, double newValue) noexcept
|
||||
{
|
||||
bindings[bindingName].mouseXPositiveMultiplier = newValue;
|
||||
}
|
||||
|
||||
static inline double const BindingsGetMouseYPositiveMultiplier(std::string bindingName) noexcept
|
||||
{
|
||||
return bindings[bindingName].mouseXPositiveMultiplier;
|
||||
}
|
||||
|
||||
static inline void BindingsSetMouseYPositiveMultiplier(std::string bindingName, double newValue) noexcept
|
||||
{
|
||||
bindings[bindingName].mouseXPositiveMultiplier = newValue;
|
||||
}
|
||||
|
||||
//Get the axis value of binding, between -1 and 1
|
||||
static double GetBindingAxis(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
|
||||
//Whether binding is being held or not
|
||||
//Does not work for mouse movement
|
||||
static bool GetBindingPositiveButton(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
static bool GetBindingNegativeButton(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
|
||||
//Whether binding is pressed down IN THIS FRAME ONLY
|
||||
//Does not work for mouse movement
|
||||
static bool GetBindingPositiveButtonDown(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
static bool GetBindingNegativeButtonDown(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
|
||||
//Whether binding is released IN THIS FRAME ONLY
|
||||
//Does not work for mouse movement
|
||||
static bool GetBindingPositiveButtonUp(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
static bool GetBindingNegativeButtonUp(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
|
||||
//Binding times
|
||||
|
||||
//Does not work for mouse movement
|
||||
static double GetBindingPositiveHeldTime(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
static double GetBindingNegativeHeldTime(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
|
||||
//Does not work for mouse movement
|
||||
static double GetBindingPositiveReleasedTime(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
static double GetBindingNegativeReleasedTime(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
|
||||
//Binding mouse velocity
|
||||
//Only for mouse movement
|
||||
static double GetBindingMouseVelocity(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Other Functions */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
@ -482,10 +810,36 @@ namespace SHADE
|
|||
/*------------------------------------------------------------------------*/
|
||||
static constexpr size_t MAX_KEYS = UCHAR_MAX + 1;
|
||||
|
||||
//How many recognised controller inputs there are
|
||||
//To see the list, see the enum class in this file
|
||||
static constexpr size_t MAX_CONTROLLER_INPUT = 20;
|
||||
|
||||
//On/off button count
|
||||
static constexpr size_t NUM_CONTROLLER_BUTTON = 14;
|
||||
|
||||
//8-bit trigger values
|
||||
static constexpr size_t NUM_CONTROLLER_TRIGGER = 2;
|
||||
|
||||
//16-bit thumbstick values
|
||||
static constexpr size_t NUM_CONTROLLER_THUMBSTICK = 4;
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
//If the last input is from controller(s) or KB/M
|
||||
//True if from controller(s), False if from KB/M
|
||||
//Useful for switching control hints between controllers and KB/M
|
||||
static bool controllerInUse;
|
||||
|
||||
//BINDINGS//////////////////////////////////////////////////////////////////
|
||||
|
||||
//Key is for binding names, they must be unique
|
||||
//Multiple physical inputs per virtual/logical input are to be added to
|
||||
//sets inside the logicalBinding values
|
||||
//TODO make this an array of 4 / 5 users for multiplayer support
|
||||
static std::map<std::string, SHLogicalBindingData> bindings;
|
||||
|
||||
//KEYBOARD AND MOUSE BUTTONS////////////////////////////////////////////////
|
||||
|
||||
//How many keys are presently being pressed
|
||||
|
@ -558,15 +912,48 @@ namespace SHADE
|
|||
|
||||
//CONTROLLER VARIABLES//////////////////////////////////////////////////////
|
||||
|
||||
//OTHER VARIABLES///////////////////////////////////////////////////////////
|
||||
//Count how many controllers are presently connected
|
||||
//Useful for if the game is to decide to take in controller or KB/M input
|
||||
//Between 0 and 4 (inclusive)
|
||||
static unsigned char controllersConnectedCount;
|
||||
|
||||
//Axis bindings
|
||||
//X
|
||||
//How many inputs (of any kind) on the controller are being used now
|
||||
//Includes analog triggers and thumbsticks
|
||||
static unsigned controllersInputCount[XUSER_MAX_COUNT];
|
||||
|
||||
//Y
|
||||
//How many DIGITAL buttons on the controller are being pressed now
|
||||
static unsigned controllersButtonCount[XUSER_MAX_COUNT];
|
||||
|
||||
//Other mappings
|
||||
//Current state of controllers
|
||||
//First index is for controller number
|
||||
//Second index is for input type
|
||||
static short controllers[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||
|
||||
//Buffer
|
||||
//State of controllers in the last frame
|
||||
//First index is for controller number
|
||||
//Second index is for input type
|
||||
static short controllersLast[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||
|
||||
//Held and released times
|
||||
|
||||
//Controller held durations
|
||||
//Stops ticking up when released
|
||||
//Will be reset when held again
|
||||
static double controllersHeldTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||
|
||||
//Key released durations
|
||||
//Stops ticking up when held
|
||||
//Will be reset when off again
|
||||
static double controllersReleasedTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Internal Helper Functions */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
//Internal helper function for checking if input is considered held or not
|
||||
static bool controllerConsideredHeld(size_t inputIdx, short value) noexcept;
|
||||
|
||||
//Internal helper function for getting normalised controller value
|
||||
static double controllerNormalisedValue(size_t inputIdx, short value) noexcept;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue