From 3570c7f03a2aa90aa634f96c0af1969af610f14d Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Fri, 24 Jun 2016 10:43:46 +0200 Subject: Reformat all the things. Have fun with merge conflicts. --- .../ControllerInterface/Android/Android.cpp | 332 +++---- .../ControllerInterface/Android/Android.h | 63 +- .../ControllerInterface/ControllerInterface.cpp | 241 ++--- .../ControllerInterface/ControllerInterface.h | 177 ++-- .../ControllerInterface/DInput/DInput.cpp | 53 +- .../ControllerInterface/DInput/DInput.h | 6 +- .../ControllerInterface/DInput/DInputJoystick.cpp | 410 ++++----- .../ControllerInterface/DInput/DInputJoystick.h | 93 +- .../DInput/DInputKeyboardMouse.cpp | 322 +++---- .../DInput/DInputKeyboardMouse.h | 143 +-- .../ControllerInterface/DInput/NamedKeys.h | 181 +--- .../ControllerInterface/DInput/XInputFilter.cpp | 199 +++-- .../ControllerInterface/DInput/XInputFilter.h | 4 +- .../InputCommon/ControllerInterface/Device.cpp | 152 ++-- .../Core/InputCommon/ControllerInterface/Device.h | 249 +++--- .../ControllerInterface/ExpressionParser.cpp | 981 ++++++++++----------- .../ControllerInterface/ExpressionParser.h | 64 +- .../ForceFeedback/ForceFeedbackDevice.cpp | 277 +++--- .../ForceFeedback/ForceFeedbackDevice.h | 45 +- .../ForceFeedback/OSX/DirectInputAdapter.h | 305 +++---- .../ForceFeedback/OSX/DirectInputConstants.h | 220 ++--- .../Core/InputCommon/ControllerInterface/OSX/OSX.h | 6 +- .../InputCommon/ControllerInterface/OSX/OSX.mm | 270 +++--- .../ControllerInterface/OSX/OSXJoystick.h | 130 ++- .../ControllerInterface/OSX/OSXJoystick.mm | 427 +++++---- .../ControllerInterface/OSX/OSXKeyboard.h | 102 ++- .../ControllerInterface/OSX/OSXKeyboard.mm | 418 +++++---- .../ControllerInterface/Pipes/Pipes.cpp | 238 +++-- .../InputCommon/ControllerInterface/Pipes/Pipes.h | 53 +- .../InputCommon/ControllerInterface/SDL/SDL.cpp | 395 ++++----- .../Core/InputCommon/ControllerInterface/SDL/SDL.h | 235 ++--- .../ControllerInterface/XInput/XInput.cpp | 325 ++++--- .../ControllerInterface/XInput/XInput.h | 131 +-- .../ControllerInterface/Xlib/XInput2.cpp | 470 +++++----- .../InputCommon/ControllerInterface/Xlib/XInput2.h | 168 ++-- .../InputCommon/ControllerInterface/Xlib/Xlib.cpp | 173 ++-- .../InputCommon/ControllerInterface/Xlib/Xlib.h | 129 ++- .../ControllerInterface/evdev/evdev.cpp | 468 +++++----- .../InputCommon/ControllerInterface/evdev/evdev.h | 110 ++- 39 files changed, 4272 insertions(+), 4493 deletions(-) (limited to 'Source/Core/InputCommon/ControllerInterface') diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp index c70f0cc3ed..3d68be633f 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp @@ -2,193 +2,227 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include #include "InputCommon/ControllerInterface/Android/Android.h" +#include namespace ciface { - namespace Android { - -void Init( std::vector& devices ) +void Init(std::vector& devices) { - devices.push_back(new Touchscreen(0)); - devices.push_back(new Touchscreen(1)); - devices.push_back(new Touchscreen(2)); - devices.push_back(new Touchscreen(3)); - devices.push_back(new Touchscreen(4)); - devices.push_back(new Touchscreen(5)); - devices.push_back(new Touchscreen(6)); - devices.push_back(new Touchscreen(7)); + devices.push_back(new Touchscreen(0)); + devices.push_back(new Touchscreen(1)); + devices.push_back(new Touchscreen(2)); + devices.push_back(new Touchscreen(3)); + devices.push_back(new Touchscreen(4)); + devices.push_back(new Touchscreen(5)); + devices.push_back(new Touchscreen(6)); + devices.push_back(new Touchscreen(7)); } // Touchscreens and stuff std::string Touchscreen::GetName() const { - return "Touchscreen"; + return "Touchscreen"; } std::string Touchscreen::GetSource() const { - return "Android"; + return "Android"; } int Touchscreen::GetId() const { - return _padID; + return _padID; } -Touchscreen::Touchscreen(int padID) - : _padID(padID) +Touchscreen::Touchscreen(int padID) : _padID(padID) { - // GC - AddInput(new Button(_padID, ButtonManager::BUTTON_A)); - AddInput(new Button(_padID, ButtonManager::BUTTON_B)); - AddInput(new Button(_padID, ButtonManager::BUTTON_START)); - AddInput(new Button(_padID, ButtonManager::BUTTON_X)); - AddInput(new Button(_padID, ButtonManager::BUTTON_Y)); - AddInput(new Button(_padID, ButtonManager::BUTTON_Z)); - AddInput(new Button(_padID, ButtonManager::BUTTON_UP)); - AddInput(new Button(_padID, ButtonManager::BUTTON_DOWN)); - AddInput(new Button(_padID, ButtonManager::BUTTON_LEFT)); - AddInput(new Button(_padID, ButtonManager::BUTTON_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::STICK_MAIN_LEFT), new Axis(_padID, ButtonManager::STICK_MAIN_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::STICK_MAIN_UP), new Axis(_padID, ButtonManager::STICK_MAIN_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::STICK_C_LEFT), new Axis(_padID, ButtonManager::STICK_C_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::STICK_C_UP), new Axis(_padID, ButtonManager::STICK_C_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::TRIGGER_L), new Axis(_padID, ButtonManager::TRIGGER_L)); - AddAnalogInputs(new Axis(_padID, ButtonManager::TRIGGER_R), new Axis(_padID, ButtonManager::TRIGGER_R)); - - // Wiimote - AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_A)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_B)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_MINUS)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_PLUS)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_HOME)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_1)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_2)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_UP)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_DOWN)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_LEFT)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_RIGHT)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_IR_HIDE)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_TILT_MODIFIER)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_SHAKE_X)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_SHAKE_Y)); - AddInput(new Button(_padID, ButtonManager::WIIMOTE_SHAKE_Z)); - AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_IR_UP), new Axis(_padID, ButtonManager::WIIMOTE_IR_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_IR_LEFT), new Axis(_padID, ButtonManager::WIIMOTE_IR_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_IR_FORWARD), new Axis(_padID, ButtonManager::WIIMOTE_IR_BACKWARD)); - AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_SWING_UP), new Axis(_padID, ButtonManager::WIIMOTE_SWING_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_SWING_LEFT), new Axis(_padID, ButtonManager::WIIMOTE_SWING_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_SWING_FORWARD), new Axis(_padID, ButtonManager::WIIMOTE_SWING_BACKWARD)); - AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_TILT_LEFT), new Axis(_padID, ButtonManager::WIIMOTE_TILT_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_TILT_FORWARD), new Axis(_padID, ButtonManager::WIIMOTE_TILT_BACKWARD)); - - //Wii ext: Nunchuk - AddInput(new Button(_padID, ButtonManager::NUNCHUK_BUTTON_C)); - AddInput(new Button(_padID, ButtonManager::NUNCHUK_BUTTON_Z)); - AddInput(new Button(_padID, ButtonManager::NUNCHUK_TILT_MODIFIER)); - AddInput(new Button(_padID, ButtonManager::NUNCHUK_SHAKE_X)); - AddInput(new Button(_padID, ButtonManager::NUNCHUK_SHAKE_Y)); - AddInput(new Button(_padID, ButtonManager::NUNCHUK_SHAKE_Z)); - AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_STICK_LEFT), new Axis(_padID, ButtonManager::NUNCHUK_STICK_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_STICK_UP), new Axis(_padID, ButtonManager::NUNCHUK_STICK_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_SWING_LEFT), new Axis(_padID, ButtonManager::NUNCHUK_SWING_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_SWING_UP), new Axis(_padID, ButtonManager::NUNCHUK_SWING_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_SWING_FORWARD), new Axis(_padID, ButtonManager::NUNCHUK_SWING_BACKWARD)); - AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_TILT_LEFT), new Axis(_padID, ButtonManager::NUNCHUK_TILT_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_TILT_FORWARD), new Axis(_padID, ButtonManager::NUNCHUK_TILT_BACKWARD)); - - // Wii ext: Classic - AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_A)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_B)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_X)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_Y)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_MINUS)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_PLUS)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_HOME)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_ZL)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_ZR)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_DPAD_UP)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_DPAD_DOWN)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_DPAD_LEFT)); - AddInput(new Button(_padID, ButtonManager::CLASSIC_DPAD_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_STICK_LEFT_LEFT), new Axis(_padID, ButtonManager::CLASSIC_STICK_LEFT_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_STICK_LEFT_UP), new Axis(_padID, ButtonManager::CLASSIC_STICK_LEFT_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_STICK_RIGHT_LEFT), new Axis(_padID, ButtonManager::CLASSIC_STICK_RIGHT_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_STICK_RIGHT_UP), new Axis(_padID, ButtonManager::CLASSIC_STICK_RIGHT_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_TRIGGER_L), new Axis(_padID, ButtonManager::CLASSIC_TRIGGER_L)); - AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_TRIGGER_R), new Axis(_padID, ButtonManager::CLASSIC_TRIGGER_R)); - - // Wii-ext: Guitar - AddInput(new Button(_padID, ButtonManager::GUITAR_BUTTON_MINUS)); - AddInput(new Button(_padID, ButtonManager::GUITAR_BUTTON_PLUS)); - AddInput(new Button(_padID, ButtonManager::GUITAR_FRET_GREEN)); - AddInput(new Button(_padID, ButtonManager::GUITAR_FRET_RED)); - AddInput(new Button(_padID, ButtonManager::GUITAR_FRET_YELLOW)); - AddInput(new Button(_padID, ButtonManager::GUITAR_FRET_BLUE)); - AddInput(new Button(_padID, ButtonManager::GUITAR_FRET_ORANGE)); - AddInput(new Button(_padID, ButtonManager::GUITAR_STRUM_UP)); - AddInput(new Button(_padID, ButtonManager::GUITAR_STRUM_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::GUITAR_STICK_LEFT), new Axis(_padID, ButtonManager::GUITAR_STICK_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::GUITAR_STICK_UP), new Axis(_padID, ButtonManager::GUITAR_STICK_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::GUITAR_WHAMMY_BAR), new Axis(_padID, ButtonManager::GUITAR_WHAMMY_BAR)); - - // Wii-ext: Drums - AddInput(new Button(_padID, ButtonManager::DRUMS_BUTTON_MINUS)); - AddInput(new Button(_padID, ButtonManager::DRUMS_BUTTON_PLUS)); - AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_RED)); - AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_YELLOW)); - AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_BLUE)); - AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_GREEN)); - AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_ORANGE)); - AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_BASS)); - AddAnalogInputs(new Axis(_padID, ButtonManager::DRUMS_STICK_LEFT), new Axis(_padID, ButtonManager::DRUMS_STICK_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::DRUMS_STICK_UP), new Axis(_padID, ButtonManager::DRUMS_STICK_DOWN)); - - // Wii-ext: Turntable - AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_GREEN_LEFT)); - AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_RED_LEFT)); - AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_BLUE_LEFT)); - AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_GREEN_RIGHT)); - AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_RED_RIGHT)); - AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_BLUE_RIGHT)); - AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_MINUS)); - AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_PLUS)); - AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_HOME)); - AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_EUPHORIA)); - AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_TABLE_LEFT_LEFT), new Axis(_padID, ButtonManager::TURNTABLE_TABLE_LEFT_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_TABLE_RIGHT_LEFT), new Axis(_padID, ButtonManager::TURNTABLE_TABLE_RIGHT_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_STICK_LEFT), new Axis(_padID, ButtonManager::TURNTABLE_STICK_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_STICK_UP), new Axis(_padID, ButtonManager::TURNTABLE_STICK_DOWN)); - AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_CROSSFADE_LEFT), new Axis(_padID, ButtonManager::TURNTABLE_CROSSFADE_RIGHT)); - AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_EFFECT_DIAL), new Axis(_padID, ButtonManager::TURNTABLE_EFFECT_DIAL)); + // GC + AddInput(new Button(_padID, ButtonManager::BUTTON_A)); + AddInput(new Button(_padID, ButtonManager::BUTTON_B)); + AddInput(new Button(_padID, ButtonManager::BUTTON_START)); + AddInput(new Button(_padID, ButtonManager::BUTTON_X)); + AddInput(new Button(_padID, ButtonManager::BUTTON_Y)); + AddInput(new Button(_padID, ButtonManager::BUTTON_Z)); + AddInput(new Button(_padID, ButtonManager::BUTTON_UP)); + AddInput(new Button(_padID, ButtonManager::BUTTON_DOWN)); + AddInput(new Button(_padID, ButtonManager::BUTTON_LEFT)); + AddInput(new Button(_padID, ButtonManager::BUTTON_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::STICK_MAIN_LEFT), + new Axis(_padID, ButtonManager::STICK_MAIN_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::STICK_MAIN_UP), + new Axis(_padID, ButtonManager::STICK_MAIN_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::STICK_C_LEFT), + new Axis(_padID, ButtonManager::STICK_C_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::STICK_C_UP), + new Axis(_padID, ButtonManager::STICK_C_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::TRIGGER_L), + new Axis(_padID, ButtonManager::TRIGGER_L)); + AddAnalogInputs(new Axis(_padID, ButtonManager::TRIGGER_R), + new Axis(_padID, ButtonManager::TRIGGER_R)); + + // Wiimote + AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_A)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_B)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_MINUS)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_PLUS)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_HOME)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_1)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_BUTTON_2)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_UP)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_DOWN)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_LEFT)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_RIGHT)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_IR_HIDE)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_TILT_MODIFIER)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_SHAKE_X)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_SHAKE_Y)); + AddInput(new Button(_padID, ButtonManager::WIIMOTE_SHAKE_Z)); + AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_IR_UP), + new Axis(_padID, ButtonManager::WIIMOTE_IR_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_IR_LEFT), + new Axis(_padID, ButtonManager::WIIMOTE_IR_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_IR_FORWARD), + new Axis(_padID, ButtonManager::WIIMOTE_IR_BACKWARD)); + AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_SWING_UP), + new Axis(_padID, ButtonManager::WIIMOTE_SWING_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_SWING_LEFT), + new Axis(_padID, ButtonManager::WIIMOTE_SWING_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_SWING_FORWARD), + new Axis(_padID, ButtonManager::WIIMOTE_SWING_BACKWARD)); + AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_TILT_LEFT), + new Axis(_padID, ButtonManager::WIIMOTE_TILT_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::WIIMOTE_TILT_FORWARD), + new Axis(_padID, ButtonManager::WIIMOTE_TILT_BACKWARD)); + + // Wii ext: Nunchuk + AddInput(new Button(_padID, ButtonManager::NUNCHUK_BUTTON_C)); + AddInput(new Button(_padID, ButtonManager::NUNCHUK_BUTTON_Z)); + AddInput(new Button(_padID, ButtonManager::NUNCHUK_TILT_MODIFIER)); + AddInput(new Button(_padID, ButtonManager::NUNCHUK_SHAKE_X)); + AddInput(new Button(_padID, ButtonManager::NUNCHUK_SHAKE_Y)); + AddInput(new Button(_padID, ButtonManager::NUNCHUK_SHAKE_Z)); + AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_STICK_LEFT), + new Axis(_padID, ButtonManager::NUNCHUK_STICK_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_STICK_UP), + new Axis(_padID, ButtonManager::NUNCHUK_STICK_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_SWING_LEFT), + new Axis(_padID, ButtonManager::NUNCHUK_SWING_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_SWING_UP), + new Axis(_padID, ButtonManager::NUNCHUK_SWING_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_SWING_FORWARD), + new Axis(_padID, ButtonManager::NUNCHUK_SWING_BACKWARD)); + AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_TILT_LEFT), + new Axis(_padID, ButtonManager::NUNCHUK_TILT_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::NUNCHUK_TILT_FORWARD), + new Axis(_padID, ButtonManager::NUNCHUK_TILT_BACKWARD)); + + // Wii ext: Classic + AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_A)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_B)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_X)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_Y)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_MINUS)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_PLUS)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_HOME)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_ZL)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_BUTTON_ZR)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_DPAD_UP)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_DPAD_DOWN)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_DPAD_LEFT)); + AddInput(new Button(_padID, ButtonManager::CLASSIC_DPAD_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_STICK_LEFT_LEFT), + new Axis(_padID, ButtonManager::CLASSIC_STICK_LEFT_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_STICK_LEFT_UP), + new Axis(_padID, ButtonManager::CLASSIC_STICK_LEFT_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_STICK_RIGHT_LEFT), + new Axis(_padID, ButtonManager::CLASSIC_STICK_RIGHT_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_STICK_RIGHT_UP), + new Axis(_padID, ButtonManager::CLASSIC_STICK_RIGHT_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_TRIGGER_L), + new Axis(_padID, ButtonManager::CLASSIC_TRIGGER_L)); + AddAnalogInputs(new Axis(_padID, ButtonManager::CLASSIC_TRIGGER_R), + new Axis(_padID, ButtonManager::CLASSIC_TRIGGER_R)); + + // Wii-ext: Guitar + AddInput(new Button(_padID, ButtonManager::GUITAR_BUTTON_MINUS)); + AddInput(new Button(_padID, ButtonManager::GUITAR_BUTTON_PLUS)); + AddInput(new Button(_padID, ButtonManager::GUITAR_FRET_GREEN)); + AddInput(new Button(_padID, ButtonManager::GUITAR_FRET_RED)); + AddInput(new Button(_padID, ButtonManager::GUITAR_FRET_YELLOW)); + AddInput(new Button(_padID, ButtonManager::GUITAR_FRET_BLUE)); + AddInput(new Button(_padID, ButtonManager::GUITAR_FRET_ORANGE)); + AddInput(new Button(_padID, ButtonManager::GUITAR_STRUM_UP)); + AddInput(new Button(_padID, ButtonManager::GUITAR_STRUM_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::GUITAR_STICK_LEFT), + new Axis(_padID, ButtonManager::GUITAR_STICK_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::GUITAR_STICK_UP), + new Axis(_padID, ButtonManager::GUITAR_STICK_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::GUITAR_WHAMMY_BAR), + new Axis(_padID, ButtonManager::GUITAR_WHAMMY_BAR)); + + // Wii-ext: Drums + AddInput(new Button(_padID, ButtonManager::DRUMS_BUTTON_MINUS)); + AddInput(new Button(_padID, ButtonManager::DRUMS_BUTTON_PLUS)); + AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_RED)); + AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_YELLOW)); + AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_BLUE)); + AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_GREEN)); + AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_ORANGE)); + AddInput(new Button(_padID, ButtonManager::DRUMS_PAD_BASS)); + AddAnalogInputs(new Axis(_padID, ButtonManager::DRUMS_STICK_LEFT), + new Axis(_padID, ButtonManager::DRUMS_STICK_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::DRUMS_STICK_UP), + new Axis(_padID, ButtonManager::DRUMS_STICK_DOWN)); + + // Wii-ext: Turntable + AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_GREEN_LEFT)); + AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_RED_LEFT)); + AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_BLUE_LEFT)); + AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_GREEN_RIGHT)); + AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_RED_RIGHT)); + AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_BLUE_RIGHT)); + AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_MINUS)); + AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_PLUS)); + AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_HOME)); + AddInput(new Button(_padID, ButtonManager::TURNTABLE_BUTTON_EUPHORIA)); + AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_TABLE_LEFT_LEFT), + new Axis(_padID, ButtonManager::TURNTABLE_TABLE_LEFT_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_TABLE_RIGHT_LEFT), + new Axis(_padID, ButtonManager::TURNTABLE_TABLE_RIGHT_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_STICK_LEFT), + new Axis(_padID, ButtonManager::TURNTABLE_STICK_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_STICK_UP), + new Axis(_padID, ButtonManager::TURNTABLE_STICK_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_CROSSFADE_LEFT), + new Axis(_padID, ButtonManager::TURNTABLE_CROSSFADE_RIGHT)); + AddAnalogInputs(new Axis(_padID, ButtonManager::TURNTABLE_EFFECT_DIAL), + new Axis(_padID, ButtonManager::TURNTABLE_EFFECT_DIAL)); } // Buttons and stuff std::string Touchscreen::Button::GetName() const { - std::ostringstream ss; - ss << "Button " << (int)_index; - return ss.str(); + std::ostringstream ss; + ss << "Button " << (int)_index; + return ss.str(); } ControlState Touchscreen::Button::GetState() const { - return ButtonManager::GetButtonPressed(_padID, _index); + return ButtonManager::GetButtonPressed(_padID, _index); } std::string Touchscreen::Axis::GetName() const { - std::ostringstream ss; - ss << "Axis " << (int)_index; - return ss.str(); + std::ostringstream ss; + ss << "Axis " << (int)_index; + return ss.str(); } ControlState Touchscreen::Axis::GetState() const { - return ButtonManager::GetAxisValue(_padID, _index) * _neg; + return ButtonManager::GetAxisValue(_padID, _index) * _neg; } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.h b/Source/Core/InputCommon/ControllerInterface/Android/Android.h index c108a86067..53b578f699 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.h +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.h @@ -11,43 +11,46 @@ namespace ciface { namespace Android { - -void Init( std::vector& devices ); +void Init(std::vector& devices); class Touchscreen : public Core::Device { private: - class Button : public Input - { - public: - std::string GetName() const; - Button(int padID, ButtonManager::ButtonType index) : _padID(padID), _index(index) {} - ControlState GetState() const; - private: - const int _padID; - const ButtonManager::ButtonType _index; - }; - class Axis : public Input - { - public: - std::string GetName() const; - Axis(int padID, ButtonManager::ButtonType index, float neg = 1.0f) : _padID(padID), _index(index), _neg(neg) {} - ControlState GetState() const; - private: - const int _padID; - const ButtonManager::ButtonType _index; - const float _neg; - }; + class Button : public Input + { + public: + std::string GetName() const; + Button(int padID, ButtonManager::ButtonType index) : _padID(padID), _index(index) {} + ControlState GetState() const; + + private: + const int _padID; + const ButtonManager::ButtonType _index; + }; + class Axis : public Input + { + public: + std::string GetName() const; + Axis(int padID, ButtonManager::ButtonType index, float neg = 1.0f) + : _padID(padID), _index(index), _neg(neg) + { + } + ControlState GetState() const; + + private: + const int _padID; + const ButtonManager::ButtonType _index; + const float _neg; + }; public: - Touchscreen(int padID); - ~Touchscreen() {} + Touchscreen(int padID); + ~Touchscreen() {} + std::string GetName() const; + int GetId() const; + std::string GetSource() const; - std::string GetName() const; - int GetId() const; - std::string GetSource() const; private: - const int _padID; + const int _padID; }; - } } diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp index 633ce40a5f..55643ece5f 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp @@ -2,35 +2,35 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include "Common/Thread.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" +#include "Common/Thread.h" #ifdef CIFACE_USE_XINPUT - #include "InputCommon/ControllerInterface/XInput/XInput.h" +#include "InputCommon/ControllerInterface/XInput/XInput.h" #endif #ifdef CIFACE_USE_DINPUT - #include "InputCommon/ControllerInterface/DInput/DInput.h" +#include "InputCommon/ControllerInterface/DInput/DInput.h" #endif #ifdef CIFACE_USE_XLIB - #include "InputCommon/ControllerInterface/Xlib/Xlib.h" - #ifdef CIFACE_USE_X11_XINPUT2 - #include "InputCommon/ControllerInterface/Xlib/XInput2.h" - #endif +#include "InputCommon/ControllerInterface/Xlib/Xlib.h" +#ifdef CIFACE_USE_X11_XINPUT2 +#include "InputCommon/ControllerInterface/Xlib/XInput2.h" +#endif #endif #ifdef CIFACE_USE_OSX - #include "InputCommon/ControllerInterface/OSX/OSX.h" +#include "InputCommon/ControllerInterface/OSX/OSX.h" #endif #ifdef CIFACE_USE_SDL - #include "InputCommon/ControllerInterface/SDL/SDL.h" +#include "InputCommon/ControllerInterface/SDL/SDL.h" #endif #ifdef CIFACE_USE_ANDROID - #include "InputCommon/ControllerInterface/Android/Android.h" +#include "InputCommon/ControllerInterface/Android/Android.h" #endif #ifdef CIFACE_USE_EVDEV - #include "InputCommon/ControllerInterface/evdev/evdev.h" +#include "InputCommon/ControllerInterface/evdev/evdev.h" #endif #ifdef CIFACE_USE_PIPES - #include "InputCommon/ControllerInterface/Pipes/Pipes.h" +#include "InputCommon/ControllerInterface/Pipes/Pipes.h" #endif using namespace ciface::ExpressionParser; @@ -49,49 +49,49 @@ ControllerInterface g_controller_interface; // void ControllerInterface::Initialize(void* const hwnd) { - if (m_is_init) - return; + if (m_is_init) + return; - m_hwnd = hwnd; + m_hwnd = hwnd; #ifdef CIFACE_USE_DINPUT - ciface::DInput::Init(m_devices, (HWND)hwnd); + ciface::DInput::Init(m_devices, (HWND)hwnd); #endif #ifdef CIFACE_USE_XINPUT - ciface::XInput::Init(m_devices); + ciface::XInput::Init(m_devices); #endif #ifdef CIFACE_USE_XLIB - ciface::Xlib::Init(m_devices, hwnd); - #ifdef CIFACE_USE_X11_XINPUT2 - ciface::XInput2::Init(m_devices, hwnd); - #endif + ciface::Xlib::Init(m_devices, hwnd); +#ifdef CIFACE_USE_X11_XINPUT2 + ciface::XInput2::Init(m_devices, hwnd); +#endif #endif #ifdef CIFACE_USE_OSX - ciface::OSX::Init(m_devices, hwnd); + ciface::OSX::Init(m_devices, hwnd); #endif #ifdef CIFACE_USE_SDL - ciface::SDL::Init(m_devices); + ciface::SDL::Init(m_devices); #endif #ifdef CIFACE_USE_ANDROID - ciface::Android::Init(m_devices); + ciface::Android::Init(m_devices); #endif #ifdef CIFACE_USE_EVDEV - ciface::evdev::Init(m_devices); + ciface::evdev::Init(m_devices); #endif #ifdef CIFACE_USE_PIPES - ciface::Pipes::Init(m_devices); + ciface::Pipes::Init(m_devices); #endif - m_is_init = true; + m_is_init = true; } void ControllerInterface::Reinitialize() { - if (!m_is_init) - return; + if (!m_is_init) + return; - Shutdown(); - Initialize(m_hwnd); + Shutdown(); + Initialize(m_hwnd); } // @@ -101,42 +101,42 @@ void ControllerInterface::Reinitialize() // void ControllerInterface::Shutdown() { - if (!m_is_init) - return; + if (!m_is_init) + return; - for (ciface::Core::Device* d : m_devices) - { - // Set outputs to ZERO before destroying device - for (ciface::Core::Device::Output* o : d->Outputs()) - o->SetState(0); + for (ciface::Core::Device* d : m_devices) + { + // Set outputs to ZERO before destroying device + for (ciface::Core::Device::Output* o : d->Outputs()) + o->SetState(0); - // Delete device - delete d; - } + // Delete device + delete d; + } - m_devices.clear(); + m_devices.clear(); #ifdef CIFACE_USE_XINPUT - ciface::XInput::DeInit(); + ciface::XInput::DeInit(); #endif #ifdef CIFACE_USE_DINPUT - // nothing needed +// nothing needed #endif #ifdef CIFACE_USE_XLIB - // nothing needed +// nothing needed #endif #ifdef CIFACE_USE_OSX - ciface::OSX::DeInit(); + ciface::OSX::DeInit(); #endif #ifdef CIFACE_USE_SDL - // TODO: there seems to be some sort of memory leak with SDL, quit isn't freeing everything up - SDL_Quit(); + // TODO: there seems to be some sort of memory leak with SDL, quit isn't freeing everything up + SDL_Quit(); #endif #ifdef CIFACE_USE_ANDROID - // nothing needed +// nothing needed #endif - m_is_init = false; + m_is_init = false; } // @@ -146,8 +146,8 @@ void ControllerInterface::Shutdown() // void ControllerInterface::UpdateInput() { - for (ciface::Core::Device* d : m_devices) - d->UpdateInput(); + for (ciface::Core::Device* d : m_devices) + d->UpdateInput(); } // @@ -156,26 +156,27 @@ void ControllerInterface::UpdateInput() // Gets the state of an input reference // override function for ControlReference::State ... // -ControlState ControllerInterface::InputReference::State( const ControlState ignore ) +ControlState ControllerInterface::InputReference::State(const ControlState ignore) { - if (parsed_expression) - return parsed_expression->GetValue() * range; - else - return 0.0; + if (parsed_expression) + return parsed_expression->GetValue() * range; + else + return 0.0; } // // OutputReference :: State // // Set the state of all binded outputs -// overrides ControlReference::State .. combined them so I could make the GUI simple / inputs == same as outputs one list +// overrides ControlReference::State .. combined them so I could make the GUI simple / inputs == +// same as outputs one list // I was lazy and it works so watever // ControlState ControllerInterface::OutputReference::State(const ControlState state) { - if (parsed_expression) - parsed_expression->SetValue(state); - return 0.0; + if (parsed_expression) + parsed_expression->SetValue(state); + return 0.0; } // @@ -184,14 +185,14 @@ ControlState ControllerInterface::OutputReference::State(const ControlState stat // Updates a controlreference's binded devices/controls // need to call this to re-parse a control reference's expression after changing it // -void ControllerInterface::UpdateReference(ControllerInterface::ControlReference* ref - , const ciface::Core::DeviceQualifier& default_device) const +void ControllerInterface::UpdateReference(ControllerInterface::ControlReference* ref, + const ciface::Core::DeviceQualifier& default_device) const { - delete ref->parsed_expression; - ref->parsed_expression = nullptr; + delete ref->parsed_expression; + ref->parsed_expression = nullptr; - ControlFinder finder(*this, default_device, ref->is_input); - ref->parse_error = ParseExpression(ref->expression, finder, &ref->parsed_expression); + ControlFinder finder(*this, default_device, ref->is_input); + ref->parse_error = ParseExpression(ref->expression, finder, &ref->parsed_expression); } // @@ -204,71 +205,77 @@ void ControllerInterface::UpdateReference(ControllerInterface::ControlReference* // upon input, return pointer to detected Control // else return nullptr // -ciface::Core::Device::Control* ControllerInterface::InputReference::Detect(const unsigned int ms, ciface::Core::Device* const device) +ciface::Core::Device::Control* +ControllerInterface::InputReference::Detect(const unsigned int ms, + ciface::Core::Device* const device) { - unsigned int time = 0; - std::vector states(device->Inputs().size()); + unsigned int time = 0; + std::vector states(device->Inputs().size()); - if (device->Inputs().size() == 0) - return nullptr; + if (device->Inputs().size() == 0) + return nullptr; - // get starting state of all inputs, - // so we can ignore those that were activated at time of Detect start - std::vector::const_iterator - i = device->Inputs().begin(), - e = device->Inputs().end(); - for (std::vector::iterator state = states.begin(); i != e; ++i) - *state++ = ((*i)->GetState() > (1 - INPUT_DETECT_THRESHOLD)); + // get starting state of all inputs, + // so we can ignore those that were activated at time of Detect start + std::vector::const_iterator i = device->Inputs().begin(), + e = device->Inputs().end(); + for (std::vector::iterator state = states.begin(); i != e; ++i) + *state++ = ((*i)->GetState() > (1 - INPUT_DETECT_THRESHOLD)); - while (time < ms) - { - device->UpdateInput(); - i = device->Inputs().begin(); - for (std::vector::iterator state = states.begin(); i != e; ++i,++state) - { - // detected an input - if ((*i)->IsDetectable() && (*i)->GetState() > INPUT_DETECT_THRESHOLD) - { - // input was released at some point during Detect call - // return the detected input - if (false == *state) - return *i; - } - else if ((*i)->GetState() < (1 - INPUT_DETECT_THRESHOLD)) - { - *state = false; - } - } - Common::SleepCurrentThread(10); time += 10; - } + while (time < ms) + { + device->UpdateInput(); + i = device->Inputs().begin(); + for (std::vector::iterator state = states.begin(); i != e; ++i, ++state) + { + // detected an input + if ((*i)->IsDetectable() && (*i)->GetState() > INPUT_DETECT_THRESHOLD) + { + // input was released at some point during Detect call + // return the detected input + if (false == *state) + return *i; + } + else if ((*i)->GetState() < (1 - INPUT_DETECT_THRESHOLD)) + { + *state = false; + } + } + Common::SleepCurrentThread(10); + time += 10; + } - // no input was detected - return nullptr; + // no input was detected + return nullptr; } // // OutputReference :: Detect // -// Totally different from the inputReference detect / I have them combined so it was simpler to make the GUI. -// The GUI doesn't know the difference between an input and an output / it's odd but I was lazy and it was easy +// Totally different from the inputReference detect / I have them combined so it was simpler to make +// the GUI. +// The GUI doesn't know the difference between an input and an output / it's odd but I was lazy and +// it was easy // // set all binded outputs to power for x milliseconds return false // -ciface::Core::Device::Control* ControllerInterface::OutputReference::Detect(const unsigned int ms, ciface::Core::Device* const device) +ciface::Core::Device::Control* +ControllerInterface::OutputReference::Detect(const unsigned int ms, + ciface::Core::Device* const device) { - // ignore device + // ignore device - // don't hang if we don't even have any controls mapped - if (BoundCount() > 0) - { - State(1); - unsigned int slept = 0; + // don't hang if we don't even have any controls mapped + if (BoundCount() > 0) + { + State(1); + unsigned int slept = 0; - // this loop is to make stuff like flashing keyboard LEDs work - while (ms > (slept += 10)) - Common::SleepCurrentThread(10); + // this loop is to make stuff like flashing keyboard LEDs work + while (ms > (slept += 10)) + Common::SleepCurrentThread(10); - State(0); - } - return nullptr; + State(0); + } + return nullptr; } diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h index e324817dd3..25154ede40 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h @@ -17,26 +17,26 @@ // enable disable sources #ifdef _WIN32 - #define CIFACE_USE_XINPUT - #define CIFACE_USE_DINPUT +#define CIFACE_USE_XINPUT +#define CIFACE_USE_DINPUT #endif #if defined(HAVE_X11) && HAVE_X11 - #define CIFACE_USE_XLIB - #if defined(HAVE_X11_XINPUT2) && HAVE_X11_XINPUT2 - #define CIFACE_USE_X11_XINPUT2 - #endif +#define CIFACE_USE_XLIB +#if defined(HAVE_X11_XINPUT2) && HAVE_X11_XINPUT2 +#define CIFACE_USE_X11_XINPUT2 +#endif #endif #if defined(__APPLE__) - #define CIFACE_USE_OSX +#define CIFACE_USE_OSX #endif #if defined(HAVE_SDL) && HAVE_SDL - #define CIFACE_USE_SDL +#define CIFACE_USE_SDL #endif #if defined(HAVE_LIBEVDEV) && defined(HAVE_LIBUDEV) - #define CIFACE_USE_EVDEV +#define CIFACE_USE_EVDEV #endif #if defined(USE_PIPES) - #define CIFACE_USE_PIPES +#define CIFACE_USE_PIPES #endif // @@ -48,86 +48,87 @@ class ControllerInterface : public ciface::Core::DeviceContainer { public: - - // - // ControlReference - // - // These are what you create to actually use the inputs, InputReference or OutputReference. - // - // After being bound to devices and controls with ControllerInterface::UpdateReference, - // each one can link to multiple devices and controls - // when you change a ControlReference's expression, - // you must use ControllerInterface::UpdateReference on it to rebind controls - // - class ControlReference - { - friend class ControllerInterface; - public: - virtual ControlState State(const ControlState state = 0) = 0; - virtual ciface::Core::Device::Control* Detect(const unsigned int ms, ciface::Core::Device* const device) = 0; - - ControlState range; - std::string expression; - const bool is_input; - ciface::ExpressionParser::ExpressionParseStatus parse_error; - - virtual ~ControlReference() - { - delete parsed_expression; - } - - int BoundCount() - { - if (parsed_expression) - return parsed_expression->num_controls; - else - return 0; - } - - protected: - ControlReference(const bool _is_input) : range(1), is_input(_is_input), parsed_expression(nullptr) {} - ciface::ExpressionParser::Expression *parsed_expression; - }; - - // - // InputReference - // - // Control reference for inputs - // - class InputReference : public ControlReference - { - public: - InputReference() : ControlReference(true) {} - ControlState State(const ControlState state) override; - ciface::Core::Device::Control* Detect(const unsigned int ms, ciface::Core::Device* const device) override; - }; - - // - // OutputReference - // - // Control reference for outputs - // - class OutputReference : public ControlReference - { - public: - OutputReference() : ControlReference(false) {} - ControlState State(const ControlState state) override; - ciface::Core::Device::Control* Detect(const unsigned int ms, ciface::Core::Device* const device) override; - }; - - ControllerInterface() : m_is_init(false), m_hwnd(nullptr) {} - - void Initialize(void* const hwnd); - void Reinitialize(); - void Shutdown(); - bool IsInit() const { return m_is_init; } - - void UpdateReference(ControlReference* control, const ciface::Core::DeviceQualifier& default_device) const; - void UpdateInput(); + // + // ControlReference + // + // These are what you create to actually use the inputs, InputReference or OutputReference. + // + // After being bound to devices and controls with ControllerInterface::UpdateReference, + // each one can link to multiple devices and controls + // when you change a ControlReference's expression, + // you must use ControllerInterface::UpdateReference on it to rebind controls + // + class ControlReference + { + friend class ControllerInterface; + + public: + virtual ControlState State(const ControlState state = 0) = 0; + virtual ciface::Core::Device::Control* Detect(const unsigned int ms, + ciface::Core::Device* const device) = 0; + + ControlState range; + std::string expression; + const bool is_input; + ciface::ExpressionParser::ExpressionParseStatus parse_error; + + virtual ~ControlReference() { delete parsed_expression; } + int BoundCount() + { + if (parsed_expression) + return parsed_expression->num_controls; + else + return 0; + } + + protected: + ControlReference(const bool _is_input) + : range(1), is_input(_is_input), parsed_expression(nullptr) + { + } + ciface::ExpressionParser::Expression* parsed_expression; + }; + + // + // InputReference + // + // Control reference for inputs + // + class InputReference : public ControlReference + { + public: + InputReference() : ControlReference(true) {} + ControlState State(const ControlState state) override; + ciface::Core::Device::Control* Detect(const unsigned int ms, + ciface::Core::Device* const device) override; + }; + + // + // OutputReference + // + // Control reference for outputs + // + class OutputReference : public ControlReference + { + public: + OutputReference() : ControlReference(false) {} + ControlState State(const ControlState state) override; + ciface::Core::Device::Control* Detect(const unsigned int ms, + ciface::Core::Device* const device) override; + }; + + ControllerInterface() : m_is_init(false), m_hwnd(nullptr) {} + void Initialize(void* const hwnd); + void Reinitialize(); + void Shutdown(); + bool IsInit() const { return m_is_init; } + void UpdateReference(ControlReference* control, + const ciface::Core::DeviceQualifier& default_device) const; + void UpdateInput(); private: - bool m_is_init; - void* m_hwnd; + bool m_is_init; + void* m_hwnd; }; extern ControllerInterface g_controller_interface; diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp index 4a68474618..09227b5932 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp @@ -16,50 +16,47 @@ namespace ciface { namespace DInput { - BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) { - ((std::list*)pvRef)->push_back(*lpddoi); - return DIENUM_CONTINUE; + ((std::list*)pvRef)->push_back(*lpddoi); + return DIENUM_CONTINUE; } BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) { - ((std::list*)pvRef)->push_back(*lpddi); - return DIENUM_CONTINUE; + ((std::list*)pvRef)->push_back(*lpddi); + return DIENUM_CONTINUE; } std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device) { - DIPROPSTRING str = {}; - str.diph.dwSize = sizeof(str); - str.diph.dwHeaderSize = sizeof(str.diph); - str.diph.dwHow = DIPH_DEVICE; - - std::string result; - if (SUCCEEDED(device->GetProperty(DIPROP_PRODUCTNAME, &str.diph))) - { - result = StripSpaces(UTF16ToUTF8(str.wsz)); - } - - return result; + DIPROPSTRING str = {}; + str.diph.dwSize = sizeof(str); + str.diph.dwHeaderSize = sizeof(str.diph); + str.diph.dwHow = DIPH_DEVICE; + + std::string result; + if (SUCCEEDED(device->GetProperty(DIPROP_PRODUCTNAME, &str.diph))) + { + result = StripSpaces(UTF16ToUTF8(str.wsz)); + } + + return result; } void Init(std::vector& devices, HWND hwnd) { - IDirectInput8* idi8; - if (FAILED(DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, - IID_IDirectInput8, (LPVOID*)&idi8, nullptr))) - { - return; - } + IDirectInput8* idi8; + if (FAILED(DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8, + (LPVOID*)&idi8, nullptr))) + { + return; + } - InitKeyboardMouse(idi8, devices, hwnd); - InitJoystick(idi8, devices, hwnd); - - idi8->Release(); + InitKeyboardMouse(idi8, devices, hwnd); + InitJoystick(idi8, devices, hwnd); + idi8->Release(); } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.h b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.h index 1823499e98..2f5e2f83a7 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.h +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.h @@ -9,20 +9,18 @@ #include #include -#include "InputCommon/ControllerInterface/Device.h" #include "InputCommon/ControllerInterface/DInput/DInput8.h" +#include "InputCommon/ControllerInterface/Device.h" namespace ciface { namespace DInput { - -//BOOL CALLBACK DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef); +// BOOL CALLBACK DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef); BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef); BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device); void Init(std::vector& devices, HWND hwnd); - } } diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp index aa1e972126..bf2c1f3e7e 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.cpp @@ -14,268 +14,270 @@ namespace ciface { namespace DInput { - #define DATA_BUFFER_SIZE 32 void InitJoystick(IDirectInput8* const idi8, std::vector& devices, HWND hwnd) { - std::list joysticks; - idi8->EnumDevices(DI8DEVCLASS_GAMECTRL, DIEnumDevicesCallback, (LPVOID)&joysticks, DIEDFL_ATTACHEDONLY); - - // this is used to number the joysticks - // multiple joysticks with the same name shall get unique ids starting at 0 - std::map< std::basic_string, int> name_counts; - - std::vector xinput_guids; - GetXInputGUIDS(&xinput_guids); - - for (DIDEVICEINSTANCE& joystick : joysticks) - { - // skip XInput Devices - if (std::find(xinput_guids.begin(), xinput_guids.end(), joystick.guidProduct.Data1) != xinput_guids.end()) - { - continue; - } - - LPDIRECTINPUTDEVICE8 js_device; - if (SUCCEEDED(idi8->CreateDevice(joystick.guidInstance, &js_device, nullptr))) - { - if (SUCCEEDED(js_device->SetDataFormat(&c_dfDIJoystick))) - { - if (FAILED(js_device->SetCooperativeLevel(GetAncestor(hwnd, GA_ROOT), DISCL_BACKGROUND | DISCL_EXCLUSIVE))) - { - //PanicAlert("SetCooperativeLevel(DISCL_EXCLUSIVE) failed!"); - // fall back to non-exclusive mode, with no rumble - if (FAILED(js_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) - { - //PanicAlert("SetCooperativeLevel failed!"); - js_device->Release(); - continue; - } - } - - Joystick* js = new Joystick(/*&*i, */js_device, name_counts[joystick.tszInstanceName]++); - // only add if it has some inputs/outputs - if (js->Inputs().size() || js->Outputs().size()) - devices.push_back(js); - else - delete js; - } - else - { - //PanicAlert("SetDataFormat failed!"); - js_device->Release(); - } - } - } + std::list joysticks; + idi8->EnumDevices(DI8DEVCLASS_GAMECTRL, DIEnumDevicesCallback, (LPVOID)&joysticks, + DIEDFL_ATTACHEDONLY); + + // this is used to number the joysticks + // multiple joysticks with the same name shall get unique ids starting at 0 + std::map, int> name_counts; + + std::vector xinput_guids; + GetXInputGUIDS(&xinput_guids); + + for (DIDEVICEINSTANCE& joystick : joysticks) + { + // skip XInput Devices + if (std::find(xinput_guids.begin(), xinput_guids.end(), joystick.guidProduct.Data1) != + xinput_guids.end()) + { + continue; + } + + LPDIRECTINPUTDEVICE8 js_device; + if (SUCCEEDED(idi8->CreateDevice(joystick.guidInstance, &js_device, nullptr))) + { + if (SUCCEEDED(js_device->SetDataFormat(&c_dfDIJoystick))) + { + if (FAILED(js_device->SetCooperativeLevel(GetAncestor(hwnd, GA_ROOT), + DISCL_BACKGROUND | DISCL_EXCLUSIVE))) + { + // PanicAlert("SetCooperativeLevel(DISCL_EXCLUSIVE) failed!"); + // fall back to non-exclusive mode, with no rumble + if (FAILED( + js_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) + { + // PanicAlert("SetCooperativeLevel failed!"); + js_device->Release(); + continue; + } + } + + Joystick* js = new Joystick(/*&*i, */ js_device, name_counts[joystick.tszInstanceName]++); + // only add if it has some inputs/outputs + if (js->Inputs().size() || js->Outputs().size()) + devices.push_back(js); + else + delete js; + } + else + { + // PanicAlert("SetDataFormat failed!"); + js_device->Release(); + } + } + } } -Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVICE8 device, const unsigned int index ) - : m_device(device) - , m_index(index) - //, m_name(TStringToString(lpddi->tszInstanceName)) +Joystick::Joystick(/*const LPCDIDEVICEINSTANCE lpddi, */ const LPDIRECTINPUTDEVICE8 device, + const unsigned int index) + : m_device(device), m_index(index) +//, m_name(TStringToString(lpddi->tszInstanceName)) { - // seems this needs to be done before GetCapabilities - // polled or buffered data - DIPROPDWORD dipdw; - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = DATA_BUFFER_SIZE; - // set the buffer size, - // if we can't set the property, we can't use buffered data - m_buffered = SUCCEEDED(m_device->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)); - - // seems this needs to be done after SetProperty of buffer size - m_device->Acquire(); - - // get joystick caps - DIDEVCAPS js_caps; - js_caps.dwSize = sizeof(js_caps); - if (FAILED(m_device->GetCapabilities(&js_caps))) - return; - - // max of 32 buttons and 4 hats / the limit of the data format I am using - js_caps.dwButtons = std::min((DWORD)32, js_caps.dwButtons); - js_caps.dwPOVs = std::min((DWORD)4, js_caps.dwPOVs); - - //m_must_poll = (js_caps.dwFlags & DIDC_POLLEDDATAFORMAT) != 0; - - // buttons - for (u8 i = 0; i != js_caps.dwButtons; ++i) - AddInput(new Button(i, m_state_in.rgbButtons[i])); - - // hats - for (u8 i = 0; i != js_caps.dwPOVs; ++i) - { - // each hat gets 4 input instances associated with it, (up down left right) - for (u8 d = 0; d != 4; ++d) - AddInput(new Hat(i, m_state_in.rgdwPOV[i], d)); - } - - // get up to 6 axes and 2 sliders - DIPROPRANGE range; - range.diph.dwSize = sizeof(range); - range.diph.dwHeaderSize = sizeof(range.diph); - range.diph.dwHow = DIPH_BYOFFSET; - // screw EnumObjects, just go through all the axis offsets and try to GetProperty - // this should be more foolproof, less code, and probably faster - for (unsigned int offset = 0; offset < DIJOFS_BUTTON(0) / sizeof(LONG); ++offset) - { - range.diph.dwObj = offset * sizeof(LONG); - // try to set some nice power of 2 values (128) to match the GameCube controls - range.lMin = -(1 << 7); - range.lMax = (1 << 7); - m_device->SetProperty(DIPROP_RANGE, &range.diph); - // but I guess not all devices support setting range - // so I getproperty right afterward incase it didn't set. - // This also checks that the axis is present - if (SUCCEEDED(m_device->GetProperty(DIPROP_RANGE, &range.diph))) - { - const LONG base = (range.lMin + range.lMax) / 2; - const LONG& ax = (&m_state_in.lX)[offset]; - - // each axis gets a negative and a positive input instance associated with it - AddAnalogInputs(new Axis(offset, ax, base, range.lMin-base), - new Axis(offset, ax, base, range.lMax-base)); - } - } - - // force feedback - std::list objects; - if (SUCCEEDED(m_device->EnumObjects(DIEnumDeviceObjectsCallback, (LPVOID)&objects, DIDFT_AXIS))) - { - InitForceFeedback(m_device, (int)objects.size()); - } - - ZeroMemory(&m_state_in, sizeof(m_state_in)); - // set hats to center - memset(m_state_in.rgdwPOV, 0xFF, sizeof(m_state_in.rgdwPOV)); + // seems this needs to be done before GetCapabilities + // polled or buffered data + DIPROPDWORD dipdw; + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = DATA_BUFFER_SIZE; + // set the buffer size, + // if we can't set the property, we can't use buffered data + m_buffered = SUCCEEDED(m_device->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)); + + // seems this needs to be done after SetProperty of buffer size + m_device->Acquire(); + + // get joystick caps + DIDEVCAPS js_caps; + js_caps.dwSize = sizeof(js_caps); + if (FAILED(m_device->GetCapabilities(&js_caps))) + return; + + // max of 32 buttons and 4 hats / the limit of the data format I am using + js_caps.dwButtons = std::min((DWORD)32, js_caps.dwButtons); + js_caps.dwPOVs = std::min((DWORD)4, js_caps.dwPOVs); + + // m_must_poll = (js_caps.dwFlags & DIDC_POLLEDDATAFORMAT) != 0; + + // buttons + for (u8 i = 0; i != js_caps.dwButtons; ++i) + AddInput(new Button(i, m_state_in.rgbButtons[i])); + + // hats + for (u8 i = 0; i != js_caps.dwPOVs; ++i) + { + // each hat gets 4 input instances associated with it, (up down left right) + for (u8 d = 0; d != 4; ++d) + AddInput(new Hat(i, m_state_in.rgdwPOV[i], d)); + } + + // get up to 6 axes and 2 sliders + DIPROPRANGE range; + range.diph.dwSize = sizeof(range); + range.diph.dwHeaderSize = sizeof(range.diph); + range.diph.dwHow = DIPH_BYOFFSET; + // screw EnumObjects, just go through all the axis offsets and try to GetProperty + // this should be more foolproof, less code, and probably faster + for (unsigned int offset = 0; offset < DIJOFS_BUTTON(0) / sizeof(LONG); ++offset) + { + range.diph.dwObj = offset * sizeof(LONG); + // try to set some nice power of 2 values (128) to match the GameCube controls + range.lMin = -(1 << 7); + range.lMax = (1 << 7); + m_device->SetProperty(DIPROP_RANGE, &range.diph); + // but I guess not all devices support setting range + // so I getproperty right afterward incase it didn't set. + // This also checks that the axis is present + if (SUCCEEDED(m_device->GetProperty(DIPROP_RANGE, &range.diph))) + { + const LONG base = (range.lMin + range.lMax) / 2; + const LONG& ax = (&m_state_in.lX)[offset]; + + // each axis gets a negative and a positive input instance associated with it + AddAnalogInputs(new Axis(offset, ax, base, range.lMin - base), + new Axis(offset, ax, base, range.lMax - base)); + } + } + + // force feedback + std::list objects; + if (SUCCEEDED(m_device->EnumObjects(DIEnumDeviceObjectsCallback, (LPVOID)&objects, DIDFT_AXIS))) + { + InitForceFeedback(m_device, (int)objects.size()); + } + + ZeroMemory(&m_state_in, sizeof(m_state_in)); + // set hats to center + memset(m_state_in.rgdwPOV, 0xFF, sizeof(m_state_in.rgdwPOV)); } Joystick::~Joystick() { - m_device->Unacquire(); - m_device->Release(); + m_device->Unacquire(); + m_device->Release(); } std::string Joystick::GetName() const { - return GetDeviceName(m_device); + return GetDeviceName(m_device); } int Joystick::GetId() const { - return m_index; + return m_index; } std::string Joystick::GetSource() const { - return DINPUT_SOURCE_NAME; + return DINPUT_SOURCE_NAME; } // update IO void Joystick::UpdateInput() { - HRESULT hr = 0; - - // just always poll, - // MSDN says if this isn't needed it doesn't do anything - m_device->Poll(); - - if (m_buffered) - { - DIDEVICEOBJECTDATA evtbuf[DATA_BUFFER_SIZE]; - DWORD numevents = DATA_BUFFER_SIZE; - hr = m_device->GetDeviceData(sizeof(*evtbuf), evtbuf, &numevents, 0); - - if (SUCCEEDED(hr)) - { - for (LPDIDEVICEOBJECTDATA evt = evtbuf; evt != (evtbuf + numevents); ++evt) - { - // all the buttons are at the end of the data format - // they are bytes rather than longs - if (evt->dwOfs < DIJOFS_BUTTON(0)) - *(DWORD*)(((BYTE*)&m_state_in) + evt->dwOfs) = evt->dwData; - else - ((BYTE*)&m_state_in)[evt->dwOfs] = (BYTE)evt->dwData; - } - - // seems like this needs to be done maybe... - if (DI_BUFFEROVERFLOW == hr) - hr = m_device->GetDeviceState(sizeof(m_state_in), &m_state_in); - } - } - else - { - hr = m_device->GetDeviceState(sizeof(m_state_in), &m_state_in); - } - - // try reacquire if input lost - if (DIERR_INPUTLOST == hr || DIERR_NOTACQUIRED == hr) - m_device->Acquire(); + HRESULT hr = 0; + + // just always poll, + // MSDN says if this isn't needed it doesn't do anything + m_device->Poll(); + + if (m_buffered) + { + DIDEVICEOBJECTDATA evtbuf[DATA_BUFFER_SIZE]; + DWORD numevents = DATA_BUFFER_SIZE; + hr = m_device->GetDeviceData(sizeof(*evtbuf), evtbuf, &numevents, 0); + + if (SUCCEEDED(hr)) + { + for (LPDIDEVICEOBJECTDATA evt = evtbuf; evt != (evtbuf + numevents); ++evt) + { + // all the buttons are at the end of the data format + // they are bytes rather than longs + if (evt->dwOfs < DIJOFS_BUTTON(0)) + *(DWORD*)(((BYTE*)&m_state_in) + evt->dwOfs) = evt->dwData; + else + ((BYTE*)&m_state_in)[evt->dwOfs] = (BYTE)evt->dwData; + } + + // seems like this needs to be done maybe... + if (DI_BUFFEROVERFLOW == hr) + hr = m_device->GetDeviceState(sizeof(m_state_in), &m_state_in); + } + } + else + { + hr = m_device->GetDeviceState(sizeof(m_state_in), &m_state_in); + } + + // try reacquire if input lost + if (DIERR_INPUTLOST == hr || DIERR_NOTACQUIRED == hr) + m_device->Acquire(); } // get name std::string Joystick::Button::GetName() const { - std::ostringstream ss; - ss << "Button " << (int)m_index; - return ss.str(); + std::ostringstream ss; + ss << "Button " << (int)m_index; + return ss.str(); } std::string Joystick::Axis::GetName() const { - std::ostringstream ss; - // axis - if (m_index < 6) - { - ss << "Axis " << (char)('X' + (m_index % 3)); - if (m_index > 2) - ss << 'r'; - } - // slider - else - { - ss << "Slider " << (int)(m_index - 6); - } - - ss << (m_range < 0 ? '-' : '+'); - return ss.str(); + std::ostringstream ss; + // axis + if (m_index < 6) + { + ss << "Axis " << (char)('X' + (m_index % 3)); + if (m_index > 2) + ss << 'r'; + } + // slider + else + { + ss << "Slider " << (int)(m_index - 6); + } + + ss << (m_range < 0 ? '-' : '+'); + return ss.str(); } std::string Joystick::Hat::GetName() const { - static char tmpstr[] = "Hat . ."; - tmpstr[4] = (char)('0' + m_index); - tmpstr[6] = "NESW"[m_direction]; - return tmpstr; + static char tmpstr[] = "Hat . ."; + tmpstr[4] = (char)('0' + m_index); + tmpstr[6] = "NESW"[m_direction]; + return tmpstr; } // get / set state ControlState Joystick::Axis::GetState() const { - return std::max(0.0, ControlState(m_axis - m_base) / m_range); + return std::max(0.0, ControlState(m_axis - m_base) / m_range); } ControlState Joystick::Button::GetState() const { - return ControlState(m_button > 0); + return ControlState(m_button > 0); } ControlState Joystick::Hat::GetState() const { - // can this func be simplified ? - // hat centered code from MSDN - if (0xFFFF == LOWORD(m_hat)) - return 0; + // can this func be simplified ? + // hat centered code from MSDN + if (0xFFFF == LOWORD(m_hat)) + return 0; - return (abs((int)(m_hat / 4500 - m_direction * 2 + 8) % 8 - 4) > 2); + return (abs((int)(m_hat / 4500 - m_direction * 2 + 8) % 8 - 4) > 2); } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h index 3064051101..9a14e910de 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputJoystick.h @@ -11,64 +11,71 @@ namespace ciface { namespace DInput { - void InitJoystick(IDirectInput8* const idi8, std::vector& devices, HWND hwnd); class Joystick : public ForceFeedback::ForceFeedbackDevice { private: - class Button : public Input - { - public: - Button(u8 index, const BYTE& button) : m_button(button), m_index(index) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const BYTE& m_button; - const u8 m_index; - }; + class Button : public Input + { + public: + Button(u8 index, const BYTE& button) : m_button(button), m_index(index) {} + std::string GetName() const override; + ControlState GetState() const override; + + private: + const BYTE& m_button; + const u8 m_index; + }; + + class Axis : public Input + { + public: + Axis(u8 index, const LONG& axis, LONG base, LONG range) + : m_axis(axis), m_base(base), m_range(range), m_index(index) + { + } + std::string GetName() const override; + ControlState GetState() const override; - class Axis : public Input - { - public: - Axis(u8 index, const LONG& axis, LONG base, LONG range) : m_axis(axis), m_base(base), m_range(range), m_index(index) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const LONG& m_axis; - const LONG m_base, m_range; - const u8 m_index; - }; + private: + const LONG& m_axis; + const LONG m_base, m_range; + const u8 m_index; + }; - class Hat : public Input - { - public: - Hat(u8 index, const DWORD& hat, u8 direction) : m_hat(hat), m_direction(direction), m_index(index) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const DWORD& m_hat; - const u8 m_index, m_direction; - }; + class Hat : public Input + { + public: + Hat(u8 index, const DWORD& hat, u8 direction) + : m_hat(hat), m_direction(direction), m_index(index) + { + } + std::string GetName() const override; + ControlState GetState() const override; + + private: + const DWORD& m_hat; + const u8 m_index, m_direction; + }; public: - void UpdateInput() override; + void UpdateInput() override; - Joystick(const LPDIRECTINPUTDEVICE8 device, const unsigned int index); - ~Joystick(); + Joystick(const LPDIRECTINPUTDEVICE8 device, const unsigned int index); + ~Joystick(); - std::string GetName() const override; - int GetId() const override; - std::string GetSource() const override; + std::string GetName() const override; + int GetId() const override; + std::string GetSource() const override; private: - const LPDIRECTINPUTDEVICE8 m_device; - const unsigned int m_index; + const LPDIRECTINPUTDEVICE8 m_device; + const unsigned int m_index; - DIJOYSTATE m_state_in; + DIJOYSTATE m_state_in; - bool m_buffered; + bool m_buffered; }; - } } diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp index 2111f24d62..92c8514825 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp @@ -7,27 +7,25 @@ #include "InputCommon/ControllerInterface/DInput/DInput.h" #include "InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h" - // (lower would be more sensitive) user can lower sensitivity by setting range - // seems decent here ( at 8 ), I don't think anyone would need more sensitive than this - // and user can lower it much farther than they would want to with the range -#define MOUSE_AXIS_SENSITIVITY 8 +// (lower would be more sensitive) user can lower sensitivity by setting range +// seems decent here ( at 8 ), I don't think anyone would need more sensitive than this +// and user can lower it much farther than they would want to with the range +#define MOUSE_AXIS_SENSITIVITY 8 - // if input hasn't been received for this many ms, mouse input will be skipped - // otherwise it is just some crazy value -#define DROP_INPUT_TIME 250 +// if input hasn't been received for this many ms, mouse input will be skipped +// otherwise it is just some crazy value +#define DROP_INPUT_TIME 250 namespace ciface { namespace DInput { - static const struct { - const BYTE code; - const char* const name; -} named_keys[] = -{ -#include "InputCommon/ControllerInterface/DInput/NamedKeys.h" // NOLINT + const BYTE code; + const char* const name; +} named_keys[] = { +#include "InputCommon/ControllerInterface/DInput/NamedKeys.h" // NOLINT }; // lil silly @@ -35,223 +33,225 @@ static HWND m_hwnd; void InitKeyboardMouse(IDirectInput8* const idi8, std::vector& devices, HWND _hwnd) { - m_hwnd = _hwnd; - - // mouse and keyboard are a combined device, to allow shift+click and stuff - // if that's dumb, I will make a VirtualDevice class that just uses ranges of inputs/outputs from other devices - // so there can be a separated Keyboard and mouse, as well as combined KeyboardMouse - - LPDIRECTINPUTDEVICE8 kb_device = nullptr; - LPDIRECTINPUTDEVICE8 mo_device = nullptr; - - if (SUCCEEDED(idi8->CreateDevice( GUID_SysKeyboard, &kb_device, nullptr))) - { - if (SUCCEEDED(kb_device->SetDataFormat(&c_dfDIKeyboard))) - { - if (SUCCEEDED(kb_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) - { - if (SUCCEEDED(idi8->CreateDevice( GUID_SysMouse, &mo_device, nullptr ))) - { - if (SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2))) - { - if (SUCCEEDED(mo_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) - { - devices.push_back(new KeyboardMouse(kb_device, mo_device)); - return; - } - } - } - } - } - } - - if (kb_device) - kb_device->Release(); - if (mo_device) - mo_device->Release(); + m_hwnd = _hwnd; + + // mouse and keyboard are a combined device, to allow shift+click and stuff + // if that's dumb, I will make a VirtualDevice class that just uses ranges of inputs/outputs from + // other devices + // so there can be a separated Keyboard and mouse, as well as combined KeyboardMouse + + LPDIRECTINPUTDEVICE8 kb_device = nullptr; + LPDIRECTINPUTDEVICE8 mo_device = nullptr; + + if (SUCCEEDED(idi8->CreateDevice(GUID_SysKeyboard, &kb_device, nullptr))) + { + if (SUCCEEDED(kb_device->SetDataFormat(&c_dfDIKeyboard))) + { + if (SUCCEEDED(kb_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) + { + if (SUCCEEDED(idi8->CreateDevice(GUID_SysMouse, &mo_device, nullptr))) + { + if (SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2))) + { + if (SUCCEEDED( + mo_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) + { + devices.push_back(new KeyboardMouse(kb_device, mo_device)); + return; + } + } + } + } + } + } + + if (kb_device) + kb_device->Release(); + if (mo_device) + mo_device->Release(); } KeyboardMouse::~KeyboardMouse() { - // kb - m_kb_device->Unacquire(); - m_kb_device->Release(); - // mouse - m_mo_device->Unacquire(); - m_mo_device->Release(); + // kb + m_kb_device->Unacquire(); + m_kb_device->Release(); + // mouse + m_mo_device->Unacquire(); + m_mo_device->Release(); } -KeyboardMouse::KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device, const LPDIRECTINPUTDEVICE8 mo_device) - : m_kb_device(kb_device) - , m_mo_device(mo_device) +KeyboardMouse::KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device, + const LPDIRECTINPUTDEVICE8 mo_device) + : m_kb_device(kb_device), m_mo_device(mo_device) { - m_kb_device->Acquire(); - m_mo_device->Acquire(); - - m_last_update = GetTickCount(); - - ZeroMemory(&m_state_in, sizeof(m_state_in)); - - // KEYBOARD - // add keys - for (u8 i = 0; i < sizeof(named_keys)/sizeof(*named_keys); ++i) - AddInput(new Key(i, m_state_in.keyboard[named_keys[i].code])); - - // MOUSE - // get caps - DIDEVCAPS mouse_caps; - ZeroMemory( &mouse_caps, sizeof(mouse_caps) ); - mouse_caps.dwSize = sizeof(mouse_caps); - m_mo_device->GetCapabilities(&mouse_caps); - // mouse buttons - for (u8 i = 0; i < mouse_caps.dwButtons; ++i) - AddInput(new Button(i, m_state_in.mouse.rgbButtons[i])); - // mouse axes - for (unsigned int i = 0; i < mouse_caps.dwAxes; ++i) - { - const LONG& ax = (&m_state_in.mouse.lX)[i]; - - // each axis gets a negative and a positive input instance associated with it - AddInput(new Axis(i, ax, (2==i) ? -1 : -MOUSE_AXIS_SENSITIVITY)); - AddInput(new Axis(i, ax, -(2==i) ? 1 : MOUSE_AXIS_SENSITIVITY)); - } - // cursor, with a hax for-loop - for (unsigned int i=0; i<4; ++i) - AddInput(new Cursor(!!(i&2), (&m_state_in.cursor.x)[i/2], !!(i&1))); + m_kb_device->Acquire(); + m_mo_device->Acquire(); + + m_last_update = GetTickCount(); + + ZeroMemory(&m_state_in, sizeof(m_state_in)); + + // KEYBOARD + // add keys + for (u8 i = 0; i < sizeof(named_keys) / sizeof(*named_keys); ++i) + AddInput(new Key(i, m_state_in.keyboard[named_keys[i].code])); + + // MOUSE + // get caps + DIDEVCAPS mouse_caps; + ZeroMemory(&mouse_caps, sizeof(mouse_caps)); + mouse_caps.dwSize = sizeof(mouse_caps); + m_mo_device->GetCapabilities(&mouse_caps); + // mouse buttons + for (u8 i = 0; i < mouse_caps.dwButtons; ++i) + AddInput(new Button(i, m_state_in.mouse.rgbButtons[i])); + // mouse axes + for (unsigned int i = 0; i < mouse_caps.dwAxes; ++i) + { + const LONG& ax = (&m_state_in.mouse.lX)[i]; + + // each axis gets a negative and a positive input instance associated with it + AddInput(new Axis(i, ax, (2 == i) ? -1 : -MOUSE_AXIS_SENSITIVITY)); + AddInput(new Axis(i, ax, -(2 == i) ? 1 : MOUSE_AXIS_SENSITIVITY)); + } + // cursor, with a hax for-loop + for (unsigned int i = 0; i < 4; ++i) + AddInput(new Cursor(!!(i & 2), (&m_state_in.cursor.x)[i / 2], !!(i & 1))); } void GetMousePos(ControlState* const x, ControlState* const y) { - POINT point = { 1, 1 }; - GetCursorPos(&point); - // Get the cursor position relative to the upper left corner of the current window (separate or render to main) - HWND hwnd = WindowFromPoint(point); - DWORD processId; - GetWindowThreadProcessId(hwnd, &processId); - if (processId == GetCurrentProcessId()) - { - ScreenToClient(hwnd, &point); - - // Get the size of the current window. (In my case Rect.top and Rect.left was zero.) - RECT rect; - GetClientRect(hwnd, &rect); - // Width and height is the size of the rendering window - unsigned int win_width = rect.right - rect.left; - unsigned int win_height = rect.bottom - rect.top; - - // Return the mouse position as a range from -1 to 1 - *x = (ControlState)point.x / (ControlState)win_width * 2 - 1; - *y = (ControlState)point.y / (ControlState)win_height * 2 - 1; - } - else - { - *x = (ControlState)1; - *y = (ControlState)1; - } + POINT point = {1, 1}; + GetCursorPos(&point); + // Get the cursor position relative to the upper left corner of the current window (separate or + // render to main) + HWND hwnd = WindowFromPoint(point); + DWORD processId; + GetWindowThreadProcessId(hwnd, &processId); + if (processId == GetCurrentProcessId()) + { + ScreenToClient(hwnd, &point); + + // Get the size of the current window. (In my case Rect.top and Rect.left was zero.) + RECT rect; + GetClientRect(hwnd, &rect); + // Width and height is the size of the rendering window + unsigned int win_width = rect.right - rect.left; + unsigned int win_height = rect.bottom - rect.top; + + // Return the mouse position as a range from -1 to 1 + *x = (ControlState)point.x / (ControlState)win_width * 2 - 1; + *y = (ControlState)point.y / (ControlState)win_height * 2 - 1; + } + else + { + *x = (ControlState)1; + *y = (ControlState)1; + } } void KeyboardMouse::UpdateInput() { - DIMOUSESTATE2 tmp_mouse; + DIMOUSESTATE2 tmp_mouse; - // if mouse position hasn't been updated in a short while, skip a dev state - DWORD cur_time = GetTickCount(); - if (cur_time - m_last_update > DROP_INPUT_TIME) - { - // set axes to zero - ZeroMemory(&m_state_in.mouse, sizeof(m_state_in.mouse)); - // skip this input state - m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse); - } + // if mouse position hasn't been updated in a short while, skip a dev state + DWORD cur_time = GetTickCount(); + if (cur_time - m_last_update > DROP_INPUT_TIME) + { + // set axes to zero + ZeroMemory(&m_state_in.mouse, sizeof(m_state_in.mouse)); + // skip this input state + m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse); + } - m_last_update = cur_time; + m_last_update = cur_time; - HRESULT kb_hr = m_kb_device->GetDeviceState(sizeof(m_state_in.keyboard), &m_state_in.keyboard); - HRESULT mo_hr = m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse); + HRESULT kb_hr = m_kb_device->GetDeviceState(sizeof(m_state_in.keyboard), &m_state_in.keyboard); + HRESULT mo_hr = m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse); - if (DIERR_INPUTLOST == kb_hr || DIERR_NOTACQUIRED == kb_hr) - m_kb_device->Acquire(); + if (DIERR_INPUTLOST == kb_hr || DIERR_NOTACQUIRED == kb_hr) + m_kb_device->Acquire(); - if (DIERR_INPUTLOST == mo_hr || DIERR_NOTACQUIRED == mo_hr) - m_mo_device->Acquire(); + if (DIERR_INPUTLOST == mo_hr || DIERR_NOTACQUIRED == mo_hr) + m_mo_device->Acquire(); - if (SUCCEEDED(kb_hr) && SUCCEEDED(mo_hr)) - { - // need to smooth out the axes, otherwise it doesn't work for shit - for (unsigned int i = 0; i < 3; ++i) - ((&m_state_in.mouse.lX)[i] += (&tmp_mouse.lX)[i]) /= 2; + if (SUCCEEDED(kb_hr) && SUCCEEDED(mo_hr)) + { + // need to smooth out the axes, otherwise it doesn't work for shit + for (unsigned int i = 0; i < 3; ++i) + ((&m_state_in.mouse.lX)[i] += (&tmp_mouse.lX)[i]) /= 2; - // copy over the buttons - memcpy(m_state_in.mouse.rgbButtons, tmp_mouse.rgbButtons, sizeof(m_state_in.mouse.rgbButtons)); + // copy over the buttons + memcpy(m_state_in.mouse.rgbButtons, tmp_mouse.rgbButtons, sizeof(m_state_in.mouse.rgbButtons)); - // update mouse cursor - GetMousePos(&m_state_in.cursor.x, &m_state_in.cursor.y); - } + // update mouse cursor + GetMousePos(&m_state_in.cursor.x, &m_state_in.cursor.y); + } } std::string KeyboardMouse::GetName() const { - return "Keyboard Mouse"; + return "Keyboard Mouse"; } int KeyboardMouse::GetId() const { - // should this be -1, idk - return 0; + // should this be -1, idk + return 0; } std::string KeyboardMouse::GetSource() const { - return DINPUT_SOURCE_NAME; + return DINPUT_SOURCE_NAME; } // names std::string KeyboardMouse::Key::GetName() const { - return named_keys[m_index].name; + return named_keys[m_index].name; } std::string KeyboardMouse::Button::GetName() const { - return std::string("Click ") + char('0' + m_index); + return std::string("Click ") + char('0' + m_index); } std::string KeyboardMouse::Axis::GetName() const { - static char tmpstr[] = "Axis .."; - tmpstr[5] = (char)('X' + m_index); - tmpstr[6] = (m_range<0 ? '-' : '+'); - return tmpstr; + static char tmpstr[] = "Axis .."; + tmpstr[5] = (char)('X' + m_index); + tmpstr[6] = (m_range < 0 ? '-' : '+'); + return tmpstr; } std::string KeyboardMouse::Cursor::GetName() const { - static char tmpstr[] = "Cursor .."; - tmpstr[7] = (char)('X' + m_index); - tmpstr[8] = (m_positive ? '+' : '-'); - return tmpstr; + static char tmpstr[] = "Cursor .."; + tmpstr[7] = (char)('X' + m_index); + tmpstr[8] = (m_positive ? '+' : '-'); + return tmpstr; } // get/set state ControlState KeyboardMouse::Key::GetState() const { - return (m_key != 0); + return (m_key != 0); } ControlState KeyboardMouse::Button::GetState() const { - return (m_button != 0); + return (m_button != 0); } ControlState KeyboardMouse::Axis::GetState() const { - return std::max(0.0, ControlState(m_axis) / m_range); + return std::max(0.0, ControlState(m_axis) / m_range); } ControlState KeyboardMouse::Cursor::GetState() const { - return std::max(0.0, ControlState(m_axis) / (m_positive ? 1.0 : -1.0)); + return std::max(0.0, ControlState(m_axis) / (m_positive ? 1.0 : -1.0)); } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h index 14d885ff94..1ba9022f9d 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.h @@ -6,93 +6,98 @@ #include -#include "InputCommon/ControllerInterface/Device.h" #include "InputCommon/ControllerInterface/DInput/DInput8.h" +#include "InputCommon/ControllerInterface/Device.h" namespace ciface { namespace DInput { - void InitKeyboardMouse(IDirectInput8* const idi8, std::vector& devices, HWND _hwnd); class KeyboardMouse : public Core::Device { private: - struct State - { - BYTE keyboard[256]; - DIMOUSESTATE2 mouse; - struct - { - ControlState x, y; - } cursor; - }; - - class Key : public Input - { - public: - Key(u8 index, const BYTE& key) : m_key(key), m_index(index) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const BYTE& m_key; - const u8 m_index; - }; - - class Button : public Input - { - public: - Button(u8 index, const BYTE& button) : m_button(button), m_index(index) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const BYTE& m_button; - const u8 m_index; - }; - - class Axis : public Input - { - public: - Axis(u8 index, const LONG& axis, LONG range) : m_axis(axis), m_range(range), m_index(index) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const LONG& m_axis; - const LONG m_range; - const u8 m_index; - }; - - class Cursor : public Input - { - public: - Cursor(u8 index, const ControlState& axis, const bool positive) : m_axis(axis), m_index(index), m_positive(positive) {} - std::string GetName() const override; - bool IsDetectable() override { return false; } - ControlState GetState() const override; - private: - const ControlState& m_axis; - const u8 m_index; - const bool m_positive; - }; + struct State + { + BYTE keyboard[256]; + DIMOUSESTATE2 mouse; + struct + { + ControlState x, y; + } cursor; + }; + + class Key : public Input + { + public: + Key(u8 index, const BYTE& key) : m_key(key), m_index(index) {} + std::string GetName() const override; + ControlState GetState() const override; + + private: + const BYTE& m_key; + const u8 m_index; + }; + + class Button : public Input + { + public: + Button(u8 index, const BYTE& button) : m_button(button), m_index(index) {} + std::string GetName() const override; + ControlState GetState() const override; + + private: + const BYTE& m_button; + const u8 m_index; + }; + + class Axis : public Input + { + public: + Axis(u8 index, const LONG& axis, LONG range) : m_axis(axis), m_range(range), m_index(index) {} + std::string GetName() const override; + ControlState GetState() const override; + + private: + const LONG& m_axis; + const LONG m_range; + const u8 m_index; + }; + + class Cursor : public Input + { + public: + Cursor(u8 index, const ControlState& axis, const bool positive) + : m_axis(axis), m_index(index), m_positive(positive) + { + } + std::string GetName() const override; + bool IsDetectable() override { return false; } + ControlState GetState() const override; + + private: + const ControlState& m_axis; + const u8 m_index; + const bool m_positive; + }; public: - void UpdateInput() override; + void UpdateInput() override; - KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device, const LPDIRECTINPUTDEVICE8 mo_device); - ~KeyboardMouse(); + KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device, const LPDIRECTINPUTDEVICE8 mo_device); + ~KeyboardMouse(); - std::string GetName() const override; - int GetId() const override; - std::string GetSource() const override; + std::string GetName() const override; + int GetId() const override; + std::string GetSource() const override; private: - const LPDIRECTINPUTDEVICE8 m_kb_device; - const LPDIRECTINPUTDEVICE8 m_mo_device; + const LPDIRECTINPUTDEVICE8 m_kb_device; + const LPDIRECTINPUTDEVICE8 m_mo_device; - DWORD m_last_update; - State m_state_in; + DWORD m_last_update; + State m_state_in; }; - } } diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/NamedKeys.h b/Source/Core/InputCommon/ControllerInterface/DInput/NamedKeys.h index 6802fd7888..2ac38a86fe 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/NamedKeys.h +++ b/Source/Core/InputCommon/ControllerInterface/DInput/NamedKeys.h @@ -2,147 +2,40 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -{ DIK_A, "A" }, -{ DIK_B, "B" }, -{ DIK_C, "C" }, -{ DIK_D, "D" }, -{ DIK_E, "E" }, -{ DIK_F, "F" }, -{ DIK_G, "G" }, -{ DIK_H, "H" }, -{ DIK_I, "I" }, -{ DIK_J, "J" }, -{ DIK_K, "K" }, -{ DIK_L, "L" }, -{ DIK_M, "M" }, -{ DIK_N, "N" }, -{ DIK_O, "O" }, -{ DIK_P, "P" }, -{ DIK_Q, "Q" }, -{ DIK_R, "R" }, -{ DIK_S, "S" }, -{ DIK_T, "T" }, -{ DIK_U, "U" }, -{ DIK_V, "V" }, -{ DIK_W, "W" }, -{ DIK_X, "X" }, -{ DIK_Y, "Y" }, -{ DIK_Z, "Z" }, -{ DIK_0, "0" }, -{ DIK_1, "1" }, -{ DIK_2, "2" }, -{ DIK_3, "3" }, -{ DIK_4, "4" }, -{ DIK_5, "5" }, -{ DIK_6, "6" }, -{ DIK_7, "7" }, -{ DIK_8, "8" }, -{ DIK_9, "9" }, -{ DIK_UP, "UP" }, -{ DIK_DOWN, "DOWN" }, -{ DIK_LEFT, "LEFT" }, -{ DIK_RIGHT, "RIGHT" }, -{ DIK_ABNT_C1, "ABNT_C1" }, -{ DIK_ABNT_C2, "ABNT_C2" }, -{ DIK_ADD, "ADD" }, -{ DIK_APOSTROPHE, "APOSTROPHE" }, -{ DIK_APPS, "APPS" }, -{ DIK_AT, "AT" }, -{ DIK_AX, "AX" }, -{ DIK_BACK, "BACK" }, -{ DIK_BACKSLASH, "BACKSLASH" }, -{ DIK_CALCULATOR, "CALCULATOR" }, -{ DIK_CAPITAL, "CAPITAL" }, -{ DIK_COLON, "COLON" }, -{ DIK_COMMA, "COMMA" }, -{ DIK_CONVERT, "CONVERT" }, -{ DIK_DECIMAL, "DECIMAL" }, -{ DIK_DELETE, "DELETE" }, -{ DIK_DIVIDE, "DIVIDE" }, -{ DIK_EQUALS, "EQUALS" }, -{ DIK_ESCAPE, "ESCAPE" }, -{ DIK_F1, "F1" }, -{ DIK_F2, "F2" }, -{ DIK_F3, "F3" }, -{ DIK_F4, "F4" }, -{ DIK_F5, "F5" }, -{ DIK_F6, "F6" }, -{ DIK_F7, "F7" }, -{ DIK_F8, "F8" }, -{ DIK_F9, "F9" }, -{ DIK_F10, "F10" }, -{ DIK_F11, "F11" }, -{ DIK_F12, "F12" }, -{ DIK_F13, "F13" }, -{ DIK_F14, "F14" }, -{ DIK_F15, "F15" }, -{ DIK_GRAVE, "GRAVE" }, -{ DIK_HOME, "HOME" }, -{ DIK_END, "END" }, -{ DIK_INSERT, "INSERT" }, -{ DIK_KANA, "KANA" }, -{ DIK_KANJI, "KANJI" }, -{ DIK_MAIL, "MAIL" }, -{ DIK_MEDIASELECT, "MEDIASELECT" }, -{ DIK_MEDIASTOP, "MEDIASTOP" }, -{ DIK_MINUS, "MINUS" }, -{ DIK_MULTIPLY, "MULTIPLY" }, -{ DIK_MUTE, "MUTE" }, -{ DIK_MYCOMPUTER, "MYCOMPUTER" }, -{ DIK_NEXTTRACK, "NEXTTRACK" }, -{ DIK_NOCONVERT, "NOCONVERT" }, -{ DIK_NUMLOCK, "NUMLOCK" }, -{ DIK_NUMPAD0, "NUMPAD0" }, -{ DIK_NUMPAD1, "NUMPAD1" }, -{ DIK_NUMPAD2, "NUMPAD2" }, -{ DIK_NUMPAD3, "NUMPAD3" }, -{ DIK_NUMPAD4, "NUMPAD4" }, -{ DIK_NUMPAD5, "NUMPAD5" }, -{ DIK_NUMPAD6, "NUMPAD6" }, -{ DIK_NUMPAD7, "NUMPAD7" }, -{ DIK_NUMPAD8, "NUMPAD8" }, -{ DIK_NUMPAD9, "NUMPAD9" }, -{ DIK_NUMPADCOMMA, "NUMPADCOMMA" }, -{ DIK_NUMPADENTER, "NUMPADENTER" }, -{ DIK_NUMPADEQUALS, "NUMPADEQUALS" }, -{ DIK_OEM_102, "OEM_102" }, -{ DIK_PAUSE, "PAUSE" }, -{ DIK_PERIOD, "PERIOD" }, -{ DIK_PLAYPAUSE, "PLAYPAUSE" }, -{ DIK_POWER, "POWER" }, -{ DIK_PREVTRACK, "PREVTRACK" }, -{ DIK_PRIOR, "PRIOR" }, -{ DIK_NEXT, "NEXT" }, -{ DIK_RETURN, "RETURN" }, -{ DIK_LBRACKET, "LBRACKET" }, -{ DIK_RBRACKET, "RBRACKET" }, -{ DIK_LCONTROL, "LCONTROL" }, -{ DIK_RCONTROL, "RCONTROL" }, -{ DIK_LMENU, "LMENU" }, -{ DIK_RMENU, "RMENU" }, -{ DIK_LSHIFT, "LSHIFT" }, -{ DIK_RSHIFT, "RSHIFT" }, -{ DIK_LWIN, "LWIN" }, -{ DIK_RWIN, "RWIN" }, -{ DIK_SCROLL, "SCROLL" }, -{ DIK_SEMICOLON, "SEMICOLON" }, -{ DIK_SLASH, "SLASH" }, -{ DIK_SLEEP, "SLEEP" }, -{ DIK_SPACE, "SPACE" }, -{ DIK_STOP, "STOP" }, -{ DIK_SUBTRACT, "SUBTRACT" }, -{ DIK_SYSRQ, "SYSRQ" }, -{ DIK_TAB, "TAB" }, -{ DIK_UNDERLINE, "UNDERLINE" }, -{ DIK_UNLABELED, "UNLABELED" }, -{ DIK_VOLUMEDOWN, "VOLUMEDOWN" }, -{ DIK_VOLUMEUP, "VOLUMEUP" }, -{ DIK_WAKE, "WAKE" }, -{ DIK_WEBBACK, "WEBBACK" }, -{ DIK_WEBFAVORITES, "WEBFAVORITES" }, -{ DIK_WEBFORWARD, "WEBFORWARD" }, -{ DIK_WEBHOME, "WEBHOME" }, -{ DIK_WEBREFRESH, "WEBREFRESH" }, -{ DIK_WEBSEARCH, "WEBSEARCH" }, -{ DIK_WEBSTOP, "WEBSTOP" }, -{ DIK_YEN, "YEN" }, +{DIK_A, "A"}, {DIK_B, "B"}, {DIK_C, "C"}, {DIK_D, "D"}, {DIK_E, "E"}, {DIK_F, "F"}, {DIK_G, "G"}, + {DIK_H, "H"}, {DIK_I, "I"}, {DIK_J, "J"}, {DIK_K, "K"}, {DIK_L, "L"}, {DIK_M, "M"}, + {DIK_N, "N"}, {DIK_O, "O"}, {DIK_P, "P"}, {DIK_Q, "Q"}, {DIK_R, "R"}, {DIK_S, "S"}, + {DIK_T, "T"}, {DIK_U, "U"}, {DIK_V, "V"}, {DIK_W, "W"}, {DIK_X, "X"}, {DIK_Y, "Y"}, + {DIK_Z, "Z"}, {DIK_0, "0"}, {DIK_1, "1"}, {DIK_2, "2"}, {DIK_3, "3"}, {DIK_4, "4"}, + {DIK_5, "5"}, {DIK_6, "6"}, {DIK_7, "7"}, {DIK_8, "8"}, {DIK_9, "9"}, {DIK_UP, "UP"}, + {DIK_DOWN, "DOWN"}, {DIK_LEFT, "LEFT"}, {DIK_RIGHT, "RIGHT"}, {DIK_ABNT_C1, "ABNT_C1"}, + {DIK_ABNT_C2, "ABNT_C2"}, {DIK_ADD, "ADD"}, {DIK_APOSTROPHE, "APOSTROPHE"}, {DIK_APPS, "APPS"}, + {DIK_AT, "AT"}, {DIK_AX, "AX"}, {DIK_BACK, "BACK"}, {DIK_BACKSLASH, "BACKSLASH"}, + {DIK_CALCULATOR, "CALCULATOR"}, {DIK_CAPITAL, "CAPITAL"}, {DIK_COLON, "COLON"}, + {DIK_COMMA, "COMMA"}, {DIK_CONVERT, "CONVERT"}, {DIK_DECIMAL, "DECIMAL"}, + {DIK_DELETE, "DELETE"}, {DIK_DIVIDE, "DIVIDE"}, {DIK_EQUALS, "EQUALS"}, {DIK_ESCAPE, "ESCAPE"}, + {DIK_F1, "F1"}, {DIK_F2, "F2"}, {DIK_F3, "F3"}, {DIK_F4, "F4"}, {DIK_F5, "F5"}, {DIK_F6, "F6"}, + {DIK_F7, "F7"}, {DIK_F8, "F8"}, {DIK_F9, "F9"}, {DIK_F10, "F10"}, {DIK_F11, "F11"}, + {DIK_F12, "F12"}, {DIK_F13, "F13"}, {DIK_F14, "F14"}, {DIK_F15, "F15"}, {DIK_GRAVE, "GRAVE"}, + {DIK_HOME, "HOME"}, {DIK_END, "END"}, {DIK_INSERT, "INSERT"}, {DIK_KANA, "KANA"}, + {DIK_KANJI, "KANJI"}, {DIK_MAIL, "MAIL"}, {DIK_MEDIASELECT, "MEDIASELECT"}, + {DIK_MEDIASTOP, "MEDIASTOP"}, {DIK_MINUS, "MINUS"}, {DIK_MULTIPLY, "MULTIPLY"}, + {DIK_MUTE, "MUTE"}, {DIK_MYCOMPUTER, "MYCOMPUTER"}, {DIK_NEXTTRACK, "NEXTTRACK"}, + {DIK_NOCONVERT, "NOCONVERT"}, {DIK_NUMLOCK, "NUMLOCK"}, {DIK_NUMPAD0, "NUMPAD0"}, + {DIK_NUMPAD1, "NUMPAD1"}, {DIK_NUMPAD2, "NUMPAD2"}, {DIK_NUMPAD3, "NUMPAD3"}, + {DIK_NUMPAD4, "NUMPAD4"}, {DIK_NUMPAD5, "NUMPAD5"}, {DIK_NUMPAD6, "NUMPAD6"}, + {DIK_NUMPAD7, "NUMPAD7"}, {DIK_NUMPAD8, "NUMPAD8"}, {DIK_NUMPAD9, "NUMPAD9"}, + {DIK_NUMPADCOMMA, "NUMPADCOMMA"}, {DIK_NUMPADENTER, "NUMPADENTER"}, + {DIK_NUMPADEQUALS, "NUMPADEQUALS"}, {DIK_OEM_102, "OEM_102"}, {DIK_PAUSE, "PAUSE"}, + {DIK_PERIOD, "PERIOD"}, {DIK_PLAYPAUSE, "PLAYPAUSE"}, {DIK_POWER, "POWER"}, + {DIK_PREVTRACK, "PREVTRACK"}, {DIK_PRIOR, "PRIOR"}, {DIK_NEXT, "NEXT"}, {DIK_RETURN, "RETURN"}, + {DIK_LBRACKET, "LBRACKET"}, {DIK_RBRACKET, "RBRACKET"}, {DIK_LCONTROL, "LCONTROL"}, + {DIK_RCONTROL, "RCONTROL"}, {DIK_LMENU, "LMENU"}, {DIK_RMENU, "RMENU"}, {DIK_LSHIFT, "LSHIFT"}, + {DIK_RSHIFT, "RSHIFT"}, {DIK_LWIN, "LWIN"}, {DIK_RWIN, "RWIN"}, {DIK_SCROLL, "SCROLL"}, + {DIK_SEMICOLON, "SEMICOLON"}, {DIK_SLASH, "SLASH"}, {DIK_SLEEP, "SLEEP"}, {DIK_SPACE, "SPACE"}, + {DIK_STOP, "STOP"}, {DIK_SUBTRACT, "SUBTRACT"}, {DIK_SYSRQ, "SYSRQ"}, {DIK_TAB, "TAB"}, + {DIK_UNDERLINE, "UNDERLINE"}, {DIK_UNLABELED, "UNLABELED"}, {DIK_VOLUMEDOWN, "VOLUMEDOWN"}, + {DIK_VOLUMEUP, "VOLUMEUP"}, {DIK_WAKE, "WAKE"}, {DIK_WEBBACK, "WEBBACK"}, + {DIK_WEBFAVORITES, "WEBFAVORITES"}, {DIK_WEBFORWARD, "WEBFORWARD"}, {DIK_WEBHOME, "WEBHOME"}, + {DIK_WEBREFRESH, "WEBREFRESH"}, {DIK_WEBSEARCH, "WEBSEARCH"}, {DIK_WEBSTOP, "WEBSTOP"}, + {DIK_YEN, "YEN"}, diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/XInputFilter.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/XInputFilter.cpp index aedfc5dc44..d6f1cab257 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/XInputFilter.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/XInputFilter.cpp @@ -5,118 +5,127 @@ // This function is contained in a separate file because WbemIdl.h pulls in files which break on // /Zc:strictStrings, so this compilation unit is compiled without /Zc:strictStrings. -#include #include #include +#include -#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=nullptr; } } +#define SAFE_RELEASE(p) \ + { \ + if (p) \ + { \ + (p)->Release(); \ + (p) = nullptr; \ + } \ + } namespace ciface { namespace DInput { - //----------------------------------------------------------------------------- // Modified some MSDN code to get all the XInput device GUID.Data1 values in a vector, // faster than checking all the devices for each DirectInput device, like MSDN says to do //----------------------------------------------------------------------------- void GetXInputGUIDS(std::vector* guids) { - IWbemLocator* pIWbemLocator = nullptr; - IEnumWbemClassObject* pEnumDevices = nullptr; - IWbemClassObject* pDevices[20] = {0}; - IWbemServices* pIWbemServices = nullptr; - BSTR bstrNamespace = nullptr; - BSTR bstrDeviceID = nullptr; - BSTR bstrClassName = nullptr; - DWORD uReturned = 0; - VARIANT var; - HRESULT hr; - - // CoInit if needed - hr = CoInitialize(nullptr); - bool bCleanupCOM = SUCCEEDED(hr); - - // Create WMI - hr = CoCreateInstance(__uuidof(WbemLocator), - nullptr, - CLSCTX_INPROC_SERVER, - __uuidof(IWbemLocator), - (LPVOID*) &pIWbemLocator); - if (FAILED(hr) || pIWbemLocator == nullptr) - goto LCleanup; - - bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == nullptr) goto LCleanup; - bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == nullptr) goto LCleanup; - bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == nullptr) goto LCleanup; - - // Connect to WMI - hr = pIWbemLocator->ConnectServer(bstrNamespace, nullptr, nullptr, 0L, 0L, nullptr, nullptr, &pIWbemServices); - if (FAILED(hr) || pIWbemServices == nullptr) - goto LCleanup; - - // Switch security level to IMPERSONATE. - CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, - RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE); - - hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, nullptr, &pEnumDevices); - if (FAILED(hr) || pEnumDevices == nullptr) - goto LCleanup; - - // Loop over all devices - while (true) - { - // Get 20 at a time - hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned); - if (FAILED(hr) || uReturned == 0) - break; - - for (UINT iDevice = 0; iDevice < uReturned; ++iDevice) - { - // For each device, get its device ID - hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, nullptr, nullptr); - if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != nullptr) - { - // Check if the device ID contains "IG_". If it does, then it's an XInput device - // This information can not be found from DirectInput - if (wcsstr(var.bstrVal, L"IG_")) - { - // If it does, then get the VID/PID from var.bstrVal - DWORD dwPid = 0, dwVid = 0; - WCHAR* strVid = wcsstr(var.bstrVal, L"VID_"); - if (strVid && swscanf(strVid, L"VID_%4X", &dwVid) != 1) - dwVid = 0; - WCHAR* strPid = wcsstr(var.bstrVal, L"PID_"); - if (strPid && swscanf(strPid, L"PID_%4X", &dwPid) != 1) - dwPid = 0; - - // Compare the VID/PID to the DInput device - DWORD dwVidPid = MAKELONG(dwVid, dwPid); - guids->push_back(dwVidPid); - //bIsXinputDevice = true; - } - } - SAFE_RELEASE(pDevices[iDevice]); - } - } + IWbemLocator* pIWbemLocator = nullptr; + IEnumWbemClassObject* pEnumDevices = nullptr; + IWbemClassObject* pDevices[20] = {0}; + IWbemServices* pIWbemServices = nullptr; + BSTR bstrNamespace = nullptr; + BSTR bstrDeviceID = nullptr; + BSTR bstrClassName = nullptr; + DWORD uReturned = 0; + VARIANT var; + HRESULT hr; + + // CoInit if needed + hr = CoInitialize(nullptr); + bool bCleanupCOM = SUCCEEDED(hr); + + // Create WMI + hr = CoCreateInstance(__uuidof(WbemLocator), nullptr, CLSCTX_INPROC_SERVER, + __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator); + if (FAILED(hr) || pIWbemLocator == nullptr) + goto LCleanup; + + bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); + if (bstrNamespace == nullptr) + goto LCleanup; + bstrClassName = SysAllocString(L"Win32_PNPEntity"); + if (bstrClassName == nullptr) + goto LCleanup; + bstrDeviceID = SysAllocString(L"DeviceID"); + if (bstrDeviceID == nullptr) + goto LCleanup; + + // Connect to WMI + hr = pIWbemLocator->ConnectServer(bstrNamespace, nullptr, nullptr, 0L, 0L, nullptr, nullptr, + &pIWbemServices); + if (FAILED(hr) || pIWbemServices == nullptr) + goto LCleanup; + + // Switch security level to IMPERSONATE. + CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE); + + hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, nullptr, &pEnumDevices); + if (FAILED(hr) || pEnumDevices == nullptr) + goto LCleanup; + + // Loop over all devices + while (true) + { + // Get 20 at a time + hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned); + if (FAILED(hr) || uReturned == 0) + break; + + for (UINT iDevice = 0; iDevice < uReturned; ++iDevice) + { + // For each device, get its device ID + hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, nullptr, nullptr); + if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != nullptr) + { + // Check if the device ID contains "IG_". If it does, then it's an XInput device + // This information can not be found from DirectInput + if (wcsstr(var.bstrVal, L"IG_")) + { + // If it does, then get the VID/PID from var.bstrVal + DWORD dwPid = 0, dwVid = 0; + WCHAR* strVid = wcsstr(var.bstrVal, L"VID_"); + if (strVid && swscanf(strVid, L"VID_%4X", &dwVid) != 1) + dwVid = 0; + WCHAR* strPid = wcsstr(var.bstrVal, L"PID_"); + if (strPid && swscanf(strPid, L"PID_%4X", &dwPid) != 1) + dwPid = 0; + + // Compare the VID/PID to the DInput device + DWORD dwVidPid = MAKELONG(dwVid, dwPid); + guids->push_back(dwVidPid); + // bIsXinputDevice = true; + } + } + SAFE_RELEASE(pDevices[iDevice]); + } + } LCleanup: - if (bstrNamespace) - SysFreeString(bstrNamespace); - if (bstrDeviceID) - SysFreeString(bstrDeviceID); - if (bstrClassName) - SysFreeString(bstrClassName); - for (UINT iDevice = 0; iDevice < 20; iDevice++) - SAFE_RELEASE(pDevices[iDevice]); - SAFE_RELEASE(pEnumDevices); - SAFE_RELEASE(pIWbemLocator); - SAFE_RELEASE(pIWbemServices); - - if (bCleanupCOM) - CoUninitialize(); + if (bstrNamespace) + SysFreeString(bstrNamespace); + if (bstrDeviceID) + SysFreeString(bstrDeviceID); + if (bstrClassName) + SysFreeString(bstrClassName); + for (UINT iDevice = 0; iDevice < 20; iDevice++) + SAFE_RELEASE(pDevices[iDevice]); + SAFE_RELEASE(pEnumDevices); + SAFE_RELEASE(pIWbemLocator); + SAFE_RELEASE(pIWbemServices); + + if (bCleanupCOM) + CoUninitialize(); } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/XInputFilter.h b/Source/Core/InputCommon/ControllerInterface/DInput/XInputFilter.h index 6506dd156e..be075deb9b 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/XInputFilter.h +++ b/Source/Core/InputCommon/ControllerInterface/DInput/XInputFilter.h @@ -4,15 +4,13 @@ #pragma once -#include #include +#include namespace ciface { namespace DInput { - void GetXInputGUIDS(std::vector* guids); - } } diff --git a/Source/Core/InputCommon/ControllerInterface/Device.cpp b/Source/Core/InputCommon/ControllerInterface/Device.cpp index fae7e98e2f..7a3b8ac845 100644 --- a/Source/Core/InputCommon/ControllerInterface/Device.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Device.cpp @@ -17,7 +17,6 @@ namespace ciface { namespace Core { - // // Device :: ~Device // @@ -25,55 +24,55 @@ namespace Core // Device::~Device() { - // delete inputs - for (Device::Input* input : m_inputs) - delete input; + // delete inputs + for (Device::Input* input : m_inputs) + delete input; - // delete outputs - for (Device::Output* output: m_outputs) - delete output; + // delete outputs + for (Device::Output* output : m_outputs) + delete output; } void Device::AddInput(Device::Input* const i) { - m_inputs.push_back(i); + m_inputs.push_back(i); } void Device::AddOutput(Device::Output* const o) { - m_outputs.push_back(o); + m_outputs.push_back(o); } -Device::Input* Device::FindInput(const std::string &name) const +Device::Input* Device::FindInput(const std::string& name) const { - for (Input* input : m_inputs) - { - if (input->GetName() == name) - return input; - } + for (Input* input : m_inputs) + { + if (input->GetName() == name) + return input; + } - return nullptr; + return nullptr; } -Device::Output* Device::FindOutput(const std::string &name) const +Device::Output* Device::FindOutput(const std::string& name) const { - for (Output* output : m_outputs) - { - if (output->GetName() == name) - return output; - } + for (Output* output : m_outputs) + { + if (output->GetName() == name) + return output; + } - return nullptr; + return nullptr; } bool Device::Control::InputGateOn() { - if (SConfig::GetInstance().m_BackgroundInput) - return true; - else if (Host_RendererHasFocus() || Host_UIHasFocus()) - return true; - else - return false; + if (SConfig::GetInstance().m_BackgroundInput) + return true; + else if (Host_RendererHasFocus() || Host_UIHasFocus()) + return true; + else + return false; } // @@ -83,16 +82,16 @@ bool Device::Control::InputGateOn() // std::string DeviceQualifier::ToString() const { - if (source.empty() && (cid < 0) && name.empty()) - return ""; + if (source.empty() && (cid < 0) && name.empty()) + return ""; - std::ostringstream ss; - ss << source << '/'; - if (cid > -1) - ss << cid; - ss << '/' << name; + std::ostringstream ss; + ss << source << '/'; + if (cid > -1) + ss << cid; + ss << '/' << name; - return ss.str(); + return ss.str(); } // @@ -102,15 +101,15 @@ std::string DeviceQualifier::ToString() const // void DeviceQualifier::FromString(const std::string& str) { - std::istringstream ss(str); + std::istringstream ss(str); - std::getline(ss, source = "", '/'); + std::getline(ss, source = "", '/'); - // silly - std::getline(ss, name, '/'); - std::istringstream(name) >> (cid = -1); + // silly + std::getline(ss, name, '/'); + std::istringstream(name) >> (cid = -1); - std::getline(ss, name = ""); + std::getline(ss, name = ""); } // @@ -120,66 +119,65 @@ void DeviceQualifier::FromString(const std::string& str) // void DeviceQualifier::FromDevice(const Device* const dev) { - name = dev->GetName(); - cid = dev->GetId(); - source= dev->GetSource(); + name = dev->GetName(); + cid = dev->GetId(); + source = dev->GetSource(); } bool DeviceQualifier::operator==(const Device* const dev) const { - if (dev->GetId() == cid) - if (dev->GetName() == name) - if (dev->GetSource() == source) - return true; + if (dev->GetId() == cid) + if (dev->GetName() == name) + if (dev->GetSource() == source) + return true; - return false; + return false; } bool DeviceQualifier::operator==(const DeviceQualifier& devq) const { - if (cid == devq.cid) - if (name == devq.name) - if (source == devq.source) - return true; + if (cid == devq.cid) + if (name == devq.name) + if (source == devq.source) + return true; - return false; + return false; } Device* DeviceContainer::FindDevice(const DeviceQualifier& devq) const { - for (Device* d : m_devices) - { - if (devq == d) - return d; - } + for (Device* d : m_devices) + { + if (devq == d) + return d; + } - return nullptr; + return nullptr; } Device::Input* DeviceContainer::FindInput(const std::string& name, const Device* def_dev) const { - if (def_dev) - { - Device::Input* const inp = def_dev->FindInput(name); - if (inp) - return inp; - } + if (def_dev) + { + Device::Input* const inp = def_dev->FindInput(name); + if (inp) + return inp; + } - for (Device* d : m_devices) - { - Device::Input* const i = d->FindInput(name); + for (Device* d : m_devices) + { + Device::Input* const i = d->FindInput(name); - if (i) - return i; - } + if (i) + return i; + } - return nullptr; + return nullptr; } Device::Output* DeviceContainer::FindOutput(const std::string& name, const Device* def_dev) const { - return def_dev->FindOutput(name); + return def_dev->FindOutput(name); } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/Device.h b/Source/Core/InputCommon/ControllerInterface/Device.h index 7e6172149f..dc60691b56 100644 --- a/Source/Core/InputCommon/ControllerInterface/Device.h +++ b/Source/Core/InputCommon/ControllerInterface/Device.h @@ -16,7 +16,6 @@ namespace ciface { namespace Core { - // Forward declarations class DeviceQualifier; @@ -28,121 +27,109 @@ class DeviceQualifier; class Device { public: - class Input; - class Output; - - // - // Control - // - // Control includes inputs and outputs - // - class Control // input or output - { - public: - virtual std::string GetName() const = 0; - virtual ~Control() {} - - bool InputGateOn(); - - virtual Input* ToInput() { return nullptr; } - virtual Output* ToOutput() { return nullptr; } - }; - - // - // Input - // - // An input on a device - // - class Input : public Control - { - public: - // things like absolute axes/ absolute mouse position will override this - virtual bool IsDetectable() { return true; } - - virtual ControlState GetState() const = 0; - - ControlState GetGatedState() - { - if (InputGateOn()) - return GetState(); - else - return 0.0; - } - - Input* ToInput() override { return this; } - }; - - // - // Output - // - // An output on a device - // - class Output : public Control - { - public: - virtual ~Output() {} - - virtual void SetState(ControlState state) = 0; - - void SetGatedState(ControlState state) - { - if (InputGateOn()) - SetState(state); - } - - Output* ToOutput() override { return this; } - }; - - virtual ~Device(); - - virtual std::string GetName() const = 0; - virtual int GetId() const = 0; - virtual std::string GetSource() const = 0; - virtual void UpdateInput() {} - - const std::vector& Inputs() const { return m_inputs; } - const std::vector& Outputs() const { return m_outputs; } - - Input* FindInput(const std::string& name) const; - Output* FindOutput(const std::string& name) const; + class Input; + class Output; + + // + // Control + // + // Control includes inputs and outputs + // + class Control // input or output + { + public: + virtual std::string GetName() const = 0; + virtual ~Control() {} + bool InputGateOn(); + + virtual Input* ToInput() { return nullptr; } + virtual Output* ToOutput() { return nullptr; } + }; + + // + // Input + // + // An input on a device + // + class Input : public Control + { + public: + // things like absolute axes/ absolute mouse position will override this + virtual bool IsDetectable() { return true; } + virtual ControlState GetState() const = 0; + + ControlState GetGatedState() + { + if (InputGateOn()) + return GetState(); + else + return 0.0; + } + + Input* ToInput() override { return this; } + }; + + // + // Output + // + // An output on a device + // + class Output : public Control + { + public: + virtual ~Output() {} + virtual void SetState(ControlState state) = 0; + + void SetGatedState(ControlState state) + { + if (InputGateOn()) + SetState(state); + } + + Output* ToOutput() override { return this; } + }; + + virtual ~Device(); + + virtual std::string GetName() const = 0; + virtual int GetId() const = 0; + virtual std::string GetSource() const = 0; + virtual void UpdateInput() {} + const std::vector& Inputs() const { return m_inputs; } + const std::vector& Outputs() const { return m_outputs; } + Input* FindInput(const std::string& name) const; + Output* FindOutput(const std::string& name) const; protected: - void AddInput(Input* const i); - void AddOutput(Output* const o); - - class FullAnalogSurface : public Input - { - public: - FullAnalogSurface(Input* low, Input* high) - : m_low(*low), m_high(*high) - {} - - ControlState GetState() const override - { - return (1 + m_high.GetState() - m_low.GetState()) / 2; - } - - std::string GetName() const override - { - return m_low.GetName() + *m_high.GetName().rbegin(); - } - - private: - Input& m_low; - Input& m_high; - }; - - void AddAnalogInputs(Input* low, Input* high) - { - AddInput(low); - AddInput(high); - AddInput(new FullAnalogSurface(low, high)); - AddInput(new FullAnalogSurface(high, low)); - } + void AddInput(Input* const i); + void AddOutput(Output* const o); + + class FullAnalogSurface : public Input + { + public: + FullAnalogSurface(Input* low, Input* high) : m_low(*low), m_high(*high) {} + ControlState GetState() const override + { + return (1 + m_high.GetState() - m_low.GetState()) / 2; + } + + std::string GetName() const override { return m_low.GetName() + *m_high.GetName().rbegin(); } + private: + Input& m_low; + Input& m_high; + }; + + void AddAnalogInputs(Input* low, Input* high) + { + AddInput(low); + AddInput(high); + AddInput(new FullAnalogSurface(low, high)); + AddInput(new FullAnalogSurface(high, low)); + } private: - std::vector m_inputs; - std::vector m_outputs; + std::vector m_inputs; + std::vector m_outputs; }; // @@ -154,31 +141,33 @@ private: class DeviceQualifier { public: - DeviceQualifier() : cid(-1) {} - DeviceQualifier(const std::string& _source, const int _id, const std::string& _name) - : source(_source), cid(_id), name(_name) {} - void FromDevice(const Device* const dev); - void FromString(const std::string& str); - std::string ToString() const; - bool operator==(const DeviceQualifier& devq) const; - bool operator==(const Device* const dev) const; - - std::string source; - int cid; - std::string name; + DeviceQualifier() : cid(-1) {} + DeviceQualifier(const std::string& _source, const int _id, const std::string& _name) + : source(_source), cid(_id), name(_name) + { + } + void FromDevice(const Device* const dev); + void FromString(const std::string& str); + std::string ToString() const; + bool operator==(const DeviceQualifier& devq) const; + bool operator==(const Device* const dev) const; + + std::string source; + int cid; + std::string name; }; class DeviceContainer { public: - Device::Input* FindInput(const std::string& name, const Device* def_dev) const; - Device::Output* FindOutput(const std::string& name, const Device* def_dev) const; + Device::Input* FindInput(const std::string& name, const Device* def_dev) const; + Device::Output* FindOutput(const std::string& name, const Device* def_dev) const; + + const std::vector& Devices() const { return m_devices; } + Device* FindDevice(const DeviceQualifier& devq) const; - const std::vector& Devices() const { return m_devices; } - Device* FindDevice(const DeviceQualifier& devq) const; protected: - std::vector m_devices; + std::vector m_devices; }; - } } diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp index bcb2c95a96..a87bdf8d35 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp @@ -17,601 +17,546 @@ namespace ciface { namespace ExpressionParser { - enum TokenType { - TOK_DISCARD, - TOK_INVALID, - TOK_EOF, - TOK_LPAREN, - TOK_RPAREN, - TOK_AND, - TOK_OR, - TOK_NOT, - TOK_ADD, - TOK_CONTROL, + TOK_DISCARD, + TOK_INVALID, + TOK_EOF, + TOK_LPAREN, + TOK_RPAREN, + TOK_AND, + TOK_OR, + TOK_NOT, + TOK_ADD, + TOK_CONTROL, }; inline std::string OpName(TokenType op) { - switch (op) - { - case TOK_AND: - return "And"; - case TOK_OR: - return "Or"; - case TOK_NOT: - return "Not"; - case TOK_ADD: - return "Add"; - default: - assert(false); - return ""; - } + switch (op) + { + case TOK_AND: + return "And"; + case TOK_OR: + return "Or"; + case TOK_NOT: + return "Not"; + case TOK_ADD: + return "Add"; + default: + assert(false); + return ""; + } } class Token { public: - TokenType type; - ControlQualifier qualifier; - - Token(TokenType type_) : type(type_) {} - Token(TokenType type_, ControlQualifier qualifier_) : type(type_), qualifier(qualifier_) {} - - operator std::string() - { - switch (type) - { - case TOK_DISCARD: - return "Discard"; - case TOK_EOF: - return "EOF"; - case TOK_LPAREN: - return "("; - case TOK_RPAREN: - return ")"; - case TOK_AND: - return "&"; - case TOK_OR: - return "|"; - case TOK_NOT: - return "!"; - case TOK_ADD: - return "+"; - case TOK_CONTROL: - return "Device(" + (std::string)qualifier + ")"; - case TOK_INVALID: - break; - } - - return "Invalid"; - } + TokenType type; + ControlQualifier qualifier; + + Token(TokenType type_) : type(type_) {} + Token(TokenType type_, ControlQualifier qualifier_) : type(type_), qualifier(qualifier_) {} + operator std::string() + { + switch (type) + { + case TOK_DISCARD: + return "Discard"; + case TOK_EOF: + return "EOF"; + case TOK_LPAREN: + return "("; + case TOK_RPAREN: + return ")"; + case TOK_AND: + return "&"; + case TOK_OR: + return "|"; + case TOK_NOT: + return "!"; + case TOK_ADD: + return "+"; + case TOK_CONTROL: + return "Device(" + (std::string)qualifier + ")"; + case TOK_INVALID: + break; + } + + return "Invalid"; + } }; -class Lexer { +class Lexer +{ public: - std::string expr; - std::string::iterator it; - - Lexer(const std::string& expr_) : expr(expr_) - { - it = expr.begin(); - } - - bool FetchBacktickString(std::string &value, char otherDelim = 0) - { - value = ""; - while (it != expr.end()) - { - char c = *it; - ++it; - if (c == '`') - return false; - if (c > 0 && c == otherDelim) - return true; - value += c; - } - return false; - } - - Token GetFullyQualifiedControl() - { - ControlQualifier qualifier; - std::string value; - - if (FetchBacktickString(value, ':')) - { - // Found colon, this is the device name - qualifier.has_device = true; - qualifier.device_qualifier.FromString(value); - FetchBacktickString(value); - } - - qualifier.control_name = value; - - return Token(TOK_CONTROL, qualifier); - } - - Token GetBarewordsControl(char c) - { - std::string name; - name += c; - - while (it != expr.end()) - { - c = *it; - if (!isalpha(c)) - break; - name += c; - ++it; - } - - ControlQualifier qualifier; - qualifier.control_name = name; - return Token(TOK_CONTROL, qualifier); - } - - Token NextToken() - { - if (it == expr.end()) - return Token(TOK_EOF); - - char c = *it++; - switch (c) - { - case ' ': - case '\t': - case '\n': - case '\r': - return Token(TOK_DISCARD); - case '(': - return Token(TOK_LPAREN); - case ')': - return Token(TOK_RPAREN); - case '&': - return Token(TOK_AND); - case '|': - return Token(TOK_OR); - case '!': - return Token(TOK_NOT); - case '+': - return Token(TOK_ADD); - case '`': - return GetFullyQualifiedControl(); - default: - if (isalpha(c)) - return GetBarewordsControl(c); - else - return Token(TOK_INVALID); - } - } - - ExpressionParseStatus Tokenize(std::vector &tokens) - { - while (true) - { - Token tok = NextToken(); - - if (tok.type == TOK_DISCARD) - continue; - - if (tok.type == TOK_INVALID) - { - tokens.clear(); - return EXPRESSION_PARSE_SYNTAX_ERROR; - } - - tokens.push_back(tok); - - if (tok.type == TOK_EOF) - break; - } - return EXPRESSION_PARSE_SUCCESS; - } + std::string expr; + std::string::iterator it; + + Lexer(const std::string& expr_) : expr(expr_) { it = expr.begin(); } + bool FetchBacktickString(std::string& value, char otherDelim = 0) + { + value = ""; + while (it != expr.end()) + { + char c = *it; + ++it; + if (c == '`') + return false; + if (c > 0 && c == otherDelim) + return true; + value += c; + } + return false; + } + + Token GetFullyQualifiedControl() + { + ControlQualifier qualifier; + std::string value; + + if (FetchBacktickString(value, ':')) + { + // Found colon, this is the device name + qualifier.has_device = true; + qualifier.device_qualifier.FromString(value); + FetchBacktickString(value); + } + + qualifier.control_name = value; + + return Token(TOK_CONTROL, qualifier); + } + + Token GetBarewordsControl(char c) + { + std::string name; + name += c; + + while (it != expr.end()) + { + c = *it; + if (!isalpha(c)) + break; + name += c; + ++it; + } + + ControlQualifier qualifier; + qualifier.control_name = name; + return Token(TOK_CONTROL, qualifier); + } + + Token NextToken() + { + if (it == expr.end()) + return Token(TOK_EOF); + + char c = *it++; + switch (c) + { + case ' ': + case '\t': + case '\n': + case '\r': + return Token(TOK_DISCARD); + case '(': + return Token(TOK_LPAREN); + case ')': + return Token(TOK_RPAREN); + case '&': + return Token(TOK_AND); + case '|': + return Token(TOK_OR); + case '!': + return Token(TOK_NOT); + case '+': + return Token(TOK_ADD); + case '`': + return GetFullyQualifiedControl(); + default: + if (isalpha(c)) + return GetBarewordsControl(c); + else + return Token(TOK_INVALID); + } + } + + ExpressionParseStatus Tokenize(std::vector& tokens) + { + while (true) + { + Token tok = NextToken(); + + if (tok.type == TOK_DISCARD) + continue; + + if (tok.type == TOK_INVALID) + { + tokens.clear(); + return EXPRESSION_PARSE_SYNTAX_ERROR; + } + + tokens.push_back(tok); + + if (tok.type == TOK_EOF) + break; + } + return EXPRESSION_PARSE_SUCCESS; + } }; class ExpressionNode { public: - virtual ~ExpressionNode() {} - virtual ControlState GetValue() { return 0; } - virtual void SetValue(ControlState state) {} - virtual int CountNumControls() { return 0; } - virtual operator std::string() { return ""; } + virtual ~ExpressionNode() {} + virtual ControlState GetValue() { return 0; } + virtual void SetValue(ControlState state) {} + virtual int CountNumControls() { return 0; } + virtual operator std::string() { return ""; } }; class DummyExpression : public ExpressionNode { public: - std::string name; - - DummyExpression(const std::string& name_) : name(name_) {} - - ControlState GetValue() override - { - return 0.0; - } - - void SetValue(ControlState value) override - { - } + std::string name; - int CountNumControls() override - { - return 0; - } - - operator std::string() override - { - return "`" + name + "`"; - } + DummyExpression(const std::string& name_) : name(name_) {} + ControlState GetValue() override { return 0.0; } + void SetValue(ControlState value) override {} + int CountNumControls() override { return 0; } + operator std::string() override { return "`" + name + "`"; } }; class ControlExpression : public ExpressionNode { public: - ControlQualifier qualifier; - Device::Control *control; - - ControlExpression(ControlQualifier qualifier_, Device::Control *control_) : qualifier(qualifier_), control(control_) {} - - ControlState GetValue() override - { - return control->ToInput()->GetGatedState(); - } - - void SetValue(ControlState value) override - { - control->ToOutput()->SetGatedState(value); - } - - int CountNumControls() override - { - return 1; - } - - operator std::string() override - { - return "`" + (std::string)qualifier + "`"; - } + ControlQualifier qualifier; + Device::Control* control; + + ControlExpression(ControlQualifier qualifier_, Device::Control* control_) + : qualifier(qualifier_), control(control_) + { + } + + ControlState GetValue() override { return control->ToInput()->GetGatedState(); } + void SetValue(ControlState value) override { control->ToOutput()->SetGatedState(value); } + int CountNumControls() override { return 1; } + operator std::string() override { return "`" + (std::string)qualifier + "`"; } }; class BinaryExpression : public ExpressionNode { public: - TokenType op; - ExpressionNode *lhs; - ExpressionNode *rhs; - - BinaryExpression(TokenType op_, ExpressionNode *lhs_, ExpressionNode *rhs_) : op(op_), lhs(lhs_), rhs(rhs_) {} - virtual ~BinaryExpression() - { - delete lhs; - delete rhs; - } - - ControlState GetValue() override - { - ControlState lhsValue = lhs->GetValue(); - ControlState rhsValue = rhs->GetValue(); - switch (op) - { - case TOK_AND: - return std::min(lhsValue, rhsValue); - case TOK_OR: - return std::max(lhsValue, rhsValue); - case TOK_ADD: - return std::min(lhsValue + rhsValue, 1.0); - default: - assert(false); - return 0; - } - } - - void SetValue(ControlState value) override - { - // Don't do anything special with the op we have. - // Treat "A & B" the same as "A | B". - lhs->SetValue(value); - rhs->SetValue(value); - } - - int CountNumControls() override - { - return lhs->CountNumControls() + rhs->CountNumControls(); - } - - operator std::string() override - { - return OpName(op) + "(" + (std::string)(*lhs) + ", " + (std::string)(*rhs) + ")"; - } + TokenType op; + ExpressionNode* lhs; + ExpressionNode* rhs; + + BinaryExpression(TokenType op_, ExpressionNode* lhs_, ExpressionNode* rhs_) + : op(op_), lhs(lhs_), rhs(rhs_) + { + } + virtual ~BinaryExpression() + { + delete lhs; + delete rhs; + } + + ControlState GetValue() override + { + ControlState lhsValue = lhs->GetValue(); + ControlState rhsValue = rhs->GetValue(); + switch (op) + { + case TOK_AND: + return std::min(lhsValue, rhsValue); + case TOK_OR: + return std::max(lhsValue, rhsValue); + case TOK_ADD: + return std::min(lhsValue + rhsValue, 1.0); + default: + assert(false); + return 0; + } + } + + void SetValue(ControlState value) override + { + // Don't do anything special with the op we have. + // Treat "A & B" the same as "A | B". + lhs->SetValue(value); + rhs->SetValue(value); + } + + int CountNumControls() override { return lhs->CountNumControls() + rhs->CountNumControls(); } + operator std::string() override + { + return OpName(op) + "(" + (std::string)(*lhs) + ", " + (std::string)(*rhs) + ")"; + } }; class UnaryExpression : public ExpressionNode { public: - TokenType op; - ExpressionNode *inner; - - UnaryExpression(TokenType op_, ExpressionNode *inner_) : op(op_), inner(inner_) {} - virtual ~UnaryExpression() - { - delete inner; - } - - ControlState GetValue() override - { - ControlState value = inner->GetValue(); - switch (op) - { - case TOK_NOT: - return 1.0 - value; - default: - assert(false); - return 0; - } - } - - void SetValue(ControlState value) override - { - switch (op) - { - case TOK_NOT: - inner->SetValue(1.0 - value); - break; - - default: - assert(false); - } - } - - int CountNumControls() override - { - return inner->CountNumControls(); - } - - operator std::string() override - { - return OpName(op) + "(" + (std::string)(*inner) + ")"; - } + TokenType op; + ExpressionNode* inner; + + UnaryExpression(TokenType op_, ExpressionNode* inner_) : op(op_), inner(inner_) {} + virtual ~UnaryExpression() { delete inner; } + ControlState GetValue() override + { + ControlState value = inner->GetValue(); + switch (op) + { + case TOK_NOT: + return 1.0 - value; + default: + assert(false); + return 0; + } + } + + void SetValue(ControlState value) override + { + switch (op) + { + case TOK_NOT: + inner->SetValue(1.0 - value); + break; + + default: + assert(false); + } + } + + int CountNumControls() override { return inner->CountNumControls(); } + operator std::string() override { return OpName(op) + "(" + (std::string)(*inner) + ")"; } }; -Device *ControlFinder::FindDevice(ControlQualifier qualifier) +Device* ControlFinder::FindDevice(ControlQualifier qualifier) { - if (qualifier.has_device) - return container.FindDevice(qualifier.device_qualifier); - else - return container.FindDevice(default_device); + if (qualifier.has_device) + return container.FindDevice(qualifier.device_qualifier); + else + return container.FindDevice(default_device); } -Device::Control *ControlFinder::FindControl(ControlQualifier qualifier) +Device::Control* ControlFinder::FindControl(ControlQualifier qualifier) { - Device *device = FindDevice(qualifier); - if (!device) - return nullptr; - - if (is_input) - return device->FindInput(qualifier.control_name); - else - return device->FindOutput(qualifier.control_name); + Device* device = FindDevice(qualifier); + if (!device) + return nullptr; + + if (is_input) + return device->FindInput(qualifier.control_name); + else + return device->FindOutput(qualifier.control_name); } class Parser { public: - - Parser(std::vector tokens_, ControlFinder &finder_) : tokens(tokens_), finder(finder_) - { - m_it = tokens.begin(); - } - - ExpressionParseStatus Parse(Expression **expr_out) - { - ExpressionNode *node; - ExpressionParseStatus status = Toplevel(&node); - if (status != EXPRESSION_PARSE_SUCCESS) - return status; - - *expr_out = new Expression(node); - return EXPRESSION_PARSE_SUCCESS; - } + Parser(std::vector tokens_, ControlFinder& finder_) : tokens(tokens_), finder(finder_) + { + m_it = tokens.begin(); + } + + ExpressionParseStatus Parse(Expression** expr_out) + { + ExpressionNode* node; + ExpressionParseStatus status = Toplevel(&node); + if (status != EXPRESSION_PARSE_SUCCESS) + return status; + + *expr_out = new Expression(node); + return EXPRESSION_PARSE_SUCCESS; + } private: - std::vector tokens; - std::vector::iterator m_it; - ControlFinder &finder; - - Token Chew() - { - return *m_it++; - } - - Token Peek() - { - return *m_it; - } - - bool Expects(TokenType type) - { - Token tok = Chew(); - return tok.type == type; - } - - ExpressionParseStatus Atom(ExpressionNode **expr_out) - { - Token tok = Chew(); - switch (tok.type) - { - case TOK_CONTROL: - { - Device::Control *control = finder.FindControl(tok.qualifier); - if (control == nullptr) - { - *expr_out = new DummyExpression(tok.qualifier); - return EXPRESSION_PARSE_SUCCESS; - } - - *expr_out = new ControlExpression(tok.qualifier, control); - return EXPRESSION_PARSE_SUCCESS; - } - case TOK_LPAREN: - return Paren(expr_out); - default: - return EXPRESSION_PARSE_SYNTAX_ERROR; - } - } - - bool IsUnaryExpression(TokenType type) - { - switch (type) - { - case TOK_NOT: - return true; - default: - return false; - } - } - - ExpressionParseStatus Unary(ExpressionNode **expr_out) - { - ExpressionParseStatus status; - - if (IsUnaryExpression(Peek().type)) - { - Token tok = Chew(); - ExpressionNode *atom_expr; - if ((status = Atom(&atom_expr)) != EXPRESSION_PARSE_SUCCESS) - return status; - *expr_out = new UnaryExpression(tok.type, atom_expr); - return EXPRESSION_PARSE_SUCCESS; - } - - return Atom(expr_out); - } - - bool IsBinaryToken(TokenType type) - { - switch (type) - { - case TOK_AND: - case TOK_OR: - case TOK_ADD: - return true; - default: - return false; - } - } - - ExpressionParseStatus Binary(ExpressionNode **expr_out) - { - ExpressionParseStatus status; - - if ((status = Unary(expr_out)) != EXPRESSION_PARSE_SUCCESS) - return status; - - while (IsBinaryToken(Peek().type)) - { - Token tok = Chew(); - ExpressionNode *unary_expr; - if ((status = Unary(&unary_expr)) != EXPRESSION_PARSE_SUCCESS) - { - delete *expr_out; - return status; - } - - *expr_out = new BinaryExpression(tok.type, *expr_out, unary_expr); - } - - return EXPRESSION_PARSE_SUCCESS; - } - - ExpressionParseStatus Paren(ExpressionNode **expr_out) - { - ExpressionParseStatus status; - - // lparen already chewed - if ((status = Toplevel(expr_out)) != EXPRESSION_PARSE_SUCCESS) - return status; - - if (!Expects(TOK_RPAREN)) - { - delete *expr_out; - return EXPRESSION_PARSE_SYNTAX_ERROR; - } - - return EXPRESSION_PARSE_SUCCESS; - } - - ExpressionParseStatus Toplevel(ExpressionNode **expr_out) - { - return Binary(expr_out); - } + std::vector tokens; + std::vector::iterator m_it; + ControlFinder& finder; + + Token Chew() { return *m_it++; } + Token Peek() { return *m_it; } + bool Expects(TokenType type) + { + Token tok = Chew(); + return tok.type == type; + } + + ExpressionParseStatus Atom(ExpressionNode** expr_out) + { + Token tok = Chew(); + switch (tok.type) + { + case TOK_CONTROL: + { + Device::Control* control = finder.FindControl(tok.qualifier); + if (control == nullptr) + { + *expr_out = new DummyExpression(tok.qualifier); + return EXPRESSION_PARSE_SUCCESS; + } + + *expr_out = new ControlExpression(tok.qualifier, control); + return EXPRESSION_PARSE_SUCCESS; + } + case TOK_LPAREN: + return Paren(expr_out); + default: + return EXPRESSION_PARSE_SYNTAX_ERROR; + } + } + + bool IsUnaryExpression(TokenType type) + { + switch (type) + { + case TOK_NOT: + return true; + default: + return false; + } + } + + ExpressionParseStatus Unary(ExpressionNode** expr_out) + { + ExpressionParseStatus status; + + if (IsUnaryExpression(Peek().type)) + { + Token tok = Chew(); + ExpressionNode* atom_expr; + if ((status = Atom(&atom_expr)) != EXPRESSION_PARSE_SUCCESS) + return status; + *expr_out = new UnaryExpression(tok.type, atom_expr); + return EXPRESSION_PARSE_SUCCESS; + } + + return Atom(expr_out); + } + + bool IsBinaryToken(TokenType type) + { + switch (type) + { + case TOK_AND: + case TOK_OR: + case TOK_ADD: + return true; + default: + return false; + } + } + + ExpressionParseStatus Binary(ExpressionNode** expr_out) + { + ExpressionParseStatus status; + + if ((status = Unary(expr_out)) != EXPRESSION_PARSE_SUCCESS) + return status; + + while (IsBinaryToken(Peek().type)) + { + Token tok = Chew(); + ExpressionNode* unary_expr; + if ((status = Unary(&unary_expr)) != EXPRESSION_PARSE_SUCCESS) + { + delete *expr_out; + return status; + } + + *expr_out = new BinaryExpression(tok.type, *expr_out, unary_expr); + } + + return EXPRESSION_PARSE_SUCCESS; + } + + ExpressionParseStatus Paren(ExpressionNode** expr_out) + { + ExpressionParseStatus status; + + // lparen already chewed + if ((status = Toplevel(expr_out)) != EXPRESSION_PARSE_SUCCESS) + return status; + + if (!Expects(TOK_RPAREN)) + { + delete *expr_out; + return EXPRESSION_PARSE_SYNTAX_ERROR; + } + + return EXPRESSION_PARSE_SUCCESS; + } + + ExpressionParseStatus Toplevel(ExpressionNode** expr_out) { return Binary(expr_out); } }; ControlState Expression::GetValue() { - return node->GetValue(); + return node->GetValue(); } void Expression::SetValue(ControlState value) { - node->SetValue(value); + node->SetValue(value); } -Expression::Expression(ExpressionNode *node_) +Expression::Expression(ExpressionNode* node_) { - node = node_; - num_controls = node->CountNumControls(); + node = node_; + num_controls = node->CountNumControls(); } Expression::~Expression() { - delete node; + delete node; } -static ExpressionParseStatus ParseExpressionInner(const std::string& str, ControlFinder &finder, Expression **expr_out) +static ExpressionParseStatus ParseExpressionInner(const std::string& str, ControlFinder& finder, + Expression** expr_out) { - ExpressionParseStatus status; - Expression *expr; - *expr_out = nullptr; - - if (str == "") - return EXPRESSION_PARSE_SUCCESS; - - Lexer l(str); - std::vector tokens; - status = l.Tokenize(tokens); - if (status != EXPRESSION_PARSE_SUCCESS) - return status; - - Parser p(tokens, finder); - status = p.Parse(&expr); - if (status != EXPRESSION_PARSE_SUCCESS) - return status; - - *expr_out = expr; - return EXPRESSION_PARSE_SUCCESS; + ExpressionParseStatus status; + Expression* expr; + *expr_out = nullptr; + + if (str == "") + return EXPRESSION_PARSE_SUCCESS; + + Lexer l(str); + std::vector tokens; + status = l.Tokenize(tokens); + if (status != EXPRESSION_PARSE_SUCCESS) + return status; + + Parser p(tokens, finder); + status = p.Parse(&expr); + if (status != EXPRESSION_PARSE_SUCCESS) + return status; + + *expr_out = expr; + return EXPRESSION_PARSE_SUCCESS; } -ExpressionParseStatus ParseExpression(const std::string& str, ControlFinder &finder, Expression **expr_out) +ExpressionParseStatus ParseExpression(const std::string& str, ControlFinder& finder, + Expression** expr_out) { - // Add compatibility with old simple expressions, which are simple - // barewords control names. + // Add compatibility with old simple expressions, which are simple + // barewords control names. - ControlQualifier qualifier; - qualifier.control_name = str; - qualifier.has_device = false; + ControlQualifier qualifier; + qualifier.control_name = str; + qualifier.has_device = false; - Device::Control *control = finder.FindControl(qualifier); - if (control) - { - *expr_out = new Expression(new ControlExpression(qualifier, control)); - return EXPRESSION_PARSE_SUCCESS; - } + Device::Control* control = finder.FindControl(qualifier); + if (control) + { + *expr_out = new Expression(new ControlExpression(qualifier, control)); + return EXPRESSION_PARSE_SUCCESS; + } - return ParseExpressionInner(str, finder, expr_out); + return ParseExpressionInner(str, finder, expr_out); } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h index 9575ff619d..6894c1924e 100644 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h +++ b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h @@ -11,59 +11,61 @@ namespace ciface { namespace ExpressionParser { - class ControlQualifier { public: - bool has_device; - Core::DeviceQualifier device_qualifier; - std::string control_name; - - ControlQualifier() : has_device(false) {} + bool has_device; + Core::DeviceQualifier device_qualifier; + std::string control_name; - operator std::string() - { - if (has_device) - return device_qualifier.ToString() + ":" + control_name; - else - return control_name; - } + ControlQualifier() : has_device(false) {} + operator std::string() + { + if (has_device) + return device_qualifier.ToString() + ":" + control_name; + else + return control_name; + } }; class ControlFinder { public: - ControlFinder(const Core::DeviceContainer &container_, const Core::DeviceQualifier &default_, const bool is_input_) : container(container_), default_device(default_), is_input(is_input_) {} - Core::Device::Control *FindControl(ControlQualifier qualifier); + ControlFinder(const Core::DeviceContainer& container_, const Core::DeviceQualifier& default_, + const bool is_input_) + : container(container_), default_device(default_), is_input(is_input_) + { + } + Core::Device::Control* FindControl(ControlQualifier qualifier); private: - Core::Device *FindDevice(ControlQualifier qualifier); - const Core::DeviceContainer &container; - const Core::DeviceQualifier &default_device; - bool is_input; + Core::Device* FindDevice(ControlQualifier qualifier); + const Core::DeviceContainer& container; + const Core::DeviceQualifier& default_device; + bool is_input; }; class ExpressionNode; class Expression { public: - Expression() : node(nullptr) {} - Expression(ExpressionNode *node); - ~Expression(); - ControlState GetValue(); - void SetValue (ControlState state); - int num_controls; - ExpressionNode *node; + Expression() : node(nullptr) {} + Expression(ExpressionNode* node); + ~Expression(); + ControlState GetValue(); + void SetValue(ControlState state); + int num_controls; + ExpressionNode* node; }; enum ExpressionParseStatus { - EXPRESSION_PARSE_SUCCESS = 0, - EXPRESSION_PARSE_SYNTAX_ERROR, - EXPRESSION_PARSE_NO_DEVICE, + EXPRESSION_PARSE_SUCCESS = 0, + EXPRESSION_PARSE_SYNTAX_ERROR, + EXPRESSION_PARSE_NO_DEVICE, }; -ExpressionParseStatus ParseExpression(const std::string& expr, ControlFinder &finder, Expression **expr_out); - +ExpressionParseStatus ParseExpression(const std::string& expr, ControlFinder& finder, + Expression** expr_out); } } diff --git a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.cpp b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.cpp index f67f63fc8b..34d0ed018b 100644 --- a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.cpp @@ -2,16 +2,15 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include "InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.h" #include #include #include "Common/Thread.h" -#include "InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.h" namespace ciface { namespace ForceFeedback { - // template instantiation template class ForceFeedbackDevice::Force; template class ForceFeedbackDevice::Force; @@ -19,192 +18,190 @@ template class ForceFeedbackDevice::Force; struct ForceType { - GUID guid; - const std::string name; + GUID guid; + const std::string name; }; -static const ForceType force_type_names[] = -{ - {GUID_ConstantForce, "Constant"}, // DICONSTANTFORCE - {GUID_RampForce, "Ramp"}, // DIRAMPFORCE - {GUID_Square, "Square"}, // DIPERIODIC ... - {GUID_Sine, "Sine"}, - {GUID_Triangle, "Triangle"}, - {GUID_SawtoothUp, "Sawtooth Up"}, - {GUID_SawtoothDown, "Sawtooth Down"}, - //{GUID_Spring, "Spring"}, // DICUSTOMFORCE ... < I think - //{GUID_Damper, "Damper"}, - //{GUID_Inertia, "Inertia"}, - //{GUID_Friction, "Friction"}, +static const ForceType force_type_names[] = { + {GUID_ConstantForce, "Constant"}, // DICONSTANTFORCE + {GUID_RampForce, "Ramp"}, // DIRAMPFORCE + {GUID_Square, "Square"}, // DIPERIODIC ... + {GUID_Sine, "Sine"}, + {GUID_Triangle, "Triangle"}, + {GUID_SawtoothUp, "Sawtooth Up"}, + {GUID_SawtoothDown, "Sawtooth Down"}, + //{GUID_Spring, "Spring"}, // DICUSTOMFORCE ... < I think + //{GUID_Damper, "Damper"}, + //{GUID_Inertia, "Inertia"}, + //{GUID_Friction, "Friction"}, }; bool ForceFeedbackDevice::InitForceFeedback(const LPDIRECTINPUTDEVICE8 device, int cAxes) { - if (cAxes == 0) - return false; - - // TODO: check for DIDC_FORCEFEEDBACK in devcaps? - - // temporary - DWORD rgdwAxes[2] = {DIJOFS_X, DIJOFS_Y}; - LONG rglDirection[2] = {-200, 0}; - - DIEFFECT eff; - memset(&eff, 0, sizeof(eff)); - eff.dwSize = sizeof(DIEFFECT); - eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; - eff.dwDuration = INFINITE; // (4 * DI_SECONDS) - eff.dwSamplePeriod = 0; - eff.dwGain = DI_FFNOMINALMAX; - eff.dwTriggerButton = DIEB_NOTRIGGER; - eff.dwTriggerRepeatInterval = 0; - eff.cAxes = std::min(1, cAxes); - eff.rgdwAxes = rgdwAxes; - eff.rglDirection = rglDirection; - - // initialize parameters - DICONSTANTFORCE diCF = { -10000 }; - diCF.lMagnitude = DI_FFNOMINALMAX; - DIRAMPFORCE diRF = { 0 }; - DIPERIODIC diPE = { 0 }; - - // doesn't seem needed - //DIENVELOPE env; - //eff.lpEnvelope = &env; - //ZeroMemory(&env, sizeof(env)); - //env.dwSize = sizeof(env); - - for (const ForceType& f : force_type_names) - { - if (f.guid == GUID_ConstantForce) - { - eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); - eff.lpvTypeSpecificParams = &diCF; - } - else if (f.guid == GUID_RampForce) - { - eff.cbTypeSpecificParams = sizeof(DIRAMPFORCE); - eff.lpvTypeSpecificParams = &diRF; - } - else - { - // all other forces need periodic parameters - eff.cbTypeSpecificParams = sizeof(DIPERIODIC); - eff.lpvTypeSpecificParams = &diPE; - } - - LPDIRECTINPUTEFFECT pEffect; - if (SUCCEEDED(device->CreateEffect(f.guid, &eff, &pEffect, nullptr))) - { - if (f.guid == GUID_ConstantForce) - AddOutput(new ForceConstant(f.name, pEffect)); - else if (f.guid == GUID_RampForce) - AddOutput(new ForceRamp(f.name, pEffect)); - else - AddOutput(new ForcePeriodic(f.name, pEffect)); - } - } - - // disable autocentering - if (Outputs().size()) - { - DIPROPDWORD dipdw; - dipdw.diph.dwSize = sizeof( DIPROPDWORD ); - dipdw.diph.dwHeaderSize = sizeof( DIPROPHEADER ); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = DIPROPAUTOCENTER_OFF; - device->SetProperty( DIPROP_AUTOCENTER, &dipdw.diph ); - } - - return true; + if (cAxes == 0) + return false; + + // TODO: check for DIDC_FORCEFEEDBACK in devcaps? + + // temporary + DWORD rgdwAxes[2] = {DIJOFS_X, DIJOFS_Y}; + LONG rglDirection[2] = {-200, 0}; + + DIEFFECT eff; + memset(&eff, 0, sizeof(eff)); + eff.dwSize = sizeof(DIEFFECT); + eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + eff.dwDuration = INFINITE; // (4 * DI_SECONDS) + eff.dwSamplePeriod = 0; + eff.dwGain = DI_FFNOMINALMAX; + eff.dwTriggerButton = DIEB_NOTRIGGER; + eff.dwTriggerRepeatInterval = 0; + eff.cAxes = std::min(1, cAxes); + eff.rgdwAxes = rgdwAxes; + eff.rglDirection = rglDirection; + + // initialize parameters + DICONSTANTFORCE diCF = {-10000}; + diCF.lMagnitude = DI_FFNOMINALMAX; + DIRAMPFORCE diRF = {0}; + DIPERIODIC diPE = {0}; + + // doesn't seem needed + // DIENVELOPE env; + // eff.lpEnvelope = &env; + // ZeroMemory(&env, sizeof(env)); + // env.dwSize = sizeof(env); + + for (const ForceType& f : force_type_names) + { + if (f.guid == GUID_ConstantForce) + { + eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + eff.lpvTypeSpecificParams = &diCF; + } + else if (f.guid == GUID_RampForce) + { + eff.cbTypeSpecificParams = sizeof(DIRAMPFORCE); + eff.lpvTypeSpecificParams = &diRF; + } + else + { + // all other forces need periodic parameters + eff.cbTypeSpecificParams = sizeof(DIPERIODIC); + eff.lpvTypeSpecificParams = &diPE; + } + + LPDIRECTINPUTEFFECT pEffect; + if (SUCCEEDED(device->CreateEffect(f.guid, &eff, &pEffect, nullptr))) + { + if (f.guid == GUID_ConstantForce) + AddOutput(new ForceConstant(f.name, pEffect)); + else if (f.guid == GUID_RampForce) + AddOutput(new ForceRamp(f.name, pEffect)); + else + AddOutput(new ForcePeriodic(f.name, pEffect)); + } + } + + // disable autocentering + if (Outputs().size()) + { + DIPROPDWORD dipdw; + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = DIPROPAUTOCENTER_OFF; + device->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph); + } + + return true; } -template +template ForceFeedbackDevice::Force

::~Force() { - m_iface->Stop(); - m_iface->Unload(); - m_iface->Release(); + m_iface->Stop(); + m_iface->Unload(); + m_iface->Release(); } -template +template void ForceFeedbackDevice::Force

::Update() { - DIEFFECT eff = {}; - eff.dwSize = sizeof(DIEFFECT); - eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + DIEFFECT eff = {}; + eff.dwSize = sizeof(DIEFFECT); + eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; - eff.cbTypeSpecificParams = sizeof(P); - eff.lpvTypeSpecificParams = ¶ms; + eff.cbTypeSpecificParams = sizeof(P); + eff.lpvTypeSpecificParams = ¶ms; - // set params and start effect - m_iface->SetParameters(&eff, DIEP_TYPESPECIFICPARAMS | DIEP_START); + // set params and start effect + m_iface->SetParameters(&eff, DIEP_TYPESPECIFICPARAMS | DIEP_START); } -template +template void ForceFeedbackDevice::Force

::Stop() { - m_iface->Stop(); + m_iface->Stop(); } -template<> +template <> void ForceFeedbackDevice::ForceConstant::SetState(const ControlState state) { - const LONG new_val = LONG(10000 * state); + const LONG new_val = LONG(10000 * state); - if (params.lMagnitude == new_val) - return; + if (params.lMagnitude == new_val) + return; - params.lMagnitude = new_val; - if (new_val) - Update(); - else - Stop(); + params.lMagnitude = new_val; + if (new_val) + Update(); + else + Stop(); } -template<> +template <> void ForceFeedbackDevice::ForceRamp::SetState(const ControlState state) { - const LONG new_val = LONG(10000 * state); + const LONG new_val = LONG(10000 * state); - if (params.lStart == new_val) - return; + if (params.lStart == new_val) + return; - params.lStart = params.lEnd = new_val; - if (new_val) - Update(); - else - Stop(); + params.lStart = params.lEnd = new_val; + if (new_val) + Update(); + else + Stop(); } -template<> +template <> void ForceFeedbackDevice::ForcePeriodic::SetState(const ControlState state) { - const DWORD new_val = DWORD(10000 * state); + const DWORD new_val = DWORD(10000 * state); - if (params.dwMagnitude == new_val) - return; + if (params.dwMagnitude == new_val) + return; - params.dwMagnitude = new_val; - if (new_val) - Update(); - else - Stop(); + params.dwMagnitude = new_val; + if (new_val) + Update(); + else + Stop(); } template ForceFeedbackDevice::Force

::Force(const std::string& name, LPDIRECTINPUTEFFECT iface) -: m_name(name), m_iface(iface) + : m_name(name), m_iface(iface) { - memset(¶ms, 0, sizeof(params)); + memset(¶ms, 0, sizeof(params)); } template std::string ForceFeedbackDevice::Force

::GetName() const { - return m_name; + return m_name; } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.h b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.h index f49198f037..5994bf2547 100644 --- a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.h +++ b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/ForceFeedbackDevice.h @@ -20,35 +20,32 @@ namespace ciface { namespace ForceFeedback { - - class ForceFeedbackDevice : public Core::Device { private: - template - class Force : public Output - { - public: - Force(const std::string& name, LPDIRECTINPUTEFFECT iface); - ~Force(); - - std::string GetName() const override; - void SetState(ControlState state) override; - void Update(); - void Stop(); - private: - const std::string m_name; - LPDIRECTINPUTEFFECT m_iface; - P params; - }; - typedef Force ForceConstant; - typedef Force ForceRamp; - typedef Force ForcePeriodic; + template + class Force : public Output + { + public: + Force(const std::string& name, LPDIRECTINPUTEFFECT iface); + ~Force(); + + std::string GetName() const override; + void SetState(ControlState state) override; + void Update(); + void Stop(); + + private: + const std::string m_name; + LPDIRECTINPUTEFFECT m_iface; + P params; + }; + typedef Force ForceConstant; + typedef Force ForceRamp; + typedef Force ForcePeriodic; public: - bool InitForceFeedback(const LPDIRECTINPUTDEVICE8, int cAxes); + bool InitForceFeedback(const LPDIRECTINPUTDEVICE8, int cAxes); }; - - } } diff --git a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/OSX/DirectInputAdapter.h b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/OSX/DirectInputAdapter.h index 133a4e2d09..84bd3bc4a5 100644 --- a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/OSX/DirectInputAdapter.h +++ b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/OSX/DirectInputAdapter.h @@ -14,210 +14,187 @@ #include -typedef LONG* LPLONG; // Missing type for ForceFeedback.h +typedef LONG* LPLONG; // Missing type for ForceFeedback.h #include #include -#include "DirectInputConstants.h" // Not stricty necessary -#include "Common/CommonTypes.h" // for LONG +#include "Common/CommonTypes.h" // for LONG +#include "DirectInputConstants.h" // Not stricty necessary namespace ciface { namespace ForceFeedback { - - // Prototypes class IUnknownImpl; class FFEffectAdapter; class FFDeviceAdapter; // Structs -typedef FFCAPABILITIES DICAPABILITIES; -typedef FFCONDITION DICONDITION; -typedef FFCONSTANTFORCE DICONSTANTFORCE; -typedef FFCUSTOMFORCE DICUSTOMFORCE; -typedef FFEFFECT DIEFFECT; -typedef FFEFFESCAPE DIEFFESCAPE; -typedef FFENVELOPE DIENVELOPE; -typedef FFPERIODIC DIPERIODIC; -typedef FFRAMPFORCE DIRAMPFORCE; +typedef FFCAPABILITIES DICAPABILITIES; +typedef FFCONDITION DICONDITION; +typedef FFCONSTANTFORCE DICONSTANTFORCE; +typedef FFCUSTOMFORCE DICUSTOMFORCE; +typedef FFEFFECT DIEFFECT; +typedef FFEFFESCAPE DIEFFESCAPE; +typedef FFENVELOPE DIENVELOPE; +typedef FFPERIODIC DIPERIODIC; +typedef FFRAMPFORCE DIRAMPFORCE; // Other types -typedef CFUUIDRef GUID; -typedef FFDeviceAdapter* FFDeviceAdapterReference; -typedef FFEffectAdapter* FFEffectAdapterReference; -typedef FFDeviceAdapterReference LPDIRECTINPUTDEVICE8; -typedef FFEffectAdapterReference LPDIRECTINPUTEFFECT; +typedef CFUUIDRef GUID; +typedef FFDeviceAdapter* FFDeviceAdapterReference; +typedef FFEffectAdapter* FFEffectAdapterReference; +typedef FFDeviceAdapterReference LPDIRECTINPUTDEVICE8; +typedef FFEffectAdapterReference LPDIRECTINPUTEFFECT; // Property structures #define DIPH_DEVICE 0 -typedef struct DIPROPHEADER { - DWORD dwSize; - DWORD dwHeaderSize; - DWORD dwObj; - DWORD dwHow; +typedef struct DIPROPHEADER +{ + DWORD dwSize; + DWORD dwHeaderSize; + DWORD dwObj; + DWORD dwHow; } DIPROPHEADER, *LPDIPROPHEADER; -typedef struct DIPROPDWORD { - DIPROPHEADER diph; - DWORD dwData; +typedef struct DIPROPDWORD +{ + DIPROPHEADER diph; + DWORD dwData; } DIPROPDWORD, *LPDIPROPDWORD; class IUnknownImpl : public IUnknown { private: - std::atomic m_cRef; + std::atomic m_cRef; public: - IUnknownImpl() : m_cRef(1) {} - virtual ~IUnknownImpl() {} - - HRESULT QueryInterface(REFIID iid, LPVOID *ppv) - { - *ppv = nullptr; - - if (CFEqual(&iid, IUnknownUUID)) - *ppv = this; - if (nullptr == *ppv) - return E_NOINTERFACE; - - ((IUnknown*)*ppv)->AddRef(); - - return S_OK; - } - - ULONG AddRef() - { - return ++m_cRef; - } - - ULONG Release() - { - if (--m_cRef == 0) - delete this; - - return m_cRef; - } + IUnknownImpl() : m_cRef(1) {} + virtual ~IUnknownImpl() {} + HRESULT QueryInterface(REFIID iid, LPVOID* ppv) + { + *ppv = nullptr; + + if (CFEqual(&iid, IUnknownUUID)) + *ppv = this; + if (nullptr == *ppv) + return E_NOINTERFACE; + + ((IUnknown*)*ppv)->AddRef(); + + return S_OK; + } + + ULONG AddRef() { return ++m_cRef; } + ULONG Release() + { + if (--m_cRef == 0) + delete this; + + return m_cRef; + } }; class FFEffectAdapter : public IUnknownImpl { private: - // Only used for destruction - FFDeviceObjectReference m_device; + // Only used for destruction + FFDeviceObjectReference m_device; public: - FFEffectObjectReference m_effect; - - FFEffectAdapter(FFDeviceObjectReference device, FFEffectObjectReference effect) : m_device(device), m_effect(effect) {} - ~FFEffectAdapter() { FFDeviceReleaseEffect(m_device, m_effect); } - - HRESULT Download() - { - return FFEffectDownload(m_effect); - } - - HRESULT Escape(FFEFFESCAPE *pFFEffectEscape) - { - return FFEffectEscape(m_effect, pFFEffectEscape); - } - - HRESULT GetEffectStatus(FFEffectStatusFlag *pFlags) - { - return FFEffectGetEffectStatus(m_effect, pFlags); - } - - HRESULT GetParameters(FFEFFECT *pFFEffect, FFEffectParameterFlag flags) - { - return FFEffectGetParameters(m_effect, pFFEffect, flags); - } - - HRESULT SetParameters(FFEFFECT *pFFEffect, FFEffectParameterFlag flags) - { - return FFEffectSetParameters(m_effect, pFFEffect, flags); - } - - HRESULT Start(UInt32 iterations, FFEffectStartFlag flags) - { - return FFEffectStart(m_effect, iterations, flags); - } - - HRESULT Stop() - { - return FFEffectStop(m_effect); - } - - HRESULT Unload() - { - return FFEffectUnload(m_effect); - } + FFEffectObjectReference m_effect; + + FFEffectAdapter(FFDeviceObjectReference device, FFEffectObjectReference effect) + : m_device(device), m_effect(effect) + { + } + ~FFEffectAdapter() { FFDeviceReleaseEffect(m_device, m_effect); } + HRESULT Download() { return FFEffectDownload(m_effect); } + HRESULT Escape(FFEFFESCAPE* pFFEffectEscape) { return FFEffectEscape(m_effect, pFFEffectEscape); } + HRESULT GetEffectStatus(FFEffectStatusFlag* pFlags) + { + return FFEffectGetEffectStatus(m_effect, pFlags); + } + + HRESULT GetParameters(FFEFFECT* pFFEffect, FFEffectParameterFlag flags) + { + return FFEffectGetParameters(m_effect, pFFEffect, flags); + } + + HRESULT SetParameters(FFEFFECT* pFFEffect, FFEffectParameterFlag flags) + { + return FFEffectSetParameters(m_effect, pFFEffect, flags); + } + + HRESULT Start(UInt32 iterations, FFEffectStartFlag flags) + { + return FFEffectStart(m_effect, iterations, flags); + } + + HRESULT Stop() { return FFEffectStop(m_effect); } + HRESULT Unload() { return FFEffectUnload(m_effect); } }; class FFDeviceAdapter : public IUnknownImpl { public: - FFDeviceObjectReference m_device; - - FFDeviceAdapter(FFDeviceObjectReference device) : m_device(device) {} - ~FFDeviceAdapter() { FFReleaseDevice(m_device); } - - static HRESULT Create(io_service_t hidDevice, FFDeviceAdapterReference *pDeviceReference) - { - FFDeviceObjectReference ref; - - HRESULT hr = FFCreateDevice(hidDevice, &ref); - if (SUCCEEDED(hr)) - *pDeviceReference = new FFDeviceAdapter(ref); - - return hr; - } - - HRESULT CreateEffect(CFUUIDRef uuidRef, FFEFFECT *pEffectDefinition, FFEffectAdapterReference *pEffectReference, IUnknown *punkOuter) - { - FFEffectObjectReference ref; - - HRESULT hr = FFDeviceCreateEffect(m_device, uuidRef, pEffectDefinition, &ref); - if (SUCCEEDED(hr)) - *pEffectReference = new FFEffectAdapter(m_device, ref); - - return hr; - } - - HRESULT Escape(FFEFFESCAPE *pFFEffectEscape) - { - return FFDeviceEscape(m_device, pFFEffectEscape); - } - - HRESULT GetForceFeedbackState(FFState *pFFState) - { - return FFDeviceGetForceFeedbackState(m_device, pFFState); - } - - HRESULT SendForceFeedbackCommand(FFCommandFlag flags) - { - return FFDeviceSendForceFeedbackCommand(m_device, flags); - } - - HRESULT SetCooperativeLevel(void *taskIdentifier, FFCooperativeLevelFlag flags) - { - return FFDeviceSetCooperativeLevel(m_device, taskIdentifier, flags); - } - - HRESULT SetProperty(FFProperty property, const LPDIPROPHEADER pdiph) - { - // There are only two properties supported - if (property != DIPROP_FFGAIN && property != DIPROP_AUTOCENTER) - return DIERR_UNSUPPORTED; - - // And they are both device properties - if (pdiph->dwHow != DIPH_DEVICE) - return DIERR_INVALIDPARAM; - - UInt32 value = ((const LPDIPROPDWORD)pdiph)->dwData; - return FFDeviceSetForceFeedbackProperty(m_device, property, &value); - } + FFDeviceObjectReference m_device; + + FFDeviceAdapter(FFDeviceObjectReference device) : m_device(device) {} + ~FFDeviceAdapter() { FFReleaseDevice(m_device); } + static HRESULT Create(io_service_t hidDevice, FFDeviceAdapterReference* pDeviceReference) + { + FFDeviceObjectReference ref; + + HRESULT hr = FFCreateDevice(hidDevice, &ref); + if (SUCCEEDED(hr)) + *pDeviceReference = new FFDeviceAdapter(ref); + + return hr; + } + + HRESULT CreateEffect(CFUUIDRef uuidRef, FFEFFECT* pEffectDefinition, + FFEffectAdapterReference* pEffectReference, IUnknown* punkOuter) + { + FFEffectObjectReference ref; + + HRESULT hr = FFDeviceCreateEffect(m_device, uuidRef, pEffectDefinition, &ref); + if (SUCCEEDED(hr)) + *pEffectReference = new FFEffectAdapter(m_device, ref); + + return hr; + } + + HRESULT Escape(FFEFFESCAPE* pFFEffectEscape) { return FFDeviceEscape(m_device, pFFEffectEscape); } + HRESULT GetForceFeedbackState(FFState* pFFState) + { + return FFDeviceGetForceFeedbackState(m_device, pFFState); + } + + HRESULT SendForceFeedbackCommand(FFCommandFlag flags) + { + return FFDeviceSendForceFeedbackCommand(m_device, flags); + } + + HRESULT SetCooperativeLevel(void* taskIdentifier, FFCooperativeLevelFlag flags) + { + return FFDeviceSetCooperativeLevel(m_device, taskIdentifier, flags); + } + + HRESULT SetProperty(FFProperty property, const LPDIPROPHEADER pdiph) + { + // There are only two properties supported + if (property != DIPROP_FFGAIN && property != DIPROP_AUTOCENTER) + return DIERR_UNSUPPORTED; + + // And they are both device properties + if (pdiph->dwHow != DIPH_DEVICE) + return DIERR_INVALIDPARAM; + + UInt32 value = ((const LPDIPROPDWORD)pdiph)->dwData; + return FFDeviceSetForceFeedbackProperty(m_device, property, &value); + } }; - } } diff --git a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/OSX/DirectInputConstants.h b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/OSX/DirectInputConstants.h index ceac035b6c..7e78eb7199 100644 --- a/Source/Core/InputCommon/ControllerInterface/ForceFeedback/OSX/DirectInputConstants.h +++ b/Source/Core/InputCommon/ControllerInterface/ForceFeedback/OSX/DirectInputConstants.h @@ -12,136 +12,136 @@ */ // UUIDs -#define GUID_ConstantForce kFFEffectType_ConstantForce_ID -#define GUID_CustomForce kFFEffectType_CustomForce_ID -#define GUID_Damper kFFEffectType_Damper_ID -#define GUID_Friction kFFEffectType_Friction_ID -#define GUID_Inertia kFFEffectType_Inertia_ID -#define GUID_RampForce kFFEffectType_RampForce_ID -#define GUID_SawtoothDown kFFEffectType_SawtoothDown_ID -#define GUID_SawtoothUp kFFEffectType_SawtoothUp_ID -#define GUID_Sine kFFEffectType_Sine_ID -#define GUID_Spring kFFEffectType_Spring_ID -#define GUID_Square kFFEffectType_Square_ID -#define GUID_Triangle kFFEffectType_Triangle_ID +#define GUID_ConstantForce kFFEffectType_ConstantForce_ID +#define GUID_CustomForce kFFEffectType_CustomForce_ID +#define GUID_Damper kFFEffectType_Damper_ID +#define GUID_Friction kFFEffectType_Friction_ID +#define GUID_Inertia kFFEffectType_Inertia_ID +#define GUID_RampForce kFFEffectType_RampForce_ID +#define GUID_SawtoothDown kFFEffectType_SawtoothDown_ID +#define GUID_SawtoothUp kFFEffectType_SawtoothUp_ID +#define GUID_Sine kFFEffectType_Sine_ID +#define GUID_Spring kFFEffectType_Spring_ID +#define GUID_Square kFFEffectType_Square_ID +#define GUID_Triangle kFFEffectType_Triangle_ID // Miscellaneous -#define DI_DEGREES FF_DEGREES -#define DI_DOWNLOADSKIPPED FF_DOWNLOADSKIPPED -#define DI_EFFECTRESTARTED FF_EFFECTRESTARTED -#define DI_FALSE FF_FALSE -#define DI_FFNOMINALMAX FF_FFNOMINALMAX -#define DI_INFINITE FF_INFINITE -#define DI_OK FF_OK -#define DI_SECONDS FF_SECONDS -#define DI_TRUNCATED FF_TRUNCATED -#define DI_TRUNCATEDANDRESTARTED FF_TRUNCATEDANDRESTARTED -#define DIEFF_OBJECTOFFSETS FFEFF_OBJECTOFFSETS -#define DIERR_DEVICEFULL FFERR_DEVICEFULL -#define DIERR_DEVICENOTREG FFERR_DEVICENOTREG -#define DIERR_DEVICEPAUSED FFERR_DEVICEPAUSED -#define DIERR_DEVICERELEASED FFERR_DEVICERELEASED -#define DIERR_EFFECTPLAYING FFERR_EFFECTPLAYING -#define DIERR_EFFECTTYPEMISMATCH FFERR_EFFECTTYPEMISMATCH -#define DIERR_EFFECTTYPENOTSUPPORTED FFERR_EFFECTTYPENOTSUPPORTED -#define DIERR_GENERIC FFERR_GENERIC -#define DIERR_HASEFFECTS FFERR_HASEFFECTS -#define DIERR_INCOMPLETEEFFECT FFERR_INCOMPLETEEFFECT -#define DIERR_INTERNAL FFERR_INTERNAL -#define DIERR_INVALIDDOWNLOADID FFERR_INVALIDDOWNLOADID -#define DIERR_INVALIDPARAM FFERR_INVALIDPARAM -#define DIERR_MOREDATA FFERR_MOREDATA -#define DIERR_NOINTERFACE FFERR_NOINTERFACE -#define DIERR_NOTDOWNLOADED FFERR_NOTDOWNLOADED -#define DIERR_NOTINITIALIZED FFERR_NOTINITIALIZED -#define DIERR_OUTOFMEMORY FFERR_OUTOFMEMORY -#define DIERR_UNPLUGGED FFERR_UNPLUGGED -#define DIERR_UNSUPPORTED FFERR_UNSUPPORTED -#define DIERR_UNSUPPORTEDAXIS FFERR_UNSUPPORTEDAXIS -#define DIJOFS_X FFJOFS_X -#define DIJOFS_Y FFJOFS_Y -#define DIJOFS_Z FFJOFS_Z +#define DI_DEGREES FF_DEGREES +#define DI_DOWNLOADSKIPPED FF_DOWNLOADSKIPPED +#define DI_EFFECTRESTARTED FF_EFFECTRESTARTED +#define DI_FALSE FF_FALSE +#define DI_FFNOMINALMAX FF_FFNOMINALMAX +#define DI_INFINITE FF_INFINITE +#define DI_OK FF_OK +#define DI_SECONDS FF_SECONDS +#define DI_TRUNCATED FF_TRUNCATED +#define DI_TRUNCATEDANDRESTARTED FF_TRUNCATEDANDRESTARTED +#define DIEFF_OBJECTOFFSETS FFEFF_OBJECTOFFSETS +#define DIERR_DEVICEFULL FFERR_DEVICEFULL +#define DIERR_DEVICENOTREG FFERR_DEVICENOTREG +#define DIERR_DEVICEPAUSED FFERR_DEVICEPAUSED +#define DIERR_DEVICERELEASED FFERR_DEVICERELEASED +#define DIERR_EFFECTPLAYING FFERR_EFFECTPLAYING +#define DIERR_EFFECTTYPEMISMATCH FFERR_EFFECTTYPEMISMATCH +#define DIERR_EFFECTTYPENOTSUPPORTED FFERR_EFFECTTYPENOTSUPPORTED +#define DIERR_GENERIC FFERR_GENERIC +#define DIERR_HASEFFECTS FFERR_HASEFFECTS +#define DIERR_INCOMPLETEEFFECT FFERR_INCOMPLETEEFFECT +#define DIERR_INTERNAL FFERR_INTERNAL +#define DIERR_INVALIDDOWNLOADID FFERR_INVALIDDOWNLOADID +#define DIERR_INVALIDPARAM FFERR_INVALIDPARAM +#define DIERR_MOREDATA FFERR_MOREDATA +#define DIERR_NOINTERFACE FFERR_NOINTERFACE +#define DIERR_NOTDOWNLOADED FFERR_NOTDOWNLOADED +#define DIERR_NOTINITIALIZED FFERR_NOTINITIALIZED +#define DIERR_OUTOFMEMORY FFERR_OUTOFMEMORY +#define DIERR_UNPLUGGED FFERR_UNPLUGGED +#define DIERR_UNSUPPORTED FFERR_UNSUPPORTED +#define DIERR_UNSUPPORTEDAXIS FFERR_UNSUPPORTEDAXIS +#define DIJOFS_X FFJOFS_X +#define DIJOFS_Y FFJOFS_Y +#define DIJOFS_Z FFJOFS_Z // FFCapabilitiesEffectSubType -#define DICAP_ST_KINESTHETIC FFCAP_ST_KINESTHETIC -#define DICAP_ST_VIBRATION FFCAP_ST_VIBRATION +#define DICAP_ST_KINESTHETIC FFCAP_ST_KINESTHETIC +#define DICAP_ST_VIBRATION FFCAP_ST_VIBRATION // FFCapabilitiesEffectType -#define DICAP_ET_CONSTANTFORCE FFCAP_ET_CONSTANTFORCE -#define DICAP_ET_RAMPFORCE FFCAP_ET_RAMPFORCE -#define DICAP_ET_SQUARE FFCAP_ET_SQUARE -#define DICAP_ET_SINE FFCAP_ET_SINE -#define DICAP_ET_TRIANGLE FFCAP_ET_TRIANGLE -#define DICAP_ET_SAWTOOTHUP FFCAP_ET_SAWTOOTHUP -#define DICAP_ET_SAWTOOTHDOWN FFCAP_ET_SAWTOOTHDOWN -#define DICAP_ET_SPRING FFCAP_ET_SPRING -#define DICAP_ET_DAMPER FFCAP_ET_DAMPER -#define DICAP_ET_INERTIA FFCAP_ET_INERTIA -#define DICAP_ET_FRICTION FFCAP_ET_FRICTION -#define DICAP_ET_CUSTOMFORCE FFCAP_ET_CUSTOMFORCE +#define DICAP_ET_CONSTANTFORCE FFCAP_ET_CONSTANTFORCE +#define DICAP_ET_RAMPFORCE FFCAP_ET_RAMPFORCE +#define DICAP_ET_SQUARE FFCAP_ET_SQUARE +#define DICAP_ET_SINE FFCAP_ET_SINE +#define DICAP_ET_TRIANGLE FFCAP_ET_TRIANGLE +#define DICAP_ET_SAWTOOTHUP FFCAP_ET_SAWTOOTHUP +#define DICAP_ET_SAWTOOTHDOWN FFCAP_ET_SAWTOOTHDOWN +#define DICAP_ET_SPRING FFCAP_ET_SPRING +#define DICAP_ET_DAMPER FFCAP_ET_DAMPER +#define DICAP_ET_INERTIA FFCAP_ET_INERTIA +#define DICAP_ET_FRICTION FFCAP_ET_FRICTION +#define DICAP_ET_CUSTOMFORCE FFCAP_ET_CUSTOMFORCE // FFCommandFlag -#define DISFFC_RESET FFSFFC_RESET -#define DISFFC_STOPALL FFSFFC_STOPALL -#define DISFFC_PAUSE FFSFFC_PAUSE -#define DISFFC_CONTINUE FFSFFC_CONTINUE -#define DISFFC_SETACTUATORSON FFSFFC_SETACTUATORSON -#define DISFFC_SETACTUATORSOFF FFSFFC_SETACTUATORSOFF +#define DISFFC_RESET FFSFFC_RESET +#define DISFFC_STOPALL FFSFFC_STOPALL +#define DISFFC_PAUSE FFSFFC_PAUSE +#define DISFFC_CONTINUE FFSFFC_CONTINUE +#define DISFFC_SETACTUATORSON FFSFFC_SETACTUATORSON +#define DISFFC_SETACTUATORSOFF FFSFFC_SETACTUATORSOFF // FFCooperativeLevelFlag -#define DISCL_EXCLUSIVE FFSCL_EXCLUSIVE -#define DISCL_NONEXCLUSIVE FFSCL_NONEXCLUSIVE -#define DISCL_FOREGROUND FFSCL_FOREGROUND -#define DISCL_BACKGROUND FFSCL_BACKGROUND +#define DISCL_EXCLUSIVE FFSCL_EXCLUSIVE +#define DISCL_NONEXCLUSIVE FFSCL_NONEXCLUSIVE +#define DISCL_FOREGROUND FFSCL_FOREGROUND +#define DISCL_BACKGROUND FFSCL_BACKGROUND // FFCoordinateSystemFlag -#define DIEFF_CARTESIAN FFEFF_CARTESIAN -#define DIEFF_POLAR FFEFF_POLAR -#define DIEFF_SPHERICAL FFEFF_SPHERICAL +#define DIEFF_CARTESIAN FFEFF_CARTESIAN +#define DIEFF_POLAR FFEFF_POLAR +#define DIEFF_SPHERICAL FFEFF_SPHERICAL // FFEffectParameterFlag -#define DIEP_DURATION FFEP_DURATION -#define DIEP_SAMPLEPERIOD FFEP_SAMPLEPERIOD -#define DIEP_GAIN FFEP_GAIN -#define DIEP_TRIGGERBUTTON FFEP_TRIGGERBUTTON -#define DIEP_TRIGGERREPEATINTERVAL FFEP_TRIGGERREPEATINTERVAL -#define DIEP_AXES FFEP_AXES -#define DIEP_DIRECTION FFEP_DIRECTION -#define DIEP_ENVELOPE FFEP_ENVELOPE -#define DIEP_TYPESPECIFICPARAMS FFEP_TYPESPECIFICPARAMS -#define DIEP_STARTDELAY FFEP_STARTDELAY -#define DIEP_ALLPARAMS FFEP_ALLPARAMS -#define DIEP_START FFEP_START -#define DIEP_NORESTART FFEP_NORESTART -#define DIEP_NODOWNLOAD FFEP_NODOWNLOAD -#define DIEB_NOTRIGGER FFEB_NOTRIGGER +#define DIEP_DURATION FFEP_DURATION +#define DIEP_SAMPLEPERIOD FFEP_SAMPLEPERIOD +#define DIEP_GAIN FFEP_GAIN +#define DIEP_TRIGGERBUTTON FFEP_TRIGGERBUTTON +#define DIEP_TRIGGERREPEATINTERVAL FFEP_TRIGGERREPEATINTERVAL +#define DIEP_AXES FFEP_AXES +#define DIEP_DIRECTION FFEP_DIRECTION +#define DIEP_ENVELOPE FFEP_ENVELOPE +#define DIEP_TYPESPECIFICPARAMS FFEP_TYPESPECIFICPARAMS +#define DIEP_STARTDELAY FFEP_STARTDELAY +#define DIEP_ALLPARAMS FFEP_ALLPARAMS +#define DIEP_START FFEP_START +#define DIEP_NORESTART FFEP_NORESTART +#define DIEP_NODOWNLOAD FFEP_NODOWNLOAD +#define DIEB_NOTRIGGER FFEB_NOTRIGGER // FFEffectStartFlag -#define DIES_SOLO FFES_SOLO -#define DIES_NODOWNLOAD FFES_NODOWNLOAD +#define DIES_SOLO FFES_SOLO +#define DIES_NODOWNLOAD FFES_NODOWNLOAD // FFEffectStatusFlag -#define DIEGES_NOTPLAYING FFEGES_NOTPLAYING -#define DIEGES_PLAYING FFEGES_PLAYING -#define DIEGES_EMULATED FFEGES_EMULATED +#define DIEGES_NOTPLAYING FFEGES_NOTPLAYING +#define DIEGES_PLAYING FFEGES_PLAYING +#define DIEGES_EMULATED FFEGES_EMULATED // FFProperty -#define DIPROP_FFGAIN FFPROP_FFGAIN -#define DIPROP_AUTOCENTER FFPROP_AUTOCENTER +#define DIPROP_FFGAIN FFPROP_FFGAIN +#define DIPROP_AUTOCENTER FFPROP_AUTOCENTER // not defined in ForceFeedbackConstants.h -#define DIPROPAUTOCENTER_OFF 0 -#define DIPROPAUTOCENTER_ON 1 +#define DIPROPAUTOCENTER_OFF 0 +#define DIPROPAUTOCENTER_ON 1 // FFState -#define DIGFFS_EMPTY FFGFFS_EMPTY -#define DIGFFS_STOPPED FFGFFS_STOPPED -#define DIGFFS_PAUSED FFGFFS_PAUSED -#define DIGFFS_ACTUATORSON FFGFFS_ACTUATORSON -#define DIGFFS_ACTUATORSOFF FFGFFS_ACTUATORSOFF -#define DIGFFS_POWERON FFGFFS_POWERON -#define DIGFFS_POWEROFF FFGFFS_POWEROFF -#define DIGFFS_SAFETYSWITCHON FFGFFS_SAFETYSWITCHON -#define DIGFFS_SAFETYSWITCHOFF FFGFFS_SAFETYSWITCHOFF -#define DIGFFS_USERFFSWITCHON FFGFFS_USERFFSWITCHON -#define DIGFFS_USERFFSWITCHOFF FFGFFS_USERFFSWITCHOFF -#define DIGFFS_DEVICELOST FFGFFS_DEVICELOST +#define DIGFFS_EMPTY FFGFFS_EMPTY +#define DIGFFS_STOPPED FFGFFS_STOPPED +#define DIGFFS_PAUSED FFGFFS_PAUSED +#define DIGFFS_ACTUATORSON FFGFFS_ACTUATORSON +#define DIGFFS_ACTUATORSOFF FFGFFS_ACTUATORSOFF +#define DIGFFS_POWERON FFGFFS_POWERON +#define DIGFFS_POWEROFF FFGFFS_POWEROFF +#define DIGFFS_SAFETYSWITCHON FFGFFS_SAFETYSWITCHON +#define DIGFFS_SAFETYSWITCHOFF FFGFFS_SAFETYSWITCHOFF +#define DIGFFS_USERFFSWITCHON FFGFFS_USERFFSWITCHON +#define DIGFFS_USERFFSWITCHOFF FFGFFS_USERFFSWITCHOFF +#define DIGFFS_DEVICELOST FFGFFS_DEVICELOST diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h index 5cb4a87fd8..c257d7e8f4 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h @@ -10,11 +10,9 @@ namespace ciface { namespace OSX { - -void Init(std::vector& devices, void *window); +void Init(std::vector& devices, void* window); void DeInit(); -void DeviceElementDebugPrint(const void *, void *); - +void DeviceElementDebugPrint(const void*, void*); } } diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm index 18542b6c50..1335b01967 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm @@ -2,13 +2,13 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include #include #include -#include #include "InputCommon/ControllerInterface/OSX/OSX.h" -#include "InputCommon/ControllerInterface/OSX/OSXKeyboard.h" #include "InputCommon/ControllerInterface/OSX/OSXJoystick.h" +#include "InputCommon/ControllerInterface/OSX/OSXKeyboard.h" #include @@ -16,103 +16,94 @@ namespace ciface { namespace OSX { - - static IOHIDManagerRef HIDManager = nullptr; static CFStringRef OurRunLoop = CFSTR("DolphinOSXInput"); static std::map kbd_name_counts, joy_name_counts; -void DeviceElementDebugPrint(const void *value, void *context) +void DeviceElementDebugPrint(const void* value, void* context) { - IOHIDElementRef e = (IOHIDElementRef)value; - bool recurse = false; - if (context) - recurse = *(bool*)context; - - std::string type = ""; - switch (IOHIDElementGetType(e)) - { - case kIOHIDElementTypeInput_Axis: - type = "axis"; - break; - case kIOHIDElementTypeInput_Button: - type = "button"; - break; - case kIOHIDElementTypeInput_Misc: - type = "misc"; - break; - case kIOHIDElementTypeInput_ScanCodes: - type = "scancodes"; - break; - case kIOHIDElementTypeOutput: - type = "output"; - break; - case kIOHIDElementTypeFeature: - type = "feature"; - break; - case kIOHIDElementTypeCollection: - type = "collection"; - break; - } - - std::string c_type = ""; - if (type == "collection") - { - switch (IOHIDElementGetCollectionType(e)) - { - case kIOHIDElementCollectionTypePhysical: - c_type = "physical"; - break; - case kIOHIDElementCollectionTypeApplication: - c_type = "application"; - break; - case kIOHIDElementCollectionTypeLogical: - c_type = "logical"; - break; - case kIOHIDElementCollectionTypeReport: - c_type = "report"; - break; - case kIOHIDElementCollectionTypeNamedArray: - c_type = "namedArray"; - break; - case kIOHIDElementCollectionTypeUsageSwitch: - c_type = "usageSwitch"; - break; - case kIOHIDElementCollectionTypeUsageModifier: - c_type = "usageModifier"; - break; - } - } - - c_type.append(" "); - NSLog(@"%s%s%spage: 0x%x usage: 0x%x name: %@ " - "lmin: %ld lmax: %ld pmin: %ld pmax: %ld", - type.c_str(), - type == "collection" ? ":" : "", - type == "collection" ? c_type.c_str() : " ", - IOHIDElementGetUsagePage(e), - IOHIDElementGetUsage(e), - IOHIDElementGetName(e), // usually just nullptr - IOHIDElementGetLogicalMin(e), - IOHIDElementGetLogicalMax(e), - IOHIDElementGetPhysicalMin(e), - IOHIDElementGetPhysicalMax(e)); - - if ((type == "collection") && recurse) - { - CFArrayRef elements = IOHIDElementGetChildren(e); - CFRange range = {0, CFArrayGetCount(elements)}; - // this leaks...but it's just debug code, right? :D - CFArrayApplyFunction(elements, range, - DeviceElementDebugPrint, nullptr); - } + IOHIDElementRef e = (IOHIDElementRef)value; + bool recurse = false; + if (context) + recurse = *(bool*)context; + + std::string type = ""; + switch (IOHIDElementGetType(e)) + { + case kIOHIDElementTypeInput_Axis: + type = "axis"; + break; + case kIOHIDElementTypeInput_Button: + type = "button"; + break; + case kIOHIDElementTypeInput_Misc: + type = "misc"; + break; + case kIOHIDElementTypeInput_ScanCodes: + type = "scancodes"; + break; + case kIOHIDElementTypeOutput: + type = "output"; + break; + case kIOHIDElementTypeFeature: + type = "feature"; + break; + case kIOHIDElementTypeCollection: + type = "collection"; + break; + } + + std::string c_type = ""; + if (type == "collection") + { + switch (IOHIDElementGetCollectionType(e)) + { + case kIOHIDElementCollectionTypePhysical: + c_type = "physical"; + break; + case kIOHIDElementCollectionTypeApplication: + c_type = "application"; + break; + case kIOHIDElementCollectionTypeLogical: + c_type = "logical"; + break; + case kIOHIDElementCollectionTypeReport: + c_type = "report"; + break; + case kIOHIDElementCollectionTypeNamedArray: + c_type = "namedArray"; + break; + case kIOHIDElementCollectionTypeUsageSwitch: + c_type = "usageSwitch"; + break; + case kIOHIDElementCollectionTypeUsageModifier: + c_type = "usageModifier"; + break; + } + } + + c_type.append(" "); + NSLog(@"%s%s%spage: 0x%x usage: 0x%x name: %@ " + "lmin: %ld lmax: %ld pmin: %ld pmax: %ld", + type.c_str(), type == "collection" ? ":" : "", type == "collection" ? c_type.c_str() : " ", + IOHIDElementGetUsagePage(e), IOHIDElementGetUsage(e), + IOHIDElementGetName(e), // usually just nullptr + IOHIDElementGetLogicalMin(e), IOHIDElementGetLogicalMax(e), IOHIDElementGetPhysicalMin(e), + IOHIDElementGetPhysicalMax(e)); + + if ((type == "collection") && recurse) + { + CFArrayRef elements = IOHIDElementGetChildren(e); + CFRange range = {0, CFArrayGetCount(elements)}; + // this leaks...but it's just debug code, right? :D + CFArrayApplyFunction(elements, range, DeviceElementDebugPrint, nullptr); + } } static void DeviceDebugPrint(IOHIDDeviceRef device) { #if 0 -#define shortlog(x) NSLog(@"%s: %@", \ - x, IOHIDDeviceGetProperty(device, CFSTR(x))); +#define shortlog(x) NSLog(@"%s: %@", x, IOHIDDeviceGetProperty(device, CFSTR(x))); NSLog(@"-------------------------"); NSLog(@"Got Device: %@", IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey))); @@ -139,81 +130,68 @@ static void DeviceDebugPrint(IOHIDDeviceRef device) #endif } -static void *g_window; +static void* g_window; -static void DeviceMatching_callback(void* inContext, - IOReturn inResult, - void *inSender, - IOHIDDeviceRef inIOHIDDeviceRef) +static void DeviceMatching_callback(void* inContext, IOReturn inResult, void* inSender, + IOHIDDeviceRef inIOHIDDeviceRef) { - NSString *pName = (NSString *) - IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDProductKey)); - std::string name = (pName != nullptr) ? [pName UTF8String] : "Unknown device"; + NSString* pName = (NSString*)IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDProductKey)); + std::string name = (pName != nullptr) ? [pName UTF8String] : "Unknown device"; - DeviceDebugPrint(inIOHIDDeviceRef); + DeviceDebugPrint(inIOHIDDeviceRef); - std::vector *devices = - (std::vector *)inContext; + std::vector* devices = (std::vector*)inContext; - // Add to the devices vector if it's of a type we want - if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, - kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) - devices->push_back(new Keyboard(inIOHIDDeviceRef, - name, kbd_name_counts[name]++, g_window)); + // Add to the devices vector if it's of a type we want + if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) + devices->push_back(new Keyboard(inIOHIDDeviceRef, name, kbd_name_counts[name]++, g_window)); #if 0 else if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) devices->push_back(new Mouse(inIOHIDDeviceRef, name, mouse_name_counts[name]++)); #endif - else - devices->push_back(new Joystick(inIOHIDDeviceRef, - name, joy_name_counts[name]++)); + else + devices->push_back(new Joystick(inIOHIDDeviceRef, name, joy_name_counts[name]++)); } -void Init(std::vector& devices, void *window) +void Init(std::vector& devices, void* window) { - HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, - kIOHIDOptionsTypeNone); - if (!HIDManager) - NSLog(@"Failed to create HID Manager reference"); - - g_window = window; - - IOHIDManagerSetDeviceMatching(HIDManager, nullptr); - - // Callbacks for acquisition or loss of a matching device - IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, - DeviceMatching_callback, (void *)&devices); - - // Match devices that are plugged in right now - IOHIDManagerScheduleWithRunLoop(HIDManager, - CFRunLoopGetCurrent(), OurRunLoop); - if (IOHIDManagerOpen(HIDManager, kIOHIDOptionsTypeNone) != - kIOReturnSuccess) - NSLog(@"Failed to open HID Manager"); - - kbd_name_counts.clear(); - joy_name_counts.clear(); - - // Wait while current devices are initialized - while (CFRunLoopRunInMode(OurRunLoop, 0, TRUE) == - kCFRunLoopRunHandledSource) {}; - - // Things should be configured now - // Disable hotplugging and other scheduling - IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, nullptr, nullptr); - IOHIDManagerUnscheduleFromRunLoop(HIDManager, - CFRunLoopGetCurrent(), OurRunLoop); + HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + if (!HIDManager) + NSLog(@"Failed to create HID Manager reference"); + + g_window = window; + + IOHIDManagerSetDeviceMatching(HIDManager, nullptr); + + // Callbacks for acquisition or loss of a matching device + IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, DeviceMatching_callback, (void*)&devices); + + // Match devices that are plugged in right now + IOHIDManagerScheduleWithRunLoop(HIDManager, CFRunLoopGetCurrent(), OurRunLoop); + if (IOHIDManagerOpen(HIDManager, kIOHIDOptionsTypeNone) != kIOReturnSuccess) + NSLog(@"Failed to open HID Manager"); + + kbd_name_counts.clear(); + joy_name_counts.clear(); + + // Wait while current devices are initialized + while (CFRunLoopRunInMode(OurRunLoop, 0, TRUE) == kCFRunLoopRunHandledSource) + { + }; + + // Things should be configured now + // Disable hotplugging and other scheduling + IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, nullptr, nullptr); + IOHIDManagerUnscheduleFromRunLoop(HIDManager, CFRunLoopGetCurrent(), OurRunLoop); } void DeInit() { - // This closes all devices as well - IOHIDManagerClose(HIDManager, kIOHIDOptionsTypeNone); - CFRelease(HIDManager); + // This closes all devices as well + IOHIDManagerClose(HIDManager, kIOHIDOptionsTypeNone); + CFRelease(HIDManager); } - - } } diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h index d0ed715130..3e3d62b2c6 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.h @@ -13,81 +13,79 @@ namespace ciface { namespace OSX { - class Joystick : public ForceFeedback::ForceFeedbackDevice { private: - class Button : public Input - { - public: - Button(IOHIDElementRef element, IOHIDDeviceRef device) - : m_element(element), m_device(device) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const IOHIDElementRef m_element; - const IOHIDDeviceRef m_device; - }; - - class Axis : public Input - { - public: - enum direction - { - positive = 0, - negative - }; - - Axis(IOHIDElementRef element, IOHIDDeviceRef device, direction dir); - std::string GetName() const override; - ControlState GetState() const override; - - private: - const IOHIDElementRef m_element; - const IOHIDDeviceRef m_device; - std::string m_name; - const direction m_direction; - float m_neutral; - float m_scale; - }; - - class Hat : public Input - { - public: - enum direction - { - up = 0, - right, - down, - left - }; - - Hat(IOHIDElementRef element, IOHIDDeviceRef device, direction dir); - std::string GetName() const override; - ControlState GetState() const override; - - private: - const IOHIDElementRef m_element; - const IOHIDDeviceRef m_device; - const char* m_name; - const direction m_direction; - }; + class Button : public Input + { + public: + Button(IOHIDElementRef element, IOHIDDeviceRef device) : m_element(element), m_device(device) {} + std::string GetName() const override; + ControlState GetState() const override; + + private: + const IOHIDElementRef m_element; + const IOHIDDeviceRef m_device; + }; + + class Axis : public Input + { + public: + enum direction + { + positive = 0, + negative + }; + + Axis(IOHIDElementRef element, IOHIDDeviceRef device, direction dir); + std::string GetName() const override; + ControlState GetState() const override; + + private: + const IOHIDElementRef m_element; + const IOHIDDeviceRef m_device; + std::string m_name; + const direction m_direction; + float m_neutral; + float m_scale; + }; + + class Hat : public Input + { + public: + enum direction + { + up = 0, + right, + down, + left + }; + + Hat(IOHIDElementRef element, IOHIDDeviceRef device, direction dir); + std::string GetName() const override; + ControlState GetState() const override; + + private: + const IOHIDElementRef m_element; + const IOHIDDeviceRef m_device; + const char* m_name; + const direction m_direction; + }; public: - Joystick(IOHIDDeviceRef device, std::string name, int index); - ~Joystick(); + Joystick(IOHIDDeviceRef device, std::string name, int index); + ~Joystick(); - std::string GetName() const override; - std::string GetSource() const override; - int GetId() const override; + std::string GetName() const override; + std::string GetSource() const override; + int GetId() const override; private: - const IOHIDDeviceRef m_device; - const std::string m_device_name; - const int m_index; + const IOHIDDeviceRef m_device; + const std::string m_device_name; + const int m_index; - ForceFeedback::FFDeviceAdapterReference m_ff_device; + ForceFeedback::FFDeviceAdapterReference m_ff_device; }; - } } diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm index bc503ec398..7eb05a52ce 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXJoystick.mm @@ -13,281 +13,266 @@ namespace ciface { namespace OSX { - - Joystick::Joystick(IOHIDDeviceRef device, std::string name, int index) - : m_device(device) - , m_device_name(name) - , m_index(index) - , m_ff_device(nullptr) + : m_device(device), m_device_name(name), m_index(index), m_ff_device(nullptr) { - // Buttons - NSDictionary *buttonDict = @{ - @kIOHIDElementTypeKey : @(kIOHIDElementTypeInput_Button), - @kIOHIDElementUsagePageKey : @(kHIDPage_Button) - }; - - CFArrayRef buttons = IOHIDDeviceCopyMatchingElements(m_device, - (CFDictionaryRef)buttonDict, kIOHIDOptionsTypeNone); - - if (buttons) - { - for (int i = 0; i < CFArrayGetCount(buttons); i++) - { - IOHIDElementRef e = - (IOHIDElementRef)CFArrayGetValueAtIndex(buttons, i); - //DeviceElementDebugPrint(e, nullptr); - - AddInput(new Button(e, m_device)); - } - CFRelease(buttons); - } - - // Axes - NSDictionary *axisDict = @{ - @kIOHIDElementTypeKey : @(kIOHIDElementTypeInput_Misc) - }; - - CFArrayRef axes = IOHIDDeviceCopyMatchingElements(m_device, - (CFDictionaryRef)axisDict, kIOHIDOptionsTypeNone); - - if (axes) - { - for (int i = 0; i < CFArrayGetCount(axes); i++) - { - IOHIDElementRef e = - (IOHIDElementRef)CFArrayGetValueAtIndex(axes, i); - //DeviceElementDebugPrint(e, nullptr); - - if (IOHIDElementGetUsage(e) == kHIDUsage_GD_Hatswitch) - { - AddInput(new Hat(e, m_device, Hat::up)); - AddInput(new Hat(e, m_device, Hat::right)); - AddInput(new Hat(e, m_device, Hat::down)); - AddInput(new Hat(e, m_device, Hat::left)); - } - else - { - AddAnalogInputs(new Axis(e, m_device, Axis::negative), - new Axis(e, m_device, Axis::positive)); - } - } - CFRelease(axes); - } - - // Force Feedback - FFCAPABILITIES ff_caps; - if (SUCCEEDED(ForceFeedback::FFDeviceAdapter::Create(IOHIDDeviceGetService(m_device), &m_ff_device)) && - SUCCEEDED(FFDeviceGetForceFeedbackCapabilities(m_ff_device->m_device, &ff_caps))) - { - InitForceFeedback(m_ff_device, ff_caps.numFfAxes); - } + // Buttons + NSDictionary* buttonDict = @{ + @kIOHIDElementTypeKey : @(kIOHIDElementTypeInput_Button), + @kIOHIDElementUsagePageKey : @(kHIDPage_Button) + }; + + CFArrayRef buttons = + IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)buttonDict, kIOHIDOptionsTypeNone); + + if (buttons) + { + for (int i = 0; i < CFArrayGetCount(buttons); i++) + { + IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(buttons, i); + // DeviceElementDebugPrint(e, nullptr); + + AddInput(new Button(e, m_device)); + } + CFRelease(buttons); + } + + // Axes + NSDictionary* axisDict = @{ @kIOHIDElementTypeKey : @(kIOHIDElementTypeInput_Misc) }; + + CFArrayRef axes = + IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)axisDict, kIOHIDOptionsTypeNone); + + if (axes) + { + for (int i = 0; i < CFArrayGetCount(axes); i++) + { + IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(axes, i); + // DeviceElementDebugPrint(e, nullptr); + + if (IOHIDElementGetUsage(e) == kHIDUsage_GD_Hatswitch) + { + AddInput(new Hat(e, m_device, Hat::up)); + AddInput(new Hat(e, m_device, Hat::right)); + AddInput(new Hat(e, m_device, Hat::down)); + AddInput(new Hat(e, m_device, Hat::left)); + } + else + { + AddAnalogInputs(new Axis(e, m_device, Axis::negative), + new Axis(e, m_device, Axis::positive)); + } + } + CFRelease(axes); + } + + // Force Feedback + FFCAPABILITIES ff_caps; + if (SUCCEEDED( + ForceFeedback::FFDeviceAdapter::Create(IOHIDDeviceGetService(m_device), &m_ff_device)) && + SUCCEEDED(FFDeviceGetForceFeedbackCapabilities(m_ff_device->m_device, &ff_caps))) + { + InitForceFeedback(m_ff_device, ff_caps.numFfAxes); + } } Joystick::~Joystick() { - if (m_ff_device) - m_ff_device->Release(); + if (m_ff_device) + m_ff_device->Release(); } std::string Joystick::GetName() const { - return m_device_name; + return m_device_name; } std::string Joystick::GetSource() const { - return "Input"; + return "Input"; } int Joystick::GetId() const { - return m_index; + return m_index; } ControlState Joystick::Button::GetState() const { - IOHIDValueRef value; - if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) - return IOHIDValueGetIntegerValue(value); - else - return 0; + IOHIDValueRef value; + if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) + return IOHIDValueGetIntegerValue(value); + else + return 0; } std::string Joystick::Button::GetName() const { - std::ostringstream s; - s << IOHIDElementGetUsage(m_element); - return std::string("Button ") + s.str(); + std::ostringstream s; + s << IOHIDElementGetUsage(m_element); + return std::string("Button ") + s.str(); } Joystick::Axis::Axis(IOHIDElementRef element, IOHIDDeviceRef device, direction dir) - : m_element(element) - , m_device(device) - , m_direction(dir) + : m_element(element), m_device(device), m_direction(dir) { - // Need to parse the element a bit first - std::string description("unk"); - - int const usage = IOHIDElementGetUsage(m_element); - switch (usage) - { - case kHIDUsage_GD_X: - description = "X"; - break; - case kHIDUsage_GD_Y: - description = "Y"; - break; - case kHIDUsage_GD_Z: - description = "Z"; - break; - case kHIDUsage_GD_Rx: - description = "Rx"; - break; - case kHIDUsage_GD_Ry: - description = "Ry"; - break; - case kHIDUsage_GD_Rz: - description = "Rz"; - break; - case kHIDUsage_GD_Wheel: - description = "Wheel"; - break; - case kHIDUsage_Csmr_ACPan: - description = "Pan"; - break; - default: - { - std::ostringstream s; - s << usage; - description = s.str(); - break; - } - } - - m_name = std::string("Axis ") + description; - m_name.append((m_direction == positive) ? "+" : "-"); - - m_neutral = (IOHIDElementGetLogicalMax(m_element) + - IOHIDElementGetLogicalMin(m_element)) / 2.; - m_scale = 1 / fabs(IOHIDElementGetLogicalMax(m_element) - m_neutral); + // Need to parse the element a bit first + std::string description("unk"); + + int const usage = IOHIDElementGetUsage(m_element); + switch (usage) + { + case kHIDUsage_GD_X: + description = "X"; + break; + case kHIDUsage_GD_Y: + description = "Y"; + break; + case kHIDUsage_GD_Z: + description = "Z"; + break; + case kHIDUsage_GD_Rx: + description = "Rx"; + break; + case kHIDUsage_GD_Ry: + description = "Ry"; + break; + case kHIDUsage_GD_Rz: + description = "Rz"; + break; + case kHIDUsage_GD_Wheel: + description = "Wheel"; + break; + case kHIDUsage_Csmr_ACPan: + description = "Pan"; + break; + default: + { + std::ostringstream s; + s << usage; + description = s.str(); + break; + } + } + + m_name = std::string("Axis ") + description; + m_name.append((m_direction == positive) ? "+" : "-"); + + m_neutral = (IOHIDElementGetLogicalMax(m_element) + IOHIDElementGetLogicalMin(m_element)) / 2.; + m_scale = 1 / fabs(IOHIDElementGetLogicalMax(m_element) - m_neutral); } ControlState Joystick::Axis::GetState() const { - IOHIDValueRef value; + IOHIDValueRef value; - if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) - { - // IOHIDValueGetIntegerValue() crashes when trying - // to convert unusually large element values. - if (IOHIDValueGetLength(value) > 2) - return 0; + if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) + { + // IOHIDValueGetIntegerValue() crashes when trying + // to convert unusually large element values. + if (IOHIDValueGetLength(value) > 2) + return 0; - float position = IOHIDValueGetIntegerValue(value); + float position = IOHIDValueGetIntegerValue(value); - if (m_direction == positive && position > m_neutral) - return (position - m_neutral) * m_scale; - if (m_direction == negative && position < m_neutral) - return (m_neutral - position) * m_scale; - } + if (m_direction == positive && position > m_neutral) + return (position - m_neutral) * m_scale; + if (m_direction == negative && position < m_neutral) + return (m_neutral - position) * m_scale; + } - return 0; + return 0; } std::string Joystick::Axis::GetName() const { - return m_name; + return m_name; } Joystick::Hat::Hat(IOHIDElementRef element, IOHIDDeviceRef device, direction dir) - : m_element(element) - , m_device(device) - , m_direction(dir) + : m_element(element), m_device(device), m_direction(dir) { - switch (dir) - { - case up: - m_name = "Up"; - break; - case right: - m_name = "Right"; - break; - case down: - m_name = "Down"; - break; - case left: - m_name = "Left"; - break; - default: - m_name = "unk"; - } + switch (dir) + { + case up: + m_name = "Up"; + break; + case right: + m_name = "Right"; + break; + case down: + m_name = "Down"; + break; + case left: + m_name = "Left"; + break; + default: + m_name = "unk"; + } } ControlState Joystick::Hat::GetState() const { - IOHIDValueRef value; - - if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) - { - int position = IOHIDValueGetIntegerValue(value); - int min = IOHIDElementGetLogicalMin(m_element); - int max = IOHIDElementGetLogicalMax(m_element); - - // if the position is outside the min or max, don't register it as a valid button press - if (position < min || position > max) - { - return 0; - } - - // normalize the position so that its lowest value is 0 - position -= min; - - switch (position) - { - case 0: - if (m_direction == up) - return 1; - break; - case 1: - if (m_direction == up || m_direction == right) - return 1; - break; - case 2: - if (m_direction == right) - return 1; - break; - case 3: - if (m_direction == right || m_direction == down) - return 1; - break; - case 4: - if (m_direction == down) - return 1; - break; - case 5: - if (m_direction == down || m_direction == left) - return 1; - break; - case 6: - if (m_direction == left) - return 1; - break; - case 7: - if (m_direction == left || m_direction == up) - return 1; - break; - }; - } - - return 0; + IOHIDValueRef value; + + if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) + { + int position = IOHIDValueGetIntegerValue(value); + int min = IOHIDElementGetLogicalMin(m_element); + int max = IOHIDElementGetLogicalMax(m_element); + + // if the position is outside the min or max, don't register it as a valid button press + if (position < min || position > max) + { + return 0; + } + + // normalize the position so that its lowest value is 0 + position -= min; + + switch (position) + { + case 0: + if (m_direction == up) + return 1; + break; + case 1: + if (m_direction == up || m_direction == right) + return 1; + break; + case 2: + if (m_direction == right) + return 1; + break; + case 3: + if (m_direction == right || m_direction == down) + return 1; + break; + case 4: + if (m_direction == down) + return 1; + break; + case 5: + if (m_direction == down || m_direction == left) + return 1; + break; + case 6: + if (m_direction == left) + return 1; + break; + case 7: + if (m_direction == left || m_direction == up) + return 1; + break; + }; + } + + return 0; } std::string Joystick::Hat::GetName() const { - return m_name; + return m_name; } - - } } diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h index d404f90684..5b3551a5b7 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.h @@ -12,67 +12,71 @@ namespace ciface { namespace OSX { - class Keyboard : public Core::Device { private: - class Key : public Input - { - public: - Key(IOHIDElementRef element, IOHIDDeviceRef device); - std::string GetName() const override; - ControlState GetState() const override; - private: - const IOHIDElementRef m_element; - const IOHIDDeviceRef m_device; - std::string m_name; - }; + class Key : public Input + { + public: + Key(IOHIDElementRef element, IOHIDDeviceRef device); + std::string GetName() const override; + ControlState GetState() const override; + + private: + const IOHIDElementRef m_element; + const IOHIDDeviceRef m_device; + std::string m_name; + }; + + class Cursor : public Input + { + public: + Cursor(u8 index, const float& axis, const bool positive) + : m_axis(axis), m_index(index), m_positive(positive) + { + } + std::string GetName() const override; + bool IsDetectable() override { return false; } + ControlState GetState() const override; - class Cursor : public Input - { - public: - Cursor(u8 index, const float& axis, const bool positive) : m_axis(axis), m_index(index), m_positive(positive) {} - std::string GetName() const override; - bool IsDetectable() override { return false; } - ControlState GetState() const override; - private: - const float& m_axis; - const u8 m_index; - const bool m_positive; - }; + private: + const float& m_axis; + const u8 m_index; + const bool m_positive; + }; - class Button : public Input - { - public: - Button(u8 index, const unsigned char& button) : m_button(button), m_index(index) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const unsigned char& m_button; - const u8 m_index; - }; + class Button : public Input + { + public: + Button(u8 index, const unsigned char& button) : m_button(button), m_index(index) {} + std::string GetName() const override; + ControlState GetState() const override; + + private: + const unsigned char& m_button; + const u8 m_index; + }; public: - void UpdateInput() override; + void UpdateInput() override; - Keyboard(IOHIDDeviceRef device, std::string name, int index, void *window); + Keyboard(IOHIDDeviceRef device, std::string name, int index, void* window); - std::string GetName() const override; - std::string GetSource() const override; - int GetId() const override; + std::string GetName() const override; + std::string GetSource() const override; + int GetId() const override; private: - struct - { - float x, y; - } m_cursor; + struct + { + float x, y; + } m_cursor; - const IOHIDDeviceRef m_device; - const std::string m_device_name; - int m_index; - uint32_t m_windowid; - unsigned char m_mousebuttons[3]; + const IOHIDDeviceRef m_device; + const std::string m_device_name; + int m_index; + uint32_t m_windowid; + unsigned char m_mousebuttons[3]; }; - } } diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm index 759e25b295..f5c1e5ac98 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSXKeyboard.mm @@ -4,9 +4,9 @@ #include +#include #include #include -#include #include "InputCommon/ControllerInterface/OSX/OSXKeyboard.h" @@ -14,261 +14,259 @@ namespace ciface { namespace OSX { - -Keyboard::Keyboard(IOHIDDeviceRef device, std::string name, int index, void *window) - : m_device(device) - , m_device_name(name) - , m_index(index) +Keyboard::Keyboard(IOHIDDeviceRef device, std::string name, int index, void* window) + : m_device(device), m_device_name(name), m_index(index) { - // This class should only recieve Keyboard or Keypad devices - // Now, filter on just the buttons we can handle sanely - NSDictionary *matchingElements = @{ - @kIOHIDElementTypeKey : @(kIOHIDElementTypeInput_Button), - @kIOHIDElementMinKey : @0, - @kIOHIDElementMaxKey : @1 - }; - - CFArrayRef elements = IOHIDDeviceCopyMatchingElements(m_device, - (CFDictionaryRef)matchingElements, kIOHIDOptionsTypeNone); - - if (elements) - { - for (int i = 0; i < CFArrayGetCount(elements); i++) - { - IOHIDElementRef e = - (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i); - //DeviceElementDebugPrint(e, nullptr); - - AddInput(new Key(e, m_device)); - } - CFRelease(elements); - } - - m_windowid = [[reinterpret_cast(window) window] windowNumber]; - - // cursor, with a hax for-loop - for (unsigned int i=0; i<4; ++i) - AddInput(new Cursor(!!(i&2), (&m_cursor.x)[i/2], !!(i&1))); - - for (u8 i = 0; i < sizeof(m_mousebuttons) / sizeof(m_mousebuttons[0]); ++i) - AddInput(new Button(i, m_mousebuttons[i])); + // This class should only recieve Keyboard or Keypad devices + // Now, filter on just the buttons we can handle sanely + NSDictionary* matchingElements = @{ + @kIOHIDElementTypeKey : @(kIOHIDElementTypeInput_Button), + @kIOHIDElementMinKey : @0, + @kIOHIDElementMaxKey : @1 + }; + + CFArrayRef elements = IOHIDDeviceCopyMatchingElements(m_device, (CFDictionaryRef)matchingElements, + kIOHIDOptionsTypeNone); + + if (elements) + { + for (int i = 0; i < CFArrayGetCount(elements); i++) + { + IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i); + // DeviceElementDebugPrint(e, nullptr); + + AddInput(new Key(e, m_device)); + } + CFRelease(elements); + } + + m_windowid = [[reinterpret_cast(window) window] windowNumber]; + + // cursor, with a hax for-loop + for (unsigned int i = 0; i < 4; ++i) + AddInput(new Cursor(!!(i & 2), (&m_cursor.x)[i / 2], !!(i & 1))); + + for (u8 i = 0; i < sizeof(m_mousebuttons) / sizeof(m_mousebuttons[0]); ++i) + AddInput(new Button(i, m_mousebuttons[i])); } void Keyboard::UpdateInput() { - CGRect bounds = CGRectZero; - uint32_t windowid[1] = { m_windowid }; - CFArrayRef windowArray = CFArrayCreate(nullptr, (const void **) windowid, 1, nullptr); - CFArrayRef windowDescriptions = CGWindowListCreateDescriptionFromArray(windowArray); - CFDictionaryRef windowDescription = (CFDictionaryRef) CFArrayGetValueAtIndex((CFArrayRef) windowDescriptions, 0); - - if (CFDictionaryContainsKey(windowDescription, kCGWindowBounds)) - { - CFDictionaryRef boundsDictionary = (CFDictionaryRef) CFDictionaryGetValue(windowDescription, kCGWindowBounds); - - if (boundsDictionary != nullptr) - CGRectMakeWithDictionaryRepresentation(boundsDictionary, &bounds); - } - - CFRelease(windowDescriptions); - CFRelease(windowArray); - - CGEventRef event = CGEventCreate(nil); - CGPoint loc = CGEventGetLocation(event); - CFRelease(event); - - loc.x -= bounds.origin.x; - loc.y -= bounds.origin.y; - m_cursor.x = loc.x / bounds.size.width * 2 - 1.0; - m_cursor.y = loc.y / bounds.size.height * 2 - 1.0; - - m_mousebuttons[0] = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonLeft); - m_mousebuttons[1] = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonRight); - m_mousebuttons[2] = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonCenter); + CGRect bounds = CGRectZero; + uint32_t windowid[1] = {m_windowid}; + CFArrayRef windowArray = CFArrayCreate(nullptr, (const void**)windowid, 1, nullptr); + CFArrayRef windowDescriptions = CGWindowListCreateDescriptionFromArray(windowArray); + CFDictionaryRef windowDescription = + (CFDictionaryRef)CFArrayGetValueAtIndex((CFArrayRef)windowDescriptions, 0); + + if (CFDictionaryContainsKey(windowDescription, kCGWindowBounds)) + { + CFDictionaryRef boundsDictionary = + (CFDictionaryRef)CFDictionaryGetValue(windowDescription, kCGWindowBounds); + + if (boundsDictionary != nullptr) + CGRectMakeWithDictionaryRepresentation(boundsDictionary, &bounds); + } + + CFRelease(windowDescriptions); + CFRelease(windowArray); + + CGEventRef event = CGEventCreate(nil); + CGPoint loc = CGEventGetLocation(event); + CFRelease(event); + + loc.x -= bounds.origin.x; + loc.y -= bounds.origin.y; + m_cursor.x = loc.x / bounds.size.width * 2 - 1.0; + m_cursor.y = loc.y / bounds.size.height * 2 - 1.0; + + m_mousebuttons[0] = + CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonLeft); + m_mousebuttons[1] = + CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonRight); + m_mousebuttons[2] = + CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonCenter); } std::string Keyboard::GetName() const { - return m_device_name; + return m_device_name; } std::string Keyboard::GetSource() const { - return "Keyboard"; + return "Keyboard"; } int Keyboard::GetId() const { - return m_index; + return m_index; } Keyboard::Key::Key(IOHIDElementRef element, IOHIDDeviceRef device) - : m_element(element) - , m_device(device) + : m_element(element), m_device(device) { - static const struct PrettyKeys - { - const uint32_t code; - const char *const name; - } named_keys[] = { - { kHIDUsage_KeyboardA, "A" }, - { kHIDUsage_KeyboardB, "B" }, - { kHIDUsage_KeyboardC, "C" }, - { kHIDUsage_KeyboardD, "D" }, - { kHIDUsage_KeyboardE, "E" }, - { kHIDUsage_KeyboardF, "F" }, - { kHIDUsage_KeyboardG, "G" }, - { kHIDUsage_KeyboardH, "H" }, - { kHIDUsage_KeyboardI, "I" }, - { kHIDUsage_KeyboardJ, "J" }, - { kHIDUsage_KeyboardK, "K" }, - { kHIDUsage_KeyboardL, "L" }, - { kHIDUsage_KeyboardM, "M" }, - { kHIDUsage_KeyboardN, "N" }, - { kHIDUsage_KeyboardO, "O" }, - { kHIDUsage_KeyboardP, "P" }, - { kHIDUsage_KeyboardQ, "Q" }, - { kHIDUsage_KeyboardR, "R" }, - { kHIDUsage_KeyboardS, "S" }, - { kHIDUsage_KeyboardT, "T" }, - { kHIDUsage_KeyboardU, "U" }, - { kHIDUsage_KeyboardV, "V" }, - { kHIDUsage_KeyboardW, "W" }, - { kHIDUsage_KeyboardX, "X" }, - { kHIDUsage_KeyboardY, "Y" }, - { kHIDUsage_KeyboardZ, "Z" }, - { kHIDUsage_Keyboard1, "1" }, - { kHIDUsage_Keyboard2, "2" }, - { kHIDUsage_Keyboard3, "3" }, - { kHIDUsage_Keyboard4, "4" }, - { kHIDUsage_Keyboard5, "5" }, - { kHIDUsage_Keyboard6, "6" }, - { kHIDUsage_Keyboard7, "7" }, - { kHIDUsage_Keyboard8, "8" }, - { kHIDUsage_Keyboard9, "9" }, - { kHIDUsage_Keyboard0, "0" }, - { kHIDUsage_KeyboardReturnOrEnter, "Return" }, - { kHIDUsage_KeyboardEscape, "Escape" }, - { kHIDUsage_KeyboardDeleteOrBackspace, "Backspace" }, - { kHIDUsage_KeyboardTab, "Tab" }, - { kHIDUsage_KeyboardSpacebar, "Space" }, - { kHIDUsage_KeyboardHyphen, "-" }, - { kHIDUsage_KeyboardEqualSign, "=" }, - { kHIDUsage_KeyboardOpenBracket, "[" }, - { kHIDUsage_KeyboardCloseBracket, "]" }, - { kHIDUsage_KeyboardBackslash, "\\" }, - { kHIDUsage_KeyboardSemicolon, ";" }, - { kHIDUsage_KeyboardQuote, "'" }, - { kHIDUsage_KeyboardGraveAccentAndTilde, "Tilde" }, - { kHIDUsage_KeyboardComma, "," }, - { kHIDUsage_KeyboardPeriod, "." }, - { kHIDUsage_KeyboardSlash, "/" }, - { kHIDUsage_KeyboardCapsLock, "Caps Lock" }, - { kHIDUsage_KeyboardF1, "F1" }, - { kHIDUsage_KeyboardF2, "F2" }, - { kHIDUsage_KeyboardF3, "F3" }, - { kHIDUsage_KeyboardF4, "F4" }, - { kHIDUsage_KeyboardF5, "F5" }, - { kHIDUsage_KeyboardF6, "F6" }, - { kHIDUsage_KeyboardF7, "F7" }, - { kHIDUsage_KeyboardF8, "F8" }, - { kHIDUsage_KeyboardF9, "F9" }, - { kHIDUsage_KeyboardF10, "F10" }, - { kHIDUsage_KeyboardF11, "F11" }, - { kHIDUsage_KeyboardF12, "F12" }, - { kHIDUsage_KeyboardInsert, "Insert" }, - { kHIDUsage_KeyboardHome, "Home" }, - { kHIDUsage_KeyboardPageUp, "Page Up" }, - { kHIDUsage_KeyboardDeleteForward, "Delete" }, - { kHIDUsage_KeyboardEnd, "End" }, - { kHIDUsage_KeyboardPageDown, "Page Down" }, - { kHIDUsage_KeyboardRightArrow, "Right Arrow" }, - { kHIDUsage_KeyboardLeftArrow, "Left Arrow" }, - { kHIDUsage_KeyboardDownArrow, "Down Arrow" }, - { kHIDUsage_KeyboardUpArrow, "Up Arrow" }, - { kHIDUsage_KeypadSlash, "Keypad /" }, - { kHIDUsage_KeypadAsterisk, "Keypad *" }, - { kHIDUsage_KeypadHyphen, "Keypad -" }, - { kHIDUsage_KeypadPlus, "Keypad +" }, - { kHIDUsage_KeypadEnter, "Keypad Enter" }, - { kHIDUsage_Keypad1, "Keypad 1" }, - { kHIDUsage_Keypad2, "Keypad 2" }, - { kHIDUsage_Keypad3, "Keypad 3" }, - { kHIDUsage_Keypad4, "Keypad 4" }, - { kHIDUsage_Keypad5, "Keypad 5" }, - { kHIDUsage_Keypad6, "Keypad 6" }, - { kHIDUsage_Keypad7, "Keypad 7" }, - { kHIDUsage_Keypad8, "Keypad 8" }, - { kHIDUsage_Keypad9, "Keypad 9" }, - { kHIDUsage_Keypad0, "Keypad 0" }, - { kHIDUsage_KeypadPeriod, "Keypad ." }, - { kHIDUsage_KeyboardNonUSBackslash, "Paragraph" }, - { kHIDUsage_KeypadEqualSign, "Keypad =" }, - { kHIDUsage_KeypadComma, "Keypad ," }, - { kHIDUsage_KeyboardLeftControl, "Left Control" }, - { kHIDUsage_KeyboardLeftShift, "Left Shift" }, - { kHIDUsage_KeyboardLeftAlt, "Left Alt" }, - { kHIDUsage_KeyboardLeftGUI, "Left Command" }, - { kHIDUsage_KeyboardRightControl, "Right Control" }, - { kHIDUsage_KeyboardRightShift, "Right Shift" }, - { kHIDUsage_KeyboardRightAlt, "Right Alt" }, - { kHIDUsage_KeyboardRightGUI, "Right Command" }, - { 184, "Eject" }, - }; - - const uint32_t keycode = IOHIDElementGetUsage(m_element); - for (auto & named_key : named_keys) - { - if (named_key.code == keycode) - { - m_name = named_key.name; - return; - } - } - - std::stringstream ss; - ss << "Key " << keycode; - m_name = ss.str(); + static const struct PrettyKeys + { + const uint32_t code; + const char* const name; + } named_keys[] = { + {kHIDUsage_KeyboardA, "A"}, + {kHIDUsage_KeyboardB, "B"}, + {kHIDUsage_KeyboardC, "C"}, + {kHIDUsage_KeyboardD, "D"}, + {kHIDUsage_KeyboardE, "E"}, + {kHIDUsage_KeyboardF, "F"}, + {kHIDUsage_KeyboardG, "G"}, + {kHIDUsage_KeyboardH, "H"}, + {kHIDUsage_KeyboardI, "I"}, + {kHIDUsage_KeyboardJ, "J"}, + {kHIDUsage_KeyboardK, "K"}, + {kHIDUsage_KeyboardL, "L"}, + {kHIDUsage_KeyboardM, "M"}, + {kHIDUsage_KeyboardN, "N"}, + {kHIDUsage_KeyboardO, "O"}, + {kHIDUsage_KeyboardP, "P"}, + {kHIDUsage_KeyboardQ, "Q"}, + {kHIDUsage_KeyboardR, "R"}, + {kHIDUsage_KeyboardS, "S"}, + {kHIDUsage_KeyboardT, "T"}, + {kHIDUsage_KeyboardU, "U"}, + {kHIDUsage_KeyboardV, "V"}, + {kHIDUsage_KeyboardW, "W"}, + {kHIDUsage_KeyboardX, "X"}, + {kHIDUsage_KeyboardY, "Y"}, + {kHIDUsage_KeyboardZ, "Z"}, + {kHIDUsage_Keyboard1, "1"}, + {kHIDUsage_Keyboard2, "2"}, + {kHIDUsage_Keyboard3, "3"}, + {kHIDUsage_Keyboard4, "4"}, + {kHIDUsage_Keyboard5, "5"}, + {kHIDUsage_Keyboard6, "6"}, + {kHIDUsage_Keyboard7, "7"}, + {kHIDUsage_Keyboard8, "8"}, + {kHIDUsage_Keyboard9, "9"}, + {kHIDUsage_Keyboard0, "0"}, + {kHIDUsage_KeyboardReturnOrEnter, "Return"}, + {kHIDUsage_KeyboardEscape, "Escape"}, + {kHIDUsage_KeyboardDeleteOrBackspace, "Backspace"}, + {kHIDUsage_KeyboardTab, "Tab"}, + {kHIDUsage_KeyboardSpacebar, "Space"}, + {kHIDUsage_KeyboardHyphen, "-"}, + {kHIDUsage_KeyboardEqualSign, "="}, + {kHIDUsage_KeyboardOpenBracket, "["}, + {kHIDUsage_KeyboardCloseBracket, "]"}, + {kHIDUsage_KeyboardBackslash, "\\"}, + {kHIDUsage_KeyboardSemicolon, ";"}, + {kHIDUsage_KeyboardQuote, "'"}, + {kHIDUsage_KeyboardGraveAccentAndTilde, "Tilde"}, + {kHIDUsage_KeyboardComma, ","}, + {kHIDUsage_KeyboardPeriod, "."}, + {kHIDUsage_KeyboardSlash, "/"}, + {kHIDUsage_KeyboardCapsLock, "Caps Lock"}, + {kHIDUsage_KeyboardF1, "F1"}, + {kHIDUsage_KeyboardF2, "F2"}, + {kHIDUsage_KeyboardF3, "F3"}, + {kHIDUsage_KeyboardF4, "F4"}, + {kHIDUsage_KeyboardF5, "F5"}, + {kHIDUsage_KeyboardF6, "F6"}, + {kHIDUsage_KeyboardF7, "F7"}, + {kHIDUsage_KeyboardF8, "F8"}, + {kHIDUsage_KeyboardF9, "F9"}, + {kHIDUsage_KeyboardF10, "F10"}, + {kHIDUsage_KeyboardF11, "F11"}, + {kHIDUsage_KeyboardF12, "F12"}, + {kHIDUsage_KeyboardInsert, "Insert"}, + {kHIDUsage_KeyboardHome, "Home"}, + {kHIDUsage_KeyboardPageUp, "Page Up"}, + {kHIDUsage_KeyboardDeleteForward, "Delete"}, + {kHIDUsage_KeyboardEnd, "End"}, + {kHIDUsage_KeyboardPageDown, "Page Down"}, + {kHIDUsage_KeyboardRightArrow, "Right Arrow"}, + {kHIDUsage_KeyboardLeftArrow, "Left Arrow"}, + {kHIDUsage_KeyboardDownArrow, "Down Arrow"}, + {kHIDUsage_KeyboardUpArrow, "Up Arrow"}, + {kHIDUsage_KeypadSlash, "Keypad /"}, + {kHIDUsage_KeypadAsterisk, "Keypad *"}, + {kHIDUsage_KeypadHyphen, "Keypad -"}, + {kHIDUsage_KeypadPlus, "Keypad +"}, + {kHIDUsage_KeypadEnter, "Keypad Enter"}, + {kHIDUsage_Keypad1, "Keypad 1"}, + {kHIDUsage_Keypad2, "Keypad 2"}, + {kHIDUsage_Keypad3, "Keypad 3"}, + {kHIDUsage_Keypad4, "Keypad 4"}, + {kHIDUsage_Keypad5, "Keypad 5"}, + {kHIDUsage_Keypad6, "Keypad 6"}, + {kHIDUsage_Keypad7, "Keypad 7"}, + {kHIDUsage_Keypad8, "Keypad 8"}, + {kHIDUsage_Keypad9, "Keypad 9"}, + {kHIDUsage_Keypad0, "Keypad 0"}, + {kHIDUsage_KeypadPeriod, "Keypad ."}, + {kHIDUsage_KeyboardNonUSBackslash, "Paragraph"}, + {kHIDUsage_KeypadEqualSign, "Keypad ="}, + {kHIDUsage_KeypadComma, "Keypad ,"}, + {kHIDUsage_KeyboardLeftControl, "Left Control"}, + {kHIDUsage_KeyboardLeftShift, "Left Shift"}, + {kHIDUsage_KeyboardLeftAlt, "Left Alt"}, + {kHIDUsage_KeyboardLeftGUI, "Left Command"}, + {kHIDUsage_KeyboardRightControl, "Right Control"}, + {kHIDUsage_KeyboardRightShift, "Right Shift"}, + {kHIDUsage_KeyboardRightAlt, "Right Alt"}, + {kHIDUsage_KeyboardRightGUI, "Right Command"}, + {184, "Eject"}, + }; + + const uint32_t keycode = IOHIDElementGetUsage(m_element); + for (auto& named_key : named_keys) + { + if (named_key.code == keycode) + { + m_name = named_key.name; + return; + } + } + + std::stringstream ss; + ss << "Key " << keycode; + m_name = ss.str(); } ControlState Keyboard::Key::GetState() const { - IOHIDValueRef value; + IOHIDValueRef value; - if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) - return IOHIDValueGetIntegerValue(value); - else - return 0; + if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) + return IOHIDValueGetIntegerValue(value); + else + return 0; } ControlState Keyboard::Cursor::GetState() const { - return std::max(0.0, ControlState(m_axis) / (m_positive ? 1.0 : -1.0)); + return std::max(0.0, ControlState(m_axis) / (m_positive ? 1.0 : -1.0)); } ControlState Keyboard::Button::GetState() const { - return (m_button != 0); + return (m_button != 0); } std::string Keyboard::Cursor::GetName() const { - static char tmpstr[] = "Cursor .."; - tmpstr[7] = (char)('X' + m_index); - tmpstr[8] = (m_positive ? '+' : '-'); - return tmpstr; + static char tmpstr[] = "Cursor .."; + tmpstr[7] = (char)('X' + m_index); + tmpstr[8] = (m_positive ? '+' : '-'); + return tmpstr; } std::string Keyboard::Button::GetName() const { - return std::string("Click ") + char('0' + m_index); + return std::string("Click ") + char('0' + m_index); } std::string Keyboard::Key::GetName() const { - return m_name; + return m_name; } - - } } diff --git a/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp b/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp index cff69fabfc..95bdcc4da2 100644 --- a/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp @@ -10,9 +10,9 @@ #include #include #include +#include #include #include -#include #include "Common/FileUtil.h" #include "Common/MathUtil.h" @@ -23,168 +23,144 @@ namespace ciface { namespace Pipes { +static const std::array s_button_tokens{ + {"A", "B", "X", "Y", "Z", "START", "L", "R", "D_UP", "D_DOWN", "D_LEFT", "D_RIGHT"}}; -static const std::array s_button_tokens -{{ - "A", - "B", - "X", - "Y", - "Z", - "START", - "L", - "R", - "D_UP", - "D_DOWN", - "D_LEFT", - "D_RIGHT" -}}; +static const std::array s_shoulder_tokens{{"L", "R"}}; -static const std::array s_shoulder_tokens -{{ - "L", - "R" -}}; - -static const std::array s_axis_tokens -{{ - "MAIN", - "C" -}}; +static const std::array s_axis_tokens{{"MAIN", "C"}}; static double StringToDouble(const std::string& text) { - std::istringstream is(text); - // ignore current locale - is.imbue(std::locale::classic()); - double result; - is >> result; - return result; + std::istringstream is(text); + // ignore current locale + is.imbue(std::locale::classic()); + double result; + is >> result; + return result; } void Init(std::vector& devices) { - // Search the Pipes directory for files that we can open in read-only, - // non-blocking mode. The device name is the virtual name of the file. - File::FSTEntry fst; - int found = 0; - std::string dir_path = File::GetUserPath(D_PIPES_IDX); - if (!File::Exists(dir_path)) - return; - fst = File::ScanDirectoryTree(dir_path, false); - if (!fst.isDirectory) - return; - for (unsigned int i = 0; i < fst.size; ++i) - { - const File::FSTEntry& child = fst.children[i]; - if (child.isDirectory) - continue; - int fd = open(child.physicalName.c_str(), O_RDONLY | O_NONBLOCK); - if (fd < 0) - continue; - devices.push_back(new PipeDevice(fd, child.virtualName, found++)); - } + // Search the Pipes directory for files that we can open in read-only, + // non-blocking mode. The device name is the virtual name of the file. + File::FSTEntry fst; + int found = 0; + std::string dir_path = File::GetUserPath(D_PIPES_IDX); + if (!File::Exists(dir_path)) + return; + fst = File::ScanDirectoryTree(dir_path, false); + if (!fst.isDirectory) + return; + for (unsigned int i = 0; i < fst.size; ++i) + { + const File::FSTEntry& child = fst.children[i]; + if (child.isDirectory) + continue; + int fd = open(child.physicalName.c_str(), O_RDONLY | O_NONBLOCK); + if (fd < 0) + continue; + devices.push_back(new PipeDevice(fd, child.virtualName, found++)); + } } -PipeDevice::PipeDevice(int fd, const std::string& name, int id) - : m_fd(fd), m_name(name), m_id(id) +PipeDevice::PipeDevice(int fd, const std::string& name, int id) : m_fd(fd), m_name(name), m_id(id) { - for (const auto& tok : s_button_tokens) - { - PipeInput* btn = new PipeInput("Button " + tok); - AddInput(btn); - m_buttons[tok] = btn; - } - for (const auto& tok : s_shoulder_tokens) - { - AddAxis(tok, 0.0); - } - for (const auto& tok : s_axis_tokens) - { - AddAxis(tok + " X", 0.5); - AddAxis(tok + " Y", 0.5); - } + for (const auto& tok : s_button_tokens) + { + PipeInput* btn = new PipeInput("Button " + tok); + AddInput(btn); + m_buttons[tok] = btn; + } + for (const auto& tok : s_shoulder_tokens) + { + AddAxis(tok, 0.0); + } + for (const auto& tok : s_axis_tokens) + { + AddAxis(tok + " X", 0.5); + AddAxis(tok + " Y", 0.5); + } } PipeDevice::~PipeDevice() { - close(m_fd); + close(m_fd); } void PipeDevice::UpdateInput() { - // Read any pending characters off the pipe. If we hit a newline, - // then dequeue a command off the front of m_buf and parse it. - char buf[32]; - ssize_t bytes_read = read(m_fd, buf, sizeof buf); - while (bytes_read > 0) - { - m_buf.append(buf, bytes_read); - bytes_read = read(m_fd, buf, sizeof buf); - } - std::size_t newline = m_buf.find("\n"); - while (newline != std::string::npos) - { - std::string command = m_buf.substr(0, newline); - ParseCommand(command); - m_buf.erase(0, newline + 1); - newline = m_buf.find("\n"); - } + // Read any pending characters off the pipe. If we hit a newline, + // then dequeue a command off the front of m_buf and parse it. + char buf[32]; + ssize_t bytes_read = read(m_fd, buf, sizeof buf); + while (bytes_read > 0) + { + m_buf.append(buf, bytes_read); + bytes_read = read(m_fd, buf, sizeof buf); + } + std::size_t newline = m_buf.find("\n"); + while (newline != std::string::npos) + { + std::string command = m_buf.substr(0, newline); + ParseCommand(command); + m_buf.erase(0, newline + 1); + newline = m_buf.find("\n"); + } } void PipeDevice::AddAxis(const std::string& name, double value) { - // Dolphin uses separate axes for left/right, which complicates things. - PipeInput* ax_hi = new PipeInput("Axis " + name + " +"); - ax_hi->SetState(value); - PipeInput* ax_lo = new PipeInput("Axis " + name + " -"); - ax_lo->SetState(value); - m_axes[name + " +"] = ax_hi; - m_axes[name + " -"] = ax_lo; - AddAnalogInputs(ax_lo, ax_hi); + // Dolphin uses separate axes for left/right, which complicates things. + PipeInput* ax_hi = new PipeInput("Axis " + name + " +"); + ax_hi->SetState(value); + PipeInput* ax_lo = new PipeInput("Axis " + name + " -"); + ax_lo->SetState(value); + m_axes[name + " +"] = ax_hi; + m_axes[name + " -"] = ax_lo; + AddAnalogInputs(ax_lo, ax_hi); } void PipeDevice::SetAxis(const std::string& entry, double value) { - value = MathUtil::Clamp(value, 0.0, 1.0); - double hi = std::max(0.0, value - 0.5) * 2.0; - double lo = (0.5 - std::min(0.5, value)) * 2.0; - auto search_hi = m_axes.find(entry + " +"); - if (search_hi != m_axes.end()) - search_hi->second->SetState(hi); - auto search_lo = m_axes.find(entry + " -"); - if (search_lo != m_axes.end()) - search_lo->second->SetState(lo); + value = MathUtil::Clamp(value, 0.0, 1.0); + double hi = std::max(0.0, value - 0.5) * 2.0; + double lo = (0.5 - std::min(0.5, value)) * 2.0; + auto search_hi = m_axes.find(entry + " +"); + if (search_hi != m_axes.end()) + search_hi->second->SetState(hi); + auto search_lo = m_axes.find(entry + " -"); + if (search_lo != m_axes.end()) + search_lo->second->SetState(lo); } void PipeDevice::ParseCommand(const std::string& command) { - std::vector tokens; - SplitString(command, ' ', tokens); - if (tokens.size() < 2 || tokens.size() > 4) - return; - if (tokens[0] == "PRESS" || tokens[0] == "RELEASE") - { - auto search = m_buttons.find(tokens[1]); - if (search != m_buttons.end()) - search->second->SetState(tokens[0] == "PRESS" ? 1.0 : 0.0); - } - else if (tokens[0] == "SET") - { - if (tokens.size() == 3) - { - double value = StringToDouble(tokens[2]); - SetAxis(tokens[1], (value / 2.0) + 0.5); - } - else if (tokens.size() == 4) - { - double x = StringToDouble(tokens[2]); - double y = StringToDouble(tokens[3]); - SetAxis(tokens[1] + " X", x); - SetAxis(tokens[1] + " Y", y); - } - } + std::vector tokens; + SplitString(command, ' ', tokens); + if (tokens.size() < 2 || tokens.size() > 4) + return; + if (tokens[0] == "PRESS" || tokens[0] == "RELEASE") + { + auto search = m_buttons.find(tokens[1]); + if (search != m_buttons.end()) + search->second->SetState(tokens[0] == "PRESS" ? 1.0 : 0.0); + } + else if (tokens[0] == "SET") + { + if (tokens.size() == 3) + { + double value = StringToDouble(tokens[2]); + SetAxis(tokens[1], (value / 2.0) + 0.5); + } + else if (tokens.size() == 4) + { + double x = StringToDouble(tokens[2]); + double y = StringToDouble(tokens[3]); + SetAxis(tokens[1] + " X", x); + SetAxis(tokens[1] + " Y", y); + } + } } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.h b/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.h index c3c2ea0063..855c45953b 100644 --- a/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.h +++ b/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.h @@ -29,37 +29,36 @@ void Init(std::vector& devices); class PipeDevice : public Core::Device { public: - PipeDevice(int fd, const std::string& name, int id); - ~PipeDevice(); - - void UpdateInput() override; - std::string GetName() const override { return m_name; } - int GetId() const override { return m_id; } - std::string GetSource() const override { return "Pipe"; } + PipeDevice(int fd, const std::string& name, int id); + ~PipeDevice(); + void UpdateInput() override; + std::string GetName() const override { return m_name; } + int GetId() const override { return m_id; } + std::string GetSource() const override { return "Pipe"; } private: - class PipeInput : public Input - { - public: - PipeInput(const std::string& name) : m_name(name), m_state(0.0) {} - std::string GetName() const override { return m_name; } - ControlState GetState() const override { return m_state; } - void SetState(ControlState state) { m_state = state; } - private: - const std::string m_name; - ControlState m_state; - }; + class PipeInput : public Input + { + public: + PipeInput(const std::string& name) : m_name(name), m_state(0.0) {} + std::string GetName() const override { return m_name; } + ControlState GetState() const override { return m_state; } + void SetState(ControlState state) { m_state = state; } + private: + const std::string m_name; + ControlState m_state; + }; - void AddAxis(const std::string& name, double value); - void ParseCommand(const std::string& command); - void SetAxis(const std::string& entry, double value); + void AddAxis(const std::string& name, double value); + void ParseCommand(const std::string& command); + void SetAxis(const std::string& entry, double value); - const int m_fd; - const std::string m_name; - const int m_id; - std::string m_buf; - std::map m_buttons; - std::map m_axes; + const int m_fd; + const std::string m_name; + const int m_id; + std::string m_buf; + std::map m_buttons; + std::map m_axes; }; } } diff --git a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp index 6cdfa470cd..8b87261480 100644 --- a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp +++ b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp @@ -17,330 +17,321 @@ namespace ciface { namespace SDL { - // 10ms = 100Hz which homebrew docs very roughly imply is within WiiMote normal // range, used for periodic haptic effects though often ignored by devices static const u16 RUMBLE_PERIOD = 10; -static const u16 RUMBLE_LENGTH_MAX = 500; // ms: enough to span multiple frames at low FPS, but still finite +static const u16 RUMBLE_LENGTH_MAX = + 500; // ms: enough to span multiple frames at low FPS, but still finite static std::string GetJoystickName(int index) { #if SDL_VERSION_ATLEAST(2, 0, 0) - return SDL_JoystickNameForIndex(index); + return SDL_JoystickNameForIndex(index); #else - return SDL_JoystickName(index); + return SDL_JoystickName(index); #endif } -void Init( std::vector& devices ) +void Init(std::vector& devices) { - // this is used to number the joysticks - // multiple joysticks with the same name shall get unique ids starting at 0 - std::map name_counts; + // this is used to number the joysticks + // multiple joysticks with the same name shall get unique ids starting at 0 + std::map name_counts; #ifdef USE_SDL_HAPTIC - if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC) >= 0) - { - // Correctly initialized - } - else + if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC) >= 0) + { + // Correctly initialized + } + else #endif - if (SDL_Init(SDL_INIT_JOYSTICK) < 0) - { - // Failed to initialize - return; - } - - // joysticks - for (int i = 0; i < SDL_NumJoysticks(); ++i) - { - SDL_Joystick* dev = SDL_JoystickOpen(i); - if (dev) - { - Joystick* js = new Joystick(dev, i, name_counts[GetJoystickName(i)]++); - // only add if it has some inputs/outputs - if (js->Inputs().size() || js->Outputs().size()) - devices.push_back( js ); - else - delete js; - } - } + if (SDL_Init(SDL_INIT_JOYSTICK) < 0) + { + // Failed to initialize + return; + } + + // joysticks + for (int i = 0; i < SDL_NumJoysticks(); ++i) + { + SDL_Joystick* dev = SDL_JoystickOpen(i); + if (dev) + { + Joystick* js = new Joystick(dev, i, name_counts[GetJoystickName(i)]++); + // only add if it has some inputs/outputs + if (js->Inputs().size() || js->Outputs().size()) + devices.push_back(js); + else + delete js; + } + } } Joystick::Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsigned int index) - : m_joystick(joystick) - , m_sdl_index(sdl_index) - , m_index(index) + : m_joystick(joystick), m_sdl_index(sdl_index), m_index(index) { - // really bad HACKS: - // to not use SDL for an XInput device - // too many people on the forums pick the SDL device and ask: - // "why don't my 360 gamepad triggers/rumble work correctly" +// really bad HACKS: +// to not use SDL for an XInput device +// too many people on the forums pick the SDL device and ask: +// "why don't my 360 gamepad triggers/rumble work correctly" #ifdef _WIN32 - // checking the name is probably good (and hacky) enough - // but I'll double check with the num of buttons/axes - std::string lcasename = GetName(); - std::transform(lcasename.begin(), lcasename.end(), lcasename.begin(), tolower); - - if ((std::string::npos != lcasename.find("xbox 360")) && - (10 == SDL_JoystickNumButtons(joystick)) && - (5 == SDL_JoystickNumAxes(joystick)) && - (1 == SDL_JoystickNumHats(joystick)) && - (0 == SDL_JoystickNumBalls(joystick))) - { - // this device won't be used - return; - } + // checking the name is probably good (and hacky) enough + // but I'll double check with the num of buttons/axes + std::string lcasename = GetName(); + std::transform(lcasename.begin(), lcasename.end(), lcasename.begin(), tolower); + + if ((std::string::npos != lcasename.find("xbox 360")) && + (10 == SDL_JoystickNumButtons(joystick)) && (5 == SDL_JoystickNumAxes(joystick)) && + (1 == SDL_JoystickNumHats(joystick)) && (0 == SDL_JoystickNumBalls(joystick))) + { + // this device won't be used + return; + } #endif - if (SDL_JoystickNumButtons(joystick) > 255 || - SDL_JoystickNumAxes(joystick) > 255 || - SDL_JoystickNumHats(joystick) > 255 || - SDL_JoystickNumBalls(joystick) > 255) - { - // This device is invalid, don't use it - // Some crazy devices(HP webcam 2100) end up as HID devices - // SDL tries parsing these as joysticks - return; - } - - // get buttons - for (u8 i = 0; i != SDL_JoystickNumButtons(m_joystick); ++i) - AddInput(new Button(i, m_joystick)); - - // get hats - for (u8 i = 0; i != SDL_JoystickNumHats(m_joystick); ++i) - { - // each hat gets 4 input instances associated with it, (up down left right) - for (u8 d = 0; d != 4; ++d) - AddInput(new Hat(i, m_joystick, d)); - } - - // get axes - for (u8 i = 0; i != SDL_JoystickNumAxes(m_joystick); ++i) - { - // each axis gets a negative and a positive input instance associated with it - AddAnalogInputs(new Axis(i, m_joystick, -32768), - new Axis(i, m_joystick, 32767)); - } + if (SDL_JoystickNumButtons(joystick) > 255 || SDL_JoystickNumAxes(joystick) > 255 || + SDL_JoystickNumHats(joystick) > 255 || SDL_JoystickNumBalls(joystick) > 255) + { + // This device is invalid, don't use it + // Some crazy devices(HP webcam 2100) end up as HID devices + // SDL tries parsing these as joysticks + return; + } + + // get buttons + for (u8 i = 0; i != SDL_JoystickNumButtons(m_joystick); ++i) + AddInput(new Button(i, m_joystick)); + + // get hats + for (u8 i = 0; i != SDL_JoystickNumHats(m_joystick); ++i) + { + // each hat gets 4 input instances associated with it, (up down left right) + for (u8 d = 0; d != 4; ++d) + AddInput(new Hat(i, m_joystick, d)); + } + + // get axes + for (u8 i = 0; i != SDL_JoystickNumAxes(m_joystick); ++i) + { + // each axis gets a negative and a positive input instance associated with it + AddAnalogInputs(new Axis(i, m_joystick, -32768), new Axis(i, m_joystick, 32767)); + } #ifdef USE_SDL_HAPTIC - // try to get supported ff effects - m_haptic = SDL_HapticOpenFromJoystick( m_joystick ); - if (m_haptic) - { - //SDL_HapticSetGain( m_haptic, 1000 ); - //SDL_HapticSetAutocenter( m_haptic, 0 ); - - const unsigned int supported_effects = SDL_HapticQuery( m_haptic ); - - // constant effect - if (supported_effects & SDL_HAPTIC_CONSTANT) - AddOutput(new ConstantEffect(m_haptic)); - - // ramp effect - if (supported_effects & SDL_HAPTIC_RAMP) - AddOutput(new RampEffect(m_haptic)); - - // sine effect - if (supported_effects & SDL_HAPTIC_SINE) - AddOutput(new SineEffect(m_haptic)); - - // triangle effect - if (supported_effects & SDL_HAPTIC_TRIANGLE) - AddOutput(new TriangleEffect(m_haptic)); - - // left-right effect - if (supported_effects & SDL_HAPTIC_LEFTRIGHT) - AddOutput(new LeftRightEffect(m_haptic)); - } + // try to get supported ff effects + m_haptic = SDL_HapticOpenFromJoystick(m_joystick); + if (m_haptic) + { + // SDL_HapticSetGain( m_haptic, 1000 ); + // SDL_HapticSetAutocenter( m_haptic, 0 ); + + const unsigned int supported_effects = SDL_HapticQuery(m_haptic); + + // constant effect + if (supported_effects & SDL_HAPTIC_CONSTANT) + AddOutput(new ConstantEffect(m_haptic)); + + // ramp effect + if (supported_effects & SDL_HAPTIC_RAMP) + AddOutput(new RampEffect(m_haptic)); + + // sine effect + if (supported_effects & SDL_HAPTIC_SINE) + AddOutput(new SineEffect(m_haptic)); + + // triangle effect + if (supported_effects & SDL_HAPTIC_TRIANGLE) + AddOutput(new TriangleEffect(m_haptic)); + + // left-right effect + if (supported_effects & SDL_HAPTIC_LEFTRIGHT) + AddOutput(new LeftRightEffect(m_haptic)); + } #endif - } Joystick::~Joystick() { #ifdef USE_SDL_HAPTIC - if (m_haptic) - { - // stop/destroy all effects - SDL_HapticStopAll(m_haptic); - // close haptic first - SDL_HapticClose(m_haptic); - } + if (m_haptic) + { + // stop/destroy all effects + SDL_HapticStopAll(m_haptic); + // close haptic first + SDL_HapticClose(m_haptic); + } #endif - // close joystick - SDL_JoystickClose(m_joystick); + // close joystick + SDL_JoystickClose(m_joystick); } #ifdef USE_SDL_HAPTIC void Joystick::HapticEffect::Update() { - if (m_id == -1 && m_effect.type > 0) - { - m_id = SDL_HapticNewEffect(m_haptic, &m_effect); - if (m_id > -1) - SDL_HapticRunEffect(m_haptic, m_id, 1); - } - else if (m_id > -1 && m_effect.type == 0) - { - SDL_HapticStopEffect(m_haptic, m_id); - SDL_HapticDestroyEffect(m_haptic, m_id); - m_id = -1; - } - else if (m_id > -1) - { - SDL_HapticUpdateEffect(m_haptic, m_id, &m_effect); - } + if (m_id == -1 && m_effect.type > 0) + { + m_id = SDL_HapticNewEffect(m_haptic, &m_effect); + if (m_id > -1) + SDL_HapticRunEffect(m_haptic, m_id, 1); + } + else if (m_id > -1 && m_effect.type == 0) + { + SDL_HapticStopEffect(m_haptic, m_id); + SDL_HapticDestroyEffect(m_haptic, m_id); + m_id = -1; + } + else if (m_id > -1) + { + SDL_HapticUpdateEffect(m_haptic, m_id, &m_effect); + } } std::string Joystick::ConstantEffect::GetName() const { - return "Constant"; + return "Constant"; } std::string Joystick::RampEffect::GetName() const { - return "Ramp"; + return "Ramp"; } std::string Joystick::SineEffect::GetName() const { - return "Sine"; + return "Sine"; } std::string Joystick::TriangleEffect::GetName() const { - return "Triangle"; + return "Triangle"; } std::string Joystick::LeftRightEffect::GetName() const { - return "LeftRight"; + return "LeftRight"; } void Joystick::HapticEffect::SetState(ControlState state) { - memset(&m_effect, 0, sizeof(m_effect)); - if (state) - { - SetSDLHapticEffect(state); - } - else - { - // this module uses type==0 to indicate 'off' - m_effect.type = 0; - } - Update(); + memset(&m_effect, 0, sizeof(m_effect)); + if (state) + { + SetSDLHapticEffect(state); + } + else + { + // this module uses type==0 to indicate 'off' + m_effect.type = 0; + } + Update(); } void Joystick::ConstantEffect::SetSDLHapticEffect(ControlState state) { - m_effect.type = SDL_HAPTIC_CONSTANT; - m_effect.constant.length = RUMBLE_LENGTH_MAX; - m_effect.constant.level = (Sint16)(state * 0x7FFF); + m_effect.type = SDL_HAPTIC_CONSTANT; + m_effect.constant.length = RUMBLE_LENGTH_MAX; + m_effect.constant.level = (Sint16)(state * 0x7FFF); } void Joystick::RampEffect::SetSDLHapticEffect(ControlState state) { - m_effect.type = SDL_HAPTIC_RAMP; - m_effect.ramp.length = RUMBLE_LENGTH_MAX; - m_effect.ramp.start = (Sint16)(state * 0x7FFF); + m_effect.type = SDL_HAPTIC_RAMP; + m_effect.ramp.length = RUMBLE_LENGTH_MAX; + m_effect.ramp.start = (Sint16)(state * 0x7FFF); } void Joystick::SineEffect::SetSDLHapticEffect(ControlState state) { - m_effect.type = SDL_HAPTIC_SINE; - m_effect.periodic.period = RUMBLE_PERIOD; - m_effect.periodic.magnitude = (Sint16)(state * 0x7FFF); - m_effect.periodic.offset = 0; - m_effect.periodic.phase = 18000; - m_effect.periodic.length = RUMBLE_LENGTH_MAX; - m_effect.periodic.delay = 0; - m_effect.periodic.attack_length = 0; + m_effect.type = SDL_HAPTIC_SINE; + m_effect.periodic.period = RUMBLE_PERIOD; + m_effect.periodic.magnitude = (Sint16)(state * 0x7FFF); + m_effect.periodic.offset = 0; + m_effect.periodic.phase = 18000; + m_effect.periodic.length = RUMBLE_LENGTH_MAX; + m_effect.periodic.delay = 0; + m_effect.periodic.attack_length = 0; } void Joystick::TriangleEffect::SetSDLHapticEffect(ControlState state) { - m_effect.type = SDL_HAPTIC_TRIANGLE; - m_effect.periodic.period = RUMBLE_PERIOD; - m_effect.periodic.magnitude = (Sint16)(state * 0x7FFF); - m_effect.periodic.offset = 0; - m_effect.periodic.phase = 18000; - m_effect.periodic.length = RUMBLE_LENGTH_MAX; - m_effect.periodic.delay = 0; - m_effect.periodic.attack_length = 0; + m_effect.type = SDL_HAPTIC_TRIANGLE; + m_effect.periodic.period = RUMBLE_PERIOD; + m_effect.periodic.magnitude = (Sint16)(state * 0x7FFF); + m_effect.periodic.offset = 0; + m_effect.periodic.phase = 18000; + m_effect.periodic.length = RUMBLE_LENGTH_MAX; + m_effect.periodic.delay = 0; + m_effect.periodic.attack_length = 0; } void Joystick::LeftRightEffect::SetSDLHapticEffect(ControlState state) { - m_effect.type = SDL_HAPTIC_LEFTRIGHT; - m_effect.leftright.length = RUMBLE_LENGTH_MAX; - // max ranges tuned to 'feel' similar in magnitude to triangle/sine on xbox360 controller - m_effect.leftright.large_magnitude = (Uint16)(state * 0x4000); - m_effect.leftright.small_magnitude = (Uint16)(state * 0xFFFF); + m_effect.type = SDL_HAPTIC_LEFTRIGHT; + m_effect.leftright.length = RUMBLE_LENGTH_MAX; + // max ranges tuned to 'feel' similar in magnitude to triangle/sine on xbox360 controller + m_effect.leftright.large_magnitude = (Uint16)(state * 0x4000); + m_effect.leftright.small_magnitude = (Uint16)(state * 0xFFFF); } #endif void Joystick::UpdateInput() { - // each joystick is doin this, o well - SDL_JoystickUpdate(); + // each joystick is doin this, o well + SDL_JoystickUpdate(); } std::string Joystick::GetName() const { - return StripSpaces(GetJoystickName(m_sdl_index)); + return StripSpaces(GetJoystickName(m_sdl_index)); } std::string Joystick::GetSource() const { - return "SDL"; + return "SDL"; } int Joystick::GetId() const { - return m_index; + return m_index; } std::string Joystick::Button::GetName() const { - std::ostringstream ss; - ss << "Button " << (int)m_index; - return ss.str(); + std::ostringstream ss; + ss << "Button " << (int)m_index; + return ss.str(); } std::string Joystick::Axis::GetName() const { - std::ostringstream ss; - ss << "Axis " << (int)m_index << (m_range<0 ? '-' : '+'); - return ss.str(); + std::ostringstream ss; + ss << "Axis " << (int)m_index << (m_range < 0 ? '-' : '+'); + return ss.str(); } std::string Joystick::Hat::GetName() const { - static char tmpstr[] = "Hat . ."; - // I don't think more than 10 hats are supported - tmpstr[4] = (char)('0' + m_index); - tmpstr[6] = "NESW"[m_direction]; - return tmpstr; + static char tmpstr[] = "Hat . ."; + // I don't think more than 10 hats are supported + tmpstr[4] = (char)('0' + m_index); + tmpstr[6] = "NESW"[m_direction]; + return tmpstr; } ControlState Joystick::Button::GetState() const { - return SDL_JoystickGetButton(m_js, m_index); + return SDL_JoystickGetButton(m_js, m_index); } ControlState Joystick::Axis::GetState() const { - return std::max(0.0, ControlState(SDL_JoystickGetAxis(m_js, m_index)) / m_range); + return std::max(0.0, ControlState(SDL_JoystickGetAxis(m_js, m_index)) / m_range); } ControlState Joystick::Hat::GetState() const { - return (SDL_JoystickGetHat(m_js, m_index) & (1 << m_direction)) > 0; + return (SDL_JoystickGetHat(m_js, m_index) & (1 << m_direction)) > 0; } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h index 751f40e9f4..10c3fab6ee 100644 --- a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h +++ b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h @@ -10,144 +10,155 @@ #include "InputCommon/ControllerInterface/Device.h" - #if SDL_VERSION_ATLEAST(1, 3, 0) - #define USE_SDL_HAPTIC +#define USE_SDL_HAPTIC #endif #ifdef USE_SDL_HAPTIC - #include +#include #endif namespace ciface { namespace SDL { - -void Init( std::vector& devices ); +void Init(std::vector& devices); class Joystick : public Core::Device { private: - - class Button : public Core::Device::Input - { - public: - std::string GetName() const override; - Button(u8 index, SDL_Joystick* js) : m_js(js), m_index(index) {} - ControlState GetState() const override; - private: - SDL_Joystick* const m_js; - const u8 m_index; - }; - - class Axis : public Core::Device::Input - { - public: - std::string GetName() const override; - Axis(u8 index, SDL_Joystick* js, Sint16 range) : m_js(js), m_range(range), m_index(index) {} - ControlState GetState() const override; - private: - SDL_Joystick* const m_js; - const Sint16 m_range; - const u8 m_index; - }; - - class Hat : public Input - { - public: - std::string GetName() const override; - Hat(u8 index, SDL_Joystick* js, u8 direction) : m_js(js), m_direction(direction), m_index(index) {} - ControlState GetState() const override; - private: - SDL_Joystick* const m_js; - const u8 m_direction; - const u8 m_index; - }; + class Button : public Core::Device::Input + { + public: + std::string GetName() const override; + Button(u8 index, SDL_Joystick* js) : m_js(js), m_index(index) {} + ControlState GetState() const override; + + private: + SDL_Joystick* const m_js; + const u8 m_index; + }; + + class Axis : public Core::Device::Input + { + public: + std::string GetName() const override; + Axis(u8 index, SDL_Joystick* js, Sint16 range) : m_js(js), m_range(range), m_index(index) {} + ControlState GetState() const override; + + private: + SDL_Joystick* const m_js; + const Sint16 m_range; + const u8 m_index; + }; + + class Hat : public Input + { + public: + std::string GetName() const override; + Hat(u8 index, SDL_Joystick* js, u8 direction) : m_js(js), m_direction(direction), m_index(index) + { + } + ControlState GetState() const override; + + private: + SDL_Joystick* const m_js; + const u8 m_direction; + const u8 m_index; + }; #ifdef USE_SDL_HAPTIC - class HapticEffect : public Output - { - public: - HapticEffect(SDL_Haptic* haptic) : m_haptic(haptic), m_id(-1) {} - ~HapticEffect() { m_effect.type = 0; Update(); } - - protected: - void Update(); - virtual void SetSDLHapticEffect(ControlState state) = 0; - - SDL_HapticEffect m_effect; - SDL_Haptic* m_haptic; - int m_id; - private: - virtual void SetState(ControlState state) override final; - }; - - class ConstantEffect : public HapticEffect - { - public: - ConstantEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} - std::string GetName() const override; - private: - void SetSDLHapticEffect(ControlState state) override; - }; - - class RampEffect : public HapticEffect - { - public: - RampEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} - std::string GetName() const override; - private: - void SetSDLHapticEffect(ControlState state) override; - }; - - class SineEffect : public HapticEffect - { - public: - SineEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} - std::string GetName() const override; - private: - void SetSDLHapticEffect(ControlState state) override; - }; - - class TriangleEffect : public HapticEffect - { - public: - TriangleEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} - std::string GetName() const override; - private: - void SetSDLHapticEffect(ControlState state) override; - }; - - class LeftRightEffect : public HapticEffect - { - public: - LeftRightEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} - std::string GetName() const override; - private: - void SetSDLHapticEffect(ControlState state) override; - }; + class HapticEffect : public Output + { + public: + HapticEffect(SDL_Haptic* haptic) : m_haptic(haptic), m_id(-1) {} + ~HapticEffect() + { + m_effect.type = 0; + Update(); + } + + protected: + void Update(); + virtual void SetSDLHapticEffect(ControlState state) = 0; + + SDL_HapticEffect m_effect; + SDL_Haptic* m_haptic; + int m_id; + + private: + virtual void SetState(ControlState state) override final; + }; + + class ConstantEffect : public HapticEffect + { + public: + ConstantEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} + std::string GetName() const override; + + private: + void SetSDLHapticEffect(ControlState state) override; + }; + + class RampEffect : public HapticEffect + { + public: + RampEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} + std::string GetName() const override; + + private: + void SetSDLHapticEffect(ControlState state) override; + }; + + class SineEffect : public HapticEffect + { + public: + SineEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} + std::string GetName() const override; + + private: + void SetSDLHapticEffect(ControlState state) override; + }; + + class TriangleEffect : public HapticEffect + { + public: + TriangleEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} + std::string GetName() const override; + + private: + void SetSDLHapticEffect(ControlState state) override; + }; + + class LeftRightEffect : public HapticEffect + { + public: + LeftRightEffect(SDL_Haptic* haptic) : HapticEffect(haptic) {} + std::string GetName() const override; + + private: + void SetSDLHapticEffect(ControlState state) override; + }; #endif public: - void UpdateInput() override; + void UpdateInput() override; - Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsigned int index); - ~Joystick(); + Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsigned int index); + ~Joystick(); - std::string GetName() const override; - int GetId() const override; - std::string GetSource() const override; + std::string GetName() const override; + int GetId() const override; + std::string GetSource() const override; private: - SDL_Joystick* const m_joystick; - const int m_sdl_index; - const unsigned int m_index; + SDL_Joystick* const m_joystick; + const int m_sdl_index; + const unsigned int m_index; #ifdef USE_SDL_HAPTIC - SDL_Haptic* m_haptic; + SDL_Haptic* m_haptic; #endif }; - } } diff --git a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp index c8438b488f..d7ed3343a0 100644 --- a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp +++ b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. - #include "InputCommon/ControllerInterface/XInput/XInput.h" #ifndef XINPUT_GAMEPAD_GUIDE @@ -13,49 +12,31 @@ namespace ciface { namespace XInput { - static const struct { - const char* const name; - const WORD bitmask; -} named_buttons[] = -{ - { "Button A", XINPUT_GAMEPAD_A }, - { "Button B", XINPUT_GAMEPAD_B }, - { "Button X", XINPUT_GAMEPAD_X }, - { "Button Y", XINPUT_GAMEPAD_Y }, - { "Pad N", XINPUT_GAMEPAD_DPAD_UP }, - { "Pad S", XINPUT_GAMEPAD_DPAD_DOWN }, - { "Pad W", XINPUT_GAMEPAD_DPAD_LEFT }, - { "Pad E", XINPUT_GAMEPAD_DPAD_RIGHT }, - { "Start", XINPUT_GAMEPAD_START }, - { "Back", XINPUT_GAMEPAD_BACK }, - { "Shoulder L", XINPUT_GAMEPAD_LEFT_SHOULDER }, - { "Shoulder R", XINPUT_GAMEPAD_RIGHT_SHOULDER }, - { "Guide", XINPUT_GAMEPAD_GUIDE }, - { "Thumb L", XINPUT_GAMEPAD_LEFT_THUMB }, - { "Thumb R", XINPUT_GAMEPAD_RIGHT_THUMB } -}; - -static const char* const named_triggers[] = -{ - "Trigger L", - "Trigger R" -}; - -static const char* const named_axes[] = -{ - "Left X", - "Left Y", - "Right X", - "Right Y" -}; - -static const char* const named_motors[] = -{ - "Motor L", - "Motor R" -}; + const char* const name; + const WORD bitmask; +} named_buttons[] = {{"Button A", XINPUT_GAMEPAD_A}, + {"Button B", XINPUT_GAMEPAD_B}, + {"Button X", XINPUT_GAMEPAD_X}, + {"Button Y", XINPUT_GAMEPAD_Y}, + {"Pad N", XINPUT_GAMEPAD_DPAD_UP}, + {"Pad S", XINPUT_GAMEPAD_DPAD_DOWN}, + {"Pad W", XINPUT_GAMEPAD_DPAD_LEFT}, + {"Pad E", XINPUT_GAMEPAD_DPAD_RIGHT}, + {"Start", XINPUT_GAMEPAD_START}, + {"Back", XINPUT_GAMEPAD_BACK}, + {"Shoulder L", XINPUT_GAMEPAD_LEFT_SHOULDER}, + {"Shoulder R", XINPUT_GAMEPAD_RIGHT_SHOULDER}, + {"Guide", XINPUT_GAMEPAD_GUIDE}, + {"Thumb L", XINPUT_GAMEPAD_LEFT_THUMB}, + {"Thumb R", XINPUT_GAMEPAD_RIGHT_THUMB}}; + +static const char* const named_triggers[] = {"Trigger L", "Trigger R"}; + +static const char* const named_axes[] = {"Left X", "Left Y", "Right X", "Right Y"}; + +static const char* const named_motors[] = {"Motor L", "Motor R"}; static HMODULE hXInput = nullptr; @@ -71,199 +52,197 @@ static bool haveGuideButton = false; void Init(std::vector& devices) { - if (!hXInput) - { - // Try for the most recent version we were compiled against (will only work if running on Win8+) - hXInput = ::LoadLibrary(XINPUT_DLL); - if (!hXInput) - { - // Drop back to DXSDK June 2010 version. Requires DX June 2010 redist. - hXInput = ::LoadLibrary(TEXT("xinput1_3.dll")); - if (!hXInput) - { - return; - } - } - - PXInputGetCapabilities = (XInputGetCapabilities_t)::GetProcAddress(hXInput, "XInputGetCapabilities"); - PXInputSetState = (XInputSetState_t)::GetProcAddress(hXInput, "XInputSetState"); - - // Ordinal 100 is the same as XInputGetState, except it doesn't dummy out the guide - // button info. Try loading it and fall back if needed. - PXInputGetState = (XInputGetState_t)::GetProcAddress(hXInput, (LPCSTR)100); - if (PXInputGetState) - haveGuideButton = true; - else - PXInputGetState = (XInputGetState_t)::GetProcAddress(hXInput, "XInputGetState"); - - if (!PXInputGetCapabilities || - !PXInputSetState || - !PXInputGetState) - { - ::FreeLibrary(hXInput); - hXInput = nullptr; - return; - } - } - - XINPUT_CAPABILITIES caps; - for (int i = 0; i != 4; ++i) - if (ERROR_SUCCESS == PXInputGetCapabilities(i, 0, &caps)) - devices.push_back(new Device(caps, i)); + if (!hXInput) + { + // Try for the most recent version we were compiled against (will only work if running on Win8+) + hXInput = ::LoadLibrary(XINPUT_DLL); + if (!hXInput) + { + // Drop back to DXSDK June 2010 version. Requires DX June 2010 redist. + hXInput = ::LoadLibrary(TEXT("xinput1_3.dll")); + if (!hXInput) + { + return; + } + } + + PXInputGetCapabilities = + (XInputGetCapabilities_t)::GetProcAddress(hXInput, "XInputGetCapabilities"); + PXInputSetState = (XInputSetState_t)::GetProcAddress(hXInput, "XInputSetState"); + + // Ordinal 100 is the same as XInputGetState, except it doesn't dummy out the guide + // button info. Try loading it and fall back if needed. + PXInputGetState = (XInputGetState_t)::GetProcAddress(hXInput, (LPCSTR)100); + if (PXInputGetState) + haveGuideButton = true; + else + PXInputGetState = (XInputGetState_t)::GetProcAddress(hXInput, "XInputGetState"); + + if (!PXInputGetCapabilities || !PXInputSetState || !PXInputGetState) + { + ::FreeLibrary(hXInput); + hXInput = nullptr; + return; + } + } + + XINPUT_CAPABILITIES caps; + for (int i = 0; i != 4; ++i) + if (ERROR_SUCCESS == PXInputGetCapabilities(i, 0, &caps)) + devices.push_back(new Device(caps, i)); } void DeInit() { - if (hXInput) - { - ::FreeLibrary(hXInput); - hXInput = nullptr; - } -} - -Device::Device(const XINPUT_CAPABILITIES& caps, u8 index) - : m_subtype(caps.SubType), m_index(index) -{ - // XInputGetCaps seems to always claim all capabilities are supported - // but I will leave all this stuff in, incase m$ fixes xinput up a bit - - // get supported buttons - for (int i = 0; i != sizeof(named_buttons)/sizeof(*named_buttons); ++i) - { - // Guide button is never reported in caps - if ((named_buttons[i].bitmask & caps.Gamepad.wButtons) || - ((named_buttons[i].bitmask & XINPUT_GAMEPAD_GUIDE) && haveGuideButton)) - AddInput(new Button(i, m_state_in.Gamepad.wButtons)); - } - - // get supported triggers - for (int i = 0; i != sizeof(named_triggers)/sizeof(*named_triggers); ++i) - { - //BYTE val = (&caps.Gamepad.bLeftTrigger)[i]; // should be max value / MSDN lies - if ((&caps.Gamepad.bLeftTrigger)[i]) - AddInput(new Trigger(i, (&m_state_in.Gamepad.bLeftTrigger)[i], 255 )); - } - - // get supported axes - for (int i = 0; i != sizeof(named_axes)/sizeof(*named_axes); ++i) - { - //SHORT val = (&caps.Gamepad.sThumbLX)[i]; // xinput doesn't give the range / MSDN is a liar - if ((&caps.Gamepad.sThumbLX)[i]) - { - const SHORT& ax = (&m_state_in.Gamepad.sThumbLX)[i]; - - // each axis gets a negative and a positive input instance associated with it - AddInput(new Axis(i, ax, -32768)); - AddInput(new Axis(i, ax, 32767)); - } - } - - // get supported motors - for (int i = 0; i != sizeof(named_motors)/sizeof(*named_motors); ++i) - { - //WORD val = (&caps.Vibration.wLeftMotorSpeed)[i]; // should be max value / nope, more lies - if ((&caps.Vibration.wLeftMotorSpeed)[i]) - AddOutput(new Motor(i, this, (&m_state_out.wLeftMotorSpeed)[i], 65535)); - } - - ZeroMemory(&m_state_in, sizeof(m_state_in)); + if (hXInput) + { + ::FreeLibrary(hXInput); + hXInput = nullptr; + } +} + +Device::Device(const XINPUT_CAPABILITIES& caps, u8 index) : m_subtype(caps.SubType), m_index(index) +{ + // XInputGetCaps seems to always claim all capabilities are supported + // but I will leave all this stuff in, incase m$ fixes xinput up a bit + + // get supported buttons + for (int i = 0; i != sizeof(named_buttons) / sizeof(*named_buttons); ++i) + { + // Guide button is never reported in caps + if ((named_buttons[i].bitmask & caps.Gamepad.wButtons) || + ((named_buttons[i].bitmask & XINPUT_GAMEPAD_GUIDE) && haveGuideButton)) + AddInput(new Button(i, m_state_in.Gamepad.wButtons)); + } + + // get supported triggers + for (int i = 0; i != sizeof(named_triggers) / sizeof(*named_triggers); ++i) + { + // BYTE val = (&caps.Gamepad.bLeftTrigger)[i]; // should be max value / MSDN lies + if ((&caps.Gamepad.bLeftTrigger)[i]) + AddInput(new Trigger(i, (&m_state_in.Gamepad.bLeftTrigger)[i], 255)); + } + + // get supported axes + for (int i = 0; i != sizeof(named_axes) / sizeof(*named_axes); ++i) + { + // SHORT val = (&caps.Gamepad.sThumbLX)[i]; // xinput doesn't give the range / MSDN is a liar + if ((&caps.Gamepad.sThumbLX)[i]) + { + const SHORT& ax = (&m_state_in.Gamepad.sThumbLX)[i]; + + // each axis gets a negative and a positive input instance associated with it + AddInput(new Axis(i, ax, -32768)); + AddInput(new Axis(i, ax, 32767)); + } + } + + // get supported motors + for (int i = 0; i != sizeof(named_motors) / sizeof(*named_motors); ++i) + { + // WORD val = (&caps.Vibration.wLeftMotorSpeed)[i]; // should be max value / nope, more lies + if ((&caps.Vibration.wLeftMotorSpeed)[i]) + AddOutput(new Motor(i, this, (&m_state_out.wLeftMotorSpeed)[i], 65535)); + } + + ZeroMemory(&m_state_in, sizeof(m_state_in)); } std::string Device::GetName() const { - switch (m_subtype) - { - case XINPUT_DEVSUBTYPE_GAMEPAD: - return "Gamepad"; - case XINPUT_DEVSUBTYPE_WHEEL: - return "Wheel"; - case XINPUT_DEVSUBTYPE_ARCADE_STICK: - return "Arcade Stick"; - case XINPUT_DEVSUBTYPE_FLIGHT_STICK: - return "Flight Stick"; - case XINPUT_DEVSUBTYPE_DANCE_PAD: - return "Dance Pad"; - case XINPUT_DEVSUBTYPE_GUITAR: - return "Guitar"; - case XINPUT_DEVSUBTYPE_DRUM_KIT: - return "Drum Kit"; - default: - return "Device"; - } + switch (m_subtype) + { + case XINPUT_DEVSUBTYPE_GAMEPAD: + return "Gamepad"; + case XINPUT_DEVSUBTYPE_WHEEL: + return "Wheel"; + case XINPUT_DEVSUBTYPE_ARCADE_STICK: + return "Arcade Stick"; + case XINPUT_DEVSUBTYPE_FLIGHT_STICK: + return "Flight Stick"; + case XINPUT_DEVSUBTYPE_DANCE_PAD: + return "Dance Pad"; + case XINPUT_DEVSUBTYPE_GUITAR: + return "Guitar"; + case XINPUT_DEVSUBTYPE_DRUM_KIT: + return "Drum Kit"; + default: + return "Device"; + } } int Device::GetId() const { - return m_index; + return m_index; } std::string Device::GetSource() const { - return "XInput"; + return "XInput"; } // Update I/O void Device::UpdateInput() { - PXInputGetState(m_index, &m_state_in); + PXInputGetState(m_index, &m_state_in); } void Device::UpdateMotors() { - // this if statement is to make rumble work better when multiple ControllerInterfaces are using the device - // only calls XInputSetState if the state changed - if (memcmp(&m_state_out, &m_current_state_out, sizeof(m_state_out))) - { - m_current_state_out = m_state_out; - PXInputSetState(m_index, &m_state_out); - } + // this if statement is to make rumble work better when multiple ControllerInterfaces are using + // the device + // only calls XInputSetState if the state changed + if (memcmp(&m_state_out, &m_current_state_out, sizeof(m_state_out))) + { + m_current_state_out = m_state_out; + PXInputSetState(m_index, &m_state_out); + } } // GET name/source/id std::string Device::Button::GetName() const { - return named_buttons[m_index].name; + return named_buttons[m_index].name; } std::string Device::Axis::GetName() const { - return std::string(named_axes[m_index]) + (m_range<0 ? '-' : '+'); + return std::string(named_axes[m_index]) + (m_range < 0 ? '-' : '+'); } std::string Device::Trigger::GetName() const { - return named_triggers[m_index]; + return named_triggers[m_index]; } std::string Device::Motor::GetName() const { - return named_motors[m_index]; + return named_motors[m_index]; } // GET / SET STATES ControlState Device::Button::GetState() const { - return (m_buttons & named_buttons[m_index].bitmask) > 0; + return (m_buttons & named_buttons[m_index].bitmask) > 0; } ControlState Device::Trigger::GetState() const { - return ControlState(m_trigger) / m_range; + return ControlState(m_trigger) / m_range; } ControlState Device::Axis::GetState() const { - return std::max( 0.0, ControlState(m_axis) / m_range ); + return std::max(0.0, ControlState(m_axis) / m_range); } void Device::Motor::SetState(ControlState state) { - m_motor = (WORD)(state * m_range); - m_parent->UpdateMotors(); + m_motor = (WORD)(state * m_range); + m_parent->UpdateMotors(); } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h index 012e99eba2..204b1ecf81 100644 --- a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h +++ b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h @@ -9,8 +9,8 @@ #pragma once -#include #include +#include #include "InputCommon/ControllerInterface/Device.h" @@ -22,80 +22,87 @@ namespace ciface { namespace XInput { - void Init(std::vector& devices); void DeInit(); class Device : public Core::Device { private: - class Button : public Core::Device::Input - { - public: - Button(u8 index, const WORD& buttons) : m_buttons(buttons), m_index(index) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const WORD& m_buttons; - u8 m_index; - }; - - class Axis : public Core::Device::Input - { - public: - Axis(u8 index, const SHORT& axis, SHORT range) : m_axis(axis), m_range(range), m_index(index) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const SHORT& m_axis; - const SHORT m_range; - const u8 m_index; - }; - - class Trigger : public Core::Device::Input - { - public: - Trigger(u8 index, const BYTE& trigger, BYTE range) : m_trigger(trigger), m_range(range), m_index(index) {} - std::string GetName() const override; - ControlState GetState() const override; - private: - const BYTE& m_trigger; - const BYTE m_range; - const u8 m_index; - }; - - class Motor : public Core::Device::Output - { - public: - Motor(u8 index, Device* parent, WORD &motor, WORD range) : m_motor(motor), m_range(range), m_index(index), m_parent(parent) {} - std::string GetName() const override; - void SetState(ControlState state) override; - private: - WORD& m_motor; - const WORD m_range; - const u8 m_index; - Device* m_parent; - }; + class Button : public Core::Device::Input + { + public: + Button(u8 index, const WORD& buttons) : m_buttons(buttons), m_index(index) {} + std::string GetName() const override; + ControlState GetState() const override; + + private: + const WORD& m_buttons; + u8 m_index; + }; + + class Axis : public Core::Device::Input + { + public: + Axis(u8 index, const SHORT& axis, SHORT range) : m_axis(axis), m_range(range), m_index(index) {} + std::string GetName() const override; + ControlState GetState() const override; + + private: + const SHORT& m_axis; + const SHORT m_range; + const u8 m_index; + }; + + class Trigger : public Core::Device::Input + { + public: + Trigger(u8 index, const BYTE& trigger, BYTE range) + : m_trigger(trigger), m_range(range), m_index(index) + { + } + std::string GetName() const override; + ControlState GetState() const override; + + private: + const BYTE& m_trigger; + const BYTE m_range; + const u8 m_index; + }; + + class Motor : public Core::Device::Output + { + public: + Motor(u8 index, Device* parent, WORD& motor, WORD range) + : m_motor(motor), m_range(range), m_index(index), m_parent(parent) + { + } + std::string GetName() const override; + void SetState(ControlState state) override; + + private: + WORD& m_motor; + const WORD m_range; + const u8 m_index; + Device* m_parent; + }; public: - void UpdateInput() override; + void UpdateInput() override; - Device(const XINPUT_CAPABILITIES& capabilities, u8 index); + Device(const XINPUT_CAPABILITIES& capabilities, u8 index); - std::string GetName() const override; - int GetId() const override; - std::string GetSource() const override; + std::string GetName() const override; + int GetId() const override; + std::string GetSource() const override; - void UpdateMotors(); + void UpdateMotors(); private: - XINPUT_STATE m_state_in; - XINPUT_VIBRATION m_state_out{}; - XINPUT_VIBRATION m_current_state_out{}; - const BYTE m_subtype; - const u8 m_index; + XINPUT_STATE m_state_in; + XINPUT_VIBRATION m_state_out{}; + XINPUT_VIBRATION m_current_state_out{}; + const BYTE m_subtype; + const u8 m_index; }; - - } } diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp index 3d7a02a3a0..79b86a487d 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include #include #include #include -#include #include "InputCommon/ControllerInterface/Xlib/XInput2.h" @@ -25,7 +25,6 @@ // * Key controls: these correspond to a limited subset of the keyboard // keys. - // Mouse axis control tuning. Unlike absolute mouse position, relative mouse // motion data needs to be tweaked and smoothed out a bit to be usable. @@ -46,325 +45,324 @@ namespace ciface { namespace XInput2 { - // This function will add zero or more KeyboardMouse objects to devices. void Init(std::vector& devices, void* const hwnd) { - Display* dpy = XOpenDisplay(nullptr); + Display* dpy = XOpenDisplay(nullptr); - // xi_opcode is important; it will be used to identify XInput events by - // the polling loop in UpdateInput. - int xi_opcode, event, error; + // xi_opcode is important; it will be used to identify XInput events by + // the polling loop in UpdateInput. + int xi_opcode, event, error; - // verify that the XInput extension is available - if (!XQueryExtension(dpy, "XInputExtension", &xi_opcode, &event, &error)) - return; + // verify that the XInput extension is available + if (!XQueryExtension(dpy, "XInputExtension", &xi_opcode, &event, &error)) + return; - // verify that the XInput extension is at at least version 2.0 - int major = 2, minor = 0; + // verify that the XInput extension is at at least version 2.0 + int major = 2, minor = 0; - if (XIQueryVersion(dpy, &major, &minor) != Success) - return; + if (XIQueryVersion(dpy, &major, &minor) != Success) + return; - // register all master devices with Dolphin + // register all master devices with Dolphin - XIDeviceInfo* all_masters; - XIDeviceInfo* current_master; - int num_masters; + XIDeviceInfo* all_masters; + XIDeviceInfo* current_master; + int num_masters; - all_masters = XIQueryDevice(dpy, XIAllMasterDevices, &num_masters); + all_masters = XIQueryDevice(dpy, XIAllMasterDevices, &num_masters); - for (int i = 0; i < num_masters; i++) - { - current_master = &all_masters[i]; - if (current_master->use == XIMasterPointer) - // Since current_master is a master pointer, its attachment must - // be a master keyboard. - devices.push_back(new KeyboardMouse((Window)hwnd, xi_opcode, current_master->deviceid, current_master->attachment)); - } + for (int i = 0; i < num_masters; i++) + { + current_master = &all_masters[i]; + if (current_master->use == XIMasterPointer) + // Since current_master is a master pointer, its attachment must + // be a master keyboard. + devices.push_back(new KeyboardMouse((Window)hwnd, xi_opcode, current_master->deviceid, + current_master->attachment)); + } - XCloseDisplay(dpy); + XCloseDisplay(dpy); - XIFreeDeviceInfo(all_masters); + XIFreeDeviceInfo(all_masters); } // Apply the event mask to the device and all its slaves. Only used in the // constructor. Remember, each KeyboardMouse has its own copy of the event // stream, which is how multiple event masks can "coexist." -void KeyboardMouse::SelectEventsForDevice(Window window, XIEventMask *mask, int deviceid) +void KeyboardMouse::SelectEventsForDevice(Window window, XIEventMask* mask, int deviceid) { - // Set the event mask for the master device. - mask->deviceid = deviceid; - XISelectEvents(m_display, window, mask, 1); - - // Query all the master device's slaves and set the same event mask for - // those too. There are two reasons we want to do this. For mouse devices, - // we want the raw motion events, and only slaves (i.e. physical hardware - // devices) emit those. For keyboard devices, selecting slaves avoids - // dealing with key focus. - - XIDeviceInfo* all_slaves; - XIDeviceInfo* current_slave; - int num_slaves; - - all_slaves = XIQueryDevice(m_display, XIAllDevices, &num_slaves); - - for (int i = 0; i < num_slaves; i++) - { - current_slave = &all_slaves[i]; - if ((current_slave->use != XISlavePointer && current_slave->use != XISlaveKeyboard) || current_slave->attachment != deviceid) - continue; - mask->deviceid = current_slave->deviceid; - XISelectEvents(m_display, window, mask, 1); - } - - XIFreeDeviceInfo(all_slaves); + // Set the event mask for the master device. + mask->deviceid = deviceid; + XISelectEvents(m_display, window, mask, 1); + + // Query all the master device's slaves and set the same event mask for + // those too. There are two reasons we want to do this. For mouse devices, + // we want the raw motion events, and only slaves (i.e. physical hardware + // devices) emit those. For keyboard devices, selecting slaves avoids + // dealing with key focus. + + XIDeviceInfo* all_slaves; + XIDeviceInfo* current_slave; + int num_slaves; + + all_slaves = XIQueryDevice(m_display, XIAllDevices, &num_slaves); + + for (int i = 0; i < num_slaves; i++) + { + current_slave = &all_slaves[i]; + if ((current_slave->use != XISlavePointer && current_slave->use != XISlaveKeyboard) || + current_slave->attachment != deviceid) + continue; + mask->deviceid = current_slave->deviceid; + XISelectEvents(m_display, window, mask, 1); + } + + XIFreeDeviceInfo(all_slaves); } KeyboardMouse::KeyboardMouse(Window window, int opcode, int pointer, int keyboard) - : m_window(window), xi_opcode(opcode), pointer_deviceid(pointer), keyboard_deviceid(keyboard) + : m_window(window), xi_opcode(opcode), pointer_deviceid(pointer), keyboard_deviceid(keyboard) { - memset(&m_state, 0, sizeof(m_state)); - - // The cool thing about each KeyboardMouse object having its own Display - // is that each one gets its own separate copy of the X11 event stream, - // which it can individually filter to get just the events it's interested - // in. So be aware that each KeyboardMouse object actually has its own X11 - // "context." - m_display = XOpenDisplay(nullptr); - - int min_keycode, max_keycode; - XDisplayKeycodes(m_display, &min_keycode, &max_keycode); - - int unused; // should always be 1 - XIDeviceInfo* pointer_device = XIQueryDevice(m_display, pointer_deviceid, &unused); - name = std::string(pointer_device->name); - XIFreeDeviceInfo(pointer_device); - - XIEventMask mask; - unsigned char mask_buf[(XI_LASTEVENT + 7)/8]; - - mask.mask_len = sizeof(mask_buf); - mask.mask = mask_buf; - memset(mask_buf, 0, sizeof(mask_buf)); - - XISetMask(mask_buf, XI_ButtonPress); - XISetMask(mask_buf, XI_ButtonRelease); - XISetMask(mask_buf, XI_RawMotion); - XISetMask(mask_buf, XI_KeyPress); - XISetMask(mask_buf, XI_KeyRelease); - - SelectEventsForDevice(DefaultRootWindow(m_display), &mask, pointer_deviceid); - SelectEventsForDevice(DefaultRootWindow(m_display), &mask, keyboard_deviceid); - - // Keyboard Keys - for (int i = min_keycode; i <= max_keycode; ++i) - { - Key* temp_key = new Key(m_display, i, m_state.keyboard); - if (temp_key->m_keyname.length()) - AddInput(temp_key); - else - delete temp_key; - } - - // Mouse Buttons - for (int i = 0; i < 5; i++) - AddInput(new Button(i, &m_state.buttons)); - - // Mouse Cursor, X-/+ and Y-/+ - for (int i = 0; i != 4; ++i) - AddInput(new Cursor(!!(i & 2), !!(i & 1), (i & 2) ? &m_state.cursor.y : &m_state.cursor.x)); - - // Mouse Axis, X-/+ and Y-/+ - for (int i = 0; i != 4; ++i) - AddInput(new Axis(!!(i & 2), !!(i & 1), (i & 2) ? &m_state.axis.y : &m_state.axis.x)); + memset(&m_state, 0, sizeof(m_state)); + + // The cool thing about each KeyboardMouse object having its own Display + // is that each one gets its own separate copy of the X11 event stream, + // which it can individually filter to get just the events it's interested + // in. So be aware that each KeyboardMouse object actually has its own X11 + // "context." + m_display = XOpenDisplay(nullptr); + + int min_keycode, max_keycode; + XDisplayKeycodes(m_display, &min_keycode, &max_keycode); + + int unused; // should always be 1 + XIDeviceInfo* pointer_device = XIQueryDevice(m_display, pointer_deviceid, &unused); + name = std::string(pointer_device->name); + XIFreeDeviceInfo(pointer_device); + + XIEventMask mask; + unsigned char mask_buf[(XI_LASTEVENT + 7) / 8]; + + mask.mask_len = sizeof(mask_buf); + mask.mask = mask_buf; + memset(mask_buf, 0, sizeof(mask_buf)); + + XISetMask(mask_buf, XI_ButtonPress); + XISetMask(mask_buf, XI_ButtonRelease); + XISetMask(mask_buf, XI_RawMotion); + XISetMask(mask_buf, XI_KeyPress); + XISetMask(mask_buf, XI_KeyRelease); + + SelectEventsForDevice(DefaultRootWindow(m_display), &mask, pointer_deviceid); + SelectEventsForDevice(DefaultRootWindow(m_display), &mask, keyboard_deviceid); + + // Keyboard Keys + for (int i = min_keycode; i <= max_keycode; ++i) + { + Key* temp_key = new Key(m_display, i, m_state.keyboard); + if (temp_key->m_keyname.length()) + AddInput(temp_key); + else + delete temp_key; + } + + // Mouse Buttons + for (int i = 0; i < 5; i++) + AddInput(new Button(i, &m_state.buttons)); + + // Mouse Cursor, X-/+ and Y-/+ + for (int i = 0; i != 4; ++i) + AddInput(new Cursor(!!(i & 2), !!(i & 1), (i & 2) ? &m_state.cursor.y : &m_state.cursor.x)); + + // Mouse Axis, X-/+ and Y-/+ + for (int i = 0; i != 4; ++i) + AddInput(new Axis(!!(i & 2), !!(i & 1), (i & 2) ? &m_state.axis.y : &m_state.axis.x)); } KeyboardMouse::~KeyboardMouse() { - XCloseDisplay(m_display); + XCloseDisplay(m_display); } // Update the mouse cursor controls void KeyboardMouse::UpdateCursor() { - double root_x, root_y, win_x, win_y; - Window root, child; + double root_x, root_y, win_x, win_y; + Window root, child; - // unused-- we're not interested in button presses here, as those are - // updated using events - XIButtonState button_state; - XIModifierState mods; - XIGroupState group; + // unused-- we're not interested in button presses here, as those are + // updated using events + XIButtonState button_state; + XIModifierState mods; + XIGroupState group; - XIQueryPointer(m_display, pointer_deviceid, m_window, &root, &child, &root_x, &root_y, &win_x, &win_y, &button_state, &mods, &group); + XIQueryPointer(m_display, pointer_deviceid, m_window, &root, &child, &root_x, &root_y, &win_x, + &win_y, &button_state, &mods, &group); - free (button_state.mask); + free(button_state.mask); - XWindowAttributes win_attribs; - XGetWindowAttributes(m_display, m_window, &win_attribs); + XWindowAttributes win_attribs; + XGetWindowAttributes(m_display, m_window, &win_attribs); - // the mouse position as a range from -1 to 1 - m_state.cursor.x = win_x / (float)win_attribs.width * 2 - 1; - m_state.cursor.y = win_y / (float)win_attribs.height * 2 - 1; + // the mouse position as a range from -1 to 1 + m_state.cursor.x = win_x / (float)win_attribs.width * 2 - 1; + m_state.cursor.y = win_y / (float)win_attribs.height * 2 - 1; } void KeyboardMouse::UpdateInput() { - XFlush(m_display); - - // Get the absolute position of the mouse pointer - UpdateCursor(); - - // for the axis controls - float delta_x = 0.0f, delta_y = 0.0f; - double delta_delta; - - // Iterate through the event queue - update the axis controls, mouse - // button controls, and keyboard controls. - XEvent event; - while (XPending(m_display)) - { - XNextEvent(m_display, &event); - - if (event.xcookie.type != GenericEvent) - continue; - if (event.xcookie.extension != xi_opcode) - continue; - if (!XGetEventData(m_display, &event.xcookie)) - continue; - - // only one of these will get used - XIDeviceEvent* dev_event = (XIDeviceEvent*)event.xcookie.data; - XIRawEvent* raw_event = (XIRawEvent*)event.xcookie.data; - - switch (event.xcookie.evtype) - { - case XI_ButtonPress: - m_state.buttons |= 1<<(dev_event->detail-1); - break; - case XI_ButtonRelease: - m_state.buttons &= ~(1<<(dev_event->detail-1)); - break; - case XI_KeyPress: - m_state.keyboard[dev_event->detail / 8] |= 1<<(dev_event->detail % 8); - break; - case XI_KeyRelease: - m_state.keyboard[dev_event->detail / 8] &= ~(1<<(dev_event->detail % 8)); - break; - case XI_RawMotion: - // always safe because there is always at least one byte in - // raw_event->valuators.mask, and if a bit is set in the mask, - // then the value in raw_values is also available. - if (XIMaskIsSet(raw_event->valuators.mask, 0)) - { - delta_delta = raw_event->raw_values[0]; - // test for inf and nan - if (delta_delta == delta_delta && 1+delta_delta != delta_delta) - delta_x += delta_delta; - } - if (XIMaskIsSet(raw_event->valuators.mask, 1)) - { - delta_delta = raw_event->raw_values[1]; - // test for inf and nan - if (delta_delta == delta_delta && 1+delta_delta != delta_delta) - delta_y += delta_delta; - } - break; - } - - XFreeEventData(m_display, &event.xcookie); - } - - // apply axis smoothing - m_state.axis.x *= MOUSE_AXIS_SMOOTHING; - m_state.axis.x += delta_x; - m_state.axis.x /= MOUSE_AXIS_SMOOTHING+1.0f; - m_state.axis.y *= MOUSE_AXIS_SMOOTHING; - m_state.axis.y += delta_y; - m_state.axis.y /= MOUSE_AXIS_SMOOTHING+1.0f; + XFlush(m_display); + + // Get the absolute position of the mouse pointer + UpdateCursor(); + + // for the axis controls + float delta_x = 0.0f, delta_y = 0.0f; + double delta_delta; + + // Iterate through the event queue - update the axis controls, mouse + // button controls, and keyboard controls. + XEvent event; + while (XPending(m_display)) + { + XNextEvent(m_display, &event); + + if (event.xcookie.type != GenericEvent) + continue; + if (event.xcookie.extension != xi_opcode) + continue; + if (!XGetEventData(m_display, &event.xcookie)) + continue; + + // only one of these will get used + XIDeviceEvent* dev_event = (XIDeviceEvent*)event.xcookie.data; + XIRawEvent* raw_event = (XIRawEvent*)event.xcookie.data; + + switch (event.xcookie.evtype) + { + case XI_ButtonPress: + m_state.buttons |= 1 << (dev_event->detail - 1); + break; + case XI_ButtonRelease: + m_state.buttons &= ~(1 << (dev_event->detail - 1)); + break; + case XI_KeyPress: + m_state.keyboard[dev_event->detail / 8] |= 1 << (dev_event->detail % 8); + break; + case XI_KeyRelease: + m_state.keyboard[dev_event->detail / 8] &= ~(1 << (dev_event->detail % 8)); + break; + case XI_RawMotion: + // always safe because there is always at least one byte in + // raw_event->valuators.mask, and if a bit is set in the mask, + // then the value in raw_values is also available. + if (XIMaskIsSet(raw_event->valuators.mask, 0)) + { + delta_delta = raw_event->raw_values[0]; + // test for inf and nan + if (delta_delta == delta_delta && 1 + delta_delta != delta_delta) + delta_x += delta_delta; + } + if (XIMaskIsSet(raw_event->valuators.mask, 1)) + { + delta_delta = raw_event->raw_values[1]; + // test for inf and nan + if (delta_delta == delta_delta && 1 + delta_delta != delta_delta) + delta_y += delta_delta; + } + break; + } + + XFreeEventData(m_display, &event.xcookie); + } + + // apply axis smoothing + m_state.axis.x *= MOUSE_AXIS_SMOOTHING; + m_state.axis.x += delta_x; + m_state.axis.x /= MOUSE_AXIS_SMOOTHING + 1.0f; + m_state.axis.y *= MOUSE_AXIS_SMOOTHING; + m_state.axis.y += delta_y; + m_state.axis.y /= MOUSE_AXIS_SMOOTHING + 1.0f; } std::string KeyboardMouse::GetName() const { - // This is the name string we got from the X server for this master - // pointer/keyboard pair. - return name; + // This is the name string we got from the X server for this master + // pointer/keyboard pair. + return name; } std::string KeyboardMouse::GetSource() const { - return "XInput2"; + return "XInput2"; } int KeyboardMouse::GetId() const { - return -1; + return -1; } KeyboardMouse::Key::Key(Display* const display, KeyCode keycode, const char* keyboard) - : m_display(display), m_keyboard(keyboard), m_keycode(keycode) + : m_display(display), m_keyboard(keyboard), m_keycode(keycode) { - int i = 0; - KeySym keysym = 0; - do - { - keysym = XkbKeycodeToKeysym(m_display, keycode, i, 0); - i++; - } - while (keysym == NoSymbol && i < 8); - - // Convert to upper case for the keyname - if (keysym >= 97 && keysym <= 122) - keysym -= 32; - - // 0x0110ffff is the top of the unicode character range according - // to keysymdef.h although it is probably more than we need. - if (keysym == NoSymbol || keysym > 0x0110ffff || - XKeysymToString(keysym) == nullptr) - m_keyname = std::string(); - else - m_keyname = std::string(XKeysymToString(keysym)); + int i = 0; + KeySym keysym = 0; + do + { + keysym = XkbKeycodeToKeysym(m_display, keycode, i, 0); + i++; + } while (keysym == NoSymbol && i < 8); + + // Convert to upper case for the keyname + if (keysym >= 97 && keysym <= 122) + keysym -= 32; + + // 0x0110ffff is the top of the unicode character range according + // to keysymdef.h although it is probably more than we need. + if (keysym == NoSymbol || keysym > 0x0110ffff || XKeysymToString(keysym) == nullptr) + m_keyname = std::string(); + else + m_keyname = std::string(XKeysymToString(keysym)); } ControlState KeyboardMouse::Key::GetState() const { - return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0; + return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0; } KeyboardMouse::Button::Button(unsigned int index, unsigned int* buttons) - : m_buttons(buttons), m_index(index) + : m_buttons(buttons), m_index(index) { - // this will be a problem if we remove the hardcoded five-button limit - name = std::string("Click ") + (char)('1' + m_index); + // this will be a problem if we remove the hardcoded five-button limit + name = std::string("Click ") + (char)('1' + m_index); } ControlState KeyboardMouse::Button::GetState() const { - return ((*m_buttons & (1 << m_index)) != 0); + return ((*m_buttons & (1 << m_index)) != 0); } KeyboardMouse::Cursor::Cursor(u8 index, bool positive, const float* cursor) - : m_cursor(cursor), m_index(index), m_positive(positive) + : m_cursor(cursor), m_index(index), m_positive(positive) { - name = std::string("Cursor ") + (char)('X' + m_index) + (m_positive ? '+' : '-'); + name = std::string("Cursor ") + (char)('X' + m_index) + (m_positive ? '+' : '-'); } ControlState KeyboardMouse::Cursor::GetState() const { - return std::max(0.0f, *m_cursor / (m_positive ? 1.0f : -1.0f)); + return std::max(0.0f, *m_cursor / (m_positive ? 1.0f : -1.0f)); } KeyboardMouse::Axis::Axis(u8 index, bool positive, const float* axis) - : m_axis(axis), m_index(index), m_positive(positive) + : m_axis(axis), m_index(index), m_positive(positive) { - name = std::string("Axis ") + (char)('X' + m_index) + (m_positive ? '+' : '-'); + name = std::string("Axis ") + (char)('X' + m_index) + (m_positive ? '+' : '-'); } ControlState KeyboardMouse::Axis::GetState() const { - return std::max(0.0f, *m_axis / (m_positive ? MOUSE_AXIS_SENSITIVITY : -MOUSE_AXIS_SENSITIVITY)); + return std::max(0.0f, *m_axis / (m_positive ? MOUSE_AXIS_SENSITIVITY : -MOUSE_AXIS_SENSITIVITY)); } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h index 09a59706e3..e8f2e2e06b 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h @@ -7,9 +7,9 @@ #pragma once extern "C" { -#include #include #include +#include } #include "InputCommon/ControllerInterface/Device.h" @@ -18,103 +18,101 @@ namespace ciface { namespace XInput2 { - void Init(std::vector& devices, void* const hwnd); class KeyboardMouse : public Core::Device { - private: - struct State - { - char keyboard[32]; - unsigned int buttons; - struct - { - float x, y; - } cursor, axis; - }; - - class Key : public Input - { - friend class KeyboardMouse; - public: - std::string GetName() const override { return m_keyname; } - Key(Display* display, KeyCode keycode, const char* keyboard); - ControlState GetState() const override; - - private: - std::string m_keyname; - Display* const m_display; - const char* const m_keyboard; - const KeyCode m_keycode; - }; - - class Button : public Input - { - public: - std::string GetName() const override { return name; } - Button(unsigned int index, unsigned int* buttons); - ControlState GetState() const override; - - private: - const unsigned int* m_buttons; - const unsigned int m_index; - std::string name; - }; - - class Cursor : public Input - { - public: - std::string GetName() const override { return name; } - bool IsDetectable() override { return false; } - Cursor(u8 index, bool positive, const float* cursor); - ControlState GetState() const override; - - private: - const float* m_cursor; - const u8 m_index; - const bool m_positive; - std::string name; - }; - - class Axis : public Input - { - public: - std::string GetName() const override { return name; } - bool IsDetectable() override { return false; } - Axis(u8 index, bool positive, const float* axis); - ControlState GetState() const override; - - private: - const float* m_axis; - const u8 m_index; - const bool m_positive; - std::string name; - }; + struct State + { + char keyboard[32]; + unsigned int buttons; + struct + { + float x, y; + } cursor, axis; + }; + + class Key : public Input + { + friend class KeyboardMouse; + + public: + std::string GetName() const override { return m_keyname; } + Key(Display* display, KeyCode keycode, const char* keyboard); + ControlState GetState() const override; + + private: + std::string m_keyname; + Display* const m_display; + const char* const m_keyboard; + const KeyCode m_keycode; + }; + + class Button : public Input + { + public: + std::string GetName() const override { return name; } + Button(unsigned int index, unsigned int* buttons); + ControlState GetState() const override; + + private: + const unsigned int* m_buttons; + const unsigned int m_index; + std::string name; + }; + + class Cursor : public Input + { + public: + std::string GetName() const override { return name; } + bool IsDetectable() override { return false; } + Cursor(u8 index, bool positive, const float* cursor); + ControlState GetState() const override; + + private: + const float* m_cursor; + const u8 m_index; + const bool m_positive; + std::string name; + }; + + class Axis : public Input + { + public: + std::string GetName() const override { return name; } + bool IsDetectable() override { return false; } + Axis(u8 index, bool positive, const float* axis); + ControlState GetState() const override; + + private: + const float* m_axis; + const u8 m_index; + const bool m_positive; + std::string name; + }; private: - void SelectEventsForDevice(Window window, XIEventMask *mask, int deviceid); - void UpdateCursor(); + void SelectEventsForDevice(Window window, XIEventMask* mask, int deviceid); + void UpdateCursor(); public: - void UpdateInput() override; + void UpdateInput() override; - KeyboardMouse(Window window, int opcode, int pointer_deviceid, int keyboard_deviceid); - ~KeyboardMouse(); + KeyboardMouse(Window window, int opcode, int pointer_deviceid, int keyboard_deviceid); + ~KeyboardMouse(); - std::string GetName() const override; - std::string GetSource() const override; - int GetId() const override; + std::string GetName() const override; + std::string GetSource() const override; + int GetId() const override; private: - Window m_window; - Display* m_display; - State m_state; - int xi_opcode; - const int pointer_deviceid, keyboard_deviceid; - std::string name; + Window m_window; + Display* m_display; + State m_state; + int xi_opcode; + const int pointer_deviceid, keyboard_deviceid; + std::string name; }; - } } diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp index e198f1112d..71269c74f7 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include #include +#include #include "InputCommon/ControllerInterface/Xlib/Xlib.h" @@ -11,149 +11,156 @@ namespace ciface { namespace Xlib { - void Init(std::vector& devices, void* const hwnd) { - devices.push_back(new KeyboardMouse((Window)hwnd)); + devices.push_back(new KeyboardMouse((Window)hwnd)); } KeyboardMouse::KeyboardMouse(Window window) : m_window(window) { - memset(&m_state, 0, sizeof(m_state)); + memset(&m_state, 0, sizeof(m_state)); - m_display = XOpenDisplay(nullptr); + m_display = XOpenDisplay(nullptr); - int min_keycode, max_keycode; - XDisplayKeycodes(m_display, &min_keycode, &max_keycode); + int min_keycode, max_keycode; + XDisplayKeycodes(m_display, &min_keycode, &max_keycode); - // Keyboard Keys - for (int i = min_keycode; i <= max_keycode; ++i) - { - Key *temp_key = new Key(m_display, i, m_state.keyboard); - if (temp_key->m_keyname.length()) - AddInput(temp_key); - else - delete temp_key; - } + // Keyboard Keys + for (int i = min_keycode; i <= max_keycode; ++i) + { + Key* temp_key = new Key(m_display, i, m_state.keyboard); + if (temp_key->m_keyname.length()) + AddInput(temp_key); + else + delete temp_key; + } - // Mouse Buttons - AddInput(new Button(Button1Mask, m_state.buttons)); - AddInput(new Button(Button2Mask, m_state.buttons)); - AddInput(new Button(Button3Mask, m_state.buttons)); - AddInput(new Button(Button4Mask, m_state.buttons)); - AddInput(new Button(Button5Mask, m_state.buttons)); + // Mouse Buttons + AddInput(new Button(Button1Mask, m_state.buttons)); + AddInput(new Button(Button2Mask, m_state.buttons)); + AddInput(new Button(Button3Mask, m_state.buttons)); + AddInput(new Button(Button4Mask, m_state.buttons)); + AddInput(new Button(Button5Mask, m_state.buttons)); - // Mouse Cursor, X-/+ and Y-/+ - for (int i = 0; i != 4; ++i) - AddInput(new Cursor(!!(i & 2), !!(i & 1), (&m_state.cursor.x)[!!(i & 2)])); + // Mouse Cursor, X-/+ and Y-/+ + for (int i = 0; i != 4; ++i) + AddInput(new Cursor(!!(i & 2), !!(i & 1), (&m_state.cursor.x)[!!(i & 2)])); } KeyboardMouse::~KeyboardMouse() { - XCloseDisplay(m_display); + XCloseDisplay(m_display); } void KeyboardMouse::UpdateInput() { - XQueryKeymap(m_display, m_state.keyboard); + XQueryKeymap(m_display, m_state.keyboard); - int root_x, root_y, win_x, win_y; - Window root, child; - XQueryPointer(m_display, m_window, &root, &child, &root_x, &root_y, &win_x, &win_y, &m_state.buttons); + int root_x, root_y, win_x, win_y; + Window root, child; + XQueryPointer(m_display, m_window, &root, &child, &root_x, &root_y, &win_x, &win_y, + &m_state.buttons); - // update mouse cursor - XWindowAttributes win_attribs; - XGetWindowAttributes(m_display, m_window, &win_attribs); + // update mouse cursor + XWindowAttributes win_attribs; + XGetWindowAttributes(m_display, m_window, &win_attribs); - // the mouse position as a range from -1 to 1 - m_state.cursor.x = (float)win_x / (float)win_attribs.width * 2 - 1; - m_state.cursor.y = (float)win_y / (float)win_attribs.height * 2 - 1; + // the mouse position as a range from -1 to 1 + m_state.cursor.x = (float)win_x / (float)win_attribs.width * 2 - 1; + m_state.cursor.y = (float)win_y / (float)win_attribs.height * 2 - 1; } std::string KeyboardMouse::GetName() const { - return "Keyboard Mouse"; + return "Keyboard Mouse"; } std::string KeyboardMouse::GetSource() const { - return "Xlib"; + return "Xlib"; } int KeyboardMouse::GetId() const { - return 0; + return 0; } KeyboardMouse::Key::Key(Display* const display, KeyCode keycode, const char* keyboard) - : m_display(display), m_keyboard(keyboard), m_keycode(keycode) -{ - int i = 0; - KeySym keysym = 0; - do - { - keysym = XkbKeycodeToKeysym(m_display, keycode, i, 0); - i++; - } - while (keysym == NoSymbol && i < 8); - - // Convert to upper case for the keyname - if (keysym >= 97 && keysym <= 122) - keysym -= 32; - - // 0x0110ffff is the top of the unicode character range according - // to keysymdef.h although it is probably more than we need. - if (keysym == NoSymbol || keysym > 0x0110ffff || - XKeysymToString(keysym) == nullptr) - m_keyname = std::string(); - else - m_keyname = std::string(XKeysymToString(keysym)); + : m_display(display), m_keyboard(keyboard), m_keycode(keycode) +{ + int i = 0; + KeySym keysym = 0; + do + { + keysym = XkbKeycodeToKeysym(m_display, keycode, i, 0); + i++; + } while (keysym == NoSymbol && i < 8); + + // Convert to upper case for the keyname + if (keysym >= 97 && keysym <= 122) + keysym -= 32; + + // 0x0110ffff is the top of the unicode character range according + // to keysymdef.h although it is probably more than we need. + if (keysym == NoSymbol || keysym > 0x0110ffff || XKeysymToString(keysym) == nullptr) + m_keyname = std::string(); + else + m_keyname = std::string(XKeysymToString(keysym)); } ControlState KeyboardMouse::Key::GetState() const { - return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0; + return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0; } ControlState KeyboardMouse::Button::GetState() const { - return ((m_buttons & m_index) != 0); + return ((m_buttons & m_index) != 0); } ControlState KeyboardMouse::Cursor::GetState() const { - return std::max(0.0f, m_cursor / (m_positive ? 1.0f : -1.0f)); + return std::max(0.0f, m_cursor / (m_positive ? 1.0f : -1.0f)); } std::string KeyboardMouse::Key::GetName() const { - return m_keyname; + return m_keyname; } std::string KeyboardMouse::Cursor::GetName() const { - static char tmpstr[] = "Cursor .."; - tmpstr[7] = (char)('X' + m_index); - tmpstr[8] = (m_positive ? '+' : '-'); - return tmpstr; + static char tmpstr[] = "Cursor .."; + tmpstr[7] = (char)('X' + m_index); + tmpstr[8] = (m_positive ? '+' : '-'); + return tmpstr; } std::string KeyboardMouse::Button::GetName() const { - char button = '0'; - switch (m_index) - { - case Button1Mask: button = '1'; break; - case Button2Mask: button = '2'; break; - case Button3Mask: button = '3'; break; - case Button4Mask: button = '4'; break; - case Button5Mask: button = '5'; break; - } - - static char tmpstr[] = "Click ."; - tmpstr[6] = button; - return tmpstr; + char button = '0'; + switch (m_index) + { + case Button1Mask: + button = '1'; + break; + case Button2Mask: + button = '2'; + break; + case Button3Mask: + button = '3'; + break; + case Button4Mask: + button = '4'; + break; + case Button5Mask: + button = '5'; + break; + } + + static char tmpstr[] = "Click ."; + tmpstr[6] = button; + return tmpstr; } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.h b/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.h index 6fe72e4da7..94388211c0 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.h +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/Xlib.h @@ -4,8 +4,8 @@ #pragma once -#include #include +#include #include "InputCommon/ControllerInterface/Device.h" @@ -13,81 +13,80 @@ namespace ciface { namespace Xlib { - void Init(std::vector& devices, void* const hwnd); class KeyboardMouse : public Core::Device { - private: - struct State - { - char keyboard[32]; - unsigned int buttons; - struct - { - float x, y; - } cursor; - }; - - class Key : public Input - { - friend class KeyboardMouse; - public: - std::string GetName() const override; - Key(Display* display, KeyCode keycode, const char* keyboard); - ControlState GetState() const override; - - private: - std::string m_keyname; - Display* const m_display; - const char* const m_keyboard; - const KeyCode m_keycode; - }; - - class Button : public Input - { - public: - std::string GetName() const override; - Button(unsigned int index, unsigned int& buttons) - : m_buttons(buttons), m_index(index) {} - ControlState GetState() const override; - - private: - const unsigned int& m_buttons; - const unsigned int m_index; - }; - - class Cursor : public Input - { - public: - std::string GetName() const override; - bool IsDetectable() override { return false; } - Cursor(u8 index, bool positive, const float& cursor) - : m_cursor(cursor), m_index(index), m_positive(positive) {} - ControlState GetState() const override; - - private: - const float& m_cursor; - const u8 m_index; - const bool m_positive; - }; + struct State + { + char keyboard[32]; + unsigned int buttons; + struct + { + float x, y; + } cursor; + }; + + class Key : public Input + { + friend class KeyboardMouse; + + public: + std::string GetName() const override; + Key(Display* display, KeyCode keycode, const char* keyboard); + ControlState GetState() const override; + + private: + std::string m_keyname; + Display* const m_display; + const char* const m_keyboard; + const KeyCode m_keycode; + }; + + class Button : public Input + { + public: + std::string GetName() const override; + Button(unsigned int index, unsigned int& buttons) : m_buttons(buttons), m_index(index) {} + ControlState GetState() const override; + + private: + const unsigned int& m_buttons; + const unsigned int m_index; + }; + + class Cursor : public Input + { + public: + std::string GetName() const override; + bool IsDetectable() override { return false; } + Cursor(u8 index, bool positive, const float& cursor) + : m_cursor(cursor), m_index(index), m_positive(positive) + { + } + ControlState GetState() const override; + + private: + const float& m_cursor; + const u8 m_index; + const bool m_positive; + }; public: - void UpdateInput() override; + void UpdateInput() override; - KeyboardMouse(Window window); - ~KeyboardMouse(); + KeyboardMouse(Window window); + ~KeyboardMouse(); - std::string GetName() const override; - std::string GetSource() const override; - int GetId() const override; + std::string GetName() const override; + std::string GetSource() const override; + int GetId() const override; private: - Window m_window; - Display* m_display; - State m_state; + Window m_window; + Display* m_display; + State m_state; }; - } } diff --git a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp index d88a44b7ef..7a6ba50713 100644 --- a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp +++ b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp @@ -11,295 +11,291 @@ #include "Common/Logging/Log.h" #include "InputCommon/ControllerInterface/evdev/evdev.h" - namespace ciface { namespace evdev { - static std::string GetName(const std::string& devnode) { - int fd = open(devnode.c_str(), O_RDWR|O_NONBLOCK); - libevdev* dev = nullptr; - int ret = libevdev_new_from_fd(fd, &dev); - if (ret != 0) - { - close(fd); - return std::string(); - } - std::string res = libevdev_get_name(dev); - libevdev_free(dev); - close(fd); - return res; + int fd = open(devnode.c_str(), O_RDWR | O_NONBLOCK); + libevdev* dev = nullptr; + int ret = libevdev_new_from_fd(fd, &dev); + if (ret != 0) + { + close(fd); + return std::string(); + } + std::string res = libevdev_get_name(dev); + libevdev_free(dev); + close(fd); + return res; } -void Init(std::vector &controllerDevices) +void Init(std::vector& controllerDevices) { - // this is used to number the joysticks - // multiple joysticks with the same name shall get unique ids starting at 0 - std::map name_counts; - - int num_controllers = 0; - - // We use Udev to find any devices. In the future this will allow for hotplugging. - // But for now it is essentially iterating over /dev/input/event0 to event31. However if the - // naming scheme is ever updated in the future, this *should* be forwards compatable. - - struct udev* udev = udev_new(); - _assert_msg_(PAD, udev != 0, "Couldn't initilize libudev."); - - // List all input devices - udev_enumerate* enumerate = udev_enumerate_new(udev); - udev_enumerate_add_match_subsystem(enumerate, "input"); - udev_enumerate_scan_devices(enumerate); - udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); - - // Iterate over all input devices - udev_list_entry* dev_list_entry; - udev_list_entry_foreach(dev_list_entry, devices) - { - const char* path = udev_list_entry_get_name(dev_list_entry); - - udev_device* dev = udev_device_new_from_syspath(udev, path); - - const char* devnode = udev_device_get_devnode(dev); - // We only care about devices which we have read/write access to. - if (devnode && access(devnode, W_OK) == 0) - { - // Unfortunately udev gives us no way to filter out the non event device interfaces. - // So we open it and see if it works with evdev ioctls or not. - std::string name = GetName(devnode); - evdevDevice* input = new evdevDevice(devnode, name_counts[name]++); - - if (input->IsInteresting()) - { - controllerDevices.push_back(input); - num_controllers++; - } - else - { - // Either it wasn't a evdev device, or it didn't have at least 8 buttons or two axis. - delete input; - } - } - udev_device_unref(dev); - } - udev_enumerate_unref(enumerate); - udev_unref(udev); + // this is used to number the joysticks + // multiple joysticks with the same name shall get unique ids starting at 0 + std::map name_counts; + + int num_controllers = 0; + + // We use Udev to find any devices. In the future this will allow for hotplugging. + // But for now it is essentially iterating over /dev/input/event0 to event31. However if the + // naming scheme is ever updated in the future, this *should* be forwards compatable. + + struct udev* udev = udev_new(); + _assert_msg_(PAD, udev != 0, "Couldn't initilize libudev."); + + // List all input devices + udev_enumerate* enumerate = udev_enumerate_new(udev); + udev_enumerate_add_match_subsystem(enumerate, "input"); + udev_enumerate_scan_devices(enumerate); + udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); + + // Iterate over all input devices + udev_list_entry* dev_list_entry; + udev_list_entry_foreach(dev_list_entry, devices) + { + const char* path = udev_list_entry_get_name(dev_list_entry); + + udev_device* dev = udev_device_new_from_syspath(udev, path); + + const char* devnode = udev_device_get_devnode(dev); + // We only care about devices which we have read/write access to. + if (devnode && access(devnode, W_OK) == 0) + { + // Unfortunately udev gives us no way to filter out the non event device interfaces. + // So we open it and see if it works with evdev ioctls or not. + std::string name = GetName(devnode); + evdevDevice* input = new evdevDevice(devnode, name_counts[name]++); + + if (input->IsInteresting()) + { + controllerDevices.push_back(input); + num_controllers++; + } + else + { + // Either it wasn't a evdev device, or it didn't have at least 8 buttons or two axis. + delete input; + } + } + udev_device_unref(dev); + } + udev_enumerate_unref(enumerate); + udev_unref(udev); } -evdevDevice::evdevDevice(const std::string &devnode, int id) : m_devfile(devnode), m_id(id) +evdevDevice::evdevDevice(const std::string& devnode, int id) : m_devfile(devnode), m_id(id) { - // The device file will be read on one of the main threads, so we open in non-blocking mode. - m_fd = open(devnode.c_str(), O_RDWR|O_NONBLOCK); - int ret = libevdev_new_from_fd(m_fd, &m_dev); - - if (ret != 0) - { - // This useally fails because the device node isn't an evdev device, such as /dev/input/js0 - m_initialized = false; - close(m_fd); - return; - } - - m_name = libevdev_get_name(m_dev); - - // Controller buttons (and keyboard keys) - int num_buttons = 0; - for (int key = 0; key < KEY_MAX; key++) - if (libevdev_has_event_code(m_dev, EV_KEY, key)) - AddInput(new Button(num_buttons++, key, m_dev)); - - // Absolute axis (thumbsticks) - int num_axis = 0; - for (int axis = 0; axis < 0x100; axis++) - if (libevdev_has_event_code(m_dev, EV_ABS, axis)) - { - AddAnalogInputs(new Axis(num_axis, axis, false, m_dev), - new Axis(num_axis, axis, true, m_dev)); - num_axis++; - } - - // Force feedback - if (libevdev_has_event_code(m_dev, EV_FF, FF_PERIODIC)) - { - for (auto type : {FF_SINE, FF_SQUARE, FF_TRIANGLE, FF_SAW_UP, FF_SAW_DOWN}) - if (libevdev_has_event_code(m_dev, EV_FF, type)) - AddOutput(new ForceFeedback(type, m_dev)); - } - if (libevdev_has_event_code(m_dev, EV_FF, FF_RUMBLE)) - { - AddOutput(new ForceFeedback(FF_RUMBLE, m_dev)); - } - - // TODO: Add leds as output devices - - m_initialized = true; - m_interesting = num_axis >= 2 || num_buttons >= 8; + // The device file will be read on one of the main threads, so we open in non-blocking mode. + m_fd = open(devnode.c_str(), O_RDWR | O_NONBLOCK); + int ret = libevdev_new_from_fd(m_fd, &m_dev); + + if (ret != 0) + { + // This useally fails because the device node isn't an evdev device, such as /dev/input/js0 + m_initialized = false; + close(m_fd); + return; + } + + m_name = libevdev_get_name(m_dev); + + // Controller buttons (and keyboard keys) + int num_buttons = 0; + for (int key = 0; key < KEY_MAX; key++) + if (libevdev_has_event_code(m_dev, EV_KEY, key)) + AddInput(new Button(num_buttons++, key, m_dev)); + + // Absolute axis (thumbsticks) + int num_axis = 0; + for (int axis = 0; axis < 0x100; axis++) + if (libevdev_has_event_code(m_dev, EV_ABS, axis)) + { + AddAnalogInputs(new Axis(num_axis, axis, false, m_dev), + new Axis(num_axis, axis, true, m_dev)); + num_axis++; + } + + // Force feedback + if (libevdev_has_event_code(m_dev, EV_FF, FF_PERIODIC)) + { + for (auto type : {FF_SINE, FF_SQUARE, FF_TRIANGLE, FF_SAW_UP, FF_SAW_DOWN}) + if (libevdev_has_event_code(m_dev, EV_FF, type)) + AddOutput(new ForceFeedback(type, m_dev)); + } + if (libevdev_has_event_code(m_dev, EV_FF, FF_RUMBLE)) + { + AddOutput(new ForceFeedback(FF_RUMBLE, m_dev)); + } + + // TODO: Add leds as output devices + + m_initialized = true; + m_interesting = num_axis >= 2 || num_buttons >= 8; } evdevDevice::~evdevDevice() { - if (m_initialized) - { - libevdev_free(m_dev); - close(m_fd); - } + if (m_initialized) + { + libevdev_free(m_dev); + close(m_fd); + } } void evdevDevice::UpdateInput() { - // Run through all evdev events - // libevdev will keep track of the actual controller state internally which can be queried - // later with libevdev_fetch_event_value() - input_event ev; - int rc = LIBEVDEV_READ_STATUS_SUCCESS; - do - { - if (rc == LIBEVDEV_READ_STATUS_SYNC) - rc = libevdev_next_event(m_dev, LIBEVDEV_READ_FLAG_SYNC, &ev); - else - rc = libevdev_next_event(m_dev, LIBEVDEV_READ_FLAG_NORMAL, &ev); - } while (rc >= 0); + // Run through all evdev events + // libevdev will keep track of the actual controller state internally which can be queried + // later with libevdev_fetch_event_value() + input_event ev; + int rc = LIBEVDEV_READ_STATUS_SUCCESS; + do + { + if (rc == LIBEVDEV_READ_STATUS_SYNC) + rc = libevdev_next_event(m_dev, LIBEVDEV_READ_FLAG_SYNC, &ev); + else + rc = libevdev_next_event(m_dev, LIBEVDEV_READ_FLAG_NORMAL, &ev); + } while (rc >= 0); } - std::string evdevDevice::Button::GetName() const { - // Buttons below 0x100 are mostly keyboard keys, and the names make sense - if (m_code < 0x100) - { - const char* name = libevdev_event_code_get_name(EV_KEY, m_code); - if (name) - return std::string(name); - } - // But controllers use codes above 0x100, and the standard label often doesn't match. - // We are better off with Button 0 and so on. - return "Button " + std::to_string(m_index); + // Buttons below 0x100 are mostly keyboard keys, and the names make sense + if (m_code < 0x100) + { + const char* name = libevdev_event_code_get_name(EV_KEY, m_code); + if (name) + return std::string(name); + } + // But controllers use codes above 0x100, and the standard label often doesn't match. + // We are better off with Button 0 and so on. + return "Button " + std::to_string(m_index); } ControlState evdevDevice::Button::GetState() const { - int value = 0; - libevdev_fetch_event_value(m_dev, EV_KEY, m_code, &value); - return value; + int value = 0; + libevdev_fetch_event_value(m_dev, EV_KEY, m_code, &value); + return value; } -evdevDevice::Axis::Axis(u8 index, u16 code, bool upper, libevdev* dev) : - m_code(code), m_index(index), m_upper(upper), m_dev(dev) +evdevDevice::Axis::Axis(u8 index, u16 code, bool upper, libevdev* dev) + : m_code(code), m_index(index), m_upper(upper), m_dev(dev) { - m_min = libevdev_get_abs_minimum(m_dev, m_code); - m_range = libevdev_get_abs_maximum(m_dev, m_code) + abs(m_min); + m_min = libevdev_get_abs_minimum(m_dev, m_code); + m_range = libevdev_get_abs_maximum(m_dev, m_code) + abs(m_min); } std::string evdevDevice::Axis::GetName() const { - return "Axis " + std::to_string(m_index) + (m_upper ? "+" : "-"); + return "Axis " + std::to_string(m_index) + (m_upper ? "+" : "-"); } ControlState evdevDevice::Axis::GetState() const { - int value = 0; - libevdev_fetch_event_value(m_dev, EV_ABS, m_code, &value); + int value = 0; + libevdev_fetch_event_value(m_dev, EV_ABS, m_code, &value); - // Value from 0.0 to 1.0 - ControlState fvalue = double(value - m_min) / double(m_range); + // Value from 0.0 to 1.0 + ControlState fvalue = double(value - m_min) / double(m_range); - // Split into two axis, each covering half the range from 0.0 to 1.0 - if (m_upper) - return std::max(0.0, fvalue - 0.5) * 2.0; - else - return (0.5 - std::min(0.5, fvalue)) * 2.0; + // Split into two axis, each covering half the range from 0.0 to 1.0 + if (m_upper) + return std::max(0.0, fvalue - 0.5) * 2.0; + else + return (0.5 - std::min(0.5, fvalue)) * 2.0; } std::string evdevDevice::ForceFeedback::GetName() const { - // We have some default names. - switch (m_type) - { - case FF_SINE: - return "Sine"; - case FF_TRIANGLE: - return "Triangle"; - case FF_SQUARE: - return "Square"; - case FF_RUMBLE: - return "LeftRight"; - default: - { - const char* name = libevdev_event_code_get_name(EV_FF, m_type); - if (name) - return std::string(name); - return "Unknown"; - } - } + // We have some default names. + switch (m_type) + { + case FF_SINE: + return "Sine"; + case FF_TRIANGLE: + return "Triangle"; + case FF_SQUARE: + return "Square"; + case FF_RUMBLE: + return "LeftRight"; + default: + { + const char* name = libevdev_event_code_get_name(EV_FF, m_type); + if (name) + return std::string(name); + return "Unknown"; + } + } } void evdevDevice::ForceFeedback::SetState(ControlState state) { - // libevdev doesn't have nice helpers for forcefeedback - // we will use the file descriptors directly. - - if (m_id != -1) // delete the previous effect (which also stops it) - { - ioctl(m_fd, EVIOCRMFF, m_id); - m_id = -1; - } - - if (state > 0) // Upload and start an effect. - { - ff_effect effect; - - effect.id = -1; - effect.direction = 0; // down - effect.replay.length = 500; // 500ms - effect.replay.delay = 0; - effect.trigger.button = 0; // don't trigger on button press - effect.trigger.interval = 0; - - // This is the the interface that XInput uses, with 2 motors of differing sizes/frequencies that - // are controlled seperatally - if (m_type == FF_RUMBLE) - { - effect.type = FF_RUMBLE; - // max ranges tuned to 'feel' similar in magnitude to triangle/sine on xbox360 controller - effect.u.rumble.strong_magnitude = u16(state * 0x4000); - effect.u.rumble.weak_magnitude = u16(state * 0xFFFF); - } - else // FF_PERIODIC, a more generic interface. - { - effect.type = FF_PERIODIC; - effect.u.periodic.waveform = m_type; - effect.u.periodic.phase = 0x7fff; // 180 degrees - effect.u.periodic.offset = 0; - effect.u.periodic.period = 10; - effect.u.periodic.magnitude = s16(state * 0x7FFF); - effect.u.periodic.envelope.attack_length = 0; // no attack - effect.u.periodic.envelope.attack_level = 0; - effect.u.periodic.envelope.fade_length = 0; - effect.u.periodic.envelope.fade_level = 0; - } - - ioctl(m_fd, EVIOCSFF, &effect); - m_id = effect.id; - - input_event play; - play.type = EV_FF; - play.code = m_id; - play.value = 1; - - write(m_fd, (const void*) &play, sizeof(play)); - } + // libevdev doesn't have nice helpers for forcefeedback + // we will use the file descriptors directly. + + if (m_id != -1) // delete the previous effect (which also stops it) + { + ioctl(m_fd, EVIOCRMFF, m_id); + m_id = -1; + } + + if (state > 0) // Upload and start an effect. + { + ff_effect effect; + + effect.id = -1; + effect.direction = 0; // down + effect.replay.length = 500; // 500ms + effect.replay.delay = 0; + effect.trigger.button = 0; // don't trigger on button press + effect.trigger.interval = 0; + + // This is the the interface that XInput uses, with 2 motors of differing sizes/frequencies that + // are controlled seperatally + if (m_type == FF_RUMBLE) + { + effect.type = FF_RUMBLE; + // max ranges tuned to 'feel' similar in magnitude to triangle/sine on xbox360 controller + effect.u.rumble.strong_magnitude = u16(state * 0x4000); + effect.u.rumble.weak_magnitude = u16(state * 0xFFFF); + } + else // FF_PERIODIC, a more generic interface. + { + effect.type = FF_PERIODIC; + effect.u.periodic.waveform = m_type; + effect.u.periodic.phase = 0x7fff; // 180 degrees + effect.u.periodic.offset = 0; + effect.u.periodic.period = 10; + effect.u.periodic.magnitude = s16(state * 0x7FFF); + effect.u.periodic.envelope.attack_length = 0; // no attack + effect.u.periodic.envelope.attack_level = 0; + effect.u.periodic.envelope.fade_length = 0; + effect.u.periodic.envelope.fade_level = 0; + } + + ioctl(m_fd, EVIOCSFF, &effect); + m_id = effect.id; + + input_event play; + play.type = EV_FF; + play.code = m_id; + play.value = 1; + + write(m_fd, (const void*)&play, sizeof(play)); + } } evdevDevice::ForceFeedback::~ForceFeedback() { - // delete the uploaded effect, so we don't leak it. - if (m_id != -1) - { - ioctl(m_fd, EVIOCRMFF, m_id); - } + // delete the uploaded effect, so we don't leak it. + if (m_id != -1) + { + ioctl(m_fd, EVIOCRMFF, m_id); + } } - } } diff --git a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.h b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.h index 5b3c23a466..ce7831bfdc 100644 --- a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.h +++ b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.h @@ -4,9 +4,9 @@ #pragma once +#include #include #include -#include #include "InputCommon/ControllerInterface/Device.h" @@ -14,74 +14,72 @@ namespace ciface { namespace evdev { - void Init(std::vector& devices); class evdevDevice : public Core::Device { private: - class Button : public Core::Device::Input - { - public: - std::string GetName() const override; - Button(u8 index, u16 code, libevdev* dev) : m_index(index), m_code(code), m_dev(dev) {} - ControlState GetState() const override; - private: - const u8 m_index; - const u16 m_code; - libevdev* m_dev; - }; + class Button : public Core::Device::Input + { + public: + std::string GetName() const override; + Button(u8 index, u16 code, libevdev* dev) : m_index(index), m_code(code), m_dev(dev) {} + ControlState GetState() const override; - class Axis : public Core::Device::Input - { - public: - std::string GetName() const override; - Axis(u8 index, u16 code, bool upper, libevdev* dev); - ControlState GetState() const override; - private: - const u16 m_code; - const u8 m_index; - const bool m_upper; - int m_range; - int m_min; - libevdev* m_dev; - }; + private: + const u8 m_index; + const u16 m_code; + libevdev* m_dev; + }; - class ForceFeedback : public Core::Device::Output - { - public: - std::string GetName() const override; - ForceFeedback(u16 type, libevdev* dev) : m_type(type), m_id(-1) { m_fd = libevdev_get_fd(dev); } - ~ForceFeedback(); - void SetState(ControlState state) override; - private: - const u16 m_type; - int m_fd; - int m_id; - }; + class Axis : public Core::Device::Input + { + public: + std::string GetName() const override; + Axis(u8 index, u16 code, bool upper, libevdev* dev); + ControlState GetState() const override; -public: - void UpdateInput() override; + private: + const u16 m_code; + const u8 m_index; + const bool m_upper; + int m_range; + int m_min; + libevdev* m_dev; + }; - evdevDevice(const std::string &devnode, int id); - ~evdevDevice(); + class ForceFeedback : public Core::Device::Output + { + public: + std::string GetName() const override; + ForceFeedback(u16 type, libevdev* dev) : m_type(type), m_id(-1) { m_fd = libevdev_get_fd(dev); } + ~ForceFeedback(); + void SetState(ControlState state) override; - std::string GetName() const override { return m_name; } - int GetId() const override { return m_id; } - std::string GetSource() const override { return "evdev"; } + private: + const u16 m_type; + int m_fd; + int m_id; + }; - bool IsInteresting() const { return m_initialized && m_interesting; } +public: + void UpdateInput() override; + + evdevDevice(const std::string& devnode, int id); + ~evdevDevice(); + std::string GetName() const override { return m_name; } + int GetId() const override { return m_id; } + std::string GetSource() const override { return "evdev"; } + bool IsInteresting() const { return m_initialized && m_interesting; } private: - const std::string m_devfile; - int m_fd; - libevdev* m_dev; - std::string m_name; - const int m_id; - bool m_initialized; - bool m_interesting; + const std::string m_devfile; + int m_fd; + libevdev* m_dev; + std::string m_name; + const int m_id; + bool m_initialized; + bool m_interesting; }; - } - } -- cgit v1.2.3