diff options
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface')
9 files changed, 1143 insertions, 1413 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp index 7a7c548cc6..a4bd7a3d46 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp @@ -1,32 +1,1142 @@ -// Copyright 2013 Dolphin Emulator Project +// Copyright 2021 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "InputCommon/ControllerInterface/Android/Android.h" +#include <algorithm> +#include <atomic> +#include <chrono> +#include <memory> +#include <string> +#include <unordered_map> +#include <utility> + +#include <fmt/format.h> + +#include <android/input.h> +#include <android/keycodes.h> +#include <jni.h> + +#include "Common/Assert.h" +#include "Common/Logging/Log.h" +#include "Common/StringUtil.h" + #include "InputCommon/ControllerInterface/ControllerInterface.h" -#include "InputCommon/ControllerInterface/Touch/Touchscreen.h" + +#include "jni/AndroidCommon/AndroidCommon.h" +#include "jni/AndroidCommon/IDCache.h" +#include "jni/Input/CoreDevice.h" + +namespace +{ +jclass s_list_class; +jmethodID s_list_get; +jmethodID s_list_size; + +jclass s_input_device_class; +jmethodID s_input_device_get_device_ids; +jmethodID s_input_device_get_device; +jmethodID s_input_device_get_controller_number; +jmethodID s_input_device_get_id; +jmethodID s_input_device_get_motion_ranges; +jmethodID s_input_device_get_name; +jmethodID s_input_device_get_sources; +jmethodID s_input_device_has_keys; + +jclass s_motion_range_class; +jmethodID s_motion_range_get_axis; +jmethodID s_motion_range_get_max; +jmethodID s_motion_range_get_min; +jmethodID s_motion_range_get_source; + +jclass s_input_event_class; +jmethodID s_input_event_get_device; + +jclass s_key_event_class; +jmethodID s_key_event_get_action; +jmethodID s_key_event_get_keycode; + +jclass s_motion_event_class; +jmethodID s_motion_event_get_axis_value; +jmethodID s_motion_event_get_source; + +jclass s_controller_interface_class; +jmethodID s_controller_interface_register_input_device_listener; +jmethodID s_controller_interface_unregister_input_device_listener; +jmethodID s_controller_interface_get_vibrator_manager; +jmethodID s_controller_interface_get_system_vibrator_manager; +jmethodID s_controller_interface_vibrate; + +jclass s_sensor_event_listener_class; +jmethodID s_sensor_event_listener_constructor; +jmethodID s_sensor_event_listener_constructor_input_device; +jmethodID s_sensor_event_listener_set_device_qualifier; +jmethodID s_sensor_event_listener_request_unsuspend_sensor; +jmethodID s_sensor_event_listener_get_axis_names; +jmethodID s_sensor_event_listener_get_negative_axes; + +jclass s_dolphin_vibrator_manager_class; +jmethodID s_dolphin_vibrator_manager_get_vibrator; +jmethodID s_dolphin_vibrator_manager_get_vibrator_ids; + +jintArray s_keycodes_array; + +using Clock = std::chrono::steady_clock; +constexpr Clock::duration ACTIVE_INPUT_TIMEOUT = std::chrono::milliseconds(1000); + +std::unordered_map<jint, ciface::Core::DeviceQualifier> s_device_id_to_device_qualifier; + +constexpr int MAX_KEYCODE = AKEYCODE_PROFILE_SWITCH; // Up to date as of SDK 31 + +const std::array<std::string_view, MAX_KEYCODE + 1> KEYCODE_NAMES = { + "Unknown", + "Soft Left", + "Soft Right", + "Home", + "Back", + "Call", + "End Call", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "Star", + "Pound", + "Up", + "Down", + "Left", + "Right", + "Center", + "Volume Up", + "Volume Down", + "Power", + "Camera", + "Clear", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "Comma", + "Period", + "Left Alt", + "Right Alt", + "Left Shift", + "Right Shift", + "Tab", + "Space", + "Sym", + "Explorer", + "Envelope", + "Enter", + "Backspace", + "Grave", + "Minus", + "Equals", + "Left Bracket", + "Right Bracket", + "Backslash", + "Semicolon", + "Apostrophe", + "Slash", + "At", + "Num", + "Headset Hook", + "Focus", + "Plus", + "Menu", + "Notification", + "Search", + "Play Pause", + "Stop", + "Next", + "Previous", + "Rewind", + "Fast Forward", + "Mute", + "Page Up", + "Page Down", + "Emoji", + "Switch Charset", + "Button A", + "Button B", + "Button C", + "Button X", + "Button Y", + "Button Z", + "Button L1", + "Button R1", + "Button L2", + "Button R2", + "Button L3", + "Button R3", + "Start", + "Select", + "Mode", + "Escape", + "Delete", + "Left Ctrl", + "Right Ctrl", + "Caps Lock", + "Scroll Lock", + "Left Meta", + "Right Meta", + "Fn", + "PrtSc SysRq", + "Pause Break", + "Move Home", + "Move End", + "Insert", + "Forward", + "Play", + "Pause", + "Close", + "Eject", + "Record", + "F1", + "F2", + "F3", + "F4", + "F5", + "F6", + "F7", + "F8", + "F9", + "F10", + "F11", + "F12", + "Num Lock", + "Numpad 0", + "Numpad 1", + "Numpad 2", + "Numpad 3", + "Numpad 4", + "Numpad 5", + "Numpad 6", + "Numpad 7", + "Numpad 8", + "Numpad 9", + "Numpad Divide", + "Numpad Multiply", + "Numpad Subtract", + "Numpad Add", + "Numpad Dot", + "Numpad Comma", + "Numpad Enter", + "Numpad Equals", + "Numpad Left Paren", + "Numpad Right Paren", + "Volume Mute", + "Info", + "Channel Up", + "Channel Down", + "Zoom In", + "Zoom Out", + "TV", + "Window", + "Guide", + "DVR", + "Bookmark", + "Captions", + "Settings", + "TV Power", + "TV Input", + "STB Power", + "STB Input", + "AVR Power", + "AVR Input", + "Prog Red", + "Prog Green", + "Prog Yellow", + "Prog Blue", + "App Switch", + "Button 1", + "Button 2", + "Button 3", + "Button 4", + "Button 5", + "Button 6", + "Button 7", + "Button 8", + "Button 9", + "Button 10", + "Button 11", + "Button 12", + "Button 13", + "Button 14", + "Button 15", + "Button 16", + "Language Switch", + "Manner Mode", + "3D Mode", + "Contacts", + "Calendar", + "Music", + "Calculator", + "Zenkaku Hankaku", + "Eisu", + "Henkan", + "Muhenkan", + "Katakana Hiragana", + "Yen", + "Ro", + "Kana", + "Assist", + "Brightness Down", + "Brightness Up", + "Audio Track", + "Sleep", + "Wakeup", + "Pairing", + "Top Menu", + "11", + "12", + "Last Channel", + "Data Service", + "Voice Assist", + "Radio Service", + "Teletext", + "Number Entry", + "Terrestrial Analog", + "Terrestrial Digital", + "Satellite", + "Satellite BS", + "Satellite CS", + "Satellite Service", + "Network", + "Antenna Cable", + "Input HDMI 1", + "Input HDMI 2", + "Input HDMI 3", + "Input HDMI 4", + "Input Composite 1", + "Input Composite 2", + "Input Component 1", + "Input Component 2", + "Input VGA 1", + "Audio Description", + "Audio Description Mix Up", + "Audio Description Mix Down", + "Zoom Mode", + "Contents Menu", + "Media Context Menu", + "Timer Programming", + "Help", + "Navigate Previous", + "Navigate Next", + "Navigate In", + "Navigate Out", + "Stem Primary", + "Stem 1", + "Stem 2", + "Stem 3", + "Up Left", + "Down Left", + "Up Right", + "Down Right", + "Skip Forward", + "Skip Backward", + "Step Forward", + "Step Backward", + "Soft Sleep", + "Cut", + "Copy", + "Paste", + "System Navigation Up", + "System Navigation Down", + "System Navigation Left", + "System Navigation Right", + "All Apps", + "Refresh", + "Thumbs Up", + "Thumbs Down", + "Profile Switch", +}; + +std::string ConstructKeyName(int keycode) +{ + return std::string(KEYCODE_NAMES[keycode]); +} + +std::string ConstructAxisNamePrefix(int source) +{ + // A device is allowed to have two axes with the same axis ID but different source IDs, + // so we have to make sure to include the source in the axis name. + + static const std::unordered_map<int, std::string> source_names{ + {AINPUT_SOURCE_KEYBOARD, "Keyboard"}, + {AINPUT_SOURCE_DPAD, "Dpad"}, + {AINPUT_SOURCE_GAMEPAD, "Gamepad"}, + {AINPUT_SOURCE_TOUCHSCREEN, "Touch"}, + {AINPUT_SOURCE_MOUSE, "Cursor"}, + {AINPUT_SOURCE_STYLUS, "Stylus"}, + {AINPUT_SOURCE_BLUETOOTH_STYLUS, "BTStylus"}, + {AINPUT_SOURCE_TRACKBALL, "Trackball"}, + {AINPUT_SOURCE_MOUSE_RELATIVE, "Mouse"}, + {AINPUT_SOURCE_TOUCHPAD, "Touchpad"}, + {AINPUT_SOURCE_TOUCH_NAVIGATION, "Touchnav"}, + {AINPUT_SOURCE_JOYSTICK, "Axis"}, // The typical source for all axes on a gamepad + {AINPUT_SOURCE_HDMI, "HDMI"}, + {AINPUT_SOURCE_SENSOR, "Sensor"}, + {AINPUT_SOURCE_ROTARY_ENCODER, "Rotary"}, + }; + + const auto it = source_names.find(source); + if (it != source_names.end()) + return fmt::format("{} ", it->second); + else + return fmt::format("Axis {:08x}/", source); +} + +std::string ConstructAxisName(int source, int axis, bool negative) +{ + const char sign = negative ? '-' : '+'; + return fmt::format("{}{}{}", ConstructAxisNamePrefix(source), axis, sign); +} + +std::shared_ptr<ciface::Core::Device> FindDevice(jint device_id) +{ + const auto it = s_device_id_to_device_qualifier.find(device_id); + if (it == s_device_id_to_device_qualifier.end()) + { + ERROR_LOG_FMT(CONTROLLERINTERFACE, "Could not find device ID {}", device_id); + return nullptr; + } + + const ciface::Core::DeviceQualifier& qualifier = it->second; + std::shared_ptr<ciface::Core::Device> device = g_controller_interface.FindDevice(qualifier); + if (!device) + { + ERROR_LOG_FMT(CONTROLLERINTERFACE, "Could not find device {}", qualifier.ToString()); + return nullptr; + } + + return device; +} + +} // namespace namespace ciface::Android { -static bool s_accelerometer_enabled = false; -static bool s_gyroscope_enabled = false; +class AndroidInput : public Core::Device::Input +{ +public: + explicit AndroidInput(std::string name) : m_name(std::move(name)) + { + DEBUG_LOG_FMT(CONTROLLERINTERFACE, "Created {}", m_name); + } + + std::string GetName() const override { return m_name; } + + ControlState GetState() const override + { + m_last_polled.store(Clock::now(), std::memory_order_relaxed); + return m_state.load(std::memory_order_relaxed); + } + + void SetState(ControlState state) { m_state.store(state, std::memory_order_relaxed); } + + Clock::time_point GetLastPolled() const { return m_last_polled.load(std::memory_order_relaxed); } + +private: + std::string m_name; + std::atomic<ControlState> m_state = 0; + mutable std::atomic<Clock::time_point> m_last_polled{}; +}; + +class AndroidKey final : public AndroidInput +{ +public: + explicit AndroidKey(int keycode) : AndroidInput(ConstructKeyName(keycode)) {} +}; + +class AndroidAxis : public AndroidInput +{ +public: + AndroidAxis(int source, int axis, bool negative) + : AndroidInput(ConstructAxisName(source, axis, negative)), m_negative(negative) + { + } + + AndroidAxis(std::string name, bool negative) : AndroidInput(std::move(name)), m_negative(negative) + { + } + + ControlState GetState() const override + { + return m_negative ? -AndroidInput::GetState() : AndroidInput::GetState(); + } + +private: + bool m_negative; +}; + +class AndroidSensorAxis final : public AndroidAxis +{ +public: + // This class does not create its own global reference to the passed-in sensor_event_listener. + // That is, it's up to the device that contains this axis to keep sensor_event_listener valid. + // It does however create its own global reference to the passed-in name. + AndroidSensorAxis(JNIEnv* env, jobject sensor_event_listener, jstring j_name, bool negative) + : AndroidAxis(GetJString(env, j_name), negative), + m_sensor_event_listener(sensor_event_listener), + m_j_name(reinterpret_cast<jstring>(env->NewGlobalRef(j_name))) + { + } + + ~AndroidSensorAxis() { IDCache::GetEnvForThread()->DeleteGlobalRef(m_j_name); } + + bool IsDetectable() const override { return false; } + + ControlState GetState() const override + { + if (m_is_suspended.load(std::memory_order_relaxed)) + { + IDCache::GetEnvForThread()->CallVoidMethod( + m_sensor_event_listener, s_sensor_event_listener_request_unsuspend_sensor, m_j_name); + + // m_is_suspended is intentionally not updated here. To prevent the C++ suspended status from + // ending up desynced with the Java suspended status, we only update m_is_suspended when Java + // calls notifySensorSuspendedState (which calls NotifyIsSuspended). This way, Java is the + // authoritative source for the suspended status, and C++ mirrors it (possibly with a delay). + } + + return AndroidAxis::GetState(); + } + + void NotifyIsSuspended(bool is_suspended) + { + m_is_suspended.store(is_suspended, std::memory_order_relaxed); + } + +private: + const jobject m_sensor_event_listener; + const jstring m_j_name; + std::atomic<bool> m_is_suspended = true; +}; + +class AndroidMotor : public Core::Device::Output +{ +public: + AndroidMotor(JNIEnv* env, jobject vibrator, jint id) + : m_vibrator(env->NewGlobalRef(vibrator)), m_id(id) + { + } + + ~AndroidMotor() { IDCache::GetEnvForThread()->DeleteGlobalRef(m_vibrator); } + + std::string GetName() const override { return "Motor " + std::to_string(m_id); } + + void SetState(ControlState state) override + { + ControlState old_state = m_state.exchange(state, std::memory_order_relaxed); + + if (old_state < 0.5 && state >= 0.5) + { + IDCache::GetEnvForThread()->CallStaticVoidMethod(s_controller_interface_class, + s_controller_interface_vibrate, m_vibrator); + } + } + +private: + const jobject m_vibrator; + const jint m_id; + std::atomic<ControlState> m_state = 0; +}; + +class AndroidDevice final : public Core::Device +{ +public: + AndroidDevice(JNIEnv* env, jobject input_device) + : m_sensor_event_listener(AddSensors(env, input_device)), + m_source(env->CallIntMethod(input_device, s_input_device_get_sources)), + m_controller_number(env->CallIntMethod(input_device, s_input_device_get_controller_number)) + { + jstring j_name = + reinterpret_cast<jstring>(env->CallObjectMethod(input_device, s_input_device_get_name)); + m_name = GetJString(env, j_name); + env->DeleteLocalRef(j_name); + + DEBUG_LOG_FMT(CONTROLLERINTERFACE, "Sources for {}: {:08x}", GetQualifiedName(), m_source); + + AddKeys(env, input_device); + AddAxes(env, input_device); + AddMotors(env, input_device); + } + + // Constructor for the device added by Dolphin to contain sensor inputs + AndroidDevice(JNIEnv* env, std::string name) + : m_sensor_event_listener(AddSensors(env, nullptr)), m_source(AINPUT_SOURCE_SENSOR), + m_controller_number(0), m_name(std::move(name)) + { + AddSystemMotors(env); + } + + ~AndroidDevice() + { + if (m_sensor_event_listener) + IDCache::GetEnvForThread()->DeleteGlobalRef(m_sensor_event_listener); + } + + std::string GetName() const override { return m_name; } + + std::string GetSource() const override { return "Android"; } + + std::optional<int> GetPreferredId() const override + { + return m_controller_number != 0 ? std::make_optional(m_controller_number) : std::nullopt; + } + + int GetSortPriority() const override + { + // If m_controller_number is non-zero, Android considers this to be a gamepad + if (m_controller_number != 0) + return 0; + + if ((m_source & AINPUT_SOURCE_KEYBOARD) != 0) + return -1; + + if ((m_source & (AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_MOUSE_RELATIVE)) != 0) + return -2; + + return -3; + } + + jobject GetSensorEventListener() { return m_sensor_event_listener; } + +private: + void AddKeys(JNIEnv* env, jobject input_device) + { + jbooleanArray keys_array = reinterpret_cast<jbooleanArray>( + env->CallObjectMethod(input_device, s_input_device_has_keys, s_keycodes_array)); + jboolean* keys = env->GetBooleanArrayElements(keys_array, nullptr); + jsize keys_count = env->GetArrayLength(keys_array); + for (jsize i = 0; i < keys_count; ++i) + { + // These specific keys never get delivered to applications, + // so there's no point in letting users try to map them + if (i == AKEYCODE_HOME || i == AKEYCODE_ASSIST || i == AKEYCODE_VOICE_ASSIST) + continue; + + if (keys[i]) + AddInput(new AndroidKey(i)); + } + env->ReleaseBooleanArrayElements(keys_array, keys, JNI_ABORT); + env->DeleteLocalRef(keys_array); + } + + void AddAxes(JNIEnv* env, jobject input_device) + { + jobject motion_ranges_list = + env->CallObjectMethod(input_device, s_input_device_get_motion_ranges); + jint motion_ranges_count = env->CallIntMethod(motion_ranges_list, s_list_size); + for (jint i = 0; i < motion_ranges_count; ++i) + { + jobject motion_range = env->CallObjectMethod(motion_ranges_list, s_list_get, i); + + jint source = env->CallIntMethod(motion_range, s_motion_range_get_source); + jint axis = env->CallIntMethod(motion_range, s_motion_range_get_axis); + jfloat min = env->CallFloatMethod(motion_range, s_motion_range_get_min); + jfloat max = env->CallFloatMethod(motion_range, s_motion_range_get_max); + + env->DeleteLocalRef(motion_range); + + AndroidAxis* positive = nullptr; + AndroidAxis* negative = nullptr; + if (max > 0) + positive = new AndroidAxis(source, axis, false); + if (min < 0) + negative = new AndroidAxis(source, axis, true); + + if (positive && negative) + AddAnalogInputs(positive, negative); + else if (positive || negative) + AddInput(positive ? positive : negative); + } + env->DeleteLocalRef(motion_ranges_list); + } + + jobject AddSensors(JNIEnv* env, jobject input_device) + { + jobject local_sensor_event_listener; + if (input_device) + { + local_sensor_event_listener = + env->NewObject(s_sensor_event_listener_class, + s_sensor_event_listener_constructor_input_device, input_device); + } + else + { + local_sensor_event_listener = + env->NewObject(s_sensor_event_listener_class, s_sensor_event_listener_constructor); + } + + jobject sensor_event_listener = env->NewGlobalRef(local_sensor_event_listener); + + env->DeleteLocalRef(local_sensor_event_listener); + + jobjectArray j_axis_names = reinterpret_cast<jobjectArray>( + env->CallObjectMethod(sensor_event_listener, s_sensor_event_listener_get_axis_names)); + + jbooleanArray j_negative_axes = reinterpret_cast<jbooleanArray>( + env->CallObjectMethod(sensor_event_listener, s_sensor_event_listener_get_negative_axes)); + jboolean* negative_axes = env->GetBooleanArrayElements(j_negative_axes, nullptr); + + const jsize axis_count = env->GetArrayLength(j_axis_names); + ASSERT(axis_count == env->GetArrayLength(j_negative_axes)); + for (jsize i = 0; i < axis_count; ++i) + { + const jstring axis_name = + reinterpret_cast<jstring>(env->GetObjectArrayElement(j_axis_names, i)); + AddInput(new AndroidSensorAxis(env, sensor_event_listener, axis_name, negative_axes[i])); + env->DeleteLocalRef(axis_name); + } + + env->DeleteLocalRef(j_axis_names); + env->ReleaseBooleanArrayElements(j_negative_axes, negative_axes, 0); + env->DeleteLocalRef(j_negative_axes); + + return sensor_event_listener; + } + + void AddMotors(JNIEnv* env, jobject input_device) + { + jobject vibrator_manager = env->CallStaticObjectMethod( + s_controller_interface_class, s_controller_interface_get_vibrator_manager, input_device); + AddMotorsFromManager(env, vibrator_manager); + env->DeleteLocalRef(vibrator_manager); + } + + void AddSystemMotors(JNIEnv* env) + { + jobject vibrator_manager = env->CallStaticObjectMethod( + s_controller_interface_class, s_controller_interface_get_system_vibrator_manager); + AddMotorsFromManager(env, vibrator_manager); + env->DeleteLocalRef(vibrator_manager); + } + + void AddMotorsFromManager(JNIEnv* env, jobject vibrator_manager) + { + jintArray j_vibrator_ids = reinterpret_cast<jintArray>( + env->CallObjectMethod(vibrator_manager, s_dolphin_vibrator_manager_get_vibrator_ids)); + jint* vibrator_ids = env->GetIntArrayElements(j_vibrator_ids, nullptr); + + jint size = env->GetArrayLength(j_vibrator_ids); + for (jint i = 0; i < size; ++i) + { + jobject vibrator = + env->CallObjectMethod(vibrator_manager, s_dolphin_vibrator_manager_get_vibrator, i); + AddOutput(new AndroidMotor(env, vibrator, i)); + env->DeleteLocalRef(vibrator); + } + + env->ReleaseIntArrayElements(j_vibrator_ids, vibrator_ids, 0); + env->DeleteLocalRef(j_vibrator_ids); + } + + const jobject m_sensor_event_listener; + const int m_source; + const int m_controller_number; + std::string m_name; +}; + +// Creates an array that contains every possible keycode +static jintArray CreateKeyCodesArray(JNIEnv* env) +{ + jintArray keycodes_array = env->NewIntArray(MAX_KEYCODE + 1); + + int* keycodes = env->GetIntArrayElements(keycodes_array, nullptr); + for (int i = 0; i <= MAX_KEYCODE; ++i) + keycodes[i] = i; + env->ReleaseIntArrayElements(keycodes_array, keycodes, 0); + + return keycodes_array; +} -void SetMotionSensorsEnabled(bool accelerometer_enabled, bool gyroscope_enabled) +void Init() { - const bool any_changes = - s_accelerometer_enabled != accelerometer_enabled || s_gyroscope_enabled != gyroscope_enabled; + JNIEnv* env = IDCache::GetEnvForThread(); + + const jclass list_class = env->FindClass("java/util/List"); + s_list_class = reinterpret_cast<jclass>(env->NewGlobalRef(list_class)); + s_list_get = env->GetMethodID(s_list_class, "get", "(I)Ljava/lang/Object;"); + s_list_size = env->GetMethodID(s_list_class, "size", "()I"); + env->DeleteLocalRef(list_class); + + const jclass input_device_class = env->FindClass("android/view/InputDevice"); + s_input_device_class = reinterpret_cast<jclass>(env->NewGlobalRef(input_device_class)); + s_input_device_get_device_ids = + env->GetStaticMethodID(s_input_device_class, "getDeviceIds", "()[I"); + s_input_device_get_device = + env->GetStaticMethodID(s_input_device_class, "getDevice", "(I)Landroid/view/InputDevice;"); + s_input_device_get_controller_number = + env->GetMethodID(s_input_device_class, "getControllerNumber", "()I"); + s_input_device_get_id = env->GetMethodID(s_input_device_class, "getId", "()I"); + s_input_device_get_motion_ranges = + env->GetMethodID(s_input_device_class, "getMotionRanges", "()Ljava/util/List;"); + s_input_device_get_name = + env->GetMethodID(s_input_device_class, "getName", "()Ljava/lang/String;"); + s_input_device_get_sources = env->GetMethodID(s_input_device_class, "getSources", "()I"); + s_input_device_has_keys = env->GetMethodID(s_input_device_class, "hasKeys", "([I)[Z"); + env->DeleteLocalRef(input_device_class); + + const jclass motion_range_class = env->FindClass("android/view/InputDevice$MotionRange"); + s_motion_range_class = reinterpret_cast<jclass>(env->NewGlobalRef(motion_range_class)); + s_motion_range_get_axis = env->GetMethodID(s_motion_range_class, "getAxis", "()I"); + s_motion_range_get_max = env->GetMethodID(s_motion_range_class, "getMax", "()F"); + s_motion_range_get_min = env->GetMethodID(s_motion_range_class, "getMin", "()F"); + s_motion_range_get_source = env->GetMethodID(s_motion_range_class, "getSource", "()I"); + env->DeleteLocalRef(motion_range_class); + + const jclass input_event_class = env->FindClass("android/view/InputEvent"); + s_input_event_class = reinterpret_cast<jclass>(env->NewGlobalRef(input_event_class)); + s_input_event_get_device = + env->GetMethodID(s_input_event_class, "getDevice", "()Landroid/view/InputDevice;"); + + const jclass key_event_class = env->FindClass("android/view/KeyEvent"); + s_key_event_class = reinterpret_cast<jclass>(env->NewGlobalRef(key_event_class)); + s_key_event_get_action = env->GetMethodID(s_key_event_class, "getAction", "()I"); + s_key_event_get_keycode = env->GetMethodID(s_key_event_class, "getKeyCode", "()I"); - s_accelerometer_enabled = accelerometer_enabled; - s_gyroscope_enabled = gyroscope_enabled; + const jclass motion_event_class = env->FindClass("android/view/MotionEvent"); + s_motion_event_class = reinterpret_cast<jclass>(env->NewGlobalRef(motion_event_class)); + s_motion_event_get_axis_value = env->GetMethodID(s_motion_event_class, "getAxisValue", "(I)F"); + s_motion_event_get_source = env->GetMethodID(s_motion_event_class, "getSource", "()I"); - if (any_changes) - g_controller_interface.RefreshDevices(); + const jclass controller_interface_class = + env->FindClass("org/dolphinemu/dolphinemu/features/input/model/ControllerInterface"); + s_controller_interface_class = + reinterpret_cast<jclass>(env->NewGlobalRef(controller_interface_class)); + s_controller_interface_register_input_device_listener = + env->GetStaticMethodID(s_controller_interface_class, "registerInputDeviceListener", "()V"); + s_controller_interface_unregister_input_device_listener = + env->GetStaticMethodID(s_controller_interface_class, "unregisterInputDeviceListener", "()V"); + s_controller_interface_get_vibrator_manager = + env->GetStaticMethodID(s_controller_interface_class, "getVibratorManager", + "(Landroid/view/InputDevice;)Lorg/dolphinemu/dolphinemu/features/" + "input/model/DolphinVibratorManager;"); + s_controller_interface_get_system_vibrator_manager = env->GetStaticMethodID( + s_controller_interface_class, "getSystemVibratorManager", + "()Lorg/dolphinemu/dolphinemu/features/input/model/DolphinVibratorManager;"); + s_controller_interface_vibrate = + env->GetStaticMethodID(s_controller_interface_class, "vibrate", "(Landroid/os/Vibrator;)V"); + + const jclass sensor_event_listener_class = + env->FindClass("org/dolphinemu/dolphinemu/features/input/model/DolphinSensorEventListener"); + s_sensor_event_listener_class = + reinterpret_cast<jclass>(env->NewGlobalRef(sensor_event_listener_class)); + s_sensor_event_listener_constructor = + env->GetMethodID(s_sensor_event_listener_class, "<init>", "()V"); + s_sensor_event_listener_constructor_input_device = + env->GetMethodID(s_sensor_event_listener_class, "<init>", "(Landroid/view/InputDevice;)V"); + s_sensor_event_listener_set_device_qualifier = env->GetMethodID( + s_sensor_event_listener_class, "setDeviceQualifier", "(Ljava/lang/String;)V"); + s_sensor_event_listener_request_unsuspend_sensor = env->GetMethodID( + s_sensor_event_listener_class, "requestUnsuspendSensor", "(Ljava/lang/String;)V"); + s_sensor_event_listener_get_axis_names = + env->GetMethodID(s_sensor_event_listener_class, "getAxisNames", "()[Ljava/lang/String;"); + s_sensor_event_listener_get_negative_axes = + env->GetMethodID(s_sensor_event_listener_class, "getNegativeAxes", "()[Z"); + + const jclass dolphin_vibrator_manager_class = + env->FindClass("org/dolphinemu/dolphinemu/features/input/model/DolphinVibratorManager"); + s_dolphin_vibrator_manager_class = + reinterpret_cast<jclass>(env->NewGlobalRef(dolphin_vibrator_manager_class)); + s_dolphin_vibrator_manager_get_vibrator = + env->GetMethodID(s_dolphin_vibrator_manager_class, "getVibrator", "(I)Landroid/os/Vibrator;"); + s_dolphin_vibrator_manager_get_vibrator_ids = + env->GetMethodID(s_dolphin_vibrator_manager_class, "getVibratorIds", "()[I"); + + jintArray keycodes_array = CreateKeyCodesArray(env); + s_keycodes_array = reinterpret_cast<jintArray>(env->NewGlobalRef(keycodes_array)); + env->DeleteLocalRef(keycodes_array); + + env->CallStaticVoidMethod(s_controller_interface_class, + s_controller_interface_register_input_device_listener); +} + +void Shutdown() +{ + JNIEnv* env = IDCache::GetEnvForThread(); + + env->CallStaticVoidMethod(s_controller_interface_class, + s_controller_interface_unregister_input_device_listener); + + env->DeleteGlobalRef(s_input_device_class); + env->DeleteGlobalRef(s_motion_range_class); + env->DeleteGlobalRef(s_input_event_class); + env->DeleteGlobalRef(s_key_event_class); + env->DeleteGlobalRef(s_motion_event_class); + env->DeleteGlobalRef(s_controller_interface_class); + env->DeleteGlobalRef(s_sensor_event_listener_class); + env->DeleteGlobalRef(s_dolphin_vibrator_manager_class); + env->DeleteGlobalRef(s_keycodes_array); +} + +static void AddDevice(JNIEnv* env, int device_id) +{ + jobject input_device = + env->CallStaticObjectMethod(s_input_device_class, s_input_device_get_device, device_id); + + auto device = std::make_shared<AndroidDevice>(env, input_device); + + env->DeleteLocalRef(input_device); + + if (device->Inputs().empty() && device->Outputs().empty()) + return; + + g_controller_interface.AddDevice(device); + + Core::DeviceQualifier qualifier; + qualifier.FromDevice(device.get()); + + INFO_LOG_FMT(CONTROLLERINTERFACE, "Added device ID {} as {}", device_id, + device->GetQualifiedName()); + s_device_id_to_device_qualifier.emplace(device_id, qualifier); + + jstring j_qualifier = ToJString(env, qualifier.ToString()); + env->CallVoidMethod(device->GetSensorEventListener(), + s_sensor_event_listener_set_device_qualifier, j_qualifier); + env->DeleteLocalRef(j_qualifier); +} + +static void AddSensorDevice(JNIEnv* env) +{ + // Device sensors (accelerometer, etc.) aren't associated with any Android InputDevice. + // Create an otherwise empty Dolphin input device so that they have somewhere to live. + + auto device = std::make_shared<AndroidDevice>(env, "Device Sensors"); + + if (device->Inputs().empty() && device->Outputs().empty()) + return; + + g_controller_interface.AddDevice(device); + + Core::DeviceQualifier qualifier; + qualifier.FromDevice(device.get()); + + INFO_LOG_FMT(CONTROLLERINTERFACE, "Added sensor device as {}", device->GetQualifiedName()); + + jstring j_qualifier = ToJString(env, qualifier.ToString()); + env->CallVoidMethod(device->GetSensorEventListener(), + s_sensor_event_listener_set_device_qualifier, j_qualifier); + env->DeleteLocalRef(j_qualifier); } void PopulateDevices() { - for (int i = 0; i < 8; ++i) - g_controller_interface.AddDevice(std::make_shared<ciface::Touch::Touchscreen>( - i, s_accelerometer_enabled, s_gyroscope_enabled)); + INFO_LOG_FMT(CONTROLLERINTERFACE, "Android populating devices"); + + JNIEnv* env = IDCache::GetEnvForThread(); + + jintArray device_ids_array = reinterpret_cast<jintArray>( + env->CallStaticObjectMethod(s_input_device_class, s_input_device_get_device_ids)); + int* device_ids = env->GetIntArrayElements(device_ids_array, nullptr); + jsize device_ids_count = env->GetArrayLength(device_ids_array); + for (jsize i = 0; i < device_ids_count; ++i) + AddDevice(env, device_ids[i]); + env->ReleaseIntArrayElements(device_ids_array, device_ids, JNI_ABORT); + env->DeleteLocalRef(device_ids_array); + + AddSensorDevice(env); } + } // namespace ciface::Android + +extern "C" { + +JNIEXPORT jboolean JNICALL +Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_dispatchKeyEvent( + JNIEnv* env, jclass, jobject key_event) +{ + const jint action = env->CallIntMethod(key_event, s_key_event_get_action); + ControlState state; + switch (action) + { + case AKEY_EVENT_ACTION_DOWN: + state = 1; + break; + case AKEY_EVENT_ACTION_UP: + state = 0; + break; + default: + return JNI_FALSE; + } + + const jobject input_device = env->CallObjectMethod(key_event, s_input_event_get_device); + const jint device_id = env->CallIntMethod(input_device, s_input_device_get_id); + env->DeleteLocalRef(input_device); + const std::shared_ptr<ciface::Core::Device> device = FindDevice(device_id); + if (!device) + return JNI_FALSE; + + const jint keycode = env->CallIntMethod(key_event, s_key_event_get_keycode); + const std::string input_name = ConstructKeyName(keycode); + + ciface::Core::Device::Input* input = device->FindInput(input_name); + if (!input) + { + ERROR_LOG_FMT(CONTROLLERINTERFACE, "Could not find input {} in device {}", input_name, + device->GetQualifiedName()); + return false; + } + + auto casted_input = static_cast<ciface::Android::AndroidInput*>(input); + casted_input->SetState(state); + const Clock::time_point last_polled = casted_input->GetLastPolled(); + + DEBUG_LOG_FMT(CONTROLLERINTERFACE, "Set {} of {} to {}", input_name, device->GetQualifiedName(), + state); + + return last_polled >= Clock::now() - ACTIVE_INPUT_TIMEOUT; +} + +JNIEXPORT jboolean JNICALL +Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_dispatchGenericMotionEvent( + JNIEnv* env, jclass, jobject motion_event) +{ + const jobject input_device = env->CallObjectMethod(motion_event, s_input_event_get_device); + const jint device_id = env->CallIntMethod(input_device, s_input_device_get_id); + env->DeleteLocalRef(input_device); + const std::shared_ptr<ciface::Core::Device> device = FindDevice(device_id); + if (!device) + return JNI_FALSE; + + const jint source = env->CallIntMethod(motion_event, s_motion_event_get_source); + const std::string axis_name_prefix = ConstructAxisNamePrefix(source); + + Clock::time_point last_polled{}; + + for (ciface::Core::Device::Input* input : device->Inputs()) + { + const std::string input_name = input->GetName(); + if (input_name.starts_with(axis_name_prefix)) + { + const std::string axis_id_str = input_name.substr( + axis_name_prefix.size(), input_name.size() - axis_name_prefix.size() - sizeof('+')); + + int axis_id; + if (!TryParse(axis_id_str, &axis_id)) + { + ERROR_LOG_FMT(CONTROLLERINTERFACE, "Failed to parse \"{}\" from \"{}\" as axis ID", + axis_id_str, input_name); + continue; + } + + float value = env->CallFloatMethod(motion_event, s_motion_event_get_axis_value, axis_id); + + auto casted_input = static_cast<ciface::Android::AndroidInput*>(input); + casted_input->SetState(value); + last_polled = std::max(last_polled, casted_input->GetLastPolled()); + + DEBUG_LOG_FMT(CONTROLLERINTERFACE, "Set {} of {} to {}", input_name, + device->GetQualifiedName(), value); + } + } + + return last_polled >= Clock::now() - ACTIVE_INPUT_TIMEOUT; +} + +JNIEXPORT jboolean JNICALL +Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_dispatchSensorEvent( + JNIEnv* env, jclass, jstring j_device_qualifier, jstring j_axis_name, jfloat value) +{ + ciface::Core::DeviceQualifier device_qualifier; + device_qualifier.FromString(GetJString(env, j_device_qualifier)); + const std::shared_ptr<ciface::Core::Device> device = + g_controller_interface.FindDevice(device_qualifier); + if (!device) + return JNI_FALSE; + + const std::string axis_name = GetJString(env, j_axis_name); + + Clock::time_point last_polled{}; + + for (ciface::Core::Device::Input* input : device->Inputs()) + { + const std::string input_name = input->GetName(); + if (input_name == axis_name) + { + auto casted_input = static_cast<ciface::Android::AndroidInput*>(input); + casted_input->SetState(value); + last_polled = std::max(last_polled, casted_input->GetLastPolled()); + } + } + + return last_polled >= Clock::now() - ACTIVE_INPUT_TIMEOUT; +} + +JNIEXPORT void JNICALL +Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_notifySensorSuspendedState( + JNIEnv* env, jclass, jstring j_device_qualifier, jobjectArray j_axis_names, jboolean suspended) +{ + ciface::Core::DeviceQualifier device_qualifier; + device_qualifier.FromString(GetJString(env, j_device_qualifier)); + const std::shared_ptr<ciface::Core::Device> device = + g_controller_interface.FindDevice(device_qualifier); + if (!device) + return; + + const std::vector<std::string> axis_names = JStringArrayToVector(env, j_axis_names); + + for (ciface::Core::Device::Input* input : device->Inputs()) + { + const std::string input_name = input->GetName(); + if (std::find(axis_names.begin(), axis_names.end(), input_name) != axis_names.end()) + { + auto casted_input = static_cast<ciface::Android::AndroidSensorAxis*>(input); + casted_input->NotifyIsSuspended(static_cast<bool>(suspended)); + } + } +} + +JNIEXPORT void JNICALL +Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_refreshDevices(JNIEnv* env, + jclass) +{ + g_controller_interface.RefreshDevices(); +} + +JNIEXPORT jobjectArray JNICALL +Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_getAllDeviceStrings( + JNIEnv* env, jclass) +{ + return VectorToJStringArray(env, g_controller_interface.GetAllDeviceStrings()); +} + +JNIEXPORT jobject JNICALL +Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_getDevice( + JNIEnv* env, jclass, jstring j_device_string) +{ + ciface::Core::DeviceQualifier qualifier; + qualifier.FromString(GetJString(env, j_device_string)); + return CoreDeviceToJava(env, g_controller_interface.FindDevice(qualifier)); +} +} diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.h b/Source/Core/InputCommon/ControllerInterface/Android/Android.h index 2cc3c5a22b..8b8478d7ac 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.h +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.h @@ -1,11 +1,13 @@ -// Copyright 2008 Dolphin Emulator Project +// Copyright 2021 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once namespace ciface::Android { -void SetMotionSensorsEnabled(bool accelerometer_enabled, bool gyroscope_enabled); +void Init(); +void Shutdown(); void PopulateDevices(); + } // namespace ciface::Android diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp index 6a6affd478..8f58525f0c 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp @@ -67,7 +67,7 @@ void ControllerInterface::Initialize(const WindowSystemInfo& wsi) m_input_backends.emplace_back(ciface::SDL::CreateInputBackend(this)); #endif #ifdef CIFACE_USE_ANDROID -// nothing needed + ciface::Android::Init(); #endif #ifdef CIFACE_USE_EVDEV m_input_backends.emplace_back(ciface::evdev::CreateInputBackend(this)); @@ -237,7 +237,7 @@ void ControllerInterface::Shutdown() ciface::Quartz::DeInit(); #endif #ifdef CIFACE_USE_ANDROID -// nothing needed + ciface::Android::Shutdown(); #endif // Empty the container of input backends to deconstruct and deinitialize them. diff --git a/Source/Core/InputCommon/ControllerInterface/CoreDevice.cpp b/Source/Core/InputCommon/ControllerInterface/CoreDevice.cpp index 4e46179fc6..222791f03f 100644 --- a/Source/Core/InputCommon/ControllerInterface/CoreDevice.cpp +++ b/Source/Core/InputCommon/ControllerInterface/CoreDevice.cpp @@ -242,6 +242,18 @@ std::shared_ptr<Device> DeviceContainer::FindDevice(const DeviceQualifier& devq) return nullptr; } +std::vector<std::shared_ptr<Device>> DeviceContainer::GetAllDevices() const +{ + std::lock_guard lk(m_devices_mutex); + + std::vector<std::shared_ptr<Device>> devices; + + for (const auto& d : m_devices) + devices.emplace_back(d); + + return devices; +} + std::vector<std::string> DeviceContainer::GetAllDeviceStrings() const { std::lock_guard lk(m_devices_mutex); diff --git a/Source/Core/InputCommon/ControllerInterface/CoreDevice.h b/Source/Core/InputCommon/ControllerInterface/CoreDevice.h index 2280ddac3b..a2176637ab 100644 --- a/Source/Core/InputCommon/ControllerInterface/CoreDevice.h +++ b/Source/Core/InputCommon/ControllerInterface/CoreDevice.h @@ -226,6 +226,7 @@ public: Device::Input* FindInput(std::string_view name, const Device* def_dev) const; Device::Output* FindOutput(std::string_view name, const Device* def_dev) const; + std::vector<std::shared_ptr<Device>> GetAllDevices() const; std::vector<std::string> GetAllDeviceStrings() const; bool HasDefaultDevice() const; std::string GetDefaultDeviceString() const; diff --git a/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.cpp b/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.cpp deleted file mode 100644 index 0111947608..0000000000 --- a/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.cpp +++ /dev/null @@ -1,788 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "InputCommon/ControllerInterface/Touch/ButtonManager.h" - -#include <array> -#include <sstream> -#include <string> -#include <unordered_map> -#include <vector> - -#include "Common/FileUtil.h" -#include "Common/IniFile.h" -#include "Common/StringUtil.h" -#include "Common/Thread.h" - -namespace ButtonManager -{ -namespace -{ -constexpr char TOUCHSCREEN_KEY[] = "Touchscreen"; -constexpr std::array<const char*, 155> CONFIG_STRINGS{{ - // GC - "InputA", - "InputB", - "InputStart", - "InputX", - "InputY", - "InputZ", - "DPadUp", - "DPadDown", - "DPadLeft", - "DPadRight", - "MainUp", - "MainDown", - "MainLeft", - "MainRight", - "CStickUp", - "CStickDown", - "CStickLeft", - "CStickRight", - "InputL", - "InputR", - // Wiimote - "WiimoteA", - "WiimoteB", - "WiimoteMinus", - "WiimotePlus", - "WiimoteHome", - "Wiimote1", - "Wiimote2", - "WiimoteUp", - "WiimoteDown", - "WiimoteLeft", - "WiimoteRight", - "IRUp", - "IRDown", - "IRLeft", - "IRRight", - "IRForward", - "IRBackward", - "IRHide", - "SwingUp", - "SwingDown", - "SwingLeft", - "SwingRight", - "SwingForward", - "SwingBackward", - "TiltForward", - "TiltBackward", - "TiltLeft", - "TiltRight", - "TiltModifier", - "ShakeX", - "ShakeY", - "ShakeZ", - // Nunchuk - "NunchukC", - "NunchukZ", - "NunchukUp", - "NunchukDown", - "NunchukLeft", - "NunchukRight", - "NunchukSwingUp", - "NunchukSwingDown", - "NunchukSwingLeft", - "NunchukSwingRight", - "NunchukSwingForward", - "NunchukSwingBackward", - "NunchukTiltForward", - "NunchukTiltBackward", - "NunchukTiltLeft", - "NunchukTiltRight", - "NunchukTiltModifier", - "NunchukShakeX", - "NunchukShakeY", - "NunchukShakeZ", - // Classic - "ClassicA", - "ClassicB", - "ClassicX", - "ClassicY", - "ClassicMinus", - "ClassicPlus", - "ClassicHome", - "ClassicZL", - "ClassicZR", - "ClassicUp", - "ClassicDown", - "ClassicLeft", - "ClassicRight", - "ClassicLeftStickUp", - "ClassicLeftStickDown", - "ClassicLeftStickLeft", - "ClassicLeftStickRight", - "ClassicRightStickUp", - "ClassicRightStickDown", - "ClassicRightStickLeft", - "ClassicRightStickRight", - "ClassicTriggerL", - "ClassicTriggerR", - // Guitar - "GuitarMinus", - "GuitarPlus", - "GuitarGreen", - "GuitarRed", - "GuitarYellow", - "GuitarBlue", - "GuitarOrange", - "GuitarStrumUp", - "GuitarStrumDown", - "GuitarUp", - "GuitarDown", - "GuitarLeft", - "GuitarRight", - "GuitarWhammy", - // Drums - "DrumsMinus", - "DrumsPlus", - "DrumsRed", - "DrumsYellow", - "DrumsBlue", - "DrumsGreen", - "DrumsOrange", - "DrumsBass", - "DrumsUp", - "DrumsDown", - "DrumsLeft", - "DrumsRight", - // Turntable - "TurntableGreenLeft", - "TurntableRedLeft", - "TurntableBlueLeft", - "TurntableGreenRight", - "TurntableRedRight", - "TurntableBlueRight", - "TurntableMinus", - "TurntablePlus", - "TurntableHome", - "TurntableEuphoria", - "TurntableLeftTLeft", - "TurntableLeftTRight", - "TurntableRightTLeft", - "TurntableRightTRight", - "TurntableUp", - "TurntableDown", - "TurntableLeft", - "TurntableRight", - "TurntableEffDial", - "TurntableCrossLeft", - "TurntableCrossRight", - // Wiimote IMU - "WiimoteAccelLeft", - "WiimoteAccelRight", - "WiimoteAccelForward", - "WiimoteAccelBackward", - "WiimoteAccelUp", - "WiimoteAccelDown", - "WiimoteGyroPitchUp", - "WiimoteGyroPitchDown", - "WiimoteGyroRollLeft", - "WiimoteGyroRollRight", - "WiimoteGyroYawLeft", - "WiimoteGyroYawRight", - // Rumble - "Rumble", -}}; - -constexpr std::array<ButtonType, 155> CONFIG_TYPES{{ - // GC - BUTTON_A, - BUTTON_B, - BUTTON_START, - BUTTON_X, - BUTTON_Y, - BUTTON_Z, - BUTTON_UP, - BUTTON_DOWN, - BUTTON_LEFT, - BUTTON_RIGHT, - STICK_MAIN_UP, - STICK_MAIN_DOWN, - STICK_MAIN_LEFT, - STICK_MAIN_RIGHT, - STICK_C_UP, - STICK_C_DOWN, - STICK_C_LEFT, - STICK_C_RIGHT, - TRIGGER_L, - TRIGGER_R, - // Wiimote - WIIMOTE_BUTTON_A, - WIIMOTE_BUTTON_B, - WIIMOTE_BUTTON_MINUS, - WIIMOTE_BUTTON_PLUS, - WIIMOTE_BUTTON_HOME, - WIIMOTE_BUTTON_1, - WIIMOTE_BUTTON_2, - WIIMOTE_UP, - WIIMOTE_DOWN, - WIIMOTE_LEFT, - WIIMOTE_RIGHT, - WIIMOTE_IR_UP, - WIIMOTE_IR_DOWN, - WIIMOTE_IR_LEFT, - WIIMOTE_IR_RIGHT, - WIIMOTE_IR_FORWARD, - WIIMOTE_IR_BACKWARD, - WIIMOTE_IR_HIDE, - WIIMOTE_SWING_UP, - WIIMOTE_SWING_DOWN, - WIIMOTE_SWING_LEFT, - WIIMOTE_SWING_RIGHT, - WIIMOTE_SWING_FORWARD, - WIIMOTE_SWING_BACKWARD, - WIIMOTE_TILT_FORWARD, - WIIMOTE_TILT_BACKWARD, - WIIMOTE_TILT_LEFT, - WIIMOTE_TILT_RIGHT, - WIIMOTE_TILT_MODIFIER, - WIIMOTE_SHAKE_X, - WIIMOTE_SHAKE_Y, - WIIMOTE_SHAKE_Z, - // Nunchuk - NUNCHUK_BUTTON_C, - NUNCHUK_BUTTON_Z, - NUNCHUK_STICK_UP, - NUNCHUK_STICK_DOWN, - NUNCHUK_STICK_LEFT, - NUNCHUK_STICK_RIGHT, - NUNCHUK_SWING_UP, - NUNCHUK_SWING_DOWN, - NUNCHUK_SWING_LEFT, - NUNCHUK_SWING_RIGHT, - NUNCHUK_SWING_FORWARD, - NUNCHUK_SWING_BACKWARD, - NUNCHUK_TILT_FORWARD, - NUNCHUK_TILT_BACKWARD, - NUNCHUK_TILT_LEFT, - NUNCHUK_TILT_RIGHT, - NUNCHUK_TILT_MODIFIER, - NUNCHUK_SHAKE_X, - NUNCHUK_SHAKE_Y, - NUNCHUK_SHAKE_Z, - // Classic - CLASSIC_BUTTON_A, - CLASSIC_BUTTON_B, - CLASSIC_BUTTON_X, - CLASSIC_BUTTON_Y, - CLASSIC_BUTTON_MINUS, - CLASSIC_BUTTON_PLUS, - CLASSIC_BUTTON_HOME, - CLASSIC_BUTTON_ZL, - CLASSIC_BUTTON_ZR, - CLASSIC_DPAD_UP, - CLASSIC_DPAD_DOWN, - CLASSIC_DPAD_LEFT, - CLASSIC_DPAD_RIGHT, - CLASSIC_STICK_LEFT_UP, - CLASSIC_STICK_LEFT_DOWN, - CLASSIC_STICK_LEFT_LEFT, - CLASSIC_STICK_LEFT_RIGHT, - CLASSIC_STICK_RIGHT_UP, - CLASSIC_STICK_RIGHT_DOWN, - CLASSIC_STICK_RIGHT_LEFT, - CLASSIC_STICK_RIGHT_RIGHT, - CLASSIC_TRIGGER_L, - CLASSIC_TRIGGER_R, - // Guitar - GUITAR_BUTTON_MINUS, - GUITAR_BUTTON_PLUS, - GUITAR_FRET_GREEN, - GUITAR_FRET_RED, - GUITAR_FRET_YELLOW, - GUITAR_FRET_BLUE, - GUITAR_FRET_ORANGE, - GUITAR_STRUM_UP, - GUITAR_STRUM_DOWN, - GUITAR_STICK_UP, - GUITAR_STICK_DOWN, - GUITAR_STICK_LEFT, - GUITAR_STICK_RIGHT, - GUITAR_WHAMMY_BAR, - // Drums - DRUMS_BUTTON_MINUS, - DRUMS_BUTTON_PLUS, - DRUMS_PAD_RED, - DRUMS_PAD_YELLOW, - DRUMS_PAD_BLUE, - DRUMS_PAD_GREEN, - DRUMS_PAD_ORANGE, - DRUMS_PAD_BASS, - DRUMS_STICK_UP, - DRUMS_STICK_DOWN, - DRUMS_STICK_LEFT, - DRUMS_STICK_RIGHT, - // Turntable - TURNTABLE_BUTTON_GREEN_LEFT, - TURNTABLE_BUTTON_RED_LEFT, - TURNTABLE_BUTTON_BLUE_LEFT, - TURNTABLE_BUTTON_GREEN_RIGHT, - TURNTABLE_BUTTON_RED_RIGHT, - TURNTABLE_BUTTON_BLUE_RIGHT, - TURNTABLE_BUTTON_MINUS, - TURNTABLE_BUTTON_PLUS, - TURNTABLE_BUTTON_HOME, - TURNTABLE_BUTTON_EUPHORIA, - TURNTABLE_TABLE_LEFT_LEFT, - TURNTABLE_TABLE_LEFT_RIGHT, - TURNTABLE_TABLE_RIGHT_LEFT, - TURNTABLE_TABLE_RIGHT_RIGHT, - TURNTABLE_STICK_UP, - TURNTABLE_STICK_DOWN, - TURNTABLE_STICK_LEFT, - TURNTABLE_STICK_RIGHT, - TURNTABLE_EFFECT_DIAL, - TURNTABLE_CROSSFADE_LEFT, - TURNTABLE_CROSSFADE_RIGHT, - // Wiimote IMU - WIIMOTE_ACCEL_LEFT, - WIIMOTE_ACCEL_RIGHT, - WIIMOTE_ACCEL_FORWARD, - WIIMOTE_ACCEL_BACKWARD, - WIIMOTE_ACCEL_UP, - WIIMOTE_ACCEL_DOWN, - WIIMOTE_GYRO_PITCH_UP, - WIIMOTE_GYRO_PITCH_DOWN, - WIIMOTE_GYRO_ROLL_LEFT, - WIIMOTE_GYRO_ROLL_RIGHT, - WIIMOTE_GYRO_YAW_LEFT, - WIIMOTE_GYRO_YAW_RIGHT, - // Rumble - RUMBLE, -}}; - -std::unordered_map<std::string, InputDevice*> m_controllers; - -void AddBind(const std::string& dev, sBind* bind) -{ - auto it = m_controllers.find(dev); - if (it != m_controllers.end()) - { - it->second->AddBind(bind); - return; - } - m_controllers[dev] = new InputDevice(dev); - m_controllers[dev]->AddBind(bind); -} -} // Anonymous namespace - -void Init(const std::string& game_id) -{ - // Initialize pad 0(gc 1) and pad 4(wii 1) as touch overlay controller - for (int a = 0; a < 5; a += 4) - { - // GC - AddBind(TOUCHSCREEN_KEY, new sBind(a, BUTTON_A, BIND_BUTTON, BUTTON_A, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, BUTTON_B, BIND_BUTTON, BUTTON_B, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, BUTTON_START, BIND_BUTTON, BUTTON_START, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, BUTTON_X, BIND_BUTTON, BUTTON_X, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, BUTTON_Y, BIND_BUTTON, BUTTON_Y, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, BUTTON_Z, BIND_BUTTON, BUTTON_Z, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, BUTTON_UP, BIND_BUTTON, BUTTON_UP, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, BUTTON_DOWN, BIND_BUTTON, BUTTON_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, BUTTON_LEFT, BIND_BUTTON, BUTTON_LEFT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, BUTTON_RIGHT, BIND_BUTTON, BUTTON_RIGHT, 1.0f)); - - AddBind(TOUCHSCREEN_KEY, new sBind(a, STICK_MAIN_UP, BIND_AXIS, STICK_MAIN_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, STICK_MAIN_DOWN, BIND_AXIS, STICK_MAIN_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, STICK_MAIN_LEFT, BIND_AXIS, STICK_MAIN_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, STICK_MAIN_RIGHT, BIND_AXIS, STICK_MAIN_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, STICK_C_UP, BIND_AXIS, STICK_C_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, STICK_C_DOWN, BIND_AXIS, STICK_C_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, STICK_C_LEFT, BIND_AXIS, STICK_C_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, STICK_C_RIGHT, BIND_AXIS, STICK_C_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, TRIGGER_L, BIND_AXIS, TRIGGER_L, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, TRIGGER_R, BIND_AXIS, TRIGGER_R, 1.0f)); - - // Wiimote - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_BUTTON_A, BIND_BUTTON, WIIMOTE_BUTTON_A, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_BUTTON_B, BIND_BUTTON, WIIMOTE_BUTTON_B, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_BUTTON_MINUS, BIND_BUTTON, WIIMOTE_BUTTON_MINUS, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_BUTTON_PLUS, BIND_BUTTON, WIIMOTE_BUTTON_PLUS, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_BUTTON_HOME, BIND_BUTTON, WIIMOTE_BUTTON_HOME, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_BUTTON_1, BIND_BUTTON, WIIMOTE_BUTTON_1, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_BUTTON_2, BIND_BUTTON, WIIMOTE_BUTTON_2, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_UP, BIND_BUTTON, WIIMOTE_UP, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_DOWN, BIND_BUTTON, WIIMOTE_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_LEFT, BIND_BUTTON, WIIMOTE_LEFT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_RIGHT, BIND_BUTTON, WIIMOTE_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_IR_HIDE, BIND_BUTTON, WIIMOTE_IR_HIDE, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_TILT_MODIFIER, BIND_BUTTON, WIIMOTE_TILT_MODIFIER, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_SHAKE_X, BIND_BUTTON, WIIMOTE_SHAKE_X, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_SHAKE_Y, BIND_BUTTON, WIIMOTE_SHAKE_Y, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_SHAKE_Z, BIND_BUTTON, WIIMOTE_SHAKE_Z, 1.0f)); - - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_IR_UP, BIND_AXIS, WIIMOTE_IR_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_IR_DOWN, BIND_AXIS, WIIMOTE_IR_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_IR_LEFT, BIND_AXIS, WIIMOTE_IR_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_IR_RIGHT, BIND_AXIS, WIIMOTE_IR_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_IR_FORWARD, BIND_AXIS, WIIMOTE_IR_FORWARD, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_IR_BACKWARD, BIND_AXIS, WIIMOTE_IR_BACKWARD, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_SWING_UP, BIND_AXIS, WIIMOTE_SWING_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_SWING_DOWN, BIND_AXIS, WIIMOTE_SWING_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_SWING_LEFT, BIND_AXIS, WIIMOTE_SWING_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_SWING_RIGHT, BIND_AXIS, WIIMOTE_SWING_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_SWING_FORWARD, BIND_AXIS, WIIMOTE_SWING_FORWARD, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_SWING_BACKWARD, BIND_AXIS, WIIMOTE_SWING_BACKWARD, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_TILT_FORWARD, BIND_AXIS, WIIMOTE_TILT_FORWARD, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_TILT_BACKWARD, BIND_AXIS, WIIMOTE_TILT_BACKWARD, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_TILT_LEFT, BIND_AXIS, WIIMOTE_TILT_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_TILT_RIGHT, BIND_AXIS, WIIMOTE_TILT_RIGHT, 1.0f)); - - // Wii: Nunchuk - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_BUTTON_C, BIND_BUTTON, NUNCHUK_BUTTON_C, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_BUTTON_Z, BIND_BUTTON, NUNCHUK_BUTTON_Z, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, NUNCHUK_TILT_MODIFIER, BIND_BUTTON, NUNCHUK_TILT_MODIFIER, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_SHAKE_X, BIND_BUTTON, NUNCHUK_SHAKE_X, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_SHAKE_Y, BIND_BUTTON, NUNCHUK_SHAKE_Y, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_SHAKE_Z, BIND_BUTTON, NUNCHUK_SHAKE_Z, 1.0f)); - - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_SWING_UP, BIND_AXIS, NUNCHUK_SWING_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_SWING_DOWN, BIND_AXIS, NUNCHUK_SWING_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, NUNCHUK_SWING_LEFT, BIND_AXIS, NUNCHUK_SWING_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, NUNCHUK_SWING_RIGHT, BIND_AXIS, NUNCHUK_SWING_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, NUNCHUK_SWING_FORWARD, BIND_AXIS, NUNCHUK_SWING_FORWARD, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, NUNCHUK_SWING_BACKWARD, BIND_BUTTON, NUNCHUK_SWING_BACKWARD, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, NUNCHUK_TILT_FORWARD, BIND_AXIS, NUNCHUK_TILT_FORWARD, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, NUNCHUK_TILT_BACKWARD, BIND_AXIS, NUNCHUK_TILT_BACKWARD, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_TILT_LEFT, BIND_AXIS, NUNCHUK_TILT_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_TILT_RIGHT, BIND_AXIS, NUNCHUK_TILT_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_STICK_UP, BIND_AXIS, NUNCHUK_STICK_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, NUNCHUK_STICK_DOWN, BIND_AXIS, NUNCHUK_STICK_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, NUNCHUK_STICK_LEFT, BIND_AXIS, NUNCHUK_STICK_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, NUNCHUK_STICK_RIGHT, BIND_AXIS, NUNCHUK_STICK_RIGHT, 1.0f)); - - // Wii: Classic - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_BUTTON_A, BIND_BUTTON, CLASSIC_BUTTON_A, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_BUTTON_B, BIND_BUTTON, CLASSIC_BUTTON_B, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_BUTTON_X, BIND_BUTTON, CLASSIC_BUTTON_X, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_BUTTON_Y, BIND_BUTTON, CLASSIC_BUTTON_Y, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_BUTTON_MINUS, BIND_BUTTON, CLASSIC_BUTTON_MINUS, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_BUTTON_PLUS, BIND_BUTTON, CLASSIC_BUTTON_PLUS, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_BUTTON_HOME, BIND_BUTTON, CLASSIC_BUTTON_HOME, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_BUTTON_ZL, BIND_BUTTON, CLASSIC_BUTTON_ZL, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_BUTTON_ZR, BIND_BUTTON, CLASSIC_BUTTON_ZR, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_DPAD_UP, BIND_BUTTON, CLASSIC_DPAD_UP, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_DPAD_DOWN, BIND_BUTTON, CLASSIC_DPAD_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_DPAD_LEFT, BIND_BUTTON, CLASSIC_DPAD_LEFT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_DPAD_RIGHT, BIND_BUTTON, CLASSIC_DPAD_RIGHT, 1.0f)); - - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_STICK_LEFT_UP, BIND_AXIS, CLASSIC_STICK_LEFT_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_STICK_LEFT_DOWN, BIND_AXIS, CLASSIC_STICK_LEFT_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_STICK_LEFT_LEFT, BIND_AXIS, CLASSIC_STICK_LEFT_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_STICK_LEFT_RIGHT, BIND_AXIS, CLASSIC_STICK_LEFT_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_STICK_RIGHT_UP, BIND_AXIS, CLASSIC_STICK_RIGHT_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_STICK_RIGHT_DOWN, BIND_AXIS, CLASSIC_STICK_RIGHT_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_STICK_RIGHT_LEFT, BIND_AXIS, CLASSIC_STICK_RIGHT_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, CLASSIC_STICK_RIGHT_RIGHT, BIND_AXIS, CLASSIC_STICK_RIGHT_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_TRIGGER_L, BIND_AXIS, CLASSIC_TRIGGER_L, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, CLASSIC_TRIGGER_R, BIND_AXIS, CLASSIC_TRIGGER_R, 1.0f)); - - // Wii: Guitar - AddBind(TOUCHSCREEN_KEY, - new sBind(a, GUITAR_BUTTON_MINUS, BIND_BUTTON, GUITAR_BUTTON_MINUS, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, GUITAR_BUTTON_PLUS, BIND_BUTTON, GUITAR_BUTTON_PLUS, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, GUITAR_FRET_GREEN, BIND_BUTTON, GUITAR_FRET_GREEN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, GUITAR_FRET_RED, BIND_BUTTON, GUITAR_FRET_RED, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, GUITAR_FRET_YELLOW, BIND_BUTTON, GUITAR_FRET_YELLOW, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, GUITAR_FRET_BLUE, BIND_BUTTON, GUITAR_FRET_BLUE, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, GUITAR_FRET_ORANGE, BIND_BUTTON, GUITAR_FRET_ORANGE, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, GUITAR_STRUM_UP, BIND_BUTTON, GUITAR_STRUM_UP, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, GUITAR_STRUM_DOWN, BIND_BUTTON, GUITAR_STRUM_DOWN, 1.0f)); - - AddBind(TOUCHSCREEN_KEY, new sBind(a, GUITAR_STICK_UP, BIND_AXIS, GUITAR_STICK_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, GUITAR_STICK_DOWN, BIND_AXIS, GUITAR_STICK_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, GUITAR_STICK_LEFT, BIND_AXIS, GUITAR_STICK_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, GUITAR_STICK_RIGHT, BIND_AXIS, GUITAR_STICK_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, GUITAR_WHAMMY_BAR, BIND_AXIS, GUITAR_WHAMMY_BAR, 1.0f)); - - // Wii: Drums - AddBind(TOUCHSCREEN_KEY, - new sBind(a, DRUMS_BUTTON_MINUS, BIND_BUTTON, DRUMS_BUTTON_MINUS, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_BUTTON_PLUS, BIND_BUTTON, DRUMS_BUTTON_PLUS, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_PAD_RED, BIND_BUTTON, DRUMS_PAD_RED, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_PAD_YELLOW, BIND_BUTTON, DRUMS_PAD_YELLOW, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_PAD_BLUE, BIND_BUTTON, DRUMS_PAD_BLUE, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_PAD_GREEN, BIND_BUTTON, DRUMS_PAD_GREEN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_PAD_ORANGE, BIND_BUTTON, DRUMS_PAD_ORANGE, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_PAD_BASS, BIND_BUTTON, DRUMS_PAD_BASS, 1.0f)); - - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_STICK_UP, BIND_AXIS, DRUMS_STICK_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_STICK_DOWN, BIND_AXIS, DRUMS_STICK_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_STICK_LEFT, BIND_AXIS, DRUMS_STICK_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, DRUMS_STICK_RIGHT, BIND_AXIS, DRUMS_STICK_RIGHT, 1.0f)); - - // Wii: Turntable - AddBind(TOUCHSCREEN_KEY, new sBind(a, TURNTABLE_BUTTON_GREEN_LEFT, BIND_BUTTON, - TURNTABLE_BUTTON_GREEN_LEFT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_BUTTON_RED_LEFT, BIND_BUTTON, TURNTABLE_BUTTON_RED_LEFT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, TURNTABLE_BUTTON_BLUE_LEFT, BIND_BUTTON, - TURNTABLE_BUTTON_BLUE_LEFT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, TURNTABLE_BUTTON_GREEN_RIGHT, BIND_BUTTON, - TURNTABLE_BUTTON_GREEN_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, TURNTABLE_BUTTON_RED_RIGHT, BIND_BUTTON, - TURNTABLE_BUTTON_RED_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, TURNTABLE_BUTTON_BLUE_RIGHT, BIND_BUTTON, - TURNTABLE_BUTTON_BLUE_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_BUTTON_MINUS, BIND_BUTTON, TURNTABLE_BUTTON_MINUS, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_BUTTON_PLUS, BIND_BUTTON, TURNTABLE_BUTTON_PLUS, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_BUTTON_HOME, BIND_BUTTON, TURNTABLE_BUTTON_HOME, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_BUTTON_EUPHORIA, BIND_BUTTON, TURNTABLE_BUTTON_EUPHORIA, 1.0f)); - - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_TABLE_LEFT_LEFT, BIND_AXIS, TURNTABLE_TABLE_LEFT_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_TABLE_LEFT_RIGHT, BIND_AXIS, TURNTABLE_TABLE_LEFT_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_TABLE_RIGHT_LEFT, BIND_AXIS, TURNTABLE_TABLE_RIGHT_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, TURNTABLE_TABLE_RIGHT_RIGHT, BIND_AXIS, - TURNTABLE_TABLE_RIGHT_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_STICK_UP, BIND_AXIS, TURNTABLE_STICK_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_STICK_DOWN, BIND_AXIS, TURNTABLE_STICK_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_STICK_LEFT, BIND_AXIS, TURNTABLE_STICK_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_STICK_RIGHT, BIND_AXIS, TURNTABLE_STICK_RIGHT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_EFFECT_DIAL, BIND_AXIS, TURNTABLE_EFFECT_DIAL, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_CROSSFADE_LEFT, BIND_AXIS, TURNTABLE_CROSSFADE_LEFT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, TURNTABLE_CROSSFADE_RIGHT, BIND_AXIS, TURNTABLE_CROSSFADE_RIGHT, 1.0f)); - - // Wiimote IMU - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_ACCEL_LEFT, BIND_AXIS, WIIMOTE_ACCEL_LEFT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_ACCEL_RIGHT, BIND_AXIS, WIIMOTE_ACCEL_RIGHT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_ACCEL_FORWARD, BIND_AXIS, WIIMOTE_ACCEL_FORWARD, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_ACCEL_BACKWARD, BIND_AXIS, WIIMOTE_ACCEL_BACKWARD, 1.0f)); - AddBind(TOUCHSCREEN_KEY, new sBind(a, WIIMOTE_ACCEL_UP, BIND_AXIS, WIIMOTE_ACCEL_UP, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_ACCEL_DOWN, BIND_AXIS, WIIMOTE_ACCEL_DOWN, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_GYRO_PITCH_UP, BIND_AXIS, WIIMOTE_GYRO_PITCH_UP, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_GYRO_PITCH_DOWN, BIND_AXIS, WIIMOTE_GYRO_PITCH_DOWN, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_GYRO_ROLL_LEFT, BIND_AXIS, WIIMOTE_GYRO_ROLL_LEFT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_GYRO_ROLL_RIGHT, BIND_AXIS, WIIMOTE_GYRO_ROLL_RIGHT, -1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_GYRO_YAW_LEFT, BIND_AXIS, WIIMOTE_GYRO_YAW_LEFT, 1.0f)); - AddBind(TOUCHSCREEN_KEY, - new sBind(a, WIIMOTE_GYRO_YAW_RIGHT, BIND_AXIS, WIIMOTE_GYRO_YAW_RIGHT, -1.0f)); - } - // Init our controller bindings - IniFile ini; - ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string("Dolphin.ini"), true); - ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + std::string(game_id + ".ini"), true); - for (u32 a = 0; a < CONFIG_STRINGS.size(); ++a) - { - for (int pad_id = 0; pad_id < 8; ++pad_id) - { - std::ostringstream config; - config << CONFIG_STRINGS[a] << "_" << pad_id; - BindType type; - int bindnum; - char dev[128]{}; - bool hasbind = false; - char modifier = '+'; - std::string value; - ini.GetOrCreateSection("Android")->Get(config.str(), &value, "None"); - if (value == "None") - continue; - if (std::string::npos != value.find("Axis")) - { - hasbind = true; - type = BIND_AXIS; - if (value.starts_with("Device ''")) - sscanf(value.c_str(), "Device ''-Axis %d%c", &bindnum, &modifier); - else - sscanf(value.c_str(), "Device '%127[^\']'-Axis %d%c", dev, &bindnum, &modifier); - } - else if (std::string::npos != value.find("Button")) - { - hasbind = true; - type = BIND_BUTTON; - if (value.starts_with("Device ''")) - sscanf(value.c_str(), "Device ''-Button %d", &bindnum); - else - sscanf(value.c_str(), "Device '%127[^\']'-Button %d", dev, &bindnum); - } - if (hasbind) - AddBind(std::string(dev), - new sBind(pad_id, CONFIG_TYPES[a], type, bindnum, modifier == '-' ? -1.0f : 1.0f)); - } - } -} - -bool GetButtonPressed(int pad_id, ButtonType button) -{ - bool pressed = m_controllers[TOUCHSCREEN_KEY]->ButtonValue(pad_id, button); - - for (const auto& ctrl : m_controllers) - pressed |= ctrl.second->ButtonValue(pad_id, button); - - return pressed; -} - -float GetAxisValue(int pad_id, ButtonType axis) -{ - float value = m_controllers[TOUCHSCREEN_KEY]->AxisValue(pad_id, axis); - if (value == 0.0f) - { - for (const auto& ctrl : m_controllers) - { - value = ctrl.second->AxisValue(pad_id, axis); - if (value != 0.0f) - return value; - } - } - return value; -} - -bool GamepadEvent(const std::string& dev, int button, int action) -{ - auto it = m_controllers.find(dev); - if (it != m_controllers.end()) - return it->second->PressEvent(button, action); - return false; -} - -void GamepadAxisEvent(const std::string& dev, int axis, float value) -{ - auto it = m_controllers.find(dev); - if (it != m_controllers.end()) - it->second->AxisEvent(axis, value); -} - -void Shutdown() -{ - for (const auto& controller : m_controllers) - delete controller.second; - m_controllers.clear(); -} - -// InputDevice -bool InputDevice::PressEvent(int button, int action) -{ - bool handled = false; - for (const auto& binding : m_input_binds) - { - if (binding.second->m_bind == button) - { - if (binding.second->m_bind_type == BIND_BUTTON) - m_buttons[binding.second->m_button_type] = action == BUTTON_PRESSED ? true : false; - else - m_axes[binding.second->m_button_type] = action == BUTTON_PRESSED ? 1.0f : 0.0f; - handled = true; - } - } - return handled; -} - -void InputDevice::AxisEvent(int axis, float value) -{ - for (const auto& binding : m_input_binds) - { - if (binding.second->m_bind == axis) - { - if (binding.second->m_bind_type == BIND_AXIS) - m_axes[binding.second->m_button_type] = value; - else - m_buttons[binding.second->m_button_type] = value > 0.5f ? true : false; - } - } -} - -bool InputDevice::ButtonValue(int pad_id, ButtonType button) const -{ - const auto binding = m_input_binds.find(std::make_pair(pad_id, button)); - if (binding == m_input_binds.end()) - return false; - - if (binding->second->m_bind_type == BIND_BUTTON) - { - const auto button = m_buttons.find(binding->second->m_button_type); - if (button == m_buttons.end()) - return false; - return button->second; - } - else - { - const auto axis = m_axes.find(binding->second->m_button_type); - if (axis == m_axes.end()) - return false; - return (axis->second * binding->second->m_neg) > 0.5f; - } -} - -float InputDevice::AxisValue(int pad_id, ButtonType axis) const -{ - const auto binding = m_input_binds.find(std::make_pair(pad_id, axis)); - if (binding == m_input_binds.end()) - return 0.0f; - - if (binding->second->m_bind_type == BIND_AXIS) - { - const auto axis = m_axes.find(binding->second->m_button_type); - if (axis == m_axes.end()) - return 0.0f; - return axis->second * binding->second->m_neg; - } - else - { - const auto button = m_buttons.find(binding->second->m_button_type); - if (button == m_buttons.end()) - return 0.0f; - return button->second == BUTTON_PRESSED ? 1.0f : 0.0f; - } -} -} // namespace ButtonManager diff --git a/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.h b/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.h deleted file mode 100644 index 08c4349c84..0000000000 --- a/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.h +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <map> -#include <string> - -namespace ButtonManager -{ -enum ButtonType -{ - // GC - BUTTON_A = 0, - BUTTON_B = 1, - BUTTON_START = 2, - BUTTON_X = 3, - BUTTON_Y = 4, - BUTTON_Z = 5, - BUTTON_UP = 6, - BUTTON_DOWN = 7, - BUTTON_LEFT = 8, - BUTTON_RIGHT = 9, - STICK_MAIN = 10, // Used on Java Side - STICK_MAIN_UP = 11, - STICK_MAIN_DOWN = 12, - STICK_MAIN_LEFT = 13, - STICK_MAIN_RIGHT = 14, - STICK_C = 15, // Used on Java Side - STICK_C_UP = 16, - STICK_C_DOWN = 17, - STICK_C_LEFT = 18, - STICK_C_RIGHT = 19, - TRIGGER_L = 20, - TRIGGER_R = 21, - // Wiimote - WIIMOTE_BUTTON_A = 100, - WIIMOTE_BUTTON_B = 101, - WIIMOTE_BUTTON_MINUS = 102, - WIIMOTE_BUTTON_PLUS = 103, - WIIMOTE_BUTTON_HOME = 104, - WIIMOTE_BUTTON_1 = 105, - WIIMOTE_BUTTON_2 = 106, - WIIMOTE_UP = 107, - WIIMOTE_DOWN = 108, - WIIMOTE_LEFT = 109, - WIIMOTE_RIGHT = 110, - WIIMOTE_IR = 111, // To Be Used on Java Side - WIIMOTE_IR_UP = 112, - WIIMOTE_IR_DOWN = 113, - WIIMOTE_IR_LEFT = 114, - WIIMOTE_IR_RIGHT = 115, - WIIMOTE_IR_FORWARD = 116, - WIIMOTE_IR_BACKWARD = 117, - WIIMOTE_IR_HIDE = 118, - WIIMOTE_SWING = 119, // To Be Used on Java Side - WIIMOTE_SWING_UP = 120, - WIIMOTE_SWING_DOWN = 121, - WIIMOTE_SWING_LEFT = 122, - WIIMOTE_SWING_RIGHT = 123, - WIIMOTE_SWING_FORWARD = 124, - WIIMOTE_SWING_BACKWARD = 125, - WIIMOTE_TILT = 126, // To Be Used on Java Side - WIIMOTE_TILT_FORWARD = 127, - WIIMOTE_TILT_BACKWARD = 128, - WIIMOTE_TILT_LEFT = 129, - WIIMOTE_TILT_RIGHT = 130, - WIIMOTE_TILT_MODIFIER = 131, - WIIMOTE_SHAKE_X = 132, - WIIMOTE_SHAKE_Y = 133, - WIIMOTE_SHAKE_Z = 134, - // Nunchuk - NUNCHUK_BUTTON_C = 200, - NUNCHUK_BUTTON_Z = 201, - NUNCHUK_STICK = 202, // To Be Used on Java Side - NUNCHUK_STICK_UP = 203, - NUNCHUK_STICK_DOWN = 204, - NUNCHUK_STICK_LEFT = 205, - NUNCHUK_STICK_RIGHT = 206, - NUNCHUK_SWING = 207, // To Be Used on Java Side - NUNCHUK_SWING_UP = 208, - NUNCHUK_SWING_DOWN = 209, - NUNCHUK_SWING_LEFT = 210, - NUNCHUK_SWING_RIGHT = 211, - NUNCHUK_SWING_FORWARD = 212, - NUNCHUK_SWING_BACKWARD = 213, - NUNCHUK_TILT = 214, // To Be Used on Java Side - NUNCHUK_TILT_FORWARD = 215, - NUNCHUK_TILT_BACKWARD = 216, - NUNCHUK_TILT_LEFT = 217, - NUNCHUK_TILT_RIGHT = 218, - NUNCHUK_TILT_MODIFIER = 219, - NUNCHUK_SHAKE_X = 220, - NUNCHUK_SHAKE_Y = 221, - NUNCHUK_SHAKE_Z = 222, - // Classic - CLASSIC_BUTTON_A = 300, - CLASSIC_BUTTON_B = 301, - CLASSIC_BUTTON_X = 302, - CLASSIC_BUTTON_Y = 303, - CLASSIC_BUTTON_MINUS = 304, - CLASSIC_BUTTON_PLUS = 305, - CLASSIC_BUTTON_HOME = 306, - CLASSIC_BUTTON_ZL = 307, - CLASSIC_BUTTON_ZR = 308, - CLASSIC_DPAD_UP = 309, - CLASSIC_DPAD_DOWN = 310, - CLASSIC_DPAD_LEFT = 311, - CLASSIC_DPAD_RIGHT = 312, - CLASSIC_STICK_LEFT = 313, // To Be Used on Java Side - CLASSIC_STICK_LEFT_UP = 314, - CLASSIC_STICK_LEFT_DOWN = 315, - CLASSIC_STICK_LEFT_LEFT = 316, - CLASSIC_STICK_LEFT_RIGHT = 317, - CLASSIC_STICK_RIGHT = 318, // To Be Used on Java Side - CLASSIC_STICK_RIGHT_UP = 319, - CLASSIC_STICK_RIGHT_DOWN = 320, - CLASSIC_STICK_RIGHT_LEFT = 321, - CLASSIC_STICK_RIGHT_RIGHT = 322, - CLASSIC_TRIGGER_L = 323, - CLASSIC_TRIGGER_R = 324, - // Guitar - GUITAR_BUTTON_MINUS = 400, - GUITAR_BUTTON_PLUS = 401, - GUITAR_FRET_GREEN = 402, - GUITAR_FRET_RED = 403, - GUITAR_FRET_YELLOW = 404, - GUITAR_FRET_BLUE = 405, - GUITAR_FRET_ORANGE = 406, - GUITAR_STRUM_UP = 407, - GUITAR_STRUM_DOWN = 408, - GUITAR_STICK = 409, // To Be Used on Java Side - GUITAR_STICK_UP = 410, - GUITAR_STICK_DOWN = 411, - GUITAR_STICK_LEFT = 412, - GUITAR_STICK_RIGHT = 413, - GUITAR_WHAMMY_BAR = 414, - // Drums - DRUMS_BUTTON_MINUS = 500, - DRUMS_BUTTON_PLUS = 501, - DRUMS_PAD_RED = 502, - DRUMS_PAD_YELLOW = 503, - DRUMS_PAD_BLUE = 504, - DRUMS_PAD_GREEN = 505, - DRUMS_PAD_ORANGE = 506, - DRUMS_PAD_BASS = 507, - DRUMS_STICK = 508, // To Be Used on Java Side - DRUMS_STICK_UP = 509, - DRUMS_STICK_DOWN = 510, - DRUMS_STICK_LEFT = 511, - DRUMS_STICK_RIGHT = 512, - // Turntable - TURNTABLE_BUTTON_GREEN_LEFT = 600, - TURNTABLE_BUTTON_RED_LEFT = 601, - TURNTABLE_BUTTON_BLUE_LEFT = 602, - TURNTABLE_BUTTON_GREEN_RIGHT = 603, - TURNTABLE_BUTTON_RED_RIGHT = 604, - TURNTABLE_BUTTON_BLUE_RIGHT = 605, - TURNTABLE_BUTTON_MINUS = 606, - TURNTABLE_BUTTON_PLUS = 607, - TURNTABLE_BUTTON_HOME = 608, - TURNTABLE_BUTTON_EUPHORIA = 609, - TURNTABLE_TABLE_LEFT = 610, // To Be Used on Java Side - TURNTABLE_TABLE_LEFT_LEFT = 611, - TURNTABLE_TABLE_LEFT_RIGHT = 612, - TURNTABLE_TABLE_RIGHT = 613, // To Be Used on Java Side - TURNTABLE_TABLE_RIGHT_LEFT = 614, - TURNTABLE_TABLE_RIGHT_RIGHT = 615, - TURNTABLE_STICK = 616, // To Be Used on Java Side - TURNTABLE_STICK_UP = 617, - TURNTABLE_STICK_DOWN = 618, - TURNTABLE_STICK_LEFT = 619, - TURNTABLE_STICK_RIGHT = 620, - TURNTABLE_EFFECT_DIAL = 621, - TURNTABLE_CROSSFADE = 622, // To Be Used on Java Side - TURNTABLE_CROSSFADE_LEFT = 623, - TURNTABLE_CROSSFADE_RIGHT = 624, - // Wiimote IMU - WIIMOTE_ACCEL_LEFT = 625, - WIIMOTE_ACCEL_RIGHT = 626, - WIIMOTE_ACCEL_FORWARD = 627, - WIIMOTE_ACCEL_BACKWARD = 628, - WIIMOTE_ACCEL_UP = 629, - WIIMOTE_ACCEL_DOWN = 630, - WIIMOTE_GYRO_PITCH_UP = 631, - WIIMOTE_GYRO_PITCH_DOWN = 632, - WIIMOTE_GYRO_ROLL_LEFT = 633, - WIIMOTE_GYRO_ROLL_RIGHT = 634, - WIIMOTE_GYRO_YAW_LEFT = 635, - WIIMOTE_GYRO_YAW_RIGHT = 636, - // Rumble - RUMBLE = 700, -}; -enum ButtonState -{ - BUTTON_RELEASED = 0, - BUTTON_PRESSED = 1 -}; -enum BindType -{ - BIND_BUTTON = 0, - BIND_AXIS -}; -class Button -{ -private: - ButtonState m_state; - -public: - Button() : m_state(BUTTON_RELEASED) {} - void SetState(ButtonState state) { m_state = state; } - bool Pressed() const { return m_state == BUTTON_PRESSED; } - ~Button() {} -}; -class Axis -{ -private: - float m_value; - -public: - Axis() : m_value(0.0f) {} - void SetValue(float value) { m_value = value; } - float AxisValue() const { return m_value; } - ~Axis() {} -}; - -struct sBind -{ - const int m_pad_id; - const ButtonType m_button_type; - const BindType m_bind_type; - const int m_bind; - const float m_neg; - sBind(int pad_id, ButtonType button_type, BindType bind_type, int bind, float neg) - : m_pad_id(pad_id), m_button_type(button_type), m_bind_type(bind_type), m_bind(bind), - m_neg(neg) - { - } -}; - -class InputDevice -{ -private: - const std::string m_dev; - std::map<ButtonType, bool> m_buttons; - std::map<ButtonType, float> m_axes; - - // Key is pad_id and ButtonType - std::map<std::pair<int, ButtonType>, sBind*> m_input_binds; - -public: - InputDevice(std::string dev) : m_dev(dev) {} - ~InputDevice() - { - for (const auto& bind : m_input_binds) - delete bind.second; - m_input_binds.clear(); - } - void AddBind(sBind* bind) - { - m_input_binds[std::make_pair(bind->m_pad_id, bind->m_button_type)] = bind; - } - bool PressEvent(int button, int action); - void AxisEvent(int axis, float value); - bool ButtonValue(int pad_id, ButtonType button) const; - float AxisValue(int pad_id, ButtonType axis) const; -}; - -void Init(const std::string&); - -// pad_id is numbered 0 to 3 for GC pads and 4 to 7 for Wiimotes -bool GetButtonPressed(int pad_id, ButtonType button); -float GetAxisValue(int pad_id, ButtonType axis); - -bool GamepadEvent(const std::string& dev, int button, int action); -void GamepadAxisEvent(const std::string& dev, int axis, float value); - -void Shutdown(); -} // namespace ButtonManager diff --git a/Source/Core/InputCommon/ControllerInterface/Touch/Touchscreen.cpp b/Source/Core/InputCommon/ControllerInterface/Touch/Touchscreen.cpp deleted file mode 100644 index a4c20b0ae0..0000000000 --- a/Source/Core/InputCommon/ControllerInterface/Touch/Touchscreen.cpp +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "InputCommon/ControllerInterface/Touch/Touchscreen.h" - -#include <sstream> -#include <thread> -#ifdef ANDROID -#include <jni/AndroidCommon/IDCache.h> -#endif - -#include "InputCommon/ControllerInterface/ControllerInterface.h" - -namespace ciface::Touch -{ -// Touchscreens and stuff -std::string Touchscreen::GetName() const -{ - return "Touchscreen"; -} - -std::string Touchscreen::GetSource() const -{ - return "Android"; -} - -Touchscreen::Touchscreen(int pad_id, bool accelerometer_enabled, bool gyroscope_enabled) - : m_pad_id(pad_id) -{ - // GC - AddInput(new Button(m_pad_id, ButtonManager::BUTTON_A)); - AddInput(new Button(m_pad_id, ButtonManager::BUTTON_B)); - AddInput(new Button(m_pad_id, ButtonManager::BUTTON_START)); - AddInput(new Button(m_pad_id, ButtonManager::BUTTON_X)); - AddInput(new Button(m_pad_id, ButtonManager::BUTTON_Y)); - AddInput(new Button(m_pad_id, ButtonManager::BUTTON_Z)); - AddInput(new Button(m_pad_id, ButtonManager::BUTTON_UP)); - AddInput(new Button(m_pad_id, ButtonManager::BUTTON_DOWN)); - AddInput(new Button(m_pad_id, ButtonManager::BUTTON_LEFT)); - AddInput(new Button(m_pad_id, ButtonManager::BUTTON_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::STICK_MAIN_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::STICK_MAIN_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::STICK_MAIN_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::STICK_MAIN_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::STICK_C_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::STICK_C_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::STICK_C_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::STICK_C_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::TRIGGER_L)); - AddInput(new Axis(m_pad_id, ButtonManager::TRIGGER_R)); - - // Wiimote - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_BUTTON_A)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_BUTTON_B)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_BUTTON_MINUS)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_BUTTON_PLUS)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_BUTTON_HOME)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_BUTTON_1)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_BUTTON_2)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_UP)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_DOWN)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_LEFT)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_RIGHT)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_IR_HIDE)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_TILT_MODIFIER)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_SHAKE_X)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_SHAKE_Y)); - AddInput(new Button(m_pad_id, ButtonManager::WIIMOTE_SHAKE_Z)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_IR_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_IR_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_IR_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_IR_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_IR_FORWARD)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_IR_BACKWARD)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_SWING_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_SWING_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_SWING_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_SWING_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_SWING_FORWARD)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_SWING_BACKWARD)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_TILT_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_TILT_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_TILT_FORWARD)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_TILT_BACKWARD)); - - // Wii ext: Nunchuk - AddInput(new Button(m_pad_id, ButtonManager::NUNCHUK_BUTTON_C)); - AddInput(new Button(m_pad_id, ButtonManager::NUNCHUK_BUTTON_Z)); - AddInput(new Button(m_pad_id, ButtonManager::NUNCHUK_TILT_MODIFIER)); - AddInput(new Button(m_pad_id, ButtonManager::NUNCHUK_SHAKE_X)); - AddInput(new Button(m_pad_id, ButtonManager::NUNCHUK_SHAKE_Y)); - AddInput(new Button(m_pad_id, ButtonManager::NUNCHUK_SHAKE_Z)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_STICK_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_STICK_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_STICK_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_STICK_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_SWING_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_SWING_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_SWING_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_SWING_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_SWING_FORWARD)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_SWING_BACKWARD)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_TILT_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_TILT_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_TILT_FORWARD)); - AddInput(new Axis(m_pad_id, ButtonManager::NUNCHUK_TILT_BACKWARD)); - - // Wii ext: Classic - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_BUTTON_A)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_BUTTON_B)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_BUTTON_X)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_BUTTON_Y)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_BUTTON_MINUS)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_BUTTON_PLUS)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_BUTTON_HOME)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_BUTTON_ZL)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_BUTTON_ZR)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_DPAD_UP)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_DPAD_DOWN)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_DPAD_LEFT)); - AddInput(new Button(m_pad_id, ButtonManager::CLASSIC_DPAD_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::CLASSIC_STICK_LEFT_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::CLASSIC_STICK_LEFT_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::CLASSIC_STICK_LEFT_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::CLASSIC_STICK_LEFT_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::CLASSIC_STICK_RIGHT_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::CLASSIC_STICK_RIGHT_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::CLASSIC_STICK_RIGHT_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::CLASSIC_STICK_RIGHT_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::CLASSIC_TRIGGER_L)); - AddInput(new Axis(m_pad_id, ButtonManager::CLASSIC_TRIGGER_R)); - - // Wii-ext: Guitar - AddInput(new Button(m_pad_id, ButtonManager::GUITAR_BUTTON_MINUS)); - AddInput(new Button(m_pad_id, ButtonManager::GUITAR_BUTTON_PLUS)); - AddInput(new Button(m_pad_id, ButtonManager::GUITAR_FRET_GREEN)); - AddInput(new Button(m_pad_id, ButtonManager::GUITAR_FRET_RED)); - AddInput(new Button(m_pad_id, ButtonManager::GUITAR_FRET_YELLOW)); - AddInput(new Button(m_pad_id, ButtonManager::GUITAR_FRET_BLUE)); - AddInput(new Button(m_pad_id, ButtonManager::GUITAR_FRET_ORANGE)); - AddInput(new Button(m_pad_id, ButtonManager::GUITAR_STRUM_UP)); - AddInput(new Button(m_pad_id, ButtonManager::GUITAR_STRUM_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::GUITAR_STICK_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::GUITAR_STICK_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::GUITAR_STICK_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::GUITAR_STICK_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::GUITAR_WHAMMY_BAR)); - - // Wii-ext: Drums - AddInput(new Button(m_pad_id, ButtonManager::DRUMS_BUTTON_MINUS)); - AddInput(new Button(m_pad_id, ButtonManager::DRUMS_BUTTON_PLUS)); - AddInput(new Button(m_pad_id, ButtonManager::DRUMS_PAD_RED)); - AddInput(new Button(m_pad_id, ButtonManager::DRUMS_PAD_YELLOW)); - AddInput(new Button(m_pad_id, ButtonManager::DRUMS_PAD_BLUE)); - AddInput(new Button(m_pad_id, ButtonManager::DRUMS_PAD_GREEN)); - AddInput(new Button(m_pad_id, ButtonManager::DRUMS_PAD_ORANGE)); - AddInput(new Button(m_pad_id, ButtonManager::DRUMS_PAD_BASS)); - AddInput(new Axis(m_pad_id, ButtonManager::DRUMS_STICK_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::DRUMS_STICK_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::DRUMS_STICK_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::DRUMS_STICK_DOWN)); - - // Wii-ext: Turntable - AddInput(new Button(m_pad_id, ButtonManager::TURNTABLE_BUTTON_GREEN_LEFT)); - AddInput(new Button(m_pad_id, ButtonManager::TURNTABLE_BUTTON_RED_LEFT)); - AddInput(new Button(m_pad_id, ButtonManager::TURNTABLE_BUTTON_BLUE_LEFT)); - AddInput(new Button(m_pad_id, ButtonManager::TURNTABLE_BUTTON_GREEN_RIGHT)); - AddInput(new Button(m_pad_id, ButtonManager::TURNTABLE_BUTTON_RED_RIGHT)); - AddInput(new Button(m_pad_id, ButtonManager::TURNTABLE_BUTTON_BLUE_RIGHT)); - AddInput(new Button(m_pad_id, ButtonManager::TURNTABLE_BUTTON_MINUS)); - AddInput(new Button(m_pad_id, ButtonManager::TURNTABLE_BUTTON_PLUS)); - AddInput(new Button(m_pad_id, ButtonManager::TURNTABLE_BUTTON_HOME)); - AddInput(new Button(m_pad_id, ButtonManager::TURNTABLE_BUTTON_EUPHORIA)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_TABLE_LEFT_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_TABLE_LEFT_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_TABLE_RIGHT_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_TABLE_RIGHT_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_STICK_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_STICK_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_STICK_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_STICK_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_CROSSFADE_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_CROSSFADE_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::TURNTABLE_EFFECT_DIAL)); - - // Wiimote IMU - // Only add inputs if we actually can receive data from the relevant sensor. - // Whether inputs exist affects what WiimoteEmu gets when calling ControlReference::BoundCount. - if (accelerometer_enabled) - { - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_ACCEL_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_ACCEL_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_ACCEL_FORWARD)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_ACCEL_BACKWARD)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_ACCEL_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_ACCEL_DOWN)); - } - if (gyroscope_enabled) - { - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_GYRO_PITCH_UP)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_GYRO_PITCH_DOWN)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_GYRO_ROLL_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_GYRO_ROLL_RIGHT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_GYRO_YAW_LEFT)); - AddInput(new Axis(m_pad_id, ButtonManager::WIIMOTE_GYRO_YAW_RIGHT)); - } - - // Rumble - AddOutput(new Motor(m_pad_id, ButtonManager::RUMBLE)); -} -// Buttons and stuff - -std::string Touchscreen::Button::GetName() const -{ - std::ostringstream ss; - ss << "Button " << static_cast<int>(m_index); - return ss.str(); -} - -ControlState Touchscreen::Button::GetState() const -{ - return ButtonManager::GetButtonPressed(m_pad_id, m_index); -} - -std::string Touchscreen::Axis::GetName() const -{ - std::ostringstream ss; - ss << "Axis " << static_cast<int>(m_index); - return ss.str(); -} - -ControlState Touchscreen::Axis::GetState() const -{ - return ButtonManager::GetAxisValue(m_pad_id, m_index) * m_neg; -} - -Touchscreen::Motor::~Motor() -{ -} - -std::string Touchscreen::Motor::GetName() const -{ - std::ostringstream ss; - ss << "Rumble " << static_cast<int>(m_index); - return ss.str(); -} - -void Touchscreen::Motor::SetState(ControlState state) -{ - if (state > 0) - { - std::thread(Rumble, m_pad_id, state).detach(); - } -} - -void Touchscreen::Motor::Rumble(int pad_id, double state) -{ -#ifdef ANDROID - JNIEnv* env = IDCache::GetEnvForThread(); - env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetDoRumble(), pad_id, - state); -#endif -} -} // namespace ciface::Touch diff --git a/Source/Core/InputCommon/ControllerInterface/Touch/Touchscreen.h b/Source/Core/InputCommon/ControllerInterface/Touch/Touchscreen.h deleted file mode 100644 index 9d12df1a4c..0000000000 --- a/Source/Core/InputCommon/ControllerInterface/Touch/Touchscreen.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "InputCommon/ControllerInterface/ControllerInterface.h" -#include "InputCommon/ControllerInterface/Touch/ButtonManager.h" - -namespace ciface::Touch -{ -class Touchscreen : public Core::Device -{ -private: - class Button : public Input - { - public: - std::string GetName() const override; - Button(int pad_id, ButtonManager::ButtonType index) : m_pad_id(pad_id), m_index(index) {} - ControlState GetState() const override; - - private: - const int m_pad_id; - const ButtonManager::ButtonType m_index; - }; - class Axis : public Input - { - public: - std::string GetName() const override; - bool IsDetectable() const override { return false; } - Axis(int pad_id, ButtonManager::ButtonType index, float neg = 1.0f) - : m_pad_id(pad_id), m_index(index), m_neg(neg) - { - } - ControlState GetState() const override; - - private: - const int m_pad_id; - const ButtonManager::ButtonType m_index; - const float m_neg; - }; - class Motor : public Core::Device::Output - { - public: - Motor(int pad_id, ButtonManager::ButtonType index) : m_pad_id(pad_id), m_index(index) {} - ~Motor(); - std::string GetName() const override; - void SetState(ControlState state) override; - - private: - const int m_pad_id; - const ButtonManager::ButtonType m_index; - static void Rumble(int pad_id, double state); - }; - -public: - Touchscreen(int pad_id, bool accelerometer_enabled, bool gyroscope_enabled); - ~Touchscreen() {} - std::string GetName() const override; - std::string GetSource() const override; - -private: - const int m_pad_id; -}; -} // namespace ciface::Touch |
