From f6f2b1fc60067b19068f2d0edbbfbfe5e73a0806 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 24 Nov 2013 15:04:53 -0600 Subject: [PATCH] [Android-overlay] Support multiple gamepads with touch screen controls. --- Source/Android/assets/GCPadNew.ini | 75 +++++++++++++++++++ .../dolphinemu/dolphinemu/NativeLibrary.java | 10 ++- .../emulation/overlay/InputOverlay.java | 8 +- .../DolphinWX/Src/Android/ButtonManager.cpp | 65 ++++++++-------- .../DolphinWX/Src/Android/ButtonManager.h | 8 +- Source/Core/DolphinWX/Src/MainAndroid.cpp | 8 +- .../ControllerInterface/Android/Android.cpp | 49 ++++++------ .../Src/ControllerInterface/Android/Android.h | 16 ++-- 8 files changed, 163 insertions(+), 76 deletions(-) diff --git a/Source/Android/assets/GCPadNew.ini b/Source/Android/assets/GCPadNew.ini index 7e770f60d3..77e790d0fa 100644 --- a/Source/Android/assets/GCPadNew.ini +++ b/Source/Android/assets/GCPadNew.ini @@ -25,5 +25,80 @@ D-Pad/Down = `Button 7` D-Pad/Left = `Button 8` D-Pad/Right = `Button 9` [GCPad2] +Device = Android/1/Touchscreen +Buttons/A = `Button 0` +Buttons/B = `Button 1` +Buttons/X = `Button 3` +Buttons/Y = `Button 4` +Buttons/Z = `Button 5` +Buttons/Start = `Button 2` +Main Stick/Up = `Axis 11` +Main Stick/Down = `Axis 12` +Main Stick/Left = `Axis 13` +Main Stick/Right = `Axis 14` +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000 +C-Stick/Up = `Axis 15` +C-Stick/Down = `Axis 16` +C-Stick/Left = `Axis 17` +C-Stick/Right = `Axis 18` +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000 +Triggers/L = `Axis 18` +Triggers/R = `Axis 19` +D-Pad/Up = `Button 6` +D-Pad/Down = `Button 7` +D-Pad/Left = `Button 8` +D-Pad/Right = `Button 9` [GCPad3] +Device = Android/2/Touchscreen +Buttons/A = `Button 0` +Buttons/B = `Button 1` +Buttons/X = `Button 3` +Buttons/Y = `Button 4` +Buttons/Z = `Button 5` +Buttons/Start = `Button 2` +Main Stick/Up = `Axis 11` +Main Stick/Down = `Axis 12` +Main Stick/Left = `Axis 13` +Main Stick/Right = `Axis 14` +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000 +C-Stick/Up = `Axis 15` +C-Stick/Down = `Axis 16` +C-Stick/Left = `Axis 17` +C-Stick/Right = `Axis 18` +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000 +Triggers/L = `Axis 18` +Triggers/R = `Axis 19` +D-Pad/Up = `Button 6` +D-Pad/Down = `Button 7` +D-Pad/Left = `Button 8` +D-Pad/Right = `Button 9` [GCPad4] +Device = Android/3/Touchscreen +Buttons/A = `Button 0` +Buttons/B = `Button 1` +Buttons/X = `Button 3` +Buttons/Y = `Button 4` +Buttons/Z = `Button 5` +Buttons/Start = `Button 2` +Main Stick/Up = `Axis 11` +Main Stick/Down = `Axis 12` +Main Stick/Left = `Axis 13` +Main Stick/Right = `Axis 14` +Main Stick/Modifier = Shift_L +Main Stick/Modifier/Range = 50.000000 +C-Stick/Up = `Axis 15` +C-Stick/Down = `Axis 16` +C-Stick/Left = `Axis 17` +C-Stick/Right = `Axis 18` +C-Stick/Modifier = Control_L +C-Stick/Modifier/Range = 50.000000 +Triggers/L = `Axis 18` +Triggers/R = `Axis 19` +D-Pad/Up = `Button 6` +D-Pad/Down = `Button 7` +D-Pad/Left = `Button 8` +D-Pad/Right = `Button 9` diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java index 7745deadba..ac6275301d 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -56,19 +56,21 @@ public final class NativeLibrary /** * Handles touch events. * - * @param Button Key code identifying which button was pressed. + * @param padID Identifier for which GCpad 0-3, + * @param Button Key code identifying which button was pressed, * @param Action Mask for the action being performed. */ - public static native void onTouchEvent(int Button, int Action); + public static native void onTouchEvent(int padID, int Button, int Action); /** * Handles axis-related touch events. * - * @param Axis Axis ID for the type of axis being altered. (Example: Main stick up, down, left, right, etc). + * @param padID Identifier for which GCpad 0-3, + * @param Axis Axis ID for the type of axis being altered. (Example: Main stick up, down, left, right, etc), * @param force How 'far down' the joystick is pushed down. 0.0f indicates center (or no force), * 1.0f indicates max force (or joystick pushed all the way down in any arbitrary direction). */ - public static native void onTouchAxisEvent(int Axis, float force); + public static native void onTouchAxisEvent(int padID, int Axis, float force); /** * Handles button press events for a gamepad. diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/emulation/overlay/InputOverlay.java b/Source/Android/src/org/dolphinemu/dolphinemu/emulation/overlay/InputOverlay.java index 26f628ed46..4f34df7dc6 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/emulation/overlay/InputOverlay.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/emulation/overlay/InputOverlay.java @@ -96,15 +96,15 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener switch (button.getId()) { case ButtonType.BUTTON_A: - NativeLibrary.onTouchEvent(ButtonType.BUTTON_A, buttonState); + NativeLibrary.onTouchEvent(0, ButtonType.BUTTON_A, buttonState); break; case ButtonType.BUTTON_B: - NativeLibrary.onTouchEvent(ButtonType.BUTTON_B, buttonState); + NativeLibrary.onTouchEvent(0, ButtonType.BUTTON_B, buttonState); break; case ButtonType.BUTTON_START: - NativeLibrary.onTouchEvent(ButtonType.BUTTON_START, buttonState); + NativeLibrary.onTouchEvent(0, ButtonType.BUTTON_START, buttonState); break; default: @@ -121,7 +121,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener for (int a = 0; a < 4; ++a) { - NativeLibrary.onTouchAxisEvent(axisIDs[a], axises[a]); + NativeLibrary.onTouchAxisEvent(0, axisIDs[a], axises[a]); } } diff --git a/Source/Core/DolphinWX/Src/Android/ButtonManager.cpp b/Source/Core/DolphinWX/Src/Android/ButtonManager.cpp index 314cdb8c83..b33148338d 100644 --- a/Source/Core/DolphinWX/Src/Android/ButtonManager.cpp +++ b/Source/Core/DolphinWX/Src/Android/ButtonManager.cpp @@ -24,8 +24,9 @@ extern void DrawButton(GLuint tex, float *coords); namespace ButtonManager { - std::unordered_map m_buttons; - std::unordered_map m_axises; + // Pair key is padID, BUTTONTYPE + std::map, Button*> m_buttons; + std::map, Axis*> m_axises; std::unordered_map m_controllers; const char *configStrings[] = { "InputA", "InputB", @@ -64,28 +65,30 @@ namespace ButtonManager void Init() { // Initialize our touchscreen buttons - m_buttons[BUTTON_A] = new Button(); - m_buttons[BUTTON_B] = new Button(); - m_buttons[BUTTON_START] = new Button(); - m_buttons[BUTTON_X] = new Button(); - m_buttons[BUTTON_Y] = new Button(); - m_buttons[BUTTON_Z] = new Button(); - m_buttons[BUTTON_UP] = new Button(); - m_buttons[BUTTON_DOWN] = new Button(); - m_buttons[BUTTON_LEFT] = new Button(); - m_buttons[BUTTON_RIGHT] = new Button(); - - m_axises[STICK_MAIN_UP] = new Axis(); - m_axises[STICK_MAIN_DOWN] = new Axis(); - m_axises[STICK_MAIN_LEFT] = new Axis(); - m_axises[STICK_MAIN_RIGHT] = new Axis(); - m_axises[STICK_C_UP] = new Axis(); - m_axises[STICK_C_DOWN] = new Axis(); - m_axises[STICK_C_LEFT] = new Axis(); - m_axises[STICK_C_RIGHT] = new Axis(); - m_axises[TRIGGER_L] = new Axis(); - m_axises[TRIGGER_R] = new Axis(); + for (int a = 0; a < 4; ++a) + { + m_buttons[std::make_pair(a, BUTTON_A)] = new Button(); + m_buttons[std::make_pair(a, BUTTON_B)] = new Button(); + m_buttons[std::make_pair(a, BUTTON_START)] = new Button(); + m_buttons[std::make_pair(a, BUTTON_X)] = new Button(); + m_buttons[std::make_pair(a, BUTTON_Y)] = new Button(); + m_buttons[std::make_pair(a, BUTTON_Z)] = new Button(); + m_buttons[std::make_pair(a, BUTTON_UP)] = new Button(); + m_buttons[std::make_pair(a, BUTTON_DOWN)] = new Button(); + m_buttons[std::make_pair(a, BUTTON_LEFT)] = new Button(); + m_buttons[std::make_pair(a, BUTTON_RIGHT)] = new Button(); + m_axises[std::make_pair(a, STICK_MAIN_UP)] = new Axis(); + m_axises[std::make_pair(a, STICK_MAIN_DOWN)] = new Axis(); + m_axises[std::make_pair(a, STICK_MAIN_LEFT)] = new Axis(); + m_axises[std::make_pair(a, STICK_MAIN_RIGHT)] = new Axis(); + m_axises[std::make_pair(a, STICK_C_UP)] = new Axis(); + m_axises[std::make_pair(a, STICK_C_DOWN)] = new Axis(); + m_axises[std::make_pair(a, STICK_C_LEFT)] = new Axis(); + m_axises[std::make_pair(a, STICK_C_RIGHT)] = new Axis(); + m_axises[std::make_pair(a, TRIGGER_L)] = new Axis(); + m_axises[std::make_pair(a, TRIGGER_R)] = new Axis(); + } // Init our controller bindings IniFile ini; ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string("Dolphin.ini")); @@ -117,33 +120,33 @@ namespace ButtonManager } } - bool GetButtonPressed(ButtonType button) + bool GetButtonPressed(int padID, ButtonType button) { bool pressed = false; - pressed = m_buttons[button]->Pressed(); + pressed = m_buttons[std::make_pair(padID, button)]->Pressed(); for (auto it = m_controllers.begin(); it != m_controllers.end(); ++it) pressed |= it->second->ButtonValue(button); return pressed; } - float GetAxisValue(ButtonType axis) + float GetAxisValue(int padID, ButtonType axis) { float value = 0.0f; - value = m_axises[axis]->AxisValue(); + value = m_axises[std::make_pair(padID, axis)]->AxisValue(); auto it = m_controllers.begin(); if (it == m_controllers.end()) return value; return it->second->AxisValue(axis); } - void TouchEvent(int button, int action) + void TouchEvent(int padID, int button, int action) { - m_buttons[button]->SetState(action ? BUTTON_PRESSED : BUTTON_RELEASED); + m_buttons[std::make_pair(padID, button)]->SetState(action ? BUTTON_PRESSED : BUTTON_RELEASED); } - void TouchAxisEvent(int axis, float value) + void TouchAxisEvent(int padID, int axis, float value) { - m_axises[axis]->SetValue(value); + m_axises[std::make_pair(padID, axis)]->SetValue(value); } void GamepadEvent(std::string dev, int button, int action) { diff --git a/Source/Core/DolphinWX/Src/Android/ButtonManager.h b/Source/Core/DolphinWX/Src/Android/ButtonManager.h index 383e52f445..f94b3596bc 100644 --- a/Source/Core/DolphinWX/Src/Android/ButtonManager.h +++ b/Source/Core/DolphinWX/Src/Android/ButtonManager.h @@ -120,10 +120,10 @@ namespace ButtonManager }; void Init(); - bool GetButtonPressed(ButtonType button); - float GetAxisValue(ButtonType axis); - void TouchEvent(int button, int action); - void TouchAxisEvent(int axis, float value); + bool GetButtonPressed(int padID, ButtonType button); + float GetAxisValue(int padID, ButtonType axis); + void TouchEvent(int padID, int button, int action); + void TouchAxisEvent(int padID, int axis, float value); void GamepadEvent(std::string dev, int button, int action); void GamepadAxisEvent(std::string dev, int axis, float value); void Shutdown(); diff --git a/Source/Core/DolphinWX/Src/MainAndroid.cpp b/Source/Core/DolphinWX/Src/MainAndroid.cpp index 0d75d91e2d..7382aba219 100644 --- a/Source/Core/DolphinWX/Src/MainAndroid.cpp +++ b/Source/Core/DolphinWX/Src/MainAndroid.cpp @@ -237,13 +237,13 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulatio Core::Stop(); updateMainFrameEvent.Set(); // Kick the waiting event } -JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onTouchEvent(JNIEnv *env, jobject obj, jint Button, jint Action) +JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onTouchEvent(JNIEnv *env, jobject obj, jint padID, jint Button, jint Action) { - ButtonManager::TouchEvent(Button, Action); + ButtonManager::TouchEvent(padID, Button, Action); } -JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onTouchAxisEvent(JNIEnv *env, jobject obj, jint Button, jfloat Action) +JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onTouchAxisEvent(JNIEnv *env, jobject obj, jint padID, jint Button, jfloat Action) { - ButtonManager::TouchAxisEvent(Button, Action); + ButtonManager::TouchAxisEvent(padID, Button, Action); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadEvent(JNIEnv *env, jobject obj, jstring jDevice, jint Button, jint Action) { diff --git a/Source/Core/InputCommon/Src/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/Src/ControllerInterface/Android/Android.cpp index ef95f9b363..ec7a7a2a56 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/Android/Android.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/Android/Android.cpp @@ -25,7 +25,10 @@ namespace Android void Init( std::vector& devices ) { - devices.push_back(new Touchscreen()); + devices.push_back(new Touchscreen(0)); + devices.push_back(new Touchscreen(1)); + devices.push_back(new Touchscreen(2)); + devices.push_back(new Touchscreen(3)); } // Touchscreens and stuff @@ -43,49 +46,49 @@ int Touchscreen::GetId() const { return 0; } -Touchscreen::Touchscreen() +Touchscreen::Touchscreen(int padID) + : _padID(padID) { - AddInput(new Button(ButtonManager::BUTTON_A)); - AddInput(new Button(ButtonManager::BUTTON_B)); - AddInput(new Button(ButtonManager::BUTTON_START)); - AddInput(new Button(ButtonManager::BUTTON_X)); - AddInput(new Button(ButtonManager::BUTTON_Y)); - AddInput(new Button(ButtonManager::BUTTON_Z)); - AddInput(new Button(ButtonManager::BUTTON_UP)); - AddInput(new Button(ButtonManager::BUTTON_DOWN)); - AddInput(new Button(ButtonManager::BUTTON_LEFT)); - AddInput(new Button(ButtonManager::BUTTON_RIGHT)); - AddAnalogInputs(new Axis(ButtonManager::STICK_MAIN_LEFT), new Axis(ButtonManager::STICK_MAIN_RIGHT)); - AddAnalogInputs(new Axis(ButtonManager::STICK_MAIN_UP), new Axis(ButtonManager::STICK_MAIN_DOWN)); - AddAnalogInputs(new Axis(ButtonManager::STICK_C_UP), new Axis(ButtonManager::STICK_C_DOWN)); - AddAnalogInputs(new Axis(ButtonManager::STICK_C_LEFT), new Axis(ButtonManager::STICK_C_RIGHT)); - AddAnalogInputs(new Axis(ButtonManager::TRIGGER_L), new Axis(ButtonManager::TRIGGER_L)); - AddAnalogInputs(new Axis(ButtonManager::TRIGGER_R), new Axis(ButtonManager::TRIGGER_R)); - + 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_UP), new Axis(_padID, ButtonManager::STICK_C_DOWN)); + AddAnalogInputs(new Axis(_padID, ButtonManager::STICK_C_LEFT), new Axis(_padID, ButtonManager::STICK_C_RIGHT)); + 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)); } // Buttons and stuff std::string Touchscreen::Button::GetName() const { std::ostringstream ss; - ss << "Button " << (int)m_index; + ss << "Button " << (int)_index; return ss.str(); } ControlState Touchscreen::Button::GetState() const { - return ButtonManager::GetButtonPressed(m_index); + return ButtonManager::GetButtonPressed(_padID, _index); } std::string Touchscreen::Axis::GetName() const { std::ostringstream ss; - ss << "Axis " << (int)m_index; + ss << "Axis " << (int)_index; return ss.str(); } ControlState Touchscreen::Axis::GetState() const { - return ButtonManager::GetAxisValue(m_index); + return ButtonManager::GetAxisValue(_padID, _index); } } diff --git a/Source/Core/InputCommon/Src/ControllerInterface/Android/Android.h b/Source/Core/InputCommon/Src/ControllerInterface/Android/Android.h index e38c6a221a..8b1fd99c23 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/Android/Android.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/Android/Android.h @@ -33,31 +33,35 @@ private: { public: std::string GetName() const; - Button(ButtonManager::ButtonType index) : m_index(index) {} + Button(int padID, ButtonManager::ButtonType index) : _padID(padID), _index(index) {} ControlState GetState() const; private: - const ButtonManager::ButtonType m_index; + const int _padID; + const ButtonManager::ButtonType _index; }; class Axis : public Input { public: std::string GetName() const; - Axis(ButtonManager::ButtonType index) : m_index(index) {} + Axis(int padID, ButtonManager::ButtonType index) : _padID(padID), _index(index) {} ControlState GetState() const; private: - const ButtonManager::ButtonType m_index; + const int _padID; + const ButtonManager::ButtonType _index; }; - + public: bool UpdateInput() { return true; } bool UpdateOutput() { return true; } - Touchscreen(); + Touchscreen(int padID); ~Touchscreen() {} std::string GetName() const; int GetId() const; std::string GetSource() const; +private: + const int _padID; }; }