diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/controlleremu/EmulatedController.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/controlleremu/EmulatedController.kt index 348e75b6a04e..e84dd201a51a 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/controlleremu/EmulatedController.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/controlleremu/EmulatedController.kt @@ -30,10 +30,15 @@ class EmulatedController private constructor(private val pointer: Long) { external fun saveProfile(path: String) + external fun getProfileName(): String + companion object { @JvmStatic external fun getGcPad(controllerIndex: Int): EmulatedController + @JvmStatic + external fun getGcKeyboard(controllerIndex: Int): EmulatedController + @JvmStatic external fun getWiimote(controllerIndex: Int): EmulatedController diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ProfileDialogPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ProfileDialogPresenter.kt index 624441aa7314..2896c815fecd 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ProfileDialogPresenter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ProfileDialogPresenter.kt @@ -100,15 +100,14 @@ class ProfileDialogPresenter { .show() } - private val profileDirectoryName: String - get() = if (menuTag.isGCPadMenu) "GCPad" else if (menuTag.isWiimoteMenu) "Wiimote" else throw UnsupportedOperationException() - - private fun getProfileDirectoryPath(stock: Boolean): String = - if (stock) { + private fun getProfileDirectoryPath(stock: Boolean): String { + val profileDirectoryName = menuTag.correspondingEmulatedController.getProfileName() + return if (stock) { "${DirectoryInitialization.getSysDirectory()}/Profiles/$profileDirectoryName/" } else { "${DirectoryInitialization.getUserDirectory()}/Config/Profiles/$profileDirectoryName/" } + } private fun getProfilePath(profileName: String, stock: Boolean): String = getProfileDirectoryPath(stock) + profileName + EXTENSION 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 b85a3999cc47..b1e1271f899e 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 @@ -2079,34 +2079,49 @@ class SettingsFragmentPresenter( } private fun addGcPadSubSettings(sl: ArrayList, gcPadNumber: Int, gcPadType: Int) { - if (gcPadType == 6) { - // Emulated - val gcPad = EmulatedController.getGcPad(gcPadNumber) + when (gcPadType) { + 6, 8, 9, 10 -> { + // Emulated + val gcPad = EmulatedController.getGcPad(gcPadNumber) - if (!TextUtils.isEmpty(gameId)) { - addControllerPerGameSettings(sl, "Pad", gcPadNumber) - } else { - addControllerMetaSettings(sl, gcPad) - addControllerMappingSettings(sl, gcPad, null) + if (!TextUtils.isEmpty(gameId)) { + addControllerPerGameSettings(sl, gcPad, gcPadNumber) + } else { + addControllerMetaSettings(sl, gcPad) + addControllerMappingSettings(sl, gcPad, null) + } } - } else if (gcPadType == 12) { - // Adapter - sl.add( - SwitchSetting( - context, - BooleanSetting.getSettingForAdapterRumble(gcPadNumber), - R.string.gc_adapter_rumble, - R.string.gc_adapter_rumble_description + 7 -> { + // Emulated keyboard controller + val gcKeyboard = EmulatedController.getGcKeyboard(gcPadNumber) + + if (!TextUtils.isEmpty(gameId)) { + addControllerPerGameSettings(sl, gcKeyboard, gcPadNumber) + } else { + sl.add(HeaderSetting(context, R.string.keyboard_controller_warning, 0)) + addControllerMetaSettings(sl, gcKeyboard) + addControllerMappingSettings(sl, gcKeyboard, null) + } + } + 12 -> { + // Adapter + sl.add( + SwitchSetting( + context, + BooleanSetting.getSettingForAdapterRumble(gcPadNumber), + R.string.gc_adapter_rumble, + R.string.gc_adapter_rumble_description + ) ) - ) - sl.add( - SwitchSetting( - context, - BooleanSetting.getSettingForSimulateKonga(gcPadNumber), - R.string.gc_adapter_bongos, - R.string.gc_adapter_bongos_description + sl.add( + SwitchSetting( + context, + BooleanSetting.getSettingForSimulateKonga(gcPadNumber), + R.string.gc_adapter_bongos, + R.string.gc_adapter_bongos_description + ) ) - ) + } } } @@ -2114,7 +2129,7 @@ class SettingsFragmentPresenter( val wiimote = EmulatedController.getWiimote(wiimoteNumber) if (!TextUtils.isEmpty(gameId)) { - addControllerPerGameSettings(sl, "Wiimote", wiimoteNumber) + addControllerPerGameSettings(sl, wiimote, wiimoteNumber) } else { addControllerMetaSettings(sl, wiimote) @@ -2210,11 +2225,11 @@ class SettingsFragmentPresenter( */ private fun addControllerPerGameSettings( sl: ArrayList, - profileString: String, + controller: EmulatedController, controllerNumber: Int ) { val profiles = ProfileDialogPresenter(menuTag).getProfileNames(false) - val profileKey = profileString + "Profile" + (controllerNumber + 1) + val profileKey = controller.getProfileName() + "Profile" + (controllerNumber + 1) sl.add( StringSingleChoiceSetting( context, diff --git a/Source/Android/app/src/main/res/values/arrays.xml b/Source/Android/app/src/main/res/values/arrays.xml index 212bcb3d2bcf..2f8adeb60cb5 100644 --- a/Source/Android/app/src/main/res/values/arrays.xml +++ b/Source/Android/app/src/main/res/values/arrays.xml @@ -367,11 +367,19 @@ @string/gcpad_disabled @string/gcpad_emulated + @string/gcpad_keyboard + @string/gcpad_steering_wheel + @string/gcpad_dance_mat + @string/gcpad_taru_konga @string/gcpad_gc_adapter 0 6 + 7 + 8 + 9 + 10 12 diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 044c1ad65d72..9575ec0eb2ee 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -47,6 +47,7 @@ Clear Clear settings for this controller. Are you sure? Your current controller settings will be deleted. + "You are configuring a \"Keyboard Controller\". This device is exclusively for \"Phantasy Star Online Episode I & II\". If you are unsure, turn back now and configure a \"Standard Controller\". Your controller settings are from an old version of Dolphin and won\'t work in this version. Press \"Default\" to start over with new settings. Input Binding @@ -773,13 +774,17 @@ It can efficiently compress both junk data and encrypted Wii data. Unknown - Disabled - Emulated + None + Standard Controller + Keyboard Controller + Steering Wheel + Dance Mat + DK Bongos GameCube Adapter - Disabled - Emulated + None + Emulated Wii Remote Real Wii Remote (DolphinBar required) diff --git a/Source/Android/jni/Input/EmulatedController.cpp b/Source/Android/jni/Input/EmulatedController.cpp index 3d2676812fab..c1dfd7ce5dca 100644 --- a/Source/Android/jni/Input/EmulatedController.cpp +++ b/Source/Android/jni/Input/EmulatedController.cpp @@ -5,6 +5,7 @@ #include "Common/FileUtil.h" #include "Common/IniFile.h" +#include "Core/HW/GCKeyboard.h" #include "Core/HW/GCPad.h" #include "Core/HW/Wiimote.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" @@ -124,6 +125,13 @@ Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedContro ini.Save(path); } +JNIEXPORT jstring JNICALL +Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getProfileName( + JNIEnv* env, jobject obj) +{ + return ToJString(env, EmulatedControllerFromJava(env, obj)->GetConfig()->GetProfileName()); +} + JNIEXPORT jobject JNICALL Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getGcPad( JNIEnv* env, jclass, jint controller_index) @@ -131,6 +139,13 @@ Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedContro return EmulatedControllerToJava(env, Pad::GetConfig()->GetController(controller_index)); } +JNIEXPORT jobject JNICALL +Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getGcKeyboard( + JNIEnv* env, jclass, jint controller_index) +{ + return EmulatedControllerToJava(env, Keyboard::GetConfig()->GetController(controller_index)); +} + JNIEXPORT jobject JNICALL Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getWiimote( JNIEnv* env, jclass, jint controller_index) diff --git a/Source/Core/Core/FreeLookManager.cpp b/Source/Core/Core/FreeLookManager.cpp index b52a3d2a9c9a..7cf64a08fae3 100644 --- a/Source/Core/Core/FreeLookManager.cpp +++ b/Source/Core/Core/FreeLookManager.cpp @@ -118,6 +118,11 @@ std::string FreeLookController::GetName() const return std::string("FreeLook") + char('1' + m_index); } +InputConfig* FreeLookController::GetConfig() const +{ + return FreeLook::GetInputConfig(); +} + void FreeLookController::LoadDefaults(const ControllerInterface& ciface) { EmulatedController::LoadDefaults(ciface); diff --git a/Source/Core/Core/FreeLookManager.h b/Source/Core/Core/FreeLookManager.h index 16cfe909e0a4..1cf8b7f12441 100644 --- a/Source/Core/Core/FreeLookManager.h +++ b/Source/Core/Core/FreeLookManager.h @@ -47,6 +47,7 @@ class FreeLookController final : public ControllerEmu::EmulatedController explicit FreeLookController(unsigned int index); std::string GetName() const override; + InputConfig* GetConfig() const override; void LoadDefaults(const ControllerInterface& ciface) override; ControllerEmu::ControlGroup* GetGroup(FreeLookGroup group) const; diff --git a/Source/Core/Core/HW/GBAPadEmu.cpp b/Source/Core/Core/HW/GBAPadEmu.cpp index c31d35df12d9..8c1b9ec8d76e 100644 --- a/Source/Core/Core/HW/GBAPadEmu.cpp +++ b/Source/Core/Core/HW/GBAPadEmu.cpp @@ -5,6 +5,8 @@ #include +#include "Core/HW/GBAPad.h" + #include "InputCommon/ControllerEmu/Control/Input.h" #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" #include "InputCommon/GCPadStatus.h" @@ -43,6 +45,11 @@ std::string GBAPad::GetName() const return fmt::format("GBA{}", m_index + 1); } +InputConfig* GBAPad::GetConfig() const +{ + return Pad::GetGBAConfig(); +} + ControllerEmu::ControlGroup* GBAPad::GetGroup(GBAPadGroup group) const { switch (group) diff --git a/Source/Core/Core/HW/GBAPadEmu.h b/Source/Core/Core/HW/GBAPadEmu.h index ca42666b48c8..c9c38f1e5a13 100644 --- a/Source/Core/Core/HW/GBAPadEmu.h +++ b/Source/Core/Core/HW/GBAPadEmu.h @@ -29,6 +29,8 @@ class GBAPad : public ControllerEmu::EmulatedController std::string GetName() const override; + InputConfig* GetConfig() const override; + ControllerEmu::ControlGroup* GetGroup(GBAPadGroup group) const; void LoadDefaults(const ControllerInterface& ciface) override; diff --git a/Source/Core/Core/HW/GCKeyboardEmu.cpp b/Source/Core/Core/HW/GCKeyboardEmu.cpp index 9cb076785295..0146b942ab95 100644 --- a/Source/Core/Core/HW/GCKeyboardEmu.cpp +++ b/Source/Core/Core/HW/GCKeyboardEmu.cpp @@ -5,6 +5,9 @@ #include "Common/Common.h" #include "Common/CommonTypes.h" + +#include "Core/HW/GCKeyboard.h" + #include "InputCommon/ControllerEmu/Control/Input.h" #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" @@ -84,6 +87,11 @@ std::string GCKeyboard::GetName() const return std::string("GCKeyboard") + char('1' + m_index); } +InputConfig* GCKeyboard::GetConfig() const +{ + return Keyboard::GetConfig(); +} + ControllerEmu::ControlGroup* GCKeyboard::GetGroup(KeyboardGroup group) { switch (group) diff --git a/Source/Core/Core/HW/GCKeyboardEmu.h b/Source/Core/Core/HW/GCKeyboardEmu.h index 17ffe82baa4e..1f0f1986d446 100644 --- a/Source/Core/Core/HW/GCKeyboardEmu.h +++ b/Source/Core/Core/HW/GCKeyboardEmu.h @@ -31,6 +31,7 @@ class GCKeyboard : public ControllerEmu::EmulatedController explicit GCKeyboard(unsigned int index); KeyboardStatus GetInput() const; std::string GetName() const override; + InputConfig* GetConfig() const override; ControllerEmu::ControlGroup* GetGroup(KeyboardGroup group); void LoadDefaults(const ControllerInterface& ciface) override; diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp index 6dd0a8b37cff..fbbcbc630e6a 100644 --- a/Source/Core/Core/HW/GCPadEmu.cpp +++ b/Source/Core/Core/HW/GCPadEmu.cpp @@ -8,6 +8,8 @@ #include "Common/Common.h" #include "Common/CommonTypes.h" +#include "Core/HW/GCPad.h" + #include "InputCommon/ControllerEmu/Control/Input.h" #include "InputCommon/ControllerEmu/Control/Output.h" #include "InputCommon/ControllerEmu/ControlGroup/AnalogStick.h" @@ -15,7 +17,6 @@ #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h" #include "InputCommon/ControllerEmu/StickGate.h" - #include "InputCommon/GCPadStatus.h" static const u16 button_bitmasks[] = { @@ -95,6 +96,11 @@ std::string GCPad::GetName() const return std::string("GCPad") + char('1' + m_index); } +InputConfig* GCPad::GetConfig() const +{ + return Pad::GetConfig(); +} + ControllerEmu::ControlGroup* GCPad::GetGroup(PadGroup group) { switch (group) diff --git a/Source/Core/Core/HW/GCPadEmu.h b/Source/Core/Core/HW/GCPadEmu.h index 66a1aee4e496..2555ee05b179 100644 --- a/Source/Core/Core/HW/GCPadEmu.h +++ b/Source/Core/Core/HW/GCPadEmu.h @@ -43,6 +43,8 @@ class GCPad : public ControllerEmu::EmulatedController std::string GetName() const override; + InputConfig* GetConfig() const override; + ControllerEmu::ControlGroup* GetGroup(PadGroup group); void LoadDefaults(const ControllerInterface& ciface) override; diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.cpp b/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.cpp index f20beef7e328..fd2b18587276 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.cpp @@ -10,6 +10,7 @@ #include "Common/CommonTypes.h" #include "Common/Inline.h" +#include "Core/HW/Wiimote.h" #include "Core/HW/WiimoteEmu/Extension/DesiredExtensionState.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" @@ -36,6 +37,11 @@ std::string Extension::GetDisplayName() const return m_display_name; } +InputConfig* Extension::GetConfig() const +{ + return ::Wiimote::GetConfig(); +} + None::None() : Extension("None") { } diff --git a/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.h b/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.h index d05295227384..4a055c597db3 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.h +++ b/Source/Core/Core/HW/WiimoteEmu/Extension/Extension.h @@ -27,6 +27,8 @@ class Extension : public ControllerEmu::EmulatedController, public I2CSlave std::string GetName() const override; std::string GetDisplayName() const override; + InputConfig* GetConfig() const override; + // Used by the wiimote to detect extension changes. // The normal extensions short this pin so it's always connected, // but M+ does some tricks with it during activation. diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 3a63bd578155..59433f879817 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -324,6 +324,11 @@ std::string Wiimote::GetName() const return fmt::format("Wiimote{}", 1 + m_index); } +InputConfig* Wiimote::GetConfig() const +{ + return ::Wiimote::GetConfig(); +} + ControllerEmu::ControlGroup* Wiimote::GetWiimoteGroup(WiimoteGroup group) const { switch (group) diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index 116e393bf2d2..fcfad80fa71a 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -137,6 +137,9 @@ class Wiimote : public ControllerEmu::EmulatedController, public WiimoteCommon:: ~Wiimote(); std::string GetName() const override; + + InputConfig* GetConfig() const override; + void LoadDefaults(const ControllerInterface& ciface) override; ControllerEmu::ControlGroup* GetWiimoteGroup(WiimoteGroup group) const; diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp index adb6a2ea4940..668c500390c3 100644 --- a/Source/Core/Core/HotkeyManager.cpp +++ b/Source/Core/Core/HotkeyManager.cpp @@ -383,6 +383,11 @@ std::string HotkeyManager::GetName() const return "Hotkeys"; } +InputConfig* HotkeyManager::GetConfig() const +{ + return HotkeyManagerEmu::GetConfig(); +} + void HotkeyManager::GetInput(HotkeyStatus* kb, bool ignore_focus) { const auto lock = GetStateLock(); diff --git a/Source/Core/Core/HotkeyManager.h b/Source/Core/Core/HotkeyManager.h index f675fd1a10c2..aae894cb5b23 100644 --- a/Source/Core/Core/HotkeyManager.h +++ b/Source/Core/Core/HotkeyManager.h @@ -233,6 +233,7 @@ class HotkeyManager : public ControllerEmu::EmulatedController void GetInput(HotkeyStatus* hk, bool ignore_focus); std::string GetName() const override; + InputConfig* GetConfig() const override; ControllerEmu::ControlGroup* GetHotkeyGroup(HotkeyGroup group) const; int FindGroupByID(int id) const; int GetIndexForGroup(int group, int id) const; diff --git a/Source/Core/InputCommon/ControllerEmu/ControllerEmu.h b/Source/Core/InputCommon/ControllerEmu/ControllerEmu.h index 2f505622eb20..b77b2ce3ed9b 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControllerEmu.h +++ b/Source/Core/InputCommon/ControllerEmu/ControllerEmu.h @@ -19,6 +19,7 @@ #include "InputCommon/ControllerInterface/CoreDevice.h" class ControllerInterface; +class InputConfig; constexpr const char* DIRECTION_UP = _trans("Up"); constexpr const char* DIRECTION_DOWN = _trans("Down"); @@ -180,6 +181,8 @@ class EmulatedController virtual std::string GetName() const = 0; virtual std::string GetDisplayName() const; + virtual InputConfig* GetConfig() const = 0; + virtual void LoadDefaults(const ControllerInterface& ciface); virtual void LoadConfig(Common::IniFile::Section* sec, const std::string& base = "");