Torna al Thread
#ifndef __XINPUT_HPP__
#define __XINPUT_HPP__
#include "d3dutil.hpp"
class Keyboard
{
public:
enum Key
{
KEY_0 = 0x0B,
KEY_1 = 0x02,
KEY_2 = 0x03,
KEY_3 = 0x04,
KEY_4 = 0x05,
KEY_5 = 0x06,
KEY_6 = 0x07,
KEY_7 = 0x08,
KEY_8 = 0x09,
KEY_9 = 0x0A,
KEY_A = 0x1E,
KEY_B = 0x30,
KEY_C = 0x2E,
KEY_D = 0x20,
KEY_E = 0x12,
KEY_F = 0x21,
KEY_G = 0x22,
KEY_H = 0x23,
KEY_I = 0x17,
KEY_J = 0x24,
KEY_K = 0x25,
KEY_L = 0x26,
KEY_M = 0x32,
KEY_N = 0x31,
KEY_O = 0x18,
KEY_P = 0x19,
KEY_Q = 0x10,
KEY_R = 0x13,
KEY_S = 0x1F,
KEY_T = 0x14,
KEY_U = 0x16,
KEY_V = 0x2F,
KEY_W = 0x11,
KEY_X = 0x2D,
KEY_Y = 0x15,
KEY_Z = 0x2C,
KEY_F1 = 0x3B,
KEY_F2 = 0x3C,
KEY_F3 = 0x3D,
KEY_F4 = 0x3E,
KEY_F5 = 0x3F,
KEY_F6 = 0x40,
KEY_F7 = 0x41,
KEY_F8 = 0x42,
KEY_F9 = 0x43,
KEY_F10 = 0x44,
KEY_F11 = 0x57,
KEY_F12 = 0x58,
KEY_NUMPAD_0 = 0x52,
KEY_NUMPAD_1 = 0x4F,
KEY_NUMPAD_2 = 0x50,
KEY_NUMPAD_3 = 0x51,
KEY_NUMPAD_4 = 0x4B,
KEY_NUMPAD_5 = 0x4C,
KEY_NUMPAD_6 = 0x4D,
KEY_NUMPAD_7 = 0x47,
KEY_NUMPAD_8 = 0x48,
KEY_NUMPAD_9 = 0x49,
KEY_NUMPAD_ADD = 0x4E,
KEY_NUMPAD_DIVIDE = 0xB5,
KEY_NUMPAD_ENTER = 0x9C,
KEY_NUMPAD_MINUS = 0x4A,
KEY_NUMPAD_MULTIPLY = 0x37,
KEY_NUMPAD_NUMLOCK = 0x45,
KEY_NUMPAD_PERIOD = 0x53,
KEY_ADD = 0x0D,
KEY_APOSTROPHE = 0x28,
KEY_APPS = 0xDD,
KEY_BACKSLASH = 0x2B,
KEY_BACKSPACE = 0x0E,
KEY_CAPSLOCK = 0x3A,
KEY_COMMA = 0x33,
KEY_ENTER = 0x1C,
KEY_ESCAPE = 0x01,
KEY_MINUS = 0x0C,
KEY_PAUSE = 0xC5,
KEY_PERIOD = 0x34,
KEY_PRINTSCREEN = 0xB7,
KEY_SCROLLLOCK = 0x46,
KEY_SEMICOLON = 0x27,
KEY_SLASH = 0x35,
KEY_SPACE = 0x39,
KEY_TAB = 0x0F,
KEY_TILDE = 0x29,
KEY_LALT = 0x38,
KEY_LBRACKET = 0x1A,
KEY_LCONTROL = 0x1D,
KEY_LSHIFT = 0x2A,
KEY_LWIN = 0xDB,
KEY_RALT = 0xB8,
KEY_RBRACKET = 0x1B,
KEY_RCONTROL = 0x9D,
KEY_RSHIFT = 0x36,
KEY_RWIN = 0xDC,
KEY_DOWN = 0xD0,
KEY_LEFT = 0xCB,
KEY_RIGHT = 0xCD,
KEY_UP = 0xC8,
KEY_DELETE = 0xD3,
KEY_END = 0xCF,
KEY_HOME = 0xC7,
KEY_INSERT = 0xD2,
KEY_PAGEDOWN = 0xD1,
KEY_PAGEUP = 0xC9,
KEY_CALCULATOR = 0xA1,
KEY_MAIL = 0xEC,
KEY_MEDIASELECT = 0xED,
KEY_MEDIASTOP = 0xA4,
KEY_MUTE = 0xA0,
KEY_MYCOMPUTER = 0xEB,
KEY_NEXTTRACK = 0x99,
KEY_PLAYPAUSE = 0xA2,
KEY_POWER = 0xDE,
KEY_PREVTRACK = 0x90,
KEY_SLEEP = 0xDF,
KEY_VOLUMEDOWN = 0xAE,
KEY_VOLUMEUP = 0xB0,
KEY_WAKE = 0xE3,
KEY_WEBBACK = 0xEA,
KEY_WEBFAVORITES = 0xE6,
KEY_WEBFORWARD = 0xE9,
KEY_WEBHOME = 0xB2,
KEY_WEBREFRESH = 0xE7,
KEY_WEBSEARCH = 0xE5,
KEY_WEBSTOP = 0xE8
};
/* */
static Keyboard &instance()
{
static Keyboard inst;
return inst;
}
/* */
void handleMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CHAR:
lastChar = static_cast<char>(wParam);
break;
default:
break;
}
}
/* */
void update()
{
if(!input || !device)
{
if(!create())
{
Release();
return;
}
}
HRESULT hr = 0;
unsigned char* temp = prevKeyStates;
prevKeyStates = currKeyStates;
currKeyStates = temp;
while(true)
{
hr = device->GetDeviceState(256, currKeyStates);
if(FAILED(hr))
{
if(hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED)
if(FAILED(device->Acquire()))
return;
}
else
break;
}
}
/* */
char getLastChar() const
{
return lastChar;
}
/* */
bool keyDown(Key key) const
{
return (currKeyStates[key] & 0x80) ? true : false;
}
/* */
bool keyUp(Key key) const
{
return (currKeyStates[key] & 0x80) ? false : true;
}
/* */
bool keyPressed(Key key) const
{
return ((currKeyStates[key] & 0x80)
&& !(prevKeyStates[key] & 0x80)) ? true : false;
}
/* */
bool keyReleased(Key key) const
{
return (!(currKeyStates[key] & 0x80)
&& (prevKeyStates[key] & 0x80)) ? true : false;
}
/* */
private:
Keyboard()
{
input = 0;
device = 0;
lastChar = 0;
prevKeyStates = keyStates[0];
currKeyStates = keyStates[1];
}
/* */
~Keyboard(){ Release(); }
/* */
bool create()
{
HINSTANCE hInstance = GetModuleHandle(0);
HWND hWnd = GetForegroundWindow();
if(FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION,
IID_IDirectInput8, reinterpret_cast<void**>(&input), 0)))
return false;
if(FAILED(input->CreateDevice(GUID_SysKeyboard, &device, 0)))
return false;
if(FAILED(device->SetDataFormat(&c_dfDIKeyboard)))
return false;
if(FAILED(device->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
return false;
if(FAILED(device->Acquire()))
return false;
ZeroMemory(&keyStates, sizeof(keyStates));
return true;
}
/* */
void Release()
{
if(device)
{
device->Unacquire();
device->Release();
device = 0;
}
ReleaseCOM(input);
}
/* */
IDirectInput8* input;
IDirectInputDevice8* device;
unsigned char* currKeyStates;
unsigned char* prevKeyStates;
unsigned char keyStates[2][256];
char lastChar;
protected:
};
/* */
class Mouse
{
public:
enum MouseButton
{
BUTTON_LEFT = 0x00,
BUTTON_RIGHT = 0x01,
BUTTON_MIDDLE = 0x02,
};
static Mouse &instance()
{
static Mouse inst;
return inst;
}
/* */
bool buttonUp(MouseButton button) const
{
return (currMouseState->rgbButtons[button] & 0x80) ? false : true;
}
/* */
bool buttonDown(MouseButton button) const
{
return (currMouseState->rgbButtons[button] & 0x80) ? true : false;
}
/* */
bool buttonPressed(MouseButton button) const
{
return ((currMouseState->rgbButtons[button] & 0x80)
&& !(prevMouseState->rgbButtons[button] & 0x80)) ? true : false;
}
/* */
bool isMouseSmoothing() const
{
return enableFiltering;
}
/* */
bool xPosReletive() const
{
return deltaX;
}
/* */
bool yPosRelative() const
{
return deltaY;
}
/* */
float getWeightModifier() const
{
return weightModifier;
}
/* */
float wheelPosition() const
{
return deltaMouseWheel;
}
/* */
void setWeightModifier(float value)
{
weightModifier = value;
}
/* */
void smoothMouse(bool value)
{
enableFiltering = value;
}
/* */
void update()
{
if(!input || !device)
{
if(!create())
{
Release();
return;
}
}
HRESULT hr = 0;
DIMOUSESTATE* temp = prevMouseState;
prevMouseState = currMouseState;
currMouseState = temp;
while(true)
{
hr = device->GetDeviceState(sizeof(DIMOUSESTATE), currMouseState);
if(FAILED(hr))
{
if(hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED)
if(FAILED(device->Acquire()))
return;
}
else
break;
}
if(enableFiltering)
{
performMouseFiltering(static_cast<float>(currMouseState->lX), static_cast<float>(currMouseState->lY));
performMouseSmoothing(deltaX, deltaY);
}
else
{
deltaX = static_cast<float>(currMouseState->lX);
deltaY = static_cast<float>(currMouseState->lY);
}
if(currMouseState->lZ > 0)
deltaMouseWheel = 1.0f;
else if(currMouseState->lZ < 0)
deltaMouseWheel = -1.0f;
else
deltaMouseWheel = 0.0f;
}
/* */
private:
Mouse()
{
input = 0;
device = 0;
currMouseState = &mouseStates[0];
prevMouseState = &mouseStates[1];
deltaX = 0.0f;
deltaY = 0.0f;
deltaMouseWheel = 0.0f;
weightModifier = WEIGHT_MODIFIER;
enableFiltering = true;
historyBufferSize = HISTORY_BUFFER_SIZE;
historyBuffer.resize(historyBufferSize);
}
/* */
~Mouse()
{
Release();
}
/* */
bool create()
{
HINSTANCE hInstance = GetModuleHandle(0);
HWND hWnd = GetForegroundWindow();
if(FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION,
IID_IDirectInput8, reinterpret_cast<void**>(&input), 0)))
return false;
if(FAILED(input->CreateDevice(GUID_SysMouse, &device, 0)))
return false;
if(FAILED(device->SetDataFormat(&c_dfDIMouse)))
return false;
if(FAILED(device->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE)))
return false;
if(FAILED(device->Acquire()))
return false;
ZeroMemory(&mouseStates, sizeof(mouseStates));
ZeroMemory(&historyBuffer[0], historyBuffer.size());
mouseIndex = 0;
mouseMovement[0].first = mouseMovement[0].second = 0.0f;
mouseMovement[1].first = mouseMovement[1].second = 0.0f;
return true;
}
/* */
void Release()
{
if(device)
{
device->Unacquire();
device->Release();
device = 0;
}
ReleaseCOM(input);
}
/* */
void performMouseSmoothing(float x, float y)
{
mouseMovement[mouseIndex].first = x;
mouseMovement[mouseIndex].second = y;
deltaX = (mouseMovement[0].first + mouseMovement[1].first) * 0.5f;
deltaY = (mouseMovement[0].second + mouseMovement[1].second) * 0.5f;
mouseIndex ^= 1;
mouseMovement[mouseIndex].first = 0.0f;
mouseMovement[mouseIndex].second = 0.0f;
}
/* */
void performMouseFiltering(float x, float y)
{
for(int i = historyBufferSize -1 ; i > 0; --i)
{
historyBuffer[i].first = historyBuffer[i - 1].first;
historyBuffer[i].second = historyBuffer[i - 1].second;
}
historyBuffer[0].first = x;
historyBuffer[0].second = y;
float avarageX = 0.0f;
float avarageY = 0.0f;
float avarageTotal = 0.0f;
float currentWeigth = 1.0f;
for(int i = 0; i < historyBufferSize; ++i)
{
avarageX += historyBuffer[i].first * currentWeigth;
avarageY += historyBuffer[i].second * currentWeigth;
avarageTotal += 1.0f * currentWeigth;
currentWeigth *= weightModifier;
}
deltaX = avarageX / avarageTotal;
deltaY = avarageY / avarageTotal;
}
/* */
static const float WEIGHT_MODIFIER;
/* */
static const int HISTORY_BUFFER_SIZE = 10;
/* */
IDirectInput8* input;
IDirectInputDevice8* device;
DIMOUSESTATE* currMouseState;
DIMOUSESTATE* prevMouseState;
DIMOUSESTATE mouseStates[2];
float deltaX;
float deltaY;
float deltaMouseWheel;
float weightModifier;
int historyBufferSize;
int mouseIndex;
bool enableFiltering;
std::vector<std::pair<float, float>> historyBuffer;
std::pair<float, float> mouseMovement[2];
protected:
};
/* */
const float Mouse::WEIGHT_MODIFIER = 0.2f;
//const int Mouse::HISTORY_BUFFER_SIZE = 10;
#endif