Files
WickedEngine/WickedEngine/wiInputManager.cpp
T
2017-05-03 17:02:00 +02:00

283 lines
6.4 KiB
C++

#include "wiInputManager.h"
#include "wiXInput.h"
#include "wiDirectInput.h"
#include "wiRawInput.h"
#include "wiWindowRegistration.h"
#include "wiHelper.h"
using namespace std;
#ifndef WINSTORE_SUPPORT
#define KEY_DOWN(vk_code) (GetAsyncKeyState(vk_code) < 0)
#define KEY_TOGGLE(vk_code) ((GetAsyncKeyState(vk_code) & 1) != 0)
#else
#define KEY_DOWN(vk_code) ((int)Windows::UI::Core::CoreWindow::GetForCurrentThread()->GetAsyncKeyState((Windows::System::VirtualKey)vk_code) < 0)
#define KEY_TOGGLE(vk_code) (((int)Windows::UI::Core::CoreWindow::GetForCurrentThread()->GetAsyncKeyState((Windows::System::VirtualKey)vk_code) & 1) != 0)
#endif //WINSTORE_SUPPORT
#define KEY_UP(vk_code) (!KEY_DOWN(vk_code))
static float mousewheel_scrolled = 0.0f;
wiInputManager::wiInputManager()
{
xinput = nullptr;
dinput = nullptr;
rawinput = nullptr;
thread([&] {
while (true)
{
Update();
wiHelper::Sleep(16.f);
}
}).detach();
}
wiInputManager::~wiInputManager()
{
}
wiInputManager* wiInputManager::GetInstance()
{
static wiInputManager* instance = nullptr;
if (instance == nullptr)
{
instance = new wiInputManager();
}
return instance;
}
void wiInputManager::addXInput(wiXInput* input){
xinput=input;
}
void wiInputManager::addDirectInput(wiDirectInput* input){
dinput = input;
}
void wiInputManager::addRawInput(wiRawInput* input){
rawinput = input;
}
void wiInputManager::CleanUp(){
SAFE_DELETE(xinput);
SAFE_DELETE(dinput);
SAFE_DELETE(rawinput);
}
void wiInputManager::Update()
{
LOCK();
if(dinput){
dinput->Frame();
}
if(xinput){
xinput->UpdateControllerState();
}
if (rawinput){
//rawinput->RetrieveBufferedData();
}
for(InputCollection::iterator iter=inputs.begin();iter!=inputs.end();){
InputType type = iter->first.type;
DWORD button = iter->first.button;
short playerIndex = iter->first.playerIndex;
bool todelete = false;
if (down(button, type, playerIndex))
{
iter->second++;
}
else
{
todelete = true;
}
if(todelete){
inputs.erase(iter++);
}
else{
++iter;
}
}
touches.clear();
mousewheel_scrolled = 0.0f;
UNLOCK();
}
bool wiInputManager::down(DWORD button, InputType inputType, short playerindex)
{
if (!wiWindowRegistration::GetInstance()->IsWindowActive())
{
return false;
}
switch (inputType)
{
case KEYBOARD:
return KEY_DOWN(static_cast<int>(button)) | KEY_TOGGLE(static_cast<int>(button));
break;
case XINPUT_JOYPAD:
if (xinput != nullptr && xinput->isButtonDown(playerindex, button))
return true;
break;
case DIRECTINPUT_JOYPAD:
if (dinput != nullptr && ( dinput->isButtonDown(playerindex, button) || dinput->getDirections(playerindex)==button )){
return true;
}
break;
default:break;
}
return false;
}
bool wiInputManager::press(DWORD button, InputType inputType, short playerindex)
{
if (!down(button, inputType, playerindex))
return false;
Input input = Input();
input.button=button;
input.type=inputType;
input.playerIndex = playerindex;
LOCK();
InputCollection::iterator iter = inputs.find(input);
if(iter==inputs.end()){
inputs.insert(InputCollection::value_type(input,0));
UNLOCK();
return true;
}
if (iter->second <= 0)
{
UNLOCK();
return true;
}
UNLOCK();
return false;
}
bool wiInputManager::hold(DWORD button, DWORD frames, bool continuous, InputType inputType, short playerIndex)
{
if (!down(button, inputType, playerIndex))
return false;
Input input = Input();
input.button=button;
input.type=inputType;
input.playerIndex=playerIndex;
LOCK();
InputCollection::iterator iter = inputs.find(input);
if(iter==inputs.end()){
inputs.insert(pair<Input,DWORD>(input,0));
UNLOCK();
return false;
}
else if ((!continuous && iter->second == frames) || (continuous && iter->second >= frames))
{
UNLOCK();
return true;
}
UNLOCK();
return false;
}
XMFLOAT4 wiInputManager::getpointer()
{
#ifndef WINSTORE_SUPPORT
POINT p;
GetCursorPos(&p);
ScreenToClient(wiWindowRegistration::GetInstance()->GetRegisteredWindow(), &p);
return XMFLOAT4((float)p.x, (float)p.y, mousewheel_scrolled, 0);
#else
auto& p = Windows::UI::Core::CoreWindow::GetForCurrentThread()->PointerPosition;
return XMFLOAT4(p.X, p.Y, mousewheel_scrolled, 0);
#endif
}
void wiInputManager::setpointer(const XMFLOAT4& props)
{
#ifndef WINSTORE_SUPPORT
POINT p;
p.x = (LONG)props.x;
p.y = (LONG)props.y;
ClientToScreen(wiWindowRegistration::GetInstance()->GetRegisteredWindow(), &p);
SetCursorPos(p.x, p.y);
#endif
mousewheel_scrolled = props.z;
}
void wiInputManager::hidepointer(bool value)
{
#ifndef WINSTORE_SUPPORT
ShowCursor(!value);
#endif
}
void AddTouch(const wiInputManager::Touch& touch)
{
wiInputManager::GetInstance()->LOCK();
wiInputManager::GetInstance()->touches.push_back(touch);
wiInputManager::GetInstance()->UNLOCK();
}
#ifdef WINSTORE_SUPPORT
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::UI::Core;
using namespace Windows::UI::Input;
using namespace Windows::System;
using namespace Windows::Foundation;
void _OnPointerPressed(CoreWindow^ window, PointerEventArgs^ pointer)
{
auto p = pointer->CurrentPoint;
wiInputManager::Touch touch;
touch.state = wiInputManager::Touch::TOUCHSTATE_PRESSED;
touch.pos = XMFLOAT2(p->Position.X, p->Position.Y);
AddTouch(touch);
}
void _OnPointerReleased(CoreWindow^ window, PointerEventArgs^ pointer)
{
auto p = pointer->CurrentPoint;
wiInputManager::Touch touch;
touch.state = wiInputManager::Touch::TOUCHSTATE_RELEASED;
touch.pos = XMFLOAT2(p->Position.X, p->Position.Y);
AddTouch(touch);
}
void _OnPointerMoved(CoreWindow^ window, PointerEventArgs^ pointer)
{
auto p = pointer->CurrentPoint;
wiInputManager::Touch touch;
touch.state = wiInputManager::Touch::TOUCHSTATE_MOVED;
touch.pos = XMFLOAT2(p->Position.X, p->Position.Y);
AddTouch(touch);
}
#endif // WINSTORE_SUPPORT
std::vector<wiInputManager::Touch> wiInputManager::getTouches()
{
static bool isRegisteredTouch = false;
if (!isRegisteredTouch)
{
#ifdef WINSTORE_SUPPORT
auto window = CoreWindow::GetForCurrentThread();
window->PointerPressed += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(_OnPointerPressed);
window->PointerReleased += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(_OnPointerReleased);
window->PointerMoved += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(_OnPointerMoved);
#endif // WINSTORE_SUPPORT
isRegisteredTouch = true;
}
return touches;
}