From 6bc4b6ab43703eebf817756b55205d68506b2a10 Mon Sep 17 00:00:00 2001 From: Ryan Dortmans Date: Mon, 27 Sep 2004 08:08:55 +0000 Subject: [PATCH] Input handler for Xbox controllers --- .../arch/InputHandler/InputHandler_Xbox.cpp | 229 ++++++++++++++++++ .../src/arch/InputHandler/InputHandler_Xbox.h | 55 +++++ 2 files changed, 284 insertions(+) create mode 100644 stepmania/src/arch/InputHandler/InputHandler_Xbox.cpp create mode 100644 stepmania/src/arch/InputHandler/InputHandler_Xbox.h diff --git a/stepmania/src/arch/InputHandler/InputHandler_Xbox.cpp b/stepmania/src/arch/InputHandler/InputHandler_Xbox.cpp new file mode 100644 index 0000000000..d1527898e4 --- /dev/null +++ b/stepmania/src/arch/InputHandler/InputHandler_Xbox.cpp @@ -0,0 +1,229 @@ +#include "global.h" +#include "InputHandler_Xbox.h" +#include "RageUtil.h" +#include "RageLog.h" +#include "RageDisplay.h" + + +#include + +struct DEVICE_STATE { + XPP_DEVICE_TYPE *pxdt; + DWORD dwState; +}; + +byte buttonMasks[] = { XINPUT_GAMEPAD_DPAD_LEFT, + XINPUT_GAMEPAD_DPAD_RIGHT, + XINPUT_GAMEPAD_DPAD_UP, + XINPUT_GAMEPAD_DPAD_DOWN, + XINPUT_GAMEPAD_START, + XINPUT_GAMEPAD_BACK, + XINPUT_GAMEPAD_LEFT_THUMB, + XINPUT_GAMEPAD_RIGHT_THUMB}; + + +/** + * XBOX controller maps to the following RageInputDevice constants: + * DPAD -> JOY_HAT_... + * START -> JOY_AUX_1 + * BACK -> JOY_AUX_2 + * Left thumb button -> JOY_AUX_3 + * Right thumb button -> JOY_AUX_4 + * Following buttons are JOY_(index): + * A, B, X, Y, BLACK, WHITE, Left trigger, right trigger + */ + +/* XXX: For some reason, with this input handler the input isn't handled on the gameplay screen! + * All other menus work, and the screen itself sees the input and bounces the arrow, but no step + * is actually registered. */ + +InputHandler_Xbox::InputHandler_Xbox() +{ + // + // Init joysticks + // + XDEVICE_PREALLOC_TYPE xdpt[] = {{XDEVICE_TYPE_GAMEPAD, 4}}; + XInitDevices( sizeof(xdpt) / sizeof(XDEVICE_PREALLOC_TYPE), xdpt ); + + getHandles(); +} + +InputHandler_Xbox::~InputHandler_Xbox() +{ + for(unsigned i = 0; i < NUM_PLAYERS; i++) + { + if(joysticks[i] != 0) + XInputClose(joysticks[i]); + } +} + +void InputHandler_Xbox::Update(float fDeltaTime) +{ + // check insertions and removals + DWORD dwInsert, dwRemove; + DEVICE_STATE devices = {XDEVICE_TYPE_GAMEPAD, 0}; + + bool changes = false; + // Check each device type to see if any changes have occurred. + if( XGetDeviceChanges( devices.pxdt, &dwInsert, &dwRemove ) ) + { + for(int j = 0; j < 4; j++) + { + if(1 << j & dwRemove) + { + changes = true; + LOG->Trace("A joystick was removed"); + } + if(1 << j & dwInsert) + { + changes = true; + LOG->Trace("A joystick was inserted"); + } + } + } + + if(changes) + { + getHandles(); + return; + } + + for(unsigned i = 0; i < NUM_PLAYERS; i++) + { + if(joysticks[i] == 0) + { + LOG->Trace("Ignoring absent joystick"); + continue; + } + + InputDevice inputDevice = InputDevice(DEVICE_JOY1 + i); + XINPUT_STATE xis; + // Query latest state. + XInputGetState( joysticks[i], &xis ); + + // check buttons + for(int j = 0; j < NUM_BUTTONS; j++) + { + DWORD nowPressed = xis.Gamepad.wButtons & buttonMasks[j]; + DWORD wasPressed = lastState[i].wButtons & buttonMasks[j]; + + if(nowPressed != wasPressed) + { + JoystickButton Button = JoystickButton(JOY_HAT_LEFT + j); + if(Button >= NUM_JOYSTICK_BUTTONS) + { + LOG->Warn("Ignored joystick event (button too high)"); + continue; + } + DeviceInput di(inputDevice, Button); + ButtonPressed(di, nowPressed != 0); + continue; + } + } + + // check analog buttons + for(int j = 0; j < NUM_ANALOG_BUTTONS; j++) + { + bool nowPressed = xis.Gamepad.bAnalogButtons[j] > XINPUT_GAMEPAD_MAX_CROSSTALK; + bool wasPressed = lastState[i].bAnalogButtons[j] > XINPUT_GAMEPAD_MAX_CROSSTALK; + + if(nowPressed != wasPressed) + { + JoystickButton Button = JoystickButton(JOY_1 + j); + if(Button >= NUM_JOYSTICK_BUTTONS) + { + LOG->Warn("Ignored joystick event (button too high)"); + continue; + } + DeviceInput di(inputDevice, Button); + ButtonPressed(di, nowPressed); + continue; + } + } + + // check thumbsticks + SHORT axes[] = { xis.Gamepad.sThumbLX, xis.Gamepad.sThumbLY, xis.Gamepad.sThumbRX, xis.Gamepad.sThumbRY}; + + for(int j = 0; j < NUM_AXES; j++) + { + if(axes[j] != 0) + { + JoystickButton neg = (JoystickButton)(JOY_LEFT + (2 * j)); + JoystickButton pos = (JoystickButton)(JOY_RIGHT + (2 * j)); + float l = SCALE( axes[j], 0.0f, 32768.0f, 0.0f, 1.0f ); + ButtonPressed(DeviceInput(inputDevice, neg,max(-l,0),RageZeroTimer), axes[j] < -16000); + ButtonPressed(DeviceInput(inputDevice, pos,max(+l,0),RageZeroTimer), axes[j] > +16000); + continue; + } + } + + memcpy(&lastState[i], &xis.Gamepad, sizeof(XINPUT_GAMEPAD)); + } +} + +void InputHandler_Xbox::GetDevicesAndDescriptions(vector& vDevicesOut, vector& vDescriptionsOut) +{ + for( int i=0; iInfo( "Found %d connected joysticks for %d players", joysFound, playersAllocated ); +} + +/* + * (c) 2004 Ryan Dortmans + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ \ No newline at end of file diff --git a/stepmania/src/arch/InputHandler/InputHandler_Xbox.h b/stepmania/src/arch/InputHandler/InputHandler_Xbox.h new file mode 100644 index 0000000000..401853037b --- /dev/null +++ b/stepmania/src/arch/InputHandler/InputHandler_Xbox.h @@ -0,0 +1,55 @@ +#ifndef INPUT_HANDLER_XBOX_H +#define INPUT_HANDLER_XBOX_H + +#include "InputHandler.h" + +#include + +#define NUM_PORTS 4 +#define NUM_PLAYERS 2 +#define NUM_BUTTONS 8 +#define NUM_ANALOG_BUTTONS 8 +#define NUM_AXES 4 + +class InputHandler_Xbox: public InputHandler +{ + HANDLE joysticks[NUM_PLAYERS]; + XINPUT_GAMEPAD lastState[NUM_PLAYERS]; + +public: + void Update(float fDeltaTime); + InputHandler_Xbox(); + ~InputHandler_Xbox(); + void GetDevicesAndDescriptions(vector& vDevicesOut, vector& vDescriptionsOut); + +private: + void getHandles(); +}; + + +#endif + +/* + * (c) 2004 Ryan Dortmans + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */