diff options
| author | JosJuice <josjuice@gmail.com> | 2022-08-14 11:32:22 +0200 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2023-03-03 22:28:24 +0100 |
| commit | 2b1dd52750c8c85796be4a6785fb769481ec191c (patch) | |
| tree | 770cc4cde9fc96414ecb57c6bd68c0f2e6caf91e /Source/Android/app/src/main/java | |
| parent | 2113bf5e3afface4acd072f677c620c60bd6edde (diff) | |
Android: Add input device selection
Diffstat (limited to 'Source/Android/app/src/main/java')
12 files changed, 149 insertions, 18 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.java index 0d6a078b4e..b2535465e8 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/ControllerInterface.java @@ -95,6 +95,8 @@ public final class ControllerInterface */ public static native void refreshDevices(); + public static native String[] getAllDeviceStrings(); + @Keep private static void registerInputDeviceListener() { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/MappingCommon.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/MappingCommon.java index cb136a908d..b0dc489fec 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/MappingCommon.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/MappingCommon.java @@ -2,6 +2,10 @@ package org.dolphinemu.dolphinemu.features.input.model; +import androidx.annotation.NonNull; + +import org.dolphinemu.dolphinemu.features.input.model.controlleremu.EmulatedController; + public final class MappingCommon { private MappingCommon() @@ -15,10 +19,13 @@ public final class MappingCommon * When this is being called, a separate thread must be calling ControllerInterface's * dispatchKeyEvent and dispatchGenericMotionEvent, otherwise no inputs will be registered. * + * @param controller The device to detect inputs from. + * @param allDevices Whether to also detect inputs from devices other than the specified one. * @return The input(s) pressed by the user in the form of an InputCommon expression, * or an empty string if there were no inputs. */ - public static native String detectInput(); + public static native String detectInput(@NonNull EmulatedController controller, + boolean allDevices); public static native void save(); } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/controlleremu/EmulatedController.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/controlleremu/EmulatedController.java index b0fbd0fd92..5a5793f530 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/controlleremu/EmulatedController.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/controlleremu/EmulatedController.java @@ -21,6 +21,10 @@ public class EmulatedController mPointer = pointer; } + public native String getDefaultDevice(); + + public native void setDefaultDevice(String device); + public native int getGroupCount(); public native ControlGroup getGroup(int index); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/view/InputDeviceSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/view/InputDeviceSetting.java new file mode 100644 index 0000000000..2462e867d3 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/view/InputDeviceSetting.java @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.input.model.view; + +import android.content.Context; + +import org.dolphinemu.dolphinemu.features.input.model.ControllerInterface; +import org.dolphinemu.dolphinemu.features.input.model.controlleremu.EmulatedController; +import org.dolphinemu.dolphinemu.features.settings.model.Settings; +import org.dolphinemu.dolphinemu.features.settings.model.view.StringSingleChoiceSetting; + +public class InputDeviceSetting extends StringSingleChoiceSetting +{ + private final EmulatedController mController; + + public InputDeviceSetting(Context context, int titleId, int descriptionId, + EmulatedController controller) + { + super(context, null, titleId, descriptionId, null, null, null); + + mController = controller; + + refreshChoicesAndValues(); + } + + @Override + public String getSelectedChoice(Settings settings) + { + return mController.getDefaultDevice(); + } + + @Override + public String getSelectedValue(Settings settings) + { + return mController.getDefaultDevice(); + } + + @Override + public void setSelectedValue(Settings settings, String newValue) + { + mController.setDefaultDevice(newValue); + } + + @Override + public void refreshChoicesAndValues() + { + String[] devices = ControllerInterface.getAllDeviceStrings(); + + mChoices = devices; + mValues = devices; + } + + @Override + public boolean canClear() + { + return true; + } + + @Override + public void clear(Settings settings) + { + setSelectedValue(settings, ""); + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/view/InputMappingControlSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/view/InputMappingControlSetting.java index 8888e2430b..a858b35099 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/view/InputMappingControlSetting.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/model/view/InputMappingControlSetting.java @@ -47,4 +47,9 @@ public final class InputMappingControlSetting extends SettingsItem { return null; } + + public EmulatedController getController() + { + return mController; + } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/MotionAlertDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/MotionAlertDialog.java index f36d9bc478..0a4afc7acf 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/MotionAlertDialog.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/MotionAlertDialog.java @@ -46,7 +46,7 @@ public final class MotionAlertDialog extends AlertDialog mRunning = true; new Thread(() -> { - String result = MappingCommon.detectInput(); + String result = MappingCommon.detectInput(mSetting.getController(), false); mActivity.runOnUiThread(() -> { if (mRunning) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java index 9c7b89c12f..6f06677be3 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java @@ -95,6 +95,11 @@ public abstract class SettingsItem return getSetting() != null; } + public boolean canClear() + { + return hasSetting(); + } + public void clear(Settings settings) { getSetting().delete(settings); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/StringSingleChoiceSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/StringSingleChoiceSetting.java index df7ee6f4e9..70463f216b 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/StringSingleChoiceSetting.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/StringSingleChoiceSetting.java @@ -14,8 +14,8 @@ public class StringSingleChoiceSetting extends SettingsItem { private AbstractStringSetting mSetting; - private String[] mChoices; - private String[] mValues; + protected String[] mChoices; + protected String[] mValues; private MenuTag mMenuTag; public StringSingleChoiceSetting(Context context, AbstractStringSetting setting, int titleId, @@ -60,6 +60,19 @@ public class StringSingleChoiceSetting extends SettingsItem return mValues; } + public String getChoiceAt(int index) + { + if (mChoices == null) + return null; + + if (index >= 0 && index < mChoices.length) + { + return mChoices[index]; + } + + return ""; + } + public String getValueAt(int index) { if (mValues == null) @@ -73,6 +86,11 @@ public class StringSingleChoiceSetting extends SettingsItem return ""; } + public String getSelectedChoice(Settings settings) + { + return getChoiceAt(getSelectedValueIndex(settings)); + } + public String getSelectedValue(Settings settings) { return mSetting.getString(settings); @@ -102,6 +120,10 @@ public class StringSingleChoiceSetting extends SettingsItem mSetting.setString(settings, selection); } + public void refreshChoicesAndValues() + { + } + @Override public int getType() { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java index 8fe3fe4602..cd2d047ecb 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java @@ -253,6 +253,8 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde mClickedItem = item; mClickedPosition = position; + item.refreshChoicesAndValues(); + mDialog = new MaterialAlertDialogBuilder(mView.getActivity()) .setTitle(item.getName()) .setSingleChoiceItems(item.getChoices(), item.getSelectedValueIndex(getSettings()), diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java index 8ace1df30b..c0540cefed 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java @@ -22,6 +22,7 @@ import org.dolphinemu.dolphinemu.features.input.model.controlleremu.ControlGroup import org.dolphinemu.dolphinemu.features.input.model.ControlGroupEnabledSetting; 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.view.InputDeviceSetting; import org.dolphinemu.dolphinemu.features.input.model.view.InputMappingControlSetting; import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting; import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting; @@ -1107,7 +1108,10 @@ public final class SettingsFragmentPresenter { if (gcPadType == 6) // Emulated { - addControllerSettings(sl, EmulatedController.getGcPad(gcPadNumber), null); + EmulatedController gcPad = EmulatedController.getGcPad(gcPadNumber); + + addControllerMetaSettings(sl, gcPad); + addControllerMappingSettings(sl, gcPad, null); } else if (gcPadType == 12) // Adapter { @@ -1120,6 +1124,10 @@ public final class SettingsFragmentPresenter private void addWiimoteSubSettings(ArrayList<SettingsItem> sl, int wiimoteNumber) { + EmulatedController wiimote = EmulatedController.getWiimote(wiimoteNumber); + + addControllerMetaSettings(sl, wiimote); + sl.add(new HeaderSetting(mContext, R.string.wiimote, 0)); sl.add(new SubmenuSetting(mContext, R.string.wiimote_general, MenuTag.getWiimoteGeneralMenuTag(wiimoteNumber))); @@ -1130,44 +1138,58 @@ public final class SettingsFragmentPresenter // TYPE_OTHER is included here instead of in addWiimoteGeneralSubSettings so that touchscreen // users won't have to dig into a submenu to find the Sideways Wii Remote setting - addControllerSettings(sl, EmulatedController.getWiimote(wiimoteNumber), + addControllerMappingSettings(sl, wiimote, new ArraySet<>(Arrays.asList(ControlGroup.TYPE_ATTACHMENTS, ControlGroup.TYPE_OTHER))); } private void addExtensionTypeSettings(ArrayList<SettingsItem> sl, int wiimoteNumber, int extensionType) { - addControllerSettings(sl, + addControllerMappingSettings(sl, EmulatedController.getWiimoteAttachment(wiimoteNumber, extensionType), null); } private void addWiimoteGeneralSubSettings(ArrayList<SettingsItem> sl, int wiimoteNumber) { - addControllerSettings(sl, EmulatedController.getWiimote(wiimoteNumber), + addControllerMappingSettings(sl, EmulatedController.getWiimote(wiimoteNumber), Collections.singleton(ControlGroup.TYPE_BUTTONS)); } private void addWiimoteMotionSimulationSubSettings(ArrayList<SettingsItem> sl, int wiimoteNumber) { - addControllerSettings(sl, EmulatedController.getWiimote(wiimoteNumber), + addControllerMappingSettings(sl, EmulatedController.getWiimote(wiimoteNumber), new ArraySet<>(Arrays.asList(ControlGroup.TYPE_FORCE, ControlGroup.TYPE_TILT, ControlGroup.TYPE_CURSOR, ControlGroup.TYPE_SHAKE))); } private void addWiimoteMotionInputSubSettings(ArrayList<SettingsItem> sl, int wiimoteNumber) { - addControllerSettings(sl, EmulatedController.getWiimote(wiimoteNumber), + addControllerMappingSettings(sl, EmulatedController.getWiimote(wiimoteNumber), new ArraySet<>(Arrays.asList(ControlGroup.TYPE_IMU_ACCELEROMETER, ControlGroup.TYPE_IMU_GYROSCOPE, ControlGroup.TYPE_IMU_CURSOR))); } /** - * @param sl The list to place controller settings into. + * Adds settings and actions that apply to a controller as a whole. + * For instance, the device setting and the Clear action. + * + * @param sl The list to place controller settings into. * @param controller The controller to add settings for. + */ + private void addControllerMetaSettings(ArrayList<SettingsItem> sl, EmulatedController controller) + { + sl.add(new InputDeviceSetting(mContext, R.string.input_device, 0, controller)); + } + + /** + * Adds mapping settings and other control-specific settings. + * + * @param sl The list to place controller settings into. + * @param controller The controller to add settings for. * @param groupTypeFilter If this is non-null, only groups whose types match this are considered. */ - private void addControllerSettings(ArrayList<SettingsItem> sl, EmulatedController controller, - Set<Integer> groupTypeFilter) + private void addControllerMappingSettings(ArrayList<SettingsItem> sl, + EmulatedController controller, Set<Integer> groupTypeFilter) { int groupCount = controller.getGroupCount(); for (int i = 0; i < groupCount; i++) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java index d34e4a1536..18fd466461 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java @@ -83,7 +83,7 @@ public abstract class SettingViewHolder extends RecyclerView.ViewHolder { SettingsItem item = getItem(); - if (item == null || !item.hasSetting()) + if (item == null || !item.canClear()) return false; if (!item.isEditable()) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java index db56ebea40..beb15867c5 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java @@ -64,10 +64,8 @@ public final class SingleChoiceViewHolder extends SettingViewHolder else if (item instanceof StringSingleChoiceSetting) { StringSingleChoiceSetting setting = (StringSingleChoiceSetting) item; - String[] choices = setting.getChoices(); - int valueIndex = setting.getSelectedValueIndex(settings); - if (valueIndex != -1) - mBinding.textSettingDescription.setText(choices[valueIndex]); + String choice = setting.getSelectedChoice(settings); + mBinding.textSettingDescription.setText(choice); } else if (item instanceof SingleChoiceSettingDynamicDescriptions) { |
