688 lines
20 KiB
C++
688 lines
20 KiB
C++
#include "UnrealProject.h"
|
|
#if PLATFORM_SPECIFIC_WIN == 0
|
|
|
|
#define _SOURCE_INPUT_MANAGER
|
|
#include "InputManager.hpp"
|
|
|
|
#include "AllowWindowsPlatformTypes.h"
|
|
|
|
#pragma comment(lib, "dinput8.lib")
|
|
#pragma comment (lib, "dxguid.lib")
|
|
|
|
#define DIRECTINPUT_VERSION 0x0800
|
|
#include <Windows.h>
|
|
|
|
#include <dinput.h>
|
|
#include <map>
|
|
|
|
using namespace std;
|
|
|
|
#define DUALSHOCK4PRODUCTDATA (0x05C4054CUL)
|
|
#define DUALSHOCK4DEVTYPE (0x00010318UL)
|
|
#define WIREDXBOXDEVTYPE (0x00010215UL)
|
|
#define PI 3.14159265359f
|
|
|
|
namespace Input
|
|
{
|
|
struct GUID_Impl
|
|
{
|
|
GUID instance;
|
|
DWORD devType;
|
|
unsigned long productData1;
|
|
};
|
|
|
|
|
|
LPDIRECTINPUT8 g_DirectInput;
|
|
HWND g_HWND;
|
|
InputManager* InputManager::s_instance;
|
|
bool InputManager::s_isInitialized = false;
|
|
vector<GUID_Impl> g_GUIDs;
|
|
|
|
bool InputManager::IsInitialized()
|
|
{
|
|
return s_isInitialized;
|
|
}
|
|
bool InputManager::Initialize()
|
|
{
|
|
if (!IsInitialized())
|
|
{
|
|
g_HWND = GetActiveWindow();
|
|
HRESULT hr;
|
|
HINSTANCE hInstance = GetModuleHandle(nullptr);
|
|
|
|
hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_DirectInput, NULL);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
s_instance = new InputManager();
|
|
|
|
|
|
s_isInitialized = true;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
void InputManager::Cleanup()
|
|
{
|
|
if (IsInitialized())
|
|
{
|
|
delete s_instance;
|
|
s_instance = nullptr;
|
|
g_DirectInput->Release();
|
|
s_isInitialized = false;
|
|
}
|
|
}
|
|
InputManager* InputManager::GetInstance()
|
|
{
|
|
if (!s_isInitialized)
|
|
Initialize();
|
|
return s_instance;
|
|
}
|
|
|
|
|
|
// Implementation of Input Devices
|
|
class Keyboard_Impl : public Keyboard
|
|
{
|
|
public:
|
|
Keyboard_Impl()
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = g_DirectInput->CreateDevice(GUID_SysKeyboard, &m_Device, NULL);
|
|
if (FAILED(hr))
|
|
{
|
|
}
|
|
hr = m_Device->SetDataFormat(&c_dfDIKeyboard);
|
|
if (FAILED(hr))
|
|
{
|
|
}
|
|
hr = m_Device->SetCooperativeLevel(g_HWND, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
|
|
if (FAILED(hr))
|
|
{
|
|
}
|
|
}
|
|
~Keyboard_Impl()
|
|
{
|
|
m_Device->Unacquire();
|
|
}
|
|
virtual void Update() override final
|
|
{
|
|
HRESULT hr;
|
|
hr = m_Device->Acquire();
|
|
memcpy(m_PreviousState, m_CurrentState, sizeof(BYTE) * 256);
|
|
m_Device->GetDeviceState(sizeof(m_CurrentState), (LPVOID)&m_CurrentState);
|
|
}
|
|
virtual bool GetKey(const InputKey a_Key) override final
|
|
{
|
|
return (m_CurrentState[a_Key] & 0x80) != 0;
|
|
}
|
|
virtual bool GetKeyDown(const InputKey a_Key) override final
|
|
{
|
|
return m_CurrentState[a_Key] & 0x80 && !(m_PreviousState[a_Key] & 0x80);
|
|
}
|
|
|
|
private:
|
|
IDirectInputDevice8* m_Device;
|
|
BYTE m_CurrentState[256];
|
|
BYTE m_PreviousState[256];
|
|
};
|
|
class Joystick_Impl : public Joystick
|
|
{
|
|
public:
|
|
Joystick_Impl(IDirectInputDevice8* a_Device)
|
|
{
|
|
HRESULT hr;
|
|
|
|
m_Device = a_Device;
|
|
|
|
hr = m_Device->SetDataFormat(&c_dfDIJoystick);
|
|
if (FAILED(hr))
|
|
{
|
|
}
|
|
hr = m_Device->SetCooperativeLevel(g_HWND, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
|
|
if (FAILED(hr))
|
|
{
|
|
}
|
|
}
|
|
virtual ~Joystick_Impl()
|
|
{
|
|
m_Device->Unacquire();
|
|
m_Device->Release();
|
|
}
|
|
virtual void Update() override final
|
|
{
|
|
HRESULT hr;
|
|
|
|
m_PreviousState = m_CurrentState;
|
|
hr = m_Device->Acquire();
|
|
if (FAILED(hr))
|
|
{
|
|
m_IsValid = false;
|
|
return;
|
|
}
|
|
hr = m_Device->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&m_CurrentState);
|
|
if (FAILED(hr))
|
|
{
|
|
m_IsValid = false;
|
|
return;
|
|
}
|
|
m_IsValid = true;
|
|
}
|
|
virtual bool IsValid() override final
|
|
{
|
|
return m_IsValid;
|
|
}
|
|
virtual bool GetButton(const InputJoystickButton a_JoystickButton)
|
|
{
|
|
return (m_CurrentState.rgbButtons[a_JoystickButton] & 0x80) != 0;
|
|
}
|
|
virtual bool GetButton(const InputJoystickPhysical a_JoystickButton)
|
|
{
|
|
return false;
|
|
}
|
|
virtual bool GetButtonDown(const InputJoystickButton a_JoystickButton)
|
|
{
|
|
return m_CurrentState.rgbButtons[a_JoystickButton] & 0x80 && !(m_PreviousState.rgbButtons[a_JoystickButton] & 0x80);
|
|
}
|
|
virtual bool GetButtonDown(const InputJoystickPhysical a_JoystickButton)
|
|
{
|
|
return false;
|
|
}
|
|
virtual bool GetButtonUp(const InputJoystickButton a_JoystickButton)
|
|
{
|
|
return m_PreviousState.rgbButtons[a_JoystickButton] & 0x80 && !(m_CurrentState.rgbButtons[a_JoystickButton] & 0x80);
|
|
}
|
|
virtual bool GetButtonUp(const InputJoystickPhysical a_JoystickButton)
|
|
{
|
|
return false;
|
|
}
|
|
virtual TeaLib::Math::Vector2f GetDelta(const InputJoystickAxis a_InputStick)
|
|
{
|
|
if (IsValid())
|
|
{
|
|
switch (a_InputStick)
|
|
{
|
|
case Input::IJA_LSTICK:
|
|
return TeaLib::Math::Vector2f((float)m_CurrentState.lX, (float)m_CurrentState.lY) / 32767.0f;
|
|
case Input::IJA_RSTICK:
|
|
return TeaLib::Math::Vector2f((float)m_CurrentState.lRx, (float)m_CurrentState.lRy) / 32767.0f;
|
|
case Input::IJA_LRTRIGGER:
|
|
return TeaLib::Math::Vector2f((float)m_CurrentState.lZ, (float)m_CurrentState.lRz) / 32767.0f;
|
|
default:
|
|
return TeaLib::Math::Vector2f();
|
|
}
|
|
}
|
|
return TeaLib::Math::Vector2f();
|
|
}
|
|
virtual InputDeviceType GetDeviceType()
|
|
{
|
|
return IDT_NOTDEFINED;
|
|
}
|
|
protected:
|
|
bool m_IsValid = false;
|
|
IDirectInputDevice8* m_Device;
|
|
DIJOYSTATE m_CurrentState, m_PreviousState;
|
|
};
|
|
class JoystickDS4_Impl : public Joystick_Impl
|
|
{
|
|
public:
|
|
JoystickDS4_Impl(IDirectInputDevice8* a_Device) : Joystick_Impl(a_Device)
|
|
{
|
|
m_PhysicalBindings[IJP_FACEDOWN] = IJB_DS4CROSS;
|
|
m_PhysicalBindings[IJP_FACERIGHT] = IJB_DS4CIRCLE;
|
|
m_PhysicalBindings[IJP_FACELEFT] = IJB_BUTTON0;
|
|
m_PhysicalBindings[IJP_FACEUP] = IJB_BUTTON3;
|
|
m_PhysicalBindings[IJP_DPADDOWN] = IJB_DS4DPADDOWN;
|
|
m_PhysicalBindings[IJP_DPADRIGHT] = IJB_DS4DPADRIGHT;
|
|
m_PhysicalBindings[IJP_DPADLEFT] = IJB_DS4DPADLEFT;
|
|
m_PhysicalBindings[IJP_DPADUP] = IJB_DS4DPADUP;
|
|
m_PhysicalBindings[IJP_SHOULDERRIGHT] = IJB_DS4R1;
|
|
m_PhysicalBindings[IJP_SHOULDERLEFT] = IJB_DS4L1;
|
|
m_PhysicalBindings[IJP_TRIGGERRIGHT] = IJB_DS4R2;
|
|
m_PhysicalBindings[IJP_TRIGGERLEFT] = IJB_DS4L2;
|
|
m_PhysicalBindings[IJP_START] = IJB_DS4OPTIONS;
|
|
m_PhysicalBindings[IJP_SELECT] = IJB_DS4SHARE;
|
|
m_PhysicalBindings[IJP_STICKLEFT] = IJB_DS4LEFTSTICK;
|
|
m_PhysicalBindings[IJP_STICKRIGHT] = IJB_DS4RIGHTSTICK;
|
|
}
|
|
virtual bool GetButton(const InputJoystickButton a_JoystickButton) override final
|
|
{
|
|
if (a_JoystickButton < 200)
|
|
return (m_CurrentState.rgbButtons[a_JoystickButton] & 0x80) != 0;
|
|
else
|
|
{
|
|
switch (a_JoystickButton)
|
|
{
|
|
case Input::IJB_DS4DPADUP:
|
|
if (m_CurrentState.rgdwPOV[0] < 36000 && m_CurrentState.rgdwPOV[0] > 27000 || m_CurrentState.rgdwPOV[0] < 9000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_DS4DPADRIGHT:
|
|
if (m_CurrentState.rgdwPOV[0] > 0 && m_CurrentState.rgdwPOV[0] < 18000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_DS4DPADDOWN:
|
|
if (m_CurrentState.rgdwPOV[0] > 9000 && m_CurrentState.rgdwPOV[0] < 27000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_DS4DPADLEFT:
|
|
if (m_CurrentState.rgdwPOV[0] > 18000 && m_CurrentState.rgdwPOV[0] < 36000)
|
|
return true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
virtual bool GetButton(const InputJoystickPhysical a_JoystickButton) override final
|
|
{
|
|
return GetButton(m_PhysicalBindings[a_JoystickButton]);
|
|
}
|
|
virtual bool GetButtonDown(const InputJoystickButton a_JoystickButton) override final
|
|
{
|
|
if (a_JoystickButton < 200)
|
|
return m_CurrentState.rgbButtons[a_JoystickButton] & 0x80 && !(m_PreviousState.rgbButtons[a_JoystickButton] & 0x80);
|
|
else
|
|
{
|
|
switch (a_JoystickButton)
|
|
{
|
|
case Input::IJB_DS4DPADUP:
|
|
if (m_CurrentState.rgdwPOV[0] == 0 && m_PreviousState.rgdwPOV[0] != 0)
|
|
return true;
|
|
break;
|
|
case Input::IJB_DS4DPADRIGHT:
|
|
if (m_CurrentState.rgdwPOV[0] == 9000 && m_PreviousState.rgdwPOV[0] != 9000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_DS4DPADDOWN:
|
|
if (m_CurrentState.rgdwPOV[0] == 18000 && m_PreviousState.rgdwPOV[0] != 18000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_DS4DPADLEFT:
|
|
if (m_CurrentState.rgdwPOV[0] == 27000 && m_PreviousState.rgdwPOV[0] != 27000)
|
|
return true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
virtual bool GetButtonDown(const InputJoystickPhysical a_JoystickButton) override final
|
|
{
|
|
return GetButtonDown(m_PhysicalBindings[a_JoystickButton]);
|
|
}
|
|
virtual bool GetButtonUp(const InputJoystickButton a_JoystickButton) override final
|
|
{
|
|
if (a_JoystickButton < 200)
|
|
return m_PreviousState.rgbButtons[a_JoystickButton] & 0x80 && !(m_CurrentState.rgbButtons[a_JoystickButton] & 0x80);
|
|
else
|
|
{
|
|
switch (a_JoystickButton)
|
|
{
|
|
case Input::IJB_DS4DPADUP:
|
|
if (m_PreviousState.rgdwPOV[0] == 0 && m_CurrentState.rgdwPOV[0] != 0)
|
|
return true;
|
|
break;
|
|
case Input::IJB_DS4DPADRIGHT:
|
|
if (m_PreviousState.rgdwPOV[0] == 9000 && m_CurrentState.rgdwPOV[0] != 9000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_DS4DPADDOWN:
|
|
if (m_PreviousState.rgdwPOV[0] == 18000 && m_CurrentState.rgdwPOV[0] != 18000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_DS4DPADLEFT:
|
|
if (m_PreviousState.rgdwPOV[0] == 27000 && m_CurrentState.rgdwPOV[0] != 27000)
|
|
return true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
virtual bool GetButtonUp(const InputJoystickPhysical a_JoystickButton) override final
|
|
{
|
|
return GetButtonUp(m_PhysicalBindings[a_JoystickButton]);
|
|
}
|
|
virtual TeaLib::Math::Vector2f GetDelta(const InputJoystickAxis a_InputStick) override final
|
|
{
|
|
if (IsValid())
|
|
{
|
|
float angle;
|
|
switch (a_InputStick)
|
|
{
|
|
case Input::IJA_LSTICK:
|
|
return TeaLib::Math::Vector2f((float)m_CurrentState.lX - 32767.0f, (float)m_CurrentState.lY - 32767.0f) / 32767.0f;
|
|
case Input::IJA_RSTICK:
|
|
return TeaLib::Math::Vector2f((float)m_CurrentState.lZ - 32767.0f, (float)m_CurrentState.lRz - 32767.0f) / 32767.0f;
|
|
case Input::IJA_LRTRIGGER:
|
|
return TeaLib::Math::Vector2f((float)m_CurrentState.lRx, (float)m_CurrentState.lRy) / 65534.0f;
|
|
case Input::IJA_DPAD:
|
|
if (m_PreviousState.rgdwPOV[0] < 90000)
|
|
{
|
|
angle = (((float)m_PreviousState.rgdwPOV[0] / 100.0f) * PI / 180.0f);
|
|
return TeaLib::Math::Vector2f(sinf(angle), -cosf(angle));
|
|
}
|
|
return TeaLib::Math::Vector2f();
|
|
default:
|
|
return TeaLib::Math::Vector2f();
|
|
}
|
|
}
|
|
return TeaLib::Math::Vector2f();
|
|
}
|
|
virtual InputDeviceType GetDeviceType() override final
|
|
{
|
|
return IDT_DS4;
|
|
}
|
|
private:
|
|
map<InputJoystickPhysical, InputJoystickButton> m_PhysicalBindings;
|
|
};
|
|
class JoystickXbox360_Impl : public Joystick_Impl
|
|
{
|
|
public:
|
|
JoystickXbox360_Impl(IDirectInputDevice8* a_Device) : Joystick_Impl(a_Device)
|
|
{
|
|
m_PhysicalBindings[IJP_FACEDOWN] = IJB_XBOXA;
|
|
m_PhysicalBindings[IJP_FACERIGHT] = IJB_XBOXB;
|
|
m_PhysicalBindings[IJP_FACELEFT] = IJB_XBOXX;
|
|
m_PhysicalBindings[IJP_FACEUP] = IJB_XBOXY;
|
|
m_PhysicalBindings[IJP_DPADDOWN] = IJB_XBOXDPADDOWN;
|
|
m_PhysicalBindings[IJP_DPADRIGHT] = IJB_XBOXDPADRIGHT;
|
|
m_PhysicalBindings[IJP_DPADLEFT] = IJB_XBOXDPADLEFT;
|
|
m_PhysicalBindings[IJP_DPADUP] = IJB_XBOXDPADUP;
|
|
m_PhysicalBindings[IJP_SHOULDERRIGHT] = IJB_XBOXRB;
|
|
m_PhysicalBindings[IJP_SHOULDERLEFT] = IJB_XBOXLB;
|
|
m_PhysicalBindings[IJP_TRIGGERRIGHT] = IJB_XBOXRT;
|
|
m_PhysicalBindings[IJP_TRIGGERLEFT] = IJB_XBOXLT;
|
|
m_PhysicalBindings[IJP_START] = IJB_XBOXSTART;
|
|
m_PhysicalBindings[IJP_SELECT] = IJB_XBOXBACK;
|
|
m_PhysicalBindings[IJP_STICKLEFT] = IJB_XBOXLEFTSTICK;
|
|
m_PhysicalBindings[IJP_STICKRIGHT] = IJB_XBOXRIGHTSTICK;
|
|
}
|
|
virtual TeaLib::Math::Vector2f GetDelta(const InputJoystickAxis a_InputStick) override final
|
|
{
|
|
if (IsValid())
|
|
{
|
|
float result;
|
|
float angle;
|
|
switch (a_InputStick)
|
|
{
|
|
case Input::IJA_LSTICK:
|
|
return TeaLib::Math::Vector2f((float)m_CurrentState.lX - 32767.0f, (float)m_CurrentState.lY - 32767.0f) / 32767.0f;
|
|
case Input::IJA_RSTICK:
|
|
return TeaLib::Math::Vector2f((float)m_CurrentState.lRx - 32767.0f, (float)m_CurrentState.lRy - 32767.0f) / 32767.0f;
|
|
case Input::IJA_LRTRIGGER:
|
|
result = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;
|
|
return TeaLib::Math::Vector2f(result, result);
|
|
case Input::IJA_DPAD:
|
|
if (m_PreviousState.rgdwPOV[0] < 90000)
|
|
{
|
|
angle = (((float)m_PreviousState.rgdwPOV[0] / 100.0f) * PI / 180.0f);
|
|
return TeaLib::Math::Vector2f(sinf(angle), -cosf(angle));
|
|
}
|
|
return TeaLib::Math::Vector2f();
|
|
default:
|
|
return TeaLib::Math::Vector2f();
|
|
}
|
|
}
|
|
return TeaLib::Math::Vector2f();
|
|
}
|
|
virtual bool GetButton(const InputJoystickButton a_JoystickButton) override final
|
|
{
|
|
if (a_JoystickButton < 200)
|
|
return (m_CurrentState.rgbButtons[a_JoystickButton] & 0x80) != 0;
|
|
else
|
|
{
|
|
float val;
|
|
switch (a_JoystickButton)
|
|
{
|
|
case Input::IJB_XBOXDPADUP:
|
|
if (m_CurrentState.rgdwPOV[0] < 36000 && m_CurrentState.rgdwPOV[0] > 27000 || m_CurrentState.rgdwPOV[0] < 9000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXDPADRIGHT:
|
|
if (m_CurrentState.rgdwPOV[0] > 0 && m_CurrentState.rgdwPOV[0] < 18000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXDPADDOWN:
|
|
if (m_CurrentState.rgdwPOV[0] > 9000 && m_CurrentState.rgdwPOV[0] < 27000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXDPADLEFT:
|
|
if (m_CurrentState.rgdwPOV[0] > 18000 && m_CurrentState.rgdwPOV[0] < 36000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXLT:
|
|
val = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;;
|
|
return val > 0.1f;
|
|
case Input::IJB_XBOXRT:
|
|
val = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;;
|
|
return val < -0.1f;
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
virtual bool GetButton(const InputJoystickPhysical a_JoystickButton) override final
|
|
{
|
|
return GetButton(m_PhysicalBindings[a_JoystickButton]);
|
|
}
|
|
virtual bool GetButtonDown(const InputJoystickButton a_JoystickButton) override final
|
|
{
|
|
if (a_JoystickButton < 200)
|
|
return m_CurrentState.rgbButtons[a_JoystickButton] & 0x80 && !(m_PreviousState.rgbButtons[a_JoystickButton] & 0x80);
|
|
else
|
|
{
|
|
float curr, prev;
|
|
switch (a_JoystickButton)
|
|
{
|
|
case Input::IJB_XBOXDPADUP:
|
|
if (m_CurrentState.rgdwPOV[0] == 0 && m_PreviousState.rgdwPOV[0] != 0)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXDPADRIGHT:
|
|
if (m_CurrentState.rgdwPOV[0] == 9000 && m_PreviousState.rgdwPOV[0] != 9000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXDPADDOWN:
|
|
if (m_CurrentState.rgdwPOV[0] == 18000 && m_PreviousState.rgdwPOV[0] != 18000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXDPADLEFT:
|
|
if (m_CurrentState.rgdwPOV[0] == 27000 && m_PreviousState.rgdwPOV[0] != 27000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXLT:
|
|
curr = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;
|
|
prev = ((float)m_PreviousState.lZ - 32767.0f) / 32767.0f;
|
|
return curr > 0.1f && prev <= 0.1f;
|
|
case Input::IJB_XBOXRT:
|
|
curr = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;
|
|
prev = ((float)m_PreviousState.lZ - 32767.0f) / 32767.0f;
|
|
return curr < -0.1f && prev >= -0.1f;
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
virtual bool GetButtonDown(const InputJoystickPhysical a_JoystickButton) override final
|
|
{
|
|
if (m_PhysicalBindings.find(a_JoystickButton) != m_PhysicalBindings.end())
|
|
return GetButtonDown(m_PhysicalBindings[a_JoystickButton]);
|
|
return false;
|
|
}
|
|
virtual bool GetButtonUp(const InputJoystickButton a_JoystickButton) override final
|
|
{
|
|
if (a_JoystickButton < 200)
|
|
return m_PreviousState.rgbButtons[a_JoystickButton] & 0x80 && !(m_CurrentState.rgbButtons[a_JoystickButton] & 0x80);
|
|
else
|
|
{
|
|
float curr, prev;
|
|
switch (a_JoystickButton)
|
|
{
|
|
case Input::IJB_XBOXDPADUP:
|
|
if (m_PreviousState.rgdwPOV[0] == 0 && m_CurrentState.rgdwPOV[0] != 0)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXDPADRIGHT:
|
|
if (m_PreviousState.rgdwPOV[0] == 9000 && m_CurrentState.rgdwPOV[0] != 9000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXDPADDOWN:
|
|
if (m_PreviousState.rgdwPOV[0] == 18000 && m_CurrentState.rgdwPOV[0] != 18000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXDPADLEFT:
|
|
if (m_PreviousState.rgdwPOV[0] == 27000 && m_CurrentState.rgdwPOV[0] != 27000)
|
|
return true;
|
|
break;
|
|
case Input::IJB_XBOXLT:
|
|
curr = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;
|
|
prev = ((float)m_PreviousState.lZ - 32767.0f) / 32767.0f;
|
|
return curr <= 0.1f && prev > 0.1f;
|
|
case Input::IJB_XBOXRT:
|
|
curr = ((float)m_CurrentState.lZ - 32767.0f) / 32767.0f;
|
|
prev = ((float)m_PreviousState.lZ - 32767.0f) / 32767.0f;
|
|
return curr >= -0.1f && prev < -0.1f;
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
virtual bool GetButtonUp(const InputJoystickPhysical a_JoystickButton) override final
|
|
{
|
|
if (m_PhysicalBindings.find(a_JoystickButton) != m_PhysicalBindings.end())
|
|
return GetButtonUp(m_PhysicalBindings[a_JoystickButton]);
|
|
return false;
|
|
}
|
|
virtual InputDeviceType GetDeviceType() override final
|
|
{
|
|
return IDT_XBOX;
|
|
}
|
|
private:
|
|
map<InputJoystickPhysical, InputJoystickButton> m_PhysicalBindings;
|
|
};
|
|
|
|
InputManager::InputManager() : joystick(nullptr)
|
|
{
|
|
keyboard = new Keyboard_Impl();
|
|
}
|
|
|
|
void InputManager::Update()
|
|
{
|
|
keyboard->Update();
|
|
if (joystick)
|
|
{
|
|
joystick->Update();
|
|
|
|
if (joystick->IsValid())
|
|
{
|
|
for (auto it : m_joystickCallbacks)
|
|
{
|
|
switch (it.first.second)
|
|
{
|
|
case IME_PRESSED:
|
|
if (joystick->GetButtonDown(it.first.first))
|
|
{
|
|
it.second->Call();
|
|
}
|
|
break;
|
|
case IME_RELEASED:
|
|
if (joystick->GetButtonUp(it.first.first))
|
|
{
|
|
it.second->Call();
|
|
}
|
|
break;
|
|
case IME_REPEAT:
|
|
if (joystick->GetButton(it.first.first))
|
|
{
|
|
it.second->Call();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
BOOL __stdcall JoystickEnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
|
|
{
|
|
InputManager* inputInstance = InputManager::GetInstance();
|
|
|
|
inputInstance->AddJoystickName(lpddi->tszProductName);
|
|
|
|
GUID_Impl newGUID;
|
|
newGUID.devType = lpddi->dwDevType;
|
|
newGUID.instance = lpddi->guidInstance;
|
|
newGUID.productData1 = lpddi->guidProduct.Data1;
|
|
|
|
g_GUIDs.push_back(newGUID);
|
|
|
|
return DIENUM_CONTINUE;
|
|
}
|
|
|
|
void InputManager::AddJoystickName(std::wstring a_name)
|
|
{
|
|
m_joystickNames.push_back(a_name);
|
|
}
|
|
|
|
void InputManager::SearchForJoystick()
|
|
{
|
|
m_joystickNames.clear();
|
|
g_GUIDs.clear();
|
|
g_DirectInput->EnumDevices(DI8DEVCLASS_GAMECTRL, &JoystickEnumCallback, NULL, DIEDFL_ATTACHEDONLY);
|
|
}
|
|
|
|
vector<wstring>& InputManager::GetJoystickNames()
|
|
{
|
|
return m_joystickNames;
|
|
}
|
|
|
|
void InputManager::ConnectJoystickByIndex(size_t a_index)
|
|
{
|
|
if (joystick)
|
|
delete joystick;
|
|
|
|
if (a_index >= g_GUIDs.size())
|
|
return;
|
|
|
|
HRESULT hr;
|
|
IDirectInputDevice8* device;
|
|
hr = g_DirectInput->CreateDevice(g_GUIDs[a_index].instance, &device, NULL);
|
|
if (!FAILED(hr))
|
|
{
|
|
if (g_GUIDs[a_index].devType == DUALSHOCK4DEVTYPE || g_GUIDs[a_index].productData1 == DUALSHOCK4PRODUCTDATA)
|
|
joystick = new JoystickDS4_Impl(device);
|
|
else if (g_GUIDs[a_index].devType == WIREDXBOXDEVTYPE)
|
|
joystick = new JoystickXbox360_Impl(device);
|
|
else
|
|
joystick = new Joystick_Impl(device);
|
|
}
|
|
}
|
|
|
|
InputManager::~InputManager()
|
|
{
|
|
delete keyboard;
|
|
delete joystick;
|
|
ClearCallbacks();
|
|
}
|
|
|
|
void InputManager::ClearCallbacks()
|
|
{
|
|
for (auto it : m_joystickCallbacks)
|
|
{
|
|
delete it.second;
|
|
}
|
|
m_joystickCallbacks.clear();
|
|
}
|
|
}
|
|
|
|
#endif |