Clean up
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
#include "Binding.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Binding::Binding()
|
||||
{
|
||||
}
|
||||
|
||||
Binding::~Binding()
|
||||
{
|
||||
for (auto& binding : InputBindings)
|
||||
delete binding;
|
||||
}
|
||||
|
||||
void Binding::AddBinding(IInputBinding* inputBinding)
|
||||
{
|
||||
InputBindings.push_back(inputBinding);
|
||||
}
|
||||
|
||||
bool Binding::AnyDown()
|
||||
{
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsDown())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Binding::AnyTapped()
|
||||
{
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsTapped())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Binding::AnyReleased()
|
||||
{
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsReleased())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Binding::GetDownCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsDown())
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int Binding::GetTappedCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsTapped())
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int Binding::GetReleasedCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (const auto& binding : InputBindings)
|
||||
{
|
||||
if (binding->IsReleased())
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "IInputBinding.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class Binding
|
||||
{
|
||||
public:
|
||||
std::vector<IInputBinding*> InputBindings;
|
||||
|
||||
Binding();
|
||||
~Binding();
|
||||
|
||||
void AddBinding(IInputBinding* inputBinding);
|
||||
|
||||
bool AnyDown();
|
||||
bool AnyTapped();
|
||||
bool AnyReleased();
|
||||
|
||||
int GetDownCount();
|
||||
int GetTappedCount();
|
||||
int GetReleasedCount();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "Ds4Binding.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
#define Ds4InstanceCheckDefault(checkFunc) (DualShock4::InstanceInitialized() ? DualShock4::GetInstance()->checkFunc : false)
|
||||
|
||||
Ds4Binding::Ds4Binding(Ds4Button button) : Button(button)
|
||||
{
|
||||
}
|
||||
|
||||
Ds4Binding::~Ds4Binding()
|
||||
{
|
||||
}
|
||||
|
||||
bool Ds4Binding::IsDown()
|
||||
{
|
||||
return Ds4InstanceCheckDefault(IsDown(Button));
|
||||
}
|
||||
|
||||
bool Ds4Binding::IsTapped()
|
||||
{
|
||||
return Ds4InstanceCheckDefault(IsTapped(Button));
|
||||
}
|
||||
|
||||
bool Ds4Binding::IsReleased()
|
||||
{
|
||||
return Ds4InstanceCheckDefault(IsReleased(Button));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "IInputBinding.h"
|
||||
#include "../DirectInput/Ds4/DualShock4.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class Ds4Binding : public IInputBinding
|
||||
{
|
||||
public:
|
||||
Ds4Button Button;
|
||||
|
||||
Ds4Binding(Ds4Button button);
|
||||
~Ds4Binding();
|
||||
|
||||
bool IsDown() override;
|
||||
bool IsTapped() override;
|
||||
bool IsReleased() override;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class IInputBinding
|
||||
{
|
||||
public:
|
||||
virtual bool IsDown() = 0;
|
||||
virtual bool IsTapped() = 0;
|
||||
virtual bool IsReleased() = 0;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "KeyboardBinding.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
KeyboardBinding::KeyboardBinding(BYTE keycode) : Keycode(keycode)
|
||||
{
|
||||
}
|
||||
|
||||
KeyboardBinding::~KeyboardBinding()
|
||||
{
|
||||
}
|
||||
|
||||
bool KeyboardBinding::IsDown()
|
||||
{
|
||||
return Keyboard::GetInstance()->IsDown(Keycode);
|
||||
}
|
||||
|
||||
bool KeyboardBinding::IsTapped()
|
||||
{
|
||||
return Keyboard::GetInstance()->IsTapped(Keycode);
|
||||
}
|
||||
|
||||
bool KeyboardBinding::IsReleased()
|
||||
{
|
||||
return Keyboard::GetInstance()->IsReleased(Keycode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "IInputBinding.h"
|
||||
#include "../Keyboard/Keyboard.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class KeyboardBinding : public IInputBinding
|
||||
{
|
||||
public:
|
||||
BYTE Keycode;
|
||||
|
||||
KeyboardBinding(BYTE keycode);
|
||||
~KeyboardBinding();
|
||||
|
||||
bool IsDown() override;
|
||||
bool IsTapped() override;
|
||||
bool IsReleased() override;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "MouseBinding.h"
|
||||
#include "../Keyboard/Keyboard.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
MouseBinding::MouseBinding(MouseAction action) : Action(action)
|
||||
{
|
||||
}
|
||||
|
||||
MouseBinding::~MouseBinding()
|
||||
{
|
||||
}
|
||||
|
||||
bool MouseBinding::IsDown()
|
||||
{
|
||||
switch (Action)
|
||||
{
|
||||
case MouseAction_LeftButton:
|
||||
return Keyboard::GetInstance()->IsDown(MK_LBUTTON);
|
||||
case MouseAction_RightButton:
|
||||
return Keyboard::GetInstance()->IsDown(MK_RBUTTON);
|
||||
case MouseAction_MiddleButton:
|
||||
return Keyboard::GetInstance()->IsDown(MK_MBUTTON);
|
||||
case MouseAction_ScrollUp:
|
||||
return Mouse::GetInstance()->GetIsScrolledUp();
|
||||
case MouseAction_ScrollDown:
|
||||
return Mouse::GetInstance()->GetIsScrolledDown();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MouseBinding::IsTapped()
|
||||
{
|
||||
switch (Action)
|
||||
{
|
||||
case MouseAction_LeftButton:
|
||||
return Keyboard::GetInstance()->IsTapped(MK_LBUTTON);
|
||||
case MouseAction_RightButton:
|
||||
return Keyboard::GetInstance()->IsTapped(MK_RBUTTON);
|
||||
case MouseAction_MiddleButton:
|
||||
return Keyboard::GetInstance()->IsTapped(MK_MBUTTON);
|
||||
case MouseAction_ScrollUp:
|
||||
return Mouse::GetInstance()->GetIsScrolledUp();
|
||||
case MouseAction_ScrollDown:
|
||||
return Mouse::GetInstance()->GetIsScrolledDown();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MouseBinding::IsReleased()
|
||||
{
|
||||
switch (Action)
|
||||
{
|
||||
case MouseAction_LeftButton:
|
||||
return Keyboard::GetInstance()->IsReleased(MK_LBUTTON);
|
||||
case MouseAction_RightButton:
|
||||
return Keyboard::GetInstance()->IsReleased(MK_RBUTTON);
|
||||
case MouseAction_MiddleButton:
|
||||
return Keyboard::GetInstance()->IsReleased(MK_MBUTTON);
|
||||
case MouseAction_ScrollUp:
|
||||
return Mouse::GetInstance()->GetWasScrolledUp();
|
||||
case MouseAction_ScrollDown:
|
||||
return Mouse::GetInstance()->GetWasScrolledDown();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include "IInputBinding.h"
|
||||
#include "../Mouse/Mouse.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
enum MouseAction
|
||||
{
|
||||
MouseAction_LeftButton,
|
||||
MouseAction_RightButton,
|
||||
MouseAction_MiddleButton,
|
||||
MouseAction_ScrollUp,
|
||||
MouseAction_ScrollDown,
|
||||
};
|
||||
|
||||
class MouseBinding : public IInputBinding
|
||||
{
|
||||
public:
|
||||
MouseAction Action;
|
||||
|
||||
MouseBinding(MouseAction action);
|
||||
~MouseBinding();
|
||||
|
||||
bool IsDown() override;
|
||||
bool IsTapped() override;
|
||||
bool IsReleased() override;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "XinputBinding.h"
|
||||
#include "..\Xinput\Xinput.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
XinputBinding::XinputBinding(BYTE keycode) : Keycode(keycode)
|
||||
{
|
||||
}
|
||||
|
||||
XinputBinding::~XinputBinding()
|
||||
{
|
||||
}
|
||||
|
||||
bool XinputBinding::IsDown()
|
||||
{
|
||||
return Xinput::GetInstance()->IsDown(Keycode);
|
||||
}
|
||||
|
||||
bool XinputBinding::IsTapped()
|
||||
{
|
||||
return Xinput::GetInstance()->IsTapped(Keycode);
|
||||
}
|
||||
|
||||
bool XinputBinding::IsReleased()
|
||||
{
|
||||
return Xinput::GetInstance()->IsReleased(Keycode);
|
||||
}
|
||||
|
||||
bool XinputBinding::IsDoubleTapped()
|
||||
{
|
||||
return Xinput::GetInstance()->IsDoubleTapped(Keycode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "IInputBinding.h"
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class XinputBinding : public IInputBinding
|
||||
{
|
||||
public:
|
||||
BYTE Keycode;
|
||||
|
||||
XinputBinding(BYTE keycode);
|
||||
~XinputBinding();
|
||||
|
||||
bool IsDown() override;
|
||||
bool IsTapped() override;
|
||||
bool IsReleased() override;
|
||||
bool IsDoubleTapped();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "Controller.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Controller::Controller()
|
||||
{
|
||||
}
|
||||
|
||||
Controller::~Controller()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "DirectInputDevice.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class Controller : public DirectInputDevice
|
||||
{
|
||||
protected:
|
||||
Controller();
|
||||
~Controller();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "DirectInput.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
IDirectInput8 *IDirectInputInstance = nullptr;
|
||||
|
||||
HRESULT InitializeDirectInput(HMODULE module)
|
||||
{
|
||||
HRESULT result = DirectInput8Create(module, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&IDirectInputInstance, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DirectInputInitialized()
|
||||
{
|
||||
return IDirectInputInstance != nullptr;
|
||||
}
|
||||
|
||||
void DisposeDirectInput()
|
||||
{
|
||||
if (IDirectInputInstance == nullptr)
|
||||
return;
|
||||
|
||||
IDirectInputInstance->Release();
|
||||
IDirectInputInstance = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
extern IDirectInput8 *IDirectInputInstance;
|
||||
|
||||
HRESULT InitializeDirectInput(HMODULE module);
|
||||
bool DirectInputInitialized();
|
||||
void DisposeDirectInput();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#include "DirectInputDevice.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
HRESULT DirectInputDevice::DI_CreateDevice(const GUID &guid)
|
||||
{
|
||||
if (!DirectInputInitialized())
|
||||
return DIERR_NOTINITIALIZED;
|
||||
|
||||
HRESULT result = IDirectInputInstance->CreateDevice(guid, &directInputdevice, NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_SetDataFormat(LPCDIDATAFORMAT dataFormat)
|
||||
{
|
||||
HRESULT result = directInputdevice->SetDataFormat(dataFormat);
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_SetCooperativeLevel(HWND windowHandle, DWORD flags)
|
||||
{
|
||||
HRESULT result = directInputdevice->SetCooperativeLevel(windowHandle, flags);
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_Acquire()
|
||||
{
|
||||
HRESULT result = directInputdevice->Acquire();
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_Unacquire()
|
||||
{
|
||||
HRESULT result = directInputdevice->Unacquire();
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_Release()
|
||||
{
|
||||
HRESULT result = directInputdevice->Release();
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_Poll()
|
||||
{
|
||||
HRESULT result = directInputdevice->Poll();
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DirectInputDevice::DI_GetDeviceState(DWORD size, LPVOID data)
|
||||
{
|
||||
HRESULT result = directInputdevice->GetDeviceState(size, data);
|
||||
return result;
|
||||
}
|
||||
|
||||
void DirectInputDevice::DI_Dispose()
|
||||
{
|
||||
if (directInputdevice == nullptr)
|
||||
return;
|
||||
|
||||
HRESULT result = NULL;
|
||||
|
||||
result = DI_Unacquire();
|
||||
result = DI_Release();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "DirectInput.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class DirectInputDevice
|
||||
{
|
||||
protected:
|
||||
IDirectInputDevice8 *directInputdevice;
|
||||
|
||||
HRESULT DI_CreateDevice(const GUID& guid);
|
||||
HRESULT DI_SetDataFormat(LPCDIDATAFORMAT dataFormat);
|
||||
HRESULT DI_SetCooperativeLevel(HWND windowHandle, DWORD flags);
|
||||
HRESULT DI_Acquire();
|
||||
HRESULT DI_Unacquire();
|
||||
HRESULT DI_Release();
|
||||
HRESULT DI_Poll();
|
||||
HRESULT DI_GetDeviceState(DWORD size, LPVOID data);
|
||||
|
||||
void DI_Dispose();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "DirectInputMouse.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
DirectInputMouse::DirectInputMouse()
|
||||
{
|
||||
HRESULT result = NULL;
|
||||
|
||||
result = DI_CreateDevice(GUID_SysMouse);
|
||||
|
||||
if (FAILED(result))
|
||||
return;
|
||||
|
||||
result = DI_SetDataFormat(&c_dfDIMouse);
|
||||
result = DI_Acquire();
|
||||
}
|
||||
|
||||
DirectInputMouse::~DirectInputMouse()
|
||||
{
|
||||
DI_Dispose();
|
||||
}
|
||||
|
||||
bool DirectInputMouse::Poll()
|
||||
{
|
||||
if (!DirectInputInitialized())
|
||||
return FALSE;
|
||||
|
||||
HRESULT result = NULL;
|
||||
|
||||
result = DI_Poll();
|
||||
result = DI_GetDeviceState(sizeof(mouseState), &mouseState);
|
||||
|
||||
return !FAILED(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "DirectInputDevice.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class DirectInputMouse : public DirectInputDevice
|
||||
{
|
||||
public:
|
||||
DirectInputMouse();
|
||||
~DirectInputMouse();
|
||||
|
||||
bool Poll();
|
||||
|
||||
inline long GetXPosition() { return mouseState.lX; };
|
||||
inline long GetYPosition() { return mouseState.lY; };
|
||||
inline long GetMouseWheel() { return mouseState.lZ; };
|
||||
|
||||
private:
|
||||
DIMOUSESTATE mouseState;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
enum Direction
|
||||
{
|
||||
DIR_UP,
|
||||
DIR_RIGHT,
|
||||
DIR_DOWN,
|
||||
DIR_LEFT
|
||||
};
|
||||
|
||||
enum Ds4Button : int
|
||||
{
|
||||
DS4_SQUARE = 0,
|
||||
DS4_CROSS = 1,
|
||||
DS4_CIRCLE = 2,
|
||||
DS4_TRIANGLE = 3,
|
||||
|
||||
DS4_L1 = 4,
|
||||
DS4_R1 = 5,
|
||||
|
||||
DS4_L_TRIGGER = 6,
|
||||
DS4_R_TRIGGER = 7,
|
||||
|
||||
DS4_SHARE = 8,
|
||||
DS4_OPTIONS = 9,
|
||||
|
||||
DS4_L3 = 10,
|
||||
DS4_R3 = 11,
|
||||
|
||||
DS4_PS = 12,
|
||||
DS4_TOUCH = 13,
|
||||
|
||||
DS4_DPAD_UP,
|
||||
DS4_DPAD_RIGHT,
|
||||
DS4_DPAD_DOWN,
|
||||
DS4_DPAD_LEFT,
|
||||
|
||||
DS4_L_STICK_UP,
|
||||
DS4_L_STICK_RIGHT,
|
||||
DS4_L_STICK_DOWN,
|
||||
DS4_L_STICK_LEFT,
|
||||
|
||||
DS4_R_STICK_UP,
|
||||
DS4_R_STICK_RIGHT,
|
||||
DS4_R_STICK_DOWN,
|
||||
DS4_R_STICK_LEFT,
|
||||
|
||||
DS4_BUTTON_MAX,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "Ds4State.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Joystick::Joystick() : XAxis(0.0f), YAxis(0.0f)
|
||||
{
|
||||
return;
|
||||
};
|
||||
|
||||
Joystick::Joystick(float xAxis, float yAxis) : XAxis(xAxis), YAxis(yAxis)
|
||||
{
|
||||
return;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include "../DirectInput.h"
|
||||
#include "Ds4Button.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
struct Joystick
|
||||
{
|
||||
FLOAT XAxis, YAxis;
|
||||
|
||||
Joystick();
|
||||
Joystick(float xAxis, float yAxis);
|
||||
};
|
||||
|
||||
struct Dpad
|
||||
{
|
||||
BOOL IsDown;
|
||||
FLOAT Angle;
|
||||
Joystick Stick;
|
||||
};
|
||||
|
||||
struct Trigger
|
||||
{
|
||||
FLOAT Axis;
|
||||
};
|
||||
|
||||
struct Ds4State
|
||||
{
|
||||
DIJOYSTATE2 DI_JoyState;
|
||||
|
||||
BYTE Buttons[DS4_BUTTON_MAX];
|
||||
|
||||
Dpad Dpad;
|
||||
Joystick LeftStick;
|
||||
Joystick RightStick;
|
||||
Trigger LeftTrigger;
|
||||
Trigger RightTrigger;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
#include "DualShock4.h"
|
||||
#include "../../../Utilities/Math.h"
|
||||
#include "../../../framework.h"
|
||||
#include <stdio.h>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
DualShock4* DualShock4::instance;
|
||||
|
||||
DualShock4::DualShock4()
|
||||
{
|
||||
}
|
||||
|
||||
DualShock4::~DualShock4()
|
||||
{
|
||||
DI_Dispose();
|
||||
}
|
||||
|
||||
bool DualShock4::TryInitializeInstance()
|
||||
{
|
||||
if (InstanceInitialized())
|
||||
return true;
|
||||
|
||||
if (!DirectInputInitialized())
|
||||
return false;
|
||||
|
||||
DualShock4 *dualShock4 = new DualShock4();
|
||||
|
||||
bool success = dualShock4->Initialize();
|
||||
instance = success ? dualShock4 : nullptr;
|
||||
|
||||
if (!success)
|
||||
delete dualShock4;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool DualShock4::Initialize()
|
||||
{
|
||||
HRESULT result = NULL;
|
||||
|
||||
const size_t guidCount = sizeof(GUID_Ds4) / sizeof(GUID);
|
||||
for (size_t i = 0; i < guidCount; i++)
|
||||
{
|
||||
result = DI_CreateDevice(GUID_Ds4[i]);
|
||||
|
||||
if (!FAILED(result))
|
||||
break;
|
||||
else if (i == guidCount - 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(result = DI_SetDataFormat(&c_dfDIJoystick2)))
|
||||
return false;
|
||||
|
||||
result = DI_Acquire();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DualShock4::PollInput()
|
||||
{
|
||||
lastState = currentState;
|
||||
|
||||
HRESULT result = NULL;
|
||||
result = DI_Poll();
|
||||
result = DI_GetDeviceState(sizeof(DIJOYSTATE2), ¤tState.DI_JoyState);
|
||||
|
||||
if (result != DI_OK)
|
||||
return false;
|
||||
|
||||
UpdateInternalDs4State(currentState);
|
||||
|
||||
for (int button = 0; button < DS4_BUTTON_MAX; button++)
|
||||
currentState.Buttons[button] = GetButtonState(currentState, (Ds4Button)button);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DualShock4::UpdateInternalDs4State(Ds4State &state)
|
||||
{
|
||||
if (state.Dpad.IsDown = state.DI_JoyState.rgdwPOV[0] != -1)
|
||||
{
|
||||
state.Dpad.Angle = (state.DI_JoyState.rgdwPOV[0] / 100.0f);
|
||||
|
||||
auto direction = Utilities::GetDirection(state.Dpad.Angle);
|
||||
state.Dpad.Stick = { direction.Y, -direction.X };
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Dpad.Angle = 0;
|
||||
state.Dpad.Stick = Joystick();
|
||||
}
|
||||
|
||||
state.LeftStick = NormalizeStick(state.DI_JoyState.lX, state.DI_JoyState.lY);
|
||||
state.RightStick = NormalizeStick(state.DI_JoyState.lZ, state.DI_JoyState.lRz);
|
||||
|
||||
state.LeftTrigger = { NormalizeTrigger(state.DI_JoyState.lRx) };
|
||||
state.RightTrigger = { NormalizeTrigger(state.DI_JoyState.lRy) };
|
||||
}
|
||||
|
||||
bool DualShock4::IsDown(Ds4Button button)
|
||||
{
|
||||
return currentState.Buttons[button];
|
||||
}
|
||||
|
||||
bool DualShock4::IsUp(Ds4Button button)
|
||||
{
|
||||
return !IsDown(button);
|
||||
}
|
||||
|
||||
bool DualShock4::IsTapped(Ds4Button button)
|
||||
{
|
||||
return IsDown(button) && WasUp(button);
|
||||
}
|
||||
|
||||
bool DualShock4::IsReleased(Ds4Button button)
|
||||
{
|
||||
return IsUp(button) && WasDown(button);
|
||||
}
|
||||
|
||||
bool DualShock4::WasDown(Ds4Button button)
|
||||
{
|
||||
return lastState.Buttons[button];
|
||||
}
|
||||
|
||||
bool DualShock4::WasUp(Ds4Button button)
|
||||
{
|
||||
return !WasDown(button);
|
||||
}
|
||||
|
||||
bool DualShock4::MatchesDirection(Joystick joystick, Direction directionEnum, float threshold)
|
||||
{
|
||||
switch (directionEnum)
|
||||
{
|
||||
case TLAC::Input::DIR_UP:
|
||||
return joystick.YAxis <= -threshold;
|
||||
|
||||
case TLAC::Input::DIR_RIGHT:
|
||||
return joystick.XAxis >= +threshold;
|
||||
|
||||
case TLAC::Input::DIR_DOWN:
|
||||
return joystick.YAxis >= +threshold;
|
||||
|
||||
case TLAC::Input::DIR_LEFT:
|
||||
return joystick.XAxis <= -threshold;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DualShock4::GetButtonState(Ds4State &state, Ds4Button button)
|
||||
{
|
||||
if (button >= DS4_SQUARE && button <= DS4_TOUCH)
|
||||
return state.DI_JoyState.rgbButtons[button];
|
||||
|
||||
if (button >= DS4_DPAD_UP && button <= DS4_DPAD_LEFT)
|
||||
return state.Dpad.IsDown ? MatchesDirection(state.Dpad.Stick, (Direction)(button - DS4_DPAD_UP), dpadThreshold) : false;
|
||||
|
||||
if (button >= DS4_L_STICK_UP && button <= DS4_L_STICK_LEFT)
|
||||
return MatchesDirection(state.LeftStick, (Direction)(button - DS4_L_STICK_UP), joystickThreshold);
|
||||
|
||||
if (button >= DS4_R_STICK_UP && button <= DS4_R_STICK_LEFT)
|
||||
return MatchesDirection(state.RightStick, (Direction)(button - DS4_R_STICK_UP), joystickThreshold);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#include "../Controller.h"
|
||||
#include "../../IInputDevice.h"
|
||||
#include "Ds4State.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
// DualShock 4 Wireless Controller Product GUIDs:
|
||||
const GUID GUID_Ds4[2] =
|
||||
{
|
||||
// First Generation: {05C4054C-0000-0000-0000-504944564944}
|
||||
{ 0x05C4054C, 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
|
||||
// Second Generation: {09CC054C-0000-0000-0000-504944564944}
|
||||
{ 0x09CC054C, 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
|
||||
};
|
||||
|
||||
class DualShock4 : public Controller, public IInputDevice
|
||||
{
|
||||
public:
|
||||
DualShock4();
|
||||
~DualShock4();
|
||||
|
||||
static bool TryInitializeInstance();
|
||||
|
||||
bool Initialize();
|
||||
bool PollInput() override;
|
||||
|
||||
bool IsDown(Ds4Button button);
|
||||
bool IsUp(Ds4Button button);
|
||||
bool IsTapped(Ds4Button button);
|
||||
bool IsReleased(Ds4Button button);
|
||||
bool WasDown(Ds4Button button);
|
||||
bool WasUp(Ds4Button button);
|
||||
|
||||
inline Joystick GetLeftStick() { return currentState.LeftStick; };
|
||||
inline Joystick GetRightStick() { return currentState.RightStick; };
|
||||
inline Joystick GetDpad() { return currentState.Dpad.Stick; };
|
||||
|
||||
static inline bool InstanceInitialized() { return instance != nullptr; };
|
||||
static inline DualShock4* GetInstance() { return instance; };
|
||||
static inline void DeleteInstance() { delete instance; instance = nullptr; };
|
||||
|
||||
private:
|
||||
static DualShock4* instance;
|
||||
|
||||
Ds4State lastState;
|
||||
Ds4State currentState;
|
||||
|
||||
const float triggerThreshold = 0.5f;
|
||||
const float joystickThreshold = 0.5f;
|
||||
const float dpadThreshold = 0.5f;
|
||||
|
||||
inline float NormalizeTrigger(long value) { return (float)value / USHRT_MAX; };
|
||||
inline float NormalizeStick(long value) { return (float)value / USHRT_MAX * 2.0f - 1.0f; };
|
||||
inline Joystick NormalizeStick(long x, long y) { return Joystick(NormalizeStick(x), NormalizeStick(y)); };
|
||||
|
||||
void UpdateInternalDs4State(Ds4State &state);
|
||||
|
||||
bool MatchesDirection(Joystick joystick, Direction directionEnum, float threshold);
|
||||
bool GetButtonState(Ds4State &state, Ds4Button button);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class IInputDevice
|
||||
{
|
||||
public:
|
||||
virtual bool PollInput() = 0;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
#include "Config.h"
|
||||
#include "windows.h"
|
||||
#include "../Bindings/KeyboardBinding.h"
|
||||
#include "../Bindings/Ds4Binding.h"
|
||||
#include "../../Utilities/Operations.h"
|
||||
#include "../Bindings/XinputBinding.h"
|
||||
#include "../../Constants.h"
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
KeycodeMap Config::Keymap =
|
||||
{
|
||||
// NumPad Keys
|
||||
{ "NumPad0", VK_NUMPAD0 },
|
||||
{ "NumPad1", VK_NUMPAD1 },
|
||||
{ "NumPad2", VK_NUMPAD2 },
|
||||
{ "NumPad3", VK_NUMPAD3 },
|
||||
{ "NumPad4", VK_NUMPAD4 },
|
||||
{ "NumPad5", VK_NUMPAD5 },
|
||||
{ "NumPad6", VK_NUMPAD6 },
|
||||
{ "NumPad7", VK_NUMPAD7 },
|
||||
{ "NumPad8", VK_NUMPAD8 },
|
||||
{ "NumPad9", VK_NUMPAD9 },
|
||||
{ "Plus", VK_ADD },
|
||||
{ "Minus", VK_SUBTRACT },
|
||||
{ "Divide", VK_DIVIDE },
|
||||
{ "Multiply", VK_MULTIPLY },
|
||||
{ "Comma", VK_OEM_COMMA },
|
||||
{ "Period", VK_OEM_PERIOD },
|
||||
{ "Slash", VK_OEM_2 },
|
||||
// F-Keys
|
||||
{ "F1", VK_F1 },
|
||||
{ "F2", VK_F2 },
|
||||
{ "F3", VK_F3 },
|
||||
{ "F4", VK_F4 },
|
||||
{ "F5", VK_F5 },
|
||||
{ "F6", VK_F6 },
|
||||
{ "F7", VK_F7 },
|
||||
{ "F8", VK_F8 },
|
||||
{ "F9", VK_F9 },
|
||||
{ "F10", VK_F10 },
|
||||
{ "F11", VK_F11 },
|
||||
{ "F12", VK_F12 },
|
||||
{ "F13", VK_F13 },
|
||||
{ "F14", VK_F14 },
|
||||
{ "F15", VK_F15 },
|
||||
{ "F16", VK_F16 },
|
||||
{ "F17", VK_F17 },
|
||||
{ "F18", VK_F18 },
|
||||
{ "F19", VK_F19 },
|
||||
{ "F20", VK_F20 },
|
||||
{ "F21", VK_F21 },
|
||||
{ "F22", VK_F22 },
|
||||
{ "F23", VK_F23 },
|
||||
{ "F24", VK_F24 },
|
||||
// Shift Keys
|
||||
{ "LeftShift", VK_LSHIFT },
|
||||
{ "LShift", VK_LSHIFT },
|
||||
{ "RightShift", VK_RSHIFT },
|
||||
{ "RShift", VK_RSHIFT },
|
||||
// Control Keys
|
||||
{ "LeftControl", VK_LCONTROL },
|
||||
{ "LControl", VK_LCONTROL },
|
||||
{ "LCtrl", VK_LCONTROL },
|
||||
{ "RightControl", VK_RCONTROL },
|
||||
{ "RControl", VK_RCONTROL },
|
||||
{ "RCtrl", VK_RCONTROL },
|
||||
// Arrow Keys
|
||||
{ "Up", VK_UP },
|
||||
{ "Down", VK_DOWN },
|
||||
{ "Left", VK_LEFT },
|
||||
{ "Right", VK_RIGHT },
|
||||
// Special Keys
|
||||
{ "Enter", VK_RETURN },
|
||||
{ "Return", VK_RETURN },
|
||||
{ "Tab", VK_TAB },
|
||||
{ "Back", VK_BACK },
|
||||
{ "Backspace", VK_BACK },
|
||||
{ "Insert", VK_INSERT },
|
||||
{ "Ins", VK_INSERT },
|
||||
{ "Delete", VK_DELETE },
|
||||
{ "Del", VK_DELETE },
|
||||
{ "Home", VK_HOME },
|
||||
{ "End", VK_END },
|
||||
{ "PageUp", VK_PRIOR },
|
||||
{ "PageDown", VK_NEXT },
|
||||
{ "ESC", VK_ESCAPE },
|
||||
{ "Escape", VK_ESCAPE },
|
||||
{ "Comma", VK_OEM_COMMA },
|
||||
{ "Period", VK_OEM_PERIOD },
|
||||
{ "Slash", VK_OEM_2 },
|
||||
// Mouse buttons
|
||||
{ "MouseLeft", VK_LBUTTON },
|
||||
{ "MouseMiddle", VK_MBUTTON },
|
||||
{ "MouseRight", VK_RBUTTON },
|
||||
{ "MouseX1", VK_XBUTTON1 },
|
||||
{ "MouseX2", VK_XBUTTON2 },
|
||||
};
|
||||
|
||||
KeycodeMap Config::XinputMap =
|
||||
{
|
||||
//XINPUT
|
||||
{ "XINPUT_A", XINPUT_A},
|
||||
{ "XINPUT_B", XINPUT_B},
|
||||
{ "XINPUT_X", XINPUT_X},
|
||||
{ "XINPUT_Y", XINPUT_Y},
|
||||
{ "XINPUT_UP", XINPUT_UP},
|
||||
{ "XINPUT_DOWN", XINPUT_DOWN},
|
||||
{ "XINPUT_LEFT", XINPUT_LEFT},
|
||||
{ "XINPUT_RIGHT", XINPUT_RIGHT},
|
||||
{ "XINPUT_START", XINPUT_START},
|
||||
{ "XINPUT_BACK", XINPUT_BACK},
|
||||
{ "XINPUT_LS", XINPUT_LS},
|
||||
{ "XINPUT_RS", XINPUT_RS},
|
||||
{ "XINPUT_LB", XINPUT_LS},
|
||||
{ "XINPUT_RB", XINPUT_RS},
|
||||
{ "XINPUT_LT", XINPUT_LT},
|
||||
{ "XINPUT_RT", XINPUT_RT},
|
||||
{ "XINPUT_LSB", XINPUT_LSB},
|
||||
{ "XINPUT_RSB", XINPUT_RSB},
|
||||
{ "XINPUT_LLEFT", XINPUT_LLEFT},
|
||||
{ "XINPUT_LRIGHT", XINPUT_LRIGHT},
|
||||
{ "XINPUT_RLEFT", XINPUT_RLEFT},
|
||||
{ "XINPUT_RRIGHT", XINPUT_RRIGHT},
|
||||
};
|
||||
|
||||
Ds4ButtonMap Config::Ds4Map =
|
||||
{
|
||||
// Face Buttons
|
||||
{ "DS4_SQUARE", DS4_SQUARE },
|
||||
{ "Ds4_Square", DS4_SQUARE },
|
||||
|
||||
{ "DS4_CROSS", DS4_CROSS },
|
||||
{ "Ds4_Cross", DS4_CROSS },
|
||||
|
||||
{ "DS4_CIRCLE", DS4_CIRCLE },
|
||||
{ "Ds4_Circle", DS4_CIRCLE },
|
||||
|
||||
{ "DS4_TRIANGLE", DS4_TRIANGLE },
|
||||
{ "Ds4_Triangle", DS4_TRIANGLE },
|
||||
|
||||
// Standard Buttons
|
||||
{ "DS4_SHARE", DS4_SHARE },
|
||||
{ "Ds4_Share", DS4_SHARE },
|
||||
|
||||
{ "DS4_OPTIONS", DS4_OPTIONS },
|
||||
{ "Ds4_Options", DS4_OPTIONS },
|
||||
|
||||
{ "DS4_PS", DS4_PS },
|
||||
{ "Ds4_PS", DS4_PS },
|
||||
|
||||
{ "DS4_TOUCH", DS4_TOUCH },
|
||||
{ "Ds4_Touch", DS4_TOUCH },
|
||||
|
||||
{ "DS4_L1", DS4_L1 },
|
||||
{ "Ds4_L1", DS4_L1 },
|
||||
|
||||
{ "DS4_R1", DS4_R1 },
|
||||
{ "Ds4_R1", DS4_R1 },
|
||||
|
||||
// D-Pad Directions
|
||||
{ "DS4_DPAD_UP", DS4_DPAD_UP },
|
||||
{ "Ds4_DPad_Up", DS4_DPAD_UP },
|
||||
|
||||
{ "DS4_DPAD_RIGHT", DS4_DPAD_RIGHT },
|
||||
{ "Ds4_DPad_Right", DS4_DPAD_RIGHT },
|
||||
|
||||
{ "DS4_DPAD_DOWN", DS4_DPAD_DOWN },
|
||||
{ "Ds4_DPad_Down", DS4_DPAD_DOWN },
|
||||
|
||||
{ "DS4_DPAD_LEFT", DS4_DPAD_LEFT },
|
||||
{ "Ds4_DPad_Left", DS4_DPAD_LEFT },
|
||||
|
||||
// Trigger Buttons
|
||||
{ "DS4_L_TRIGGER", DS4_L_TRIGGER },
|
||||
{ "Ds4_L_Trigger", DS4_L_TRIGGER },
|
||||
|
||||
{ "DS4_R_TRIGGER", DS4_R_TRIGGER },
|
||||
{ "Ds4_R_Trigger", DS4_R_TRIGGER },
|
||||
|
||||
// Joystick Buttons
|
||||
{ "DS4_L3", DS4_L3 },
|
||||
{ "Ds4_L3", DS4_L3 },
|
||||
|
||||
{ "DS4_R3", DS4_R3 },
|
||||
{ "Ds4_R3", DS4_R3 },
|
||||
|
||||
// Left Joystick
|
||||
{ "DS4_L_STICK_UP", DS4_L_STICK_UP },
|
||||
{ "Ds4_L_Stick_Up", DS4_L_STICK_UP },
|
||||
|
||||
{ "DS4_L_STICK_RIGHT", DS4_L_STICK_RIGHT },
|
||||
{ "Ds4_L_Stick_Right", DS4_L_STICK_RIGHT },
|
||||
|
||||
{ "DS4_L_STICK_DOWN", DS4_L_STICK_DOWN },
|
||||
{ "Ds4_L_Stick_Down", DS4_L_STICK_DOWN },
|
||||
|
||||
{ "DS4_L_STICK_LEFT", DS4_L_STICK_LEFT },
|
||||
{ "Ds4_L_Stick_Left", DS4_L_STICK_LEFT },
|
||||
|
||||
// Right Joystick
|
||||
{ "DS4_R_STICK_UP", DS4_R_STICK_UP },
|
||||
{ "Ds4_R_Stick_Up", DS4_R_STICK_UP },
|
||||
|
||||
{ "DS4_R_STICK_RIGHT", DS4_R_STICK_RIGHT },
|
||||
{ "Ds4_R_Stick_Right", DS4_R_STICK_RIGHT },
|
||||
|
||||
{ "DS4_R_STICK_DOWN", DS4_R_STICK_DOWN },
|
||||
{ "Ds4_R_Stick_Down", DS4_R_STICK_DOWN },
|
||||
|
||||
{ "DS4_R_STICK_LEFT", DS4_R_STICK_LEFT },
|
||||
{ "Ds4_R_Stick_Left", DS4_R_STICK_LEFT },
|
||||
};
|
||||
|
||||
void Config::BindConfigKeys(std::unordered_map<std::string, std::string> &configMap, const char *configKeyName, Binding &bindObj, std::vector<std::string> defaultKeys)
|
||||
{
|
||||
std::vector<std::string> keys;
|
||||
|
||||
auto configPair = configMap.find(configKeyName);
|
||||
|
||||
// config variable was found in the ini
|
||||
if (configPair != configMap.end())
|
||||
{
|
||||
keys = Utilities::Split(configPair->second, ",");
|
||||
}
|
||||
else
|
||||
{
|
||||
keys = defaultKeys;
|
||||
}
|
||||
|
||||
for (std::string key : keys)
|
||||
{
|
||||
Utilities::Trim(key);
|
||||
|
||||
// Applies only for Single-Character keys
|
||||
if (key.length() == 1)
|
||||
{
|
||||
bindObj.AddBinding(new KeyboardBinding(key[0]));
|
||||
}
|
||||
else // for special key names
|
||||
{
|
||||
auto keycode = Config::Keymap.find(key.c_str());
|
||||
|
||||
// name is known in the special keys map
|
||||
if (keycode != Config::Keymap.end())
|
||||
{
|
||||
bindObj.AddBinding(new KeyboardBinding(keycode->second));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto xinputBtn = Config::XinputMap.find(key.c_str());
|
||||
|
||||
if (xinputBtn != Config::XinputMap.end())
|
||||
{
|
||||
bindObj.AddBinding(new XinputBinding(xinputBtn->second));
|
||||
}
|
||||
else
|
||||
{
|
||||
// just gonna be lazy for now and put this inside an else statement
|
||||
auto ds4Button = Config::Ds4Map.find(key.c_str());
|
||||
|
||||
if (ds4Button != Config::Ds4Map.end())
|
||||
{
|
||||
bindObj.AddBinding(new Ds4Binding(ds4Button->second));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[TLAC] Config::BindConfigKeys(): Unable to parse key: '%s'\n", key.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include "KeyString.h"
|
||||
#include "KeyStringHash.h"
|
||||
#include "../Bindings/Binding.h"
|
||||
#include "../DirectInput/Ds4/Ds4Button.h"
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
typedef std::unordered_map<KeyString, uint8_t, KeyStringHash> KeycodeMap;
|
||||
typedef std::unordered_map<KeyString, Ds4Button, KeyStringHash> Ds4ButtonMap;
|
||||
|
||||
class Config
|
||||
{
|
||||
public:
|
||||
static KeycodeMap Keymap;
|
||||
static Ds4ButtonMap Ds4Map;
|
||||
static KeycodeMap XinputMap;
|
||||
|
||||
static void BindConfigKeys(std::unordered_map<std::string, std::string> &configMap, const char *configKeyName, Binding &bindObj, std::vector<std::string> defaultKeys);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "KeyString.h"
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
KeyString::KeyString(const char* str) : value(str)
|
||||
{
|
||||
}
|
||||
|
||||
bool KeyString::operator==(const KeyString& rsv) const
|
||||
{
|
||||
return !_strcmpi(value.c_str(), rsv.value.c_str());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
struct KeyString
|
||||
{
|
||||
std::string value;
|
||||
|
||||
KeyString(const char* str);
|
||||
bool operator==(const KeyString& rsv) const;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "KeyStringHash.h"
|
||||
#include <filesystem>
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
size_t KeyStringHash::operator()(const KeyString& key) const
|
||||
{
|
||||
std::string ret = key.value;
|
||||
std::transform(ret.begin(), ret.end(), ret.begin(),
|
||||
[](unsigned char c) { return std::tolower(c, std::locale()); });
|
||||
return std::hash<std::string>()(ret);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "KeyString.h"
|
||||
|
||||
namespace TLAC::Input::KeyConfig
|
||||
{
|
||||
struct KeyStringHash
|
||||
{
|
||||
size_t operator()(const KeyString& key) const;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
#include "Keyboard.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Keyboard* Keyboard::instance;
|
||||
|
||||
Keyboard::Keyboard()
|
||||
{
|
||||
}
|
||||
|
||||
Keyboard* Keyboard::GetInstance()
|
||||
{
|
||||
if (instance == nullptr)
|
||||
instance = new Keyboard();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool Keyboard::PollInput()
|
||||
{
|
||||
lastState = currentState;
|
||||
|
||||
float elapsed = keyIntervalWatch.Restart();
|
||||
|
||||
for (BYTE i = 0; i < KEYBOARD_KEYS; i++)
|
||||
{
|
||||
// DOWN
|
||||
bool isDown = GetAsyncKeyState(i) < 0;
|
||||
currentState.KeyStates[i] = isDown;
|
||||
|
||||
// DOUBLE TAPPED
|
||||
bool isTapped = IsTapped(i);
|
||||
keyDoubleTapStates[i] = isTapped ? keyDoubleTapWatches[i].Restart() <= DOUBLE_TAP_THRESHOLD : false;
|
||||
|
||||
// INTERVAL TAPPED
|
||||
keyIntervalTapStates[i] = isTapped;
|
||||
|
||||
if (isTapped)
|
||||
{
|
||||
keyIntervalTapTimes[i] = 0;
|
||||
keyIntervalInitials[i] = true;
|
||||
}
|
||||
else if (isDown)
|
||||
{
|
||||
float threshold = keyIntervalInitials[i] ? INTERVAL_TAP_DELAY_THRESHOLD : INTERVAL_TAP_THRESHOLD;
|
||||
|
||||
bool intervalTapped = (keyIntervalTapTimes[i] += elapsed) > threshold;
|
||||
keyIntervalTapStates[i] = intervalTapped;
|
||||
|
||||
if (intervalTapped)
|
||||
{
|
||||
keyIntervalTapTimes[i] = 0;
|
||||
keyIntervalInitials[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Keyboard::IsDown(BYTE keycode)
|
||||
{
|
||||
return currentState.IsDown(keycode);
|
||||
}
|
||||
|
||||
bool Keyboard::IsUp(BYTE keycode)
|
||||
{
|
||||
return !IsDown(keycode);
|
||||
}
|
||||
|
||||
bool Keyboard::IsTapped(BYTE keycode)
|
||||
{
|
||||
return IsDown(keycode) && WasUp(keycode);
|
||||
}
|
||||
|
||||
bool Keyboard::IsDoubleTapped(BYTE keycode)
|
||||
{
|
||||
return keyDoubleTapStates[keycode];
|
||||
}
|
||||
|
||||
bool Keyboard::IsReleased(BYTE keycode)
|
||||
{
|
||||
return IsUp(keycode) && WasDown(keycode);
|
||||
}
|
||||
|
||||
inline bool Keyboard::WasDown(BYTE keycode)
|
||||
{
|
||||
return lastState.IsDown(keycode);
|
||||
}
|
||||
|
||||
inline bool Keyboard::WasUp(BYTE keycode)
|
||||
{
|
||||
return !WasDown(keycode);
|
||||
}
|
||||
|
||||
bool Keyboard::IsIntervalTapped(BYTE keycode)
|
||||
{
|
||||
return keyIntervalTapStates[keycode];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include "../IInputDevice.h"
|
||||
#include "KeyboardState.h"
|
||||
#include "../../Utilities/Stopwatch.h"
|
||||
|
||||
using Stopwatch = TLAC::Utilities::Stopwatch;
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
constexpr float DOUBLE_TAP_THRESHOLD = 200.0f;
|
||||
constexpr float INTERVAL_TAP_DELAY_THRESHOLD = 500.0f;
|
||||
constexpr float INTERVAL_TAP_THRESHOLD = 75.0f;
|
||||
|
||||
class Keyboard : public IInputDevice
|
||||
{
|
||||
public:
|
||||
static Keyboard* GetInstance();
|
||||
|
||||
bool PollInput() override;
|
||||
bool IsDown(BYTE keycode);
|
||||
bool IsUp(BYTE keycode);
|
||||
bool IsTapped(BYTE keycode);
|
||||
bool IsDoubleTapped(BYTE keycode);
|
||||
bool IsReleased(BYTE keycode);
|
||||
bool IsIntervalTapped(BYTE keycode);
|
||||
|
||||
bool WasDown(BYTE keycode);
|
||||
bool WasUp(BYTE keycode);
|
||||
|
||||
private:
|
||||
Keyboard();
|
||||
KeyboardState lastState;
|
||||
KeyboardState currentState;
|
||||
|
||||
Stopwatch keyIntervalWatch;
|
||||
|
||||
BYTE keyDoubleTapStates[KEYBOARD_KEYS];
|
||||
Stopwatch keyDoubleTapWatches[KEYBOARD_KEYS];
|
||||
|
||||
BOOL keyIntervalInitials[KEYBOARD_KEYS];
|
||||
BYTE keyIntervalTapStates[KEYBOARD_KEYS];
|
||||
FLOAT keyIntervalTapTimes[KEYBOARD_KEYS];
|
||||
|
||||
static Keyboard* instance;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "KeyboardState.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
bool KeyboardState::IsDown(BYTE keycode)
|
||||
{
|
||||
return KeyStates[keycode];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
const int KEYBOARD_KEYS = 0xFF;
|
||||
|
||||
struct KeyboardState
|
||||
{
|
||||
BYTE KeyStates[KEYBOARD_KEYS];
|
||||
|
||||
bool IsDown(BYTE keycode);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
#include "Mouse.h"
|
||||
#include "../../framework.h"
|
||||
#include "../../Constants.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Mouse* Mouse::instance;
|
||||
|
||||
Mouse::Mouse()
|
||||
{
|
||||
directInputMouse = new DirectInputMouse();
|
||||
}
|
||||
|
||||
Mouse::~Mouse()
|
||||
{
|
||||
if (directInputMouse != nullptr)
|
||||
delete directInputMouse;
|
||||
}
|
||||
|
||||
Mouse* Mouse::GetInstance()
|
||||
{
|
||||
if (instance == nullptr)
|
||||
instance = new Mouse();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
POINT Mouse::GetPosition()
|
||||
{
|
||||
return currentState.Position;
|
||||
}
|
||||
|
||||
POINT Mouse::GetRelativePosition()
|
||||
{
|
||||
return currentState.RelativePosition;
|
||||
}
|
||||
|
||||
POINT Mouse::GetDeltaPosition()
|
||||
{
|
||||
return
|
||||
{
|
||||
currentState.Position.x - lastState.Position.x,
|
||||
currentState.Position.y - lastState.Position.y
|
||||
};
|
||||
}
|
||||
|
||||
long Mouse::GetMouseWheel()
|
||||
{
|
||||
return currentState.MouseWheel;
|
||||
}
|
||||
|
||||
long Mouse::GetDeltaMouseWheel()
|
||||
{
|
||||
return currentState.MouseWheel - lastState.MouseWheel;
|
||||
}
|
||||
|
||||
bool Mouse::HasMoved()
|
||||
{
|
||||
POINT delta = GetDeltaPosition();
|
||||
return delta.x != 0 || delta.y != 0;
|
||||
}
|
||||
|
||||
bool Mouse::GetIsScrolledUp()
|
||||
{
|
||||
return currentState.ScrolledUp;
|
||||
}
|
||||
|
||||
bool Mouse::GetIsScrolledDown()
|
||||
{
|
||||
return currentState.ScrolledDown;
|
||||
}
|
||||
|
||||
bool Mouse::GetWasScrolledUp()
|
||||
{
|
||||
return lastState.ScrolledUp;
|
||||
}
|
||||
|
||||
bool Mouse::GetWasScrolledDown()
|
||||
{
|
||||
return lastState.ScrolledDown;
|
||||
}
|
||||
|
||||
void Mouse::SetPosition(int x, int y)
|
||||
{
|
||||
lastState.Position.x = x;
|
||||
lastState.Position.y = y;
|
||||
SetCursorPos(x, y);
|
||||
}
|
||||
|
||||
bool Mouse::PollInput()
|
||||
{
|
||||
lastState = currentState;
|
||||
|
||||
GetCursorPos(¤tState.Position);
|
||||
currentState.RelativePosition = currentState.Position;
|
||||
|
||||
if (framework::DivaWindowHandle != NULL)
|
||||
ScreenToClient(framework::DivaWindowHandle, ¤tState.RelativePosition);
|
||||
|
||||
RECT hWindow;
|
||||
GetClientRect(TLAC::framework::DivaWindowHandle, &hWindow);
|
||||
|
||||
gameHeight = (int*)RESOLUTION_HEIGHT_ADDRESS;
|
||||
gameWidth = (int*)RESOLUTION_WIDTH_ADDRESS;
|
||||
fbWidth = (int*)FB_WIDTH_ADDRESS;
|
||||
fbHeight = (int*)FB_HEIGHT_ADDRESS;
|
||||
|
||||
if (directInputMouse != nullptr)
|
||||
{
|
||||
if (directInputMouse->Poll())
|
||||
currentState.MouseWheel += directInputMouse->GetMouseWheel();
|
||||
|
||||
currentState.ScrolledUp = (GetDeltaMouseWheel() > 0);
|
||||
currentState.ScrolledDown = (GetDeltaMouseWheel() < 0);
|
||||
}
|
||||
|
||||
if ((fbWidth != gameWidth) && (fbHeight != gameHeight)) {
|
||||
xoffset = ((float)16 / (float)9) * (hWindow.bottom - hWindow.top);
|
||||
if (xoffset != (hWindow.right - hWindow.left))
|
||||
{
|
||||
scale = xoffset / (hWindow.right - hWindow.left);
|
||||
xoffset = ((hWindow.right - hWindow.left) / 2) - (xoffset / 2);
|
||||
}
|
||||
else {
|
||||
xoffset = 0;
|
||||
scale = 1;
|
||||
}
|
||||
|
||||
currentState.RelativePosition.x = ((currentState.RelativePosition.x - round(xoffset)) * *gameWidth / (hWindow.right - hWindow.left)) / scale;
|
||||
currentState.RelativePosition.y = currentState.RelativePosition.y * *gameHeight / (hWindow.bottom - hWindow.top);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#include "../IInputDevice.h"
|
||||
#include "../DirectInput/DirectInputMouse.h"
|
||||
#include "MouseState.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class Mouse : public IInputDevice
|
||||
{
|
||||
public:
|
||||
~Mouse();
|
||||
|
||||
static Mouse* GetInstance();
|
||||
|
||||
bool PollInput() override;
|
||||
|
||||
POINT GetPosition();
|
||||
POINT GetRelativePosition();
|
||||
POINT GetDeltaPosition();
|
||||
|
||||
long GetMouseWheel();
|
||||
long GetDeltaMouseWheel();
|
||||
|
||||
bool HasMoved();
|
||||
bool GetIsScrolledUp();
|
||||
bool GetIsScrolledDown();
|
||||
bool GetWasScrolledUp();
|
||||
bool GetWasScrolledDown();
|
||||
|
||||
void SetPosition(int x, int y);
|
||||
|
||||
private:
|
||||
Mouse();
|
||||
MouseState lastState;
|
||||
MouseState currentState;
|
||||
DirectInputMouse* directInputMouse = nullptr;
|
||||
|
||||
int* gameWidth;
|
||||
int* gameHeight;
|
||||
int* fbWidth;
|
||||
int* fbHeight;
|
||||
|
||||
float xoffset;
|
||||
float scale;
|
||||
|
||||
static Mouse* instance;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
struct MouseState
|
||||
{
|
||||
POINT Position;
|
||||
POINT RelativePosition;
|
||||
long MouseWheel;
|
||||
bool ScrolledUp;
|
||||
bool ScrolledDown;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
#include <windows.h>
|
||||
#include "Xinput.h"
|
||||
#include "../../Constants.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
Xinput* Xinput::instance;
|
||||
|
||||
Xinput::Xinput()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Xinput* Xinput::GetInstance()
|
||||
{
|
||||
if (instance == nullptr)
|
||||
{
|
||||
instance = new Xinput();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
void Xinput::SetTapStates(BYTE keycode, float elapsed)
|
||||
{
|
||||
KeyDoubleTapStates[keycode] = IsTapped(keycode) ? KeyDoubleTapWatches[keycode].Restart() <= DOUBLE_TAP_THRESHOLD : false;
|
||||
|
||||
bool isDown = currentState.KeyStates[keycode];
|
||||
bool isTapped = IsTapped(keycode);
|
||||
|
||||
keyIntervalTapStates[keycode] = isTapped;
|
||||
|
||||
if (isTapped)
|
||||
{
|
||||
keyIntervalTapTimes[keycode] = 0;
|
||||
keyIntervalInitials[keycode] = true;
|
||||
}
|
||||
else if (isDown)
|
||||
{
|
||||
float threshold = keyIntervalInitials[keycode] ? INTERVAL_TAP_DELAY_THRESHOLD : INTERVAL_TAP_THRESHOLD;
|
||||
|
||||
bool intervalTapped = (keyIntervalTapTimes[keycode] += elapsed) > threshold;
|
||||
keyIntervalTapStates[keycode] = intervalTapped;
|
||||
|
||||
if (intervalTapped)
|
||||
{
|
||||
keyIntervalTapTimes[keycode] = 0;
|
||||
keyIntervalInitials[keycode] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Xinput::PollInput()
|
||||
{
|
||||
lastState = currentState;
|
||||
ZeroMemory(&state, sizeof(XINPUT_STATE));
|
||||
float elapsed = keyIntervalWatch.Restart();
|
||||
|
||||
if (XInputGetState(0, &state) == ERROR_SUCCESS)
|
||||
{
|
||||
BYTE i = XINPUT_A;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_DOWN;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_B;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_B)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_RIGHT;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_X;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_X)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_LEFT;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_Y;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_UP;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_LS;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_RS;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_LSB;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_RSB;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_START;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_START)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_BACK;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_LT;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.bLeftTrigger > 230)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
i = XINPUT_RT;
|
||||
{
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.bRightTrigger > 230)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
//float normLX = fmaxf(-1, (float)state.Gamepad.sThumbLX / 32767);
|
||||
i = XINPUT_LRIGHT;
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.sThumbLX > 10000)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
|
||||
i = XINPUT_LLEFT;
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.sThumbLX < -10000)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
|
||||
{
|
||||
//float normLX = fmaxf(-1, (float)state.Gamepad.sThumbRX / 32767);
|
||||
i = XINPUT_RRIGHT;
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.sThumbRX > 10000)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
|
||||
i = XINPUT_RLEFT;
|
||||
currentState.KeyStates[i] = false;
|
||||
if (state.Gamepad.sThumbRX < -10000)
|
||||
currentState.KeyStates[i] = true;
|
||||
SetTapStates(i, elapsed);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ZeroMemory(&state, sizeof(XINPUT_STATE));
|
||||
ZeroMemory(¤tState, sizeof(currentState));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
bool Xinput::IsDown(BYTE keycode)
|
||||
{
|
||||
return currentState.IsDown(keycode);
|
||||
}
|
||||
|
||||
bool Xinput::IsUp(BYTE keycode)
|
||||
{
|
||||
return !IsDown(keycode);
|
||||
}
|
||||
|
||||
bool Xinput::IsTapped(BYTE keycode)
|
||||
{
|
||||
return IsDown(keycode) && WasUp(keycode);
|
||||
}
|
||||
|
||||
bool Xinput::IsDoubleTapped(BYTE keycode)
|
||||
{
|
||||
return KeyDoubleTapStates[keycode];
|
||||
}
|
||||
|
||||
bool Xinput::IsReleased(BYTE keycode)
|
||||
{
|
||||
return IsUp(keycode) && WasDown(keycode);
|
||||
}
|
||||
|
||||
inline bool Xinput::WasDown(BYTE keycode)
|
||||
{
|
||||
return lastState.IsDown(keycode);
|
||||
}
|
||||
|
||||
inline bool Xinput::WasUp(BYTE keycode)
|
||||
{
|
||||
return !WasDown(keycode);
|
||||
}
|
||||
|
||||
bool Xinput::IsIntervalTapped(BYTE keycode)
|
||||
{
|
||||
return keyIntervalTapStates[keycode];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
#include "../IInputDevice.h"
|
||||
#include <xinput.h>
|
||||
#include "../../Utilities/Stopwatch.h"
|
||||
#include "XinputState.h"
|
||||
|
||||
using Stopwatch = TLAC::Utilities::Stopwatch;
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
class Xinput : public IInputDevice
|
||||
{
|
||||
const float DOUBLE_TAP_THRESHOLD = 200.0f;
|
||||
const float INTERVAL_TAP_DELAY_THRESHOLD = 500.0f;
|
||||
const float INTERVAL_TAP_THRESHOLD = 75.0f;
|
||||
|
||||
public:
|
||||
static Xinput* GetInstance();
|
||||
|
||||
bool PollInput() override;
|
||||
bool IsDown(BYTE keycode);
|
||||
bool IsUp(BYTE keycode);
|
||||
bool IsTapped(BYTE keycode);
|
||||
bool IsReleased(BYTE keycode);
|
||||
bool IsDoubleTapped(BYTE keycode);
|
||||
bool IsIntervalTapped(BYTE keycode);
|
||||
|
||||
bool WasDown(BYTE keycode);
|
||||
bool WasUp(BYTE keycode);
|
||||
|
||||
private:
|
||||
Xinput();
|
||||
XinputState lastState;
|
||||
XinputState currentState;
|
||||
|
||||
XINPUT_STATE state;
|
||||
|
||||
BYTE KeyDoubleTapStates[0xFF];
|
||||
Utilities::Stopwatch KeyDoubleTapWatches[0xFF];
|
||||
|
||||
Stopwatch keyIntervalWatch;
|
||||
|
||||
BOOL keyIntervalInitials[0xFF];
|
||||
BYTE keyIntervalTapStates[0xFF];
|
||||
FLOAT keyIntervalTapTimes[0xFF];
|
||||
|
||||
static Xinput* instance;
|
||||
|
||||
void SetTapStates(BYTE keycode, float elapsed);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "XinputState.h"
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
bool XinputState::IsDown(BYTE keycode)
|
||||
{
|
||||
return KeyStates[keycode];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
namespace TLAC::Input
|
||||
{
|
||||
struct XinputState
|
||||
{
|
||||
bool KeyStates[0x8F];
|
||||
|
||||
bool IsDown(BYTE keycode);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user