Gamepad vibration on Windows

This commit is contained in:
rdb 2015-12-19 21:04:49 +01:00
parent bfea37f64d
commit 44f9b22323
3 changed files with 41 additions and 2 deletions

View File

@ -1,2 +1,3 @@
struct XINPUT_STATE;
struct XINPUT_CAPABILITIES;
struct XINPUT_VIBRATION;

View File

@ -63,11 +63,13 @@ struct XINPUT_BUSINFO {
};
typedef DWORD (*pXInputGetState)(DWORD, XINPUT_STATE *);
typedef DWORD (*pXInputSetState)(DWORD, XINPUT_VIBRATION *);
typedef DWORD (*pXInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES *);
typedef DWORD (*pXInputGetBatteryInformation)(DWORD, BYTE, XINPUT_BATTERY_INFORMATION *);
typedef DWORD (*pXInputGetBaseBusInformation)(DWORD, XINPUT_BUSINFO *);
static pXInputGetState get_state = NULL;
static pXInputSetState set_state = NULL;
static pXInputGetCapabilities get_capabilities = NULL;
static pXInputGetBatteryInformation get_battery_information = NULL;
static pXInputGetBaseBusInformation get_base_bus_information = NULL;
@ -132,6 +134,17 @@ XInputDevice(DWORD user_index) :
}
}
////////////////////////////////////////////////////////////////////
// Function: XInputDevice::Constructor
// Access: Published
// Description: Creates a new device using the Linux joystick
// device using the given device filename.
////////////////////////////////////////////////////////////////////
XInputDevice::
~XInputDevice() {
do_set_vibration(0, 0);
}
////////////////////////////////////////////////////////////////////
// Function: XInputDevice::detect
// Access: Public
@ -210,6 +223,13 @@ init_xinput() {
}
}
set_state = (pXInputSetState)GetProcAddress(module, "XInputSetState");
if (set_state == NULL) {
device_cat.error()
<< "Failed to find function XInputSetState in " << dll_name << ".\n";
return false;
}
get_capabilities = (pXInputGetCapabilities)GetProcAddress(module, "XInputGetCapabilities");
if (get_capabilities == NULL) {
device_cat.error()
@ -234,7 +254,7 @@ init_xinput() {
// just connected.
////////////////////////////////////////////////////////////////////
void XInputDevice::
init_device(XINPUT_CAPABILITIES &caps, XINPUT_STATE &state) {
init_device(const XINPUT_CAPABILITIES &caps, const XINPUT_STATE &state) {
if (caps.Type == XINPUT_DEVTYPE_GAMEPAD) {
_device_class = DC_gamepad;
} else {
@ -324,6 +344,22 @@ init_device(XINPUT_CAPABILITIES &caps, XINPUT_STATE &state) {
_last_packet = state.dwPacketNumber;
}
////////////////////////////////////////////////////////////////////
// Function: XInputDevice::do_set_vibration
// Access: Private, Virtual
// Description: Sets the vibration strength. The first argument
// controls a low-frequency motor, if present, and
// the latter controls a high-frequency motor. The
// values are within the 0-1 range.
////////////////////////////////////////////////////////////////////
void XInputDevice::
do_set_vibration(double strong, double weak) {
XINPUT_VIBRATION vibration;
vibration.wLeftMotorSpeed = strong * 0xffff;
vibration.wRightMotorSpeed = weak * 0xffff;
set_state(_index, &vibration);
}
////////////////////////////////////////////////////////////////////
// Function: InputDevice::do_poll
// Access: Public, Virtual

View File

@ -33,12 +33,14 @@ typedef struct _XINPUT_STATE XINPUT_STATE;
class EXPCL_PANDA_DEVICE XInputDevice FINAL : public InputDevice {
public:
XInputDevice(DWORD user_index);
~XInputDevice();
void detect(InputDeviceManager *mgr);
static bool init_xinput();
private:
void init_device(XINPUT_CAPABILITIES &caps, XINPUT_STATE &state);
void init_device(const XINPUT_CAPABILITIES &caps, const XINPUT_STATE &state);
virtual void do_set_vibration(double strong, double weak);
virtual void do_poll();
private: