From 6d2abe95b4a05ccbe3ecd92c9c3f58a5c36f63e2 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Mon, 1 Apr 2013 04:55:38 +0300 Subject: [PATCH] Windows: add support DirectInput gamepads (devices); --- Windows/DinputDevice.cpp | 123 +++++++++++++++++++++++++++++++++ Windows/DinputDevice.h | 35 ++++++++++ Windows/InputDevice.cpp | 2 + Windows/PPSSPP.vcxproj | 2 + Windows/PPSSPP.vcxproj.filters | 6 ++ 5 files changed, 168 insertions(+) create mode 100644 Windows/DinputDevice.cpp create mode 100644 Windows/DinputDevice.h diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp new file mode 100644 index 0000000000..383740f9f1 --- /dev/null +++ b/Windows/DinputDevice.cpp @@ -0,0 +1,123 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include +#include "DinputDevice.h" +#include "input/input_state.h" +#include "Core/Reporting.h" +#pragma comment(lib,"dxguid.lib") +#pragma comment(lib,"dinput8.lib") + +static const unsigned int dinput_ctrl_map[] = { + 9, PAD_BUTTON_START, + 8, PAD_BUTTON_SELECT, + 4, PAD_BUTTON_LBUMPER, + 5, PAD_BUTTON_RBUMPER, + 1, PAD_BUTTON_A, + 2, PAD_BUTTON_B, + 0, PAD_BUTTON_X, + 3, PAD_BUTTON_Y, +}; + +DinputDevice::DinputDevice() +{ + pJoystick = NULL; + pDI = NULL; + + if(FAILED(DirectInput8Create(GetModuleHandle(NULL),DIRECTINPUT_VERSION,IID_IDirectInput8,(void**)&pDI,NULL))) + return; + + if(FAILED(pDI->CreateDevice(GUID_Joystick, &pJoystick, NULL ))) + { + pDI->Release(); + pDI = NULL; + return; + } + + if(FAILED(pJoystick->SetDataFormat(&c_dfDIJoystick2))) + { + pJoystick->Release(); + pJoystick = NULL; + return; + } + + DIPROPRANGE diprg; + diprg.diph.dwSize = sizeof(DIPROPRANGE); + diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); + diprg.diph.dwHow = DIPH_DEVICE; + diprg.diph.dwObj = 0; + diprg.lMin = -10000; + diprg.lMax = 10000; + + analog = FAILED(pJoystick->SetProperty(DIPROP_RANGE, &diprg.diph))?false:true; +} + +DinputDevice::~DinputDevice() +{ + if (pJoystick) + { + pJoystick->Release(); + pJoystick= NULL; + } + + if (pDI) + { + pDI->Release(); + pDI= NULL; + } +} + +int DinputDevice::UpdateState(InputState &input_state) +{ + if (!pJoystick) return -1; + + DIJOYSTATE2 js; + + if (FAILED(pJoystick->Poll())) + { + if(pJoystick->Acquire() == DIERR_INPUTLOST) + return -1; + } + + if(FAILED(pJoystick->GetDeviceState(sizeof(DIJOYSTATE2), &js))) + return -1; + + switch (js.rgdwPOV[0]) + { + case JOY_POVFORWARD: input_state.pad_buttons |= PAD_BUTTON_UP; break; + case JOY_POVBACKWARD: input_state.pad_buttons |= PAD_BUTTON_DOWN; break; + case JOY_POVLEFT: input_state.pad_buttons |= PAD_BUTTON_LEFT; break; + case JOY_POVRIGHT: input_state.pad_buttons |= PAD_BUTTON_RIGHT; break; + } + + if (analog) + { + input_state.pad_lstick_x = (float)js.lX / 10000.f; + input_state.pad_lstick_y = -((float)js.lY / 10000.f); + } + + for (u8 i = 0; i < sizeof(dinput_ctrl_map)/sizeof(dinput_ctrl_map[0]); i += 2) + { + if (js.rgbButtons[dinput_ctrl_map[i]] & 0x80) + { + input_state.pad_buttons |= dinput_ctrl_map[i+1]; + } + } + + return 0; +} + diff --git a/Windows/DinputDevice.h b/Windows/DinputDevice.h new file mode 100644 index 0000000000..70d4f97dbd --- /dev/null +++ b/Windows/DinputDevice.h @@ -0,0 +1,35 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once +#define DIRECTINPUT_VERSION 0x0800 +#include "InputDevice.h" +#include "dinput.h" + +class DinputDevice : + public InputDevice +{ +public: + DinputDevice(); + ~DinputDevice(); + virtual int UpdateState(InputState &input_state); +private: + LPDIRECTINPUT8 pDI; + LPDIRECTINPUTDEVICE8 pJoystick; + bool analog; +}; + diff --git a/Windows/InputDevice.cpp b/Windows/InputDevice.cpp index ad882a2c73..8c1aa7eabd 100644 --- a/Windows/InputDevice.cpp +++ b/Windows/InputDevice.cpp @@ -1,5 +1,6 @@ #include "InputDevice.h" #include "XinputDevice.h" +#include "DinputDevice.h" #include "KeyboardDevice.h" #include #include @@ -8,6 +9,7 @@ std::list> getInputDevices() { std::list> list; PUSH_BACK(XinputDevice); + PUSH_BACK(DinputDevice); PUSH_BACK(KeyboardDevice); return list; } diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 294910b9a9..b0db3a8474 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -252,6 +252,7 @@ + @@ -288,6 +289,7 @@ + diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index 576c9e2946..0a68a7ed76 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -95,6 +95,9 @@ Android + + Windows\Input + @@ -167,6 +170,9 @@ Android + + Windows\Input +