diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt index 71b37ff513..70a2aebbff 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.kt @@ -98,6 +98,8 @@ object ControllerInterface { external fun getAllDeviceStrings(): Array external fun getDevice(deviceString: String): CoreDevice? + + external fun getDescriptorForDevice(deviceString: String): String private fun onInputStateChanged() { // When a single SensorEvent is dispatched, this method is likely to get called many times. diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt index 32a7a64025..c070001471 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt @@ -25,6 +25,7 @@ import org.dolphinemu.dolphinemu.features.input.model.controlleremu.ControlGroup import org.dolphinemu.dolphinemu.features.input.model.controlleremu.ControlGroupContainer import org.dolphinemu.dolphinemu.features.input.model.controlleremu.EmulatedController import org.dolphinemu.dolphinemu.features.input.model.controlleremu.NumericSetting +import org.dolphinemu.dolphinemu.features.input.model.ControllerInterface import org.dolphinemu.dolphinemu.features.input.model.view.InputDeviceSetting import org.dolphinemu.dolphinemu.features.input.model.view.InputMappingControlSetting import org.dolphinemu.dolphinemu.features.input.ui.ProfileDialog @@ -32,6 +33,7 @@ import org.dolphinemu.dolphinemu.features.input.ui.ProfileDialogPresenter import org.dolphinemu.dolphinemu.features.settings.model.* import org.dolphinemu.dolphinemu.features.settings.model.view.* import org.dolphinemu.dolphinemu.features.settings.model.AchievementModel.logout +import org.dolphinemu.dolphinemu.features.settings.model.view.InputStringSetting import org.dolphinemu.dolphinemu.model.GpuDriverMetadata import org.dolphinemu.dolphinemu.utils.* import kotlin.collections.ArrayList @@ -2586,6 +2588,50 @@ class SettingsFragmentPresenter( ) ) + sl.add( + InputStringSetting( + context, + object : AbstractStringSetting { + override val isOverridden: Boolean = false + override val isRuntimeEditable: Boolean = true + + override fun delete(settings: Settings): Boolean { + val descriptor = ControllerInterface.getDescriptorForDevice( + controller.getDefaultDevice() + ) + val key = if (descriptor.isNotEmpty()) descriptor else controller.getDefaultDevice() + NativeConfig.deleteKey(NativeConfig.LAYER_BASE, "Dolphin", "ControllerLabels", key) + NativeConfig.save(NativeConfig.LAYER_BASE) + return true + } + + override val string: String + get() { + val descriptor = ControllerInterface.getDescriptorForDevice( + controller.getDefaultDevice() + ) + val key = if (descriptor.isNotEmpty()) descriptor else controller.getDefaultDevice() + return NativeConfig.getString(NativeConfig.LAYER_BASE, "Dolphin", "ControllerLabels", key, "") + } + + override fun setString(settings: Settings, newValue: String) { + val descriptor = ControllerInterface.getDescriptorForDevice( + controller.getDefaultDevice() + ) + val key = if (descriptor.isNotEmpty()) descriptor else controller.getDefaultDevice() + if (newValue.isEmpty()) { + NativeConfig.deleteKey(NativeConfig.LAYER_BASE, "Dolphin", "ControllerLabels", key) + } else { + NativeConfig.setString(NativeConfig.LAYER_BASE, "Dolphin", "ControllerLabels", key, newValue) + } + NativeConfig.save(NativeConfig.LAYER_BASE) + } + }, + R.string.input_controller_label, + R.string.input_controller_label_description + ) + ) + sl.add(SwitchSetting(context, object : AbstractBooleanSetting { override val isOverridden: Boolean = false diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 04c48bcba4..ce73fb8a3c 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -32,6 +32,8 @@ Extension Device + Controller Label + Give this controller a unique name Create Mappings for Other Devices Detects inputs from all devices, not just the selected device. Profile diff --git a/Source/Android/gradle/gradle-daemon-jvm.properties b/Source/Android/gradle/gradle-daemon-jvm.properties new file mode 100644 index 0000000000..6c1139ec06 --- /dev/null +++ b/Source/Android/gradle/gradle-daemon-jvm.properties @@ -0,0 +1,12 @@ +#This file is generated by updateDaemonJvm +toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect +toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect +toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect +toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect +toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/73bcfb608d1fde9fb62e462f834a3299/redirect +toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/846ee0d876d26a26f37aa1ce8de73224/redirect +toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect +toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect +toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/9482ddec596298c84656d31d16652665/redirect +toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/39701d92e1756bb2f141eb67cd4c660e/redirect +toolchainVersion=21 diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp index 0b0609f010..f17262ecc9 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp @@ -43,6 +43,7 @@ jmethodID s_input_device_get_device; jmethodID s_input_device_get_controller_number; jmethodID s_input_device_get_motion_ranges; jmethodID s_input_device_get_name; +jmethodID s_input_device_get_descriptor; jmethodID s_input_device_get_sources; jmethodID s_input_device_has_keys; @@ -624,6 +625,11 @@ public: m_name = GetJString(env, j_name); env->DeleteLocalRef(j_name); + jstring j_descriptor = reinterpret_cast( + env->CallObjectMethod(input_device, s_input_device_get_descriptor)); + m_descriptor = GetJString(env, j_descriptor); + env->DeleteLocalRef(j_descriptor); + DEBUG_LOG_FMT(CONTROLLERINTERFACE, "Sources for {}: {:08x}", GetQualifiedName(), m_source); AddKeys(env, input_device); @@ -671,6 +677,8 @@ public: std::optional GetDeviceID() const { return m_device_id; } + std::string GetDescriptor() const { return m_descriptor; } + jobject GetSensorEventListener() { return m_sensor_event_listener; } private: @@ -808,6 +816,7 @@ private: const int m_controller_number; const std::optional m_device_id; std::string m_name; + std::string m_descriptor; }; // Creates an array that contains every possible keycode @@ -846,6 +855,8 @@ InputBackend::InputBackend(ControllerInterface* controller_interface) 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_descriptor = + env->GetMethodID(s_input_device_class, "getDescriptor", "()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); @@ -1219,4 +1230,18 @@ Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_getDevic qualifier.FromString(GetJString(env, j_device_string)); return CoreDeviceToJava(env, g_controller_interface.FindDevice(qualifier)); } + +JNIEXPORT jstring JNICALL +Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_getDescriptorForDevice( + JNIEnv* env, jclass, jstring j_device_string) +{ + ciface::Core::DeviceQualifier qualifier; + qualifier.FromString(GetJString(env, j_device_string)); + auto device = g_controller_interface.FindDevice(qualifier); + if (!device || device->GetSource() != SOURCE) + return ToJString(env, ""); + + return ToJString(env, + static_cast(device.get())->GetDescriptor()); +} }