diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index 3b7838a814..e8efa523e6 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -100,9 +100,10 @@ public final class EmulationActivity extends AppCompatActivity MENU_ACTION_SAVE_SLOT6, MENU_ACTION_LOAD_SLOT1, MENU_ACTION_LOAD_SLOT2, MENU_ACTION_LOAD_SLOT3, MENU_ACTION_LOAD_SLOT4, MENU_ACTION_LOAD_SLOT5, MENU_ACTION_LOAD_SLOT6, MENU_ACTION_EXIT, MENU_ACTION_CHANGE_DISC, - MENU_ACTION_RESET_OVERLAY, MENU_SET_IR_SENSITIVITY, MENU_ACTION_CHOOSE_DOUBLETAP, - MENU_ACTION_MOTION_CONTROLS, MENU_ACTION_PAUSE_EMULATION, MENU_ACTION_UNPAUSE_EMULATION, - MENU_ACTION_OVERLAY_CONTROLS, MENU_ACTION_SETTINGS}) + MENU_ACTION_RESET_OVERLAY, MENU_SET_IR_RECENTER, MENU_SET_IR_MODE, + MENU_SET_IR_SENSITIVITY, MENU_ACTION_CHOOSE_DOUBLETAP, MENU_ACTION_MOTION_CONTROLS, + MENU_ACTION_PAUSE_EMULATION, MENU_ACTION_UNPAUSE_EMULATION, MENU_ACTION_OVERLAY_CONTROLS, + MENU_ACTION_SETTINGS}) public @interface MenuAction { } @@ -134,13 +135,15 @@ public final class EmulationActivity extends AppCompatActivity public static final int MENU_ACTION_JOYSTICK_REL_CENTER = 24; public static final int MENU_ACTION_RUMBLE = 25; public static final int MENU_ACTION_RESET_OVERLAY = 26; - public static final int MENU_SET_IR_SENSITIVITY = 27; - public static final int MENU_ACTION_CHOOSE_DOUBLETAP = 28; - public static final int MENU_ACTION_MOTION_CONTROLS = 29; - public static final int MENU_ACTION_PAUSE_EMULATION = 30; - public static final int MENU_ACTION_UNPAUSE_EMULATION = 31; - public static final int MENU_ACTION_OVERLAY_CONTROLS = 32; - public static final int MENU_ACTION_SETTINGS = 33; + public static final int MENU_SET_IR_RECENTER = 27; + public static final int MENU_SET_IR_MODE = 28; + public static final int MENU_SET_IR_SENSITIVITY = 29; + public static final int MENU_ACTION_CHOOSE_DOUBLETAP = 30; + public static final int MENU_ACTION_MOTION_CONTROLS = 31; + public static final int MENU_ACTION_PAUSE_EMULATION = 32; + public static final int MENU_ACTION_UNPAUSE_EMULATION = 33; + public static final int MENU_ACTION_OVERLAY_CONTROLS = 34; + public static final int MENU_ACTION_SETTINGS = 35; private static final SparseIntArray buttonsActionsMap = new SparseIntArray(); @@ -159,6 +162,10 @@ public final class EmulationActivity extends AppCompatActivity buttonsActionsMap.append(R.id.menu_emulation_rumble, EmulationActivity.MENU_ACTION_RUMBLE); buttonsActionsMap .append(R.id.menu_emulation_reset_overlay, EmulationActivity.MENU_ACTION_RESET_OVERLAY); + buttonsActionsMap.append(R.id.menu_emulation_ir_recenter, + EmulationActivity.MENU_SET_IR_RECENTER); + buttonsActionsMap.append(R.id.menu_emulation_set_ir_mode, + EmulationActivity.MENU_SET_IR_MODE); buttonsActionsMap.append(R.id.menu_emulation_set_ir_sensitivity, EmulationActivity.MENU_SET_IR_SENSITIVITY); buttonsActionsMap.append(R.id.menu_emulation_choose_doubletap, @@ -512,6 +519,11 @@ public final class EmulationActivity extends AppCompatActivity .setChecked(BooleanSetting.MAIN_JOYSTICK_REL_CENTER.getBoolean(mSettings)); menu.findItem(R.id.menu_emulation_rumble) .setChecked(BooleanSetting.MAIN_PHONE_RUMBLE.getBoolean(mSettings)); + if (wii) + { + menu.findItem(R.id.menu_emulation_ir_recenter) + .setChecked(BooleanSetting.MAIN_IR_ALWAYS_RECENTER.getBoolean(mSettings)); + } popup.setOnMenuItemClickListener(this::onOptionsItemSelected); @@ -550,6 +562,10 @@ public final class EmulationActivity extends AppCompatActivity item.setChecked(!item.isChecked()); toggleRumble(item.isChecked()); break; + case MENU_SET_IR_RECENTER: + item.setChecked(!item.isChecked()); + toggleRecenter(item.isChecked()); + break; } } @@ -676,6 +692,10 @@ public final class EmulationActivity extends AppCompatActivity startActivityForResult(intent, REQUEST_CHANGE_DISC); break; + case MENU_SET_IR_MODE: + setIRMode(); + break; + case MENU_SET_IR_SENSITIVITY: setIRSensitivity(); break; @@ -724,6 +744,12 @@ public final class EmulationActivity extends AppCompatActivity Rumble.setPhoneVibrator(state, this); } + private void toggleRecenter(boolean state) + { + BooleanSetting.MAIN_IR_ALWAYS_RECENTER.setBoolean(mSettings, state); + mEmulationFragment.refreshOverlayPointer(mSettings); + } + private void editControlsPlacement() { if (mEmulationFragment.isConfiguringControls()) @@ -971,6 +997,20 @@ public final class EmulationActivity extends AppCompatActivity builder.show(); } + private void setIRMode() + { + AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.DolphinDialogBase); + builder.setTitle(R.string.emulation_ir_mode); + builder.setSingleChoiceItems(R.array.irModeEntries, + IntSetting.MAIN_IR_MODE.getInt(mSettings), + (dialog, indexSelected) -> + IntSetting.MAIN_IR_MODE.setInt(mSettings, indexSelected)); + builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> + mEmulationFragment.refreshOverlayPointer(mSettings)); + + builder.show(); + } + private void setIRSensitivity() { // IR settings always get saved per-game since WiimoteNew.ini is wiped upon reinstall. diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java index 2f93288884..a7c47a03ad 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java @@ -71,6 +71,8 @@ public enum BooleanSetting implements AbstractBooleanSetting "PhoneRumble", true), MAIN_SHOW_INPUT_OVERLAY(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "ShowInputOverlay", true), + MAIN_IR_ALWAYS_RECENTER(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, + "IRAlwaysRecenter", false), MAIN_BUTTON_TOGGLE_GC_0(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS, "ButtonToggleGCButtonA", true), diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java index 152609d3b8..d28603cbef 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java @@ -30,6 +30,8 @@ public enum IntSetting implements AbstractIntSetting "EmulationOrientation", ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE), MAIN_LAST_PLATFORM_TAB(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "LastPlatformTab", 0), MAIN_MOTION_CONTROLS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "MotionControls", 1), + MAIN_IR_MODE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "IRMode", + InputOverlayPointer.MODE_FOLLOW), MAIN_DOUBLE_TAP_BUTTON(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS, "DoubleTapButton", diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java index 01d6ab6719..3f5c1de39f 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java @@ -166,6 +166,12 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C mInputOverlay.refreshControls(); } + public void refreshOverlayPointer(Settings settings) + { + if (mInputOverlay != null) + mInputOverlay.refreshOverlayPointer(settings); + } + public void resetInputOverlay() { if (mInputOverlay != null) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java index 5b3b232af4..c627603900 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java @@ -164,7 +164,9 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener doubleTapButton = InputOverlayPointer.DOUBLE_TAP_A; } - overlayPointer = new InputOverlayPointer(mSurfacePosition, doubleTapButton); + overlayPointer = new InputOverlayPointer(mSurfacePosition, doubleTapButton, + IntSetting.MAIN_IR_MODE.getIntGlobal(), + BooleanSetting.MAIN_IR_ALWAYS_RECENTER.getBooleanGlobal()); } @Override @@ -769,6 +771,15 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener invalidate(); } + public void refreshOverlayPointer(Settings settings) + { + if (overlayPointer != null) + { + overlayPointer.setMode(IntSetting.MAIN_IR_MODE.getInt(settings)); + overlayPointer.setRecenter(BooleanSetting.MAIN_IR_ALWAYS_RECENTER.getBoolean(settings)); + } + } + public void resetButtonPlacement() { boolean isLandscape = diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java index 6ad9c29ca3..c592dbfcd0 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java @@ -17,13 +17,24 @@ public class InputOverlayPointer public static final int DOUBLE_TAP_2 = 2; public static final int DOUBLE_TAP_CLASSIC_A = 3; + public static final int MODE_DISABLED = 0; + public static final int MODE_FOLLOW = 1; + public static final int MODE_DRAG = 2; + private final float[] axes = {0f, 0f}; + private final float[] oldaxes = {0f, 0f}; private float mGameCenterX; private float mGameCenterY; private float mGameWidthHalfInv; private float mGameHeightHalfInv; + private float mTouchStartX; + private float mTouchStartY; + + private int mMode; + private boolean mRecenter; + private boolean doubleTap = false; private int doubleTapButton; private int trackId = -1; @@ -38,9 +49,11 @@ public class InputOverlayPointer DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.CLASSIC_BUTTON_A); } - public InputOverlayPointer(Rect surfacePosition, int button) + public InputOverlayPointer(Rect surfacePosition, int button, int mode, boolean recenter) { doubleTapButton = button; + mMode = mode; + mRecenter = recenter; mGameCenterX = (surfacePosition.left + surfacePosition.right) / 2.0f; mGameCenterY = (surfacePosition.top + surfacePosition.bottom) / 2.0f; @@ -76,38 +89,69 @@ public class InputOverlayPointer case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: trackId = event.getPointerId(pointerIndex); + mTouchStartX = event.getX(pointerIndex); + mTouchStartY = event.getY(pointerIndex); touchPress(); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: if (trackId == event.getPointerId(pointerIndex)) trackId = -1; + if (mMode == MODE_DRAG) + updateOldAxes(); + if (mRecenter) + reset(); break; } if (trackId == -1) return; - axes[0] = (event.getY(event.findPointerIndex(trackId)) - mGameCenterY) * mGameHeightHalfInv; - axes[1] = (event.getX(event.findPointerIndex(trackId)) - mGameCenterX) * mGameWidthHalfInv; + if (mMode == MODE_FOLLOW) + { + axes[0] = (event.getY(event.findPointerIndex(trackId)) - mGameCenterY) * mGameHeightHalfInv; + axes[1] = (event.getX(event.findPointerIndex(trackId)) - mGameCenterX) * mGameWidthHalfInv; + } + else if (mMode == MODE_DRAG) + { + axes[0] = oldaxes[0] + + (event.getY(event.findPointerIndex(trackId)) - mTouchStartY) * mGameHeightHalfInv; + axes[1] = oldaxes[1] + + (event.getX(event.findPointerIndex(trackId)) - mTouchStartX) * mGameWidthHalfInv; + } } private void touchPress() { - if (doubleTap) + if (mMode != MODE_DISABLED) { - NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, - doubleTapButton, NativeLibrary.ButtonState.PRESSED); - new Handler().postDelayed(() -> NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, - doubleTapButton, NativeLibrary.ButtonState.RELEASED), 50); - } - else - { - doubleTap = true; - new Handler().postDelayed(() -> doubleTap = false, 300); + if (doubleTap) + { + NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, + doubleTapButton, NativeLibrary.ButtonState.PRESSED); + new Handler() + .postDelayed(() -> NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, + doubleTapButton, NativeLibrary.ButtonState.RELEASED), 50); + } + else + { + doubleTap = true; + new Handler().postDelayed(() -> doubleTap = false, 300); + } } } + private void updateOldAxes() + { + oldaxes[0] = axes[0]; + oldaxes[1] = axes[1]; + } + + private void reset() + { + axes[0] = axes[1] = oldaxes[0] = oldaxes[1] = 0f; + } + public float[] getAxisValues() { float[] iraxes = {0f, 0f, 0f, 0f}; @@ -117,4 +161,16 @@ public class InputOverlayPointer iraxes[2] = axes[1]; return iraxes; } + + public void setMode(int mode) + { + mMode = mode; + if (mode == MODE_DRAG) + updateOldAxes(); + } + + public void setRecenter(boolean recenter) + { + mRecenter = recenter; + } } diff --git a/Source/Android/app/src/main/res/menu/menu_overlay_controls_wii.xml b/Source/Android/app/src/main/res/menu/menu_overlay_controls_wii.xml index 2d1148aa2a..e5182f6ffe 100644 --- a/Source/Android/app/src/main/res/menu/menu_overlay_controls_wii.xml +++ b/Source/Android/app/src/main/res/menu/menu_overlay_controls_wii.xml @@ -38,6 +38,13 @@ android:id="@+id/menu_emulation_ir_group" android:title="@string/emulation_ir_group">