mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-27 09:51:23 +02:00
Android: add IR pointer modes to InputOverlayPointer
* Disabled: disables the overlay pointer * Follow: default behaviour, IR pointer follows touch position * Drag: IR pointer moves relative to the initial touch event position
This commit is contained in:
parent
e8bbfc26fe
commit
fe9ac4ed1d
@ -9,7 +9,6 @@ import android.content.SharedPreferences;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
import android.view.InputDevice;
|
import android.view.InputDevice;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@ -99,9 +98,9 @@ public final class EmulationActivity extends AppCompatActivity
|
|||||||
MENU_ACTION_SAVE_SLOT6, MENU_ACTION_LOAD_SLOT1, MENU_ACTION_LOAD_SLOT2,
|
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_SLOT3, MENU_ACTION_LOAD_SLOT4, MENU_ACTION_LOAD_SLOT5,
|
||||||
MENU_ACTION_LOAD_SLOT6, MENU_ACTION_EXIT, MENU_ACTION_CHANGE_DISC,
|
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_RESET_OVERLAY, MENU_SET_IR_MODE, MENU_SET_IR_SENSITIVITY,
|
||||||
MENU_ACTION_MOTION_CONTROLS, MENU_ACTION_PAUSE_EMULATION, MENU_ACTION_UNPAUSE_EMULATION,
|
MENU_ACTION_CHOOSE_DOUBLETAP, MENU_ACTION_MOTION_CONTROLS, MENU_ACTION_PAUSE_EMULATION,
|
||||||
MENU_ACTION_OVERLAY_CONTROLS, MENU_ACTION_SETTINGS})
|
MENU_ACTION_UNPAUSE_EMULATION, MENU_ACTION_OVERLAY_CONTROLS, MENU_ACTION_SETTINGS})
|
||||||
public @interface MenuAction
|
public @interface MenuAction
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -133,13 +132,14 @@ public final class EmulationActivity extends AppCompatActivity
|
|||||||
public static final int MENU_ACTION_JOYSTICK_REL_CENTER = 24;
|
public static final int MENU_ACTION_JOYSTICK_REL_CENTER = 24;
|
||||||
public static final int MENU_ACTION_RUMBLE = 25;
|
public static final int MENU_ACTION_RUMBLE = 25;
|
||||||
public static final int MENU_ACTION_RESET_OVERLAY = 26;
|
public static final int MENU_ACTION_RESET_OVERLAY = 26;
|
||||||
public static final int MENU_SET_IR_SENSITIVITY = 27;
|
public static final int MENU_SET_IR_MODE = 27;
|
||||||
public static final int MENU_ACTION_CHOOSE_DOUBLETAP = 28;
|
public static final int MENU_SET_IR_SENSITIVITY = 28;
|
||||||
public static final int MENU_ACTION_MOTION_CONTROLS = 29;
|
public static final int MENU_ACTION_CHOOSE_DOUBLETAP = 29;
|
||||||
public static final int MENU_ACTION_PAUSE_EMULATION = 30;
|
public static final int MENU_ACTION_MOTION_CONTROLS = 30;
|
||||||
public static final int MENU_ACTION_UNPAUSE_EMULATION = 31;
|
public static final int MENU_ACTION_PAUSE_EMULATION = 31;
|
||||||
public static final int MENU_ACTION_OVERLAY_CONTROLS = 32;
|
public static final int MENU_ACTION_UNPAUSE_EMULATION = 32;
|
||||||
public static final int MENU_ACTION_SETTINGS = 33;
|
public static final int MENU_ACTION_OVERLAY_CONTROLS = 33;
|
||||||
|
public static final int MENU_ACTION_SETTINGS = 34;
|
||||||
|
|
||||||
private static final SparseIntArray buttonsActionsMap = new SparseIntArray();
|
private static final SparseIntArray buttonsActionsMap = new SparseIntArray();
|
||||||
|
|
||||||
@ -158,6 +158,8 @@ public final class EmulationActivity extends AppCompatActivity
|
|||||||
buttonsActionsMap.append(R.id.menu_emulation_rumble, EmulationActivity.MENU_ACTION_RUMBLE);
|
buttonsActionsMap.append(R.id.menu_emulation_rumble, EmulationActivity.MENU_ACTION_RUMBLE);
|
||||||
buttonsActionsMap
|
buttonsActionsMap
|
||||||
.append(R.id.menu_emulation_reset_overlay, EmulationActivity.MENU_ACTION_RESET_OVERLAY);
|
.append(R.id.menu_emulation_reset_overlay, EmulationActivity.MENU_ACTION_RESET_OVERLAY);
|
||||||
|
buttonsActionsMap.append(R.id.menu_emulation_set_ir_mode,
|
||||||
|
EmulationActivity.MENU_SET_IR_MODE);
|
||||||
buttonsActionsMap.append(R.id.menu_emulation_set_ir_sensitivity,
|
buttonsActionsMap.append(R.id.menu_emulation_set_ir_sensitivity,
|
||||||
EmulationActivity.MENU_SET_IR_SENSITIVITY);
|
EmulationActivity.MENU_SET_IR_SENSITIVITY);
|
||||||
buttonsActionsMap.append(R.id.menu_emulation_choose_doubletap,
|
buttonsActionsMap.append(R.id.menu_emulation_choose_doubletap,
|
||||||
@ -644,6 +646,10 @@ public final class EmulationActivity extends AppCompatActivity
|
|||||||
startActivityForResult(intent, REQUEST_CHANGE_DISC);
|
startActivityForResult(intent, REQUEST_CHANGE_DISC);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MENU_SET_IR_MODE:
|
||||||
|
setIRMode();
|
||||||
|
break;
|
||||||
|
|
||||||
case MENU_SET_IR_SENSITIVITY:
|
case MENU_SET_IR_SENSITIVITY:
|
||||||
setIRSensitivity();
|
setIRSensitivity();
|
||||||
break;
|
break;
|
||||||
@ -939,6 +945,20 @@ public final class EmulationActivity extends AppCompatActivity
|
|||||||
builder.show();
|
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()
|
private void setIRSensitivity()
|
||||||
{
|
{
|
||||||
// IR settings always get saved per-game since WiimoteNew.ini is wiped upon reinstall.
|
// IR settings always get saved per-game since WiimoteNew.ini is wiped upon reinstall.
|
||||||
|
@ -30,6 +30,8 @@ public enum IntSetting implements AbstractIntSetting
|
|||||||
"EmulationOrientation", ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE),
|
"EmulationOrientation", ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE),
|
||||||
MAIN_LAST_PLATFORM_TAB(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "LastPlatformTab", 0),
|
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_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,
|
MAIN_DOUBLE_TAP_BUTTON(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||||
"DoubleTapButton",
|
"DoubleTapButton",
|
||||||
|
@ -162,6 +162,12 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
|||||||
mInputOverlay.refreshControls();
|
mInputOverlay.refreshControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void refreshOverlayPointer(Settings settings)
|
||||||
|
{
|
||||||
|
if (mInputOverlay != null)
|
||||||
|
mInputOverlay.refreshOverlayPointer(settings);
|
||||||
|
}
|
||||||
|
|
||||||
public void resetInputOverlay()
|
public void resetInputOverlay()
|
||||||
{
|
{
|
||||||
if (mInputOverlay != null)
|
if (mInputOverlay != null)
|
||||||
|
@ -164,7 +164,8 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
|||||||
doubleTapButton = InputOverlayPointer.DOUBLE_TAP_A;
|
doubleTapButton = InputOverlayPointer.DOUBLE_TAP_A;
|
||||||
}
|
}
|
||||||
|
|
||||||
overlayPointer = new InputOverlayPointer(mSurfacePosition, doubleTapButton);
|
overlayPointer = new InputOverlayPointer(mSurfacePosition, doubleTapButton,
|
||||||
|
IntSetting.MAIN_IR_MODE.getIntGlobal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -769,6 +770,14 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
|||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void refreshOverlayPointer(Settings settings)
|
||||||
|
{
|
||||||
|
if (overlayPointer != null)
|
||||||
|
{
|
||||||
|
overlayPointer.setMode(IntSetting.MAIN_IR_MODE.getInt(settings));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void resetButtonPlacement()
|
public void resetButtonPlacement()
|
||||||
{
|
{
|
||||||
boolean isLandscape =
|
boolean isLandscape =
|
||||||
|
@ -17,13 +17,23 @@ public class InputOverlayPointer
|
|||||||
public static final int DOUBLE_TAP_2 = 2;
|
public static final int DOUBLE_TAP_2 = 2;
|
||||||
public static final int DOUBLE_TAP_CLASSIC_A = 3;
|
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[] axes = {0f, 0f};
|
||||||
|
private final float[] oldaxes = {0f, 0f};
|
||||||
|
|
||||||
private float mGameCenterX;
|
private float mGameCenterX;
|
||||||
private float mGameCenterY;
|
private float mGameCenterY;
|
||||||
private float mGameWidthHalfInv;
|
private float mGameWidthHalfInv;
|
||||||
private float mGameHeightHalfInv;
|
private float mGameHeightHalfInv;
|
||||||
|
|
||||||
|
private float mTouchStartX;
|
||||||
|
private float mTouchStartY;
|
||||||
|
|
||||||
|
private int mMode;
|
||||||
|
|
||||||
private boolean doubleTap = false;
|
private boolean doubleTap = false;
|
||||||
private int doubleTapButton;
|
private int doubleTapButton;
|
||||||
private int trackId = -1;
|
private int trackId = -1;
|
||||||
@ -38,9 +48,10 @@ public class InputOverlayPointer
|
|||||||
DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.CLASSIC_BUTTON_A);
|
DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.CLASSIC_BUTTON_A);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputOverlayPointer(Rect surfacePosition, int button)
|
public InputOverlayPointer(Rect surfacePosition, int button, int mode)
|
||||||
{
|
{
|
||||||
doubleTapButton = button;
|
doubleTapButton = button;
|
||||||
|
mMode = mode;
|
||||||
|
|
||||||
mGameCenterX = (surfacePosition.left + surfacePosition.right) / 2.0f;
|
mGameCenterX = (surfacePosition.left + surfacePosition.right) / 2.0f;
|
||||||
mGameCenterY = (surfacePosition.top + surfacePosition.bottom) / 2.0f;
|
mGameCenterY = (surfacePosition.top + surfacePosition.bottom) / 2.0f;
|
||||||
@ -76,38 +87,62 @@ public class InputOverlayPointer
|
|||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
case MotionEvent.ACTION_POINTER_DOWN:
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
trackId = event.getPointerId(pointerIndex);
|
trackId = event.getPointerId(pointerIndex);
|
||||||
|
mTouchStartX = event.getX(pointerIndex);
|
||||||
|
mTouchStartY = event.getY(pointerIndex);
|
||||||
touchPress();
|
touchPress();
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
case MotionEvent.ACTION_POINTER_UP:
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
if (trackId == event.getPointerId(pointerIndex))
|
if (trackId == event.getPointerId(pointerIndex))
|
||||||
trackId = -1;
|
trackId = -1;
|
||||||
|
if (mMode == MODE_DRAG)
|
||||||
|
updateOldAxes();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trackId == -1)
|
if (trackId == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
axes[0] = (event.getY(event.findPointerIndex(trackId)) - mGameCenterY) * mGameHeightHalfInv;
|
if (mMode == MODE_FOLLOW)
|
||||||
axes[1] = (event.getX(event.findPointerIndex(trackId)) - mGameCenterX) * mGameWidthHalfInv;
|
{
|
||||||
|
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()
|
private void touchPress()
|
||||||
{
|
{
|
||||||
if (doubleTap)
|
if (mMode != MODE_DISABLED)
|
||||||
{
|
{
|
||||||
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice,
|
if (doubleTap)
|
||||||
doubleTapButton, NativeLibrary.ButtonState.PRESSED);
|
{
|
||||||
new Handler().postDelayed(() -> NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice,
|
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice,
|
||||||
doubleTapButton, NativeLibrary.ButtonState.RELEASED), 50);
|
doubleTapButton, NativeLibrary.ButtonState.PRESSED);
|
||||||
}
|
new Handler()
|
||||||
else
|
.postDelayed(() -> NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice,
|
||||||
{
|
doubleTapButton, NativeLibrary.ButtonState.RELEASED), 50);
|
||||||
doubleTap = true;
|
}
|
||||||
new Handler().postDelayed(() -> doubleTap = false, 300);
|
else
|
||||||
|
{
|
||||||
|
doubleTap = true;
|
||||||
|
new Handler().postDelayed(() -> doubleTap = false, 300);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateOldAxes()
|
||||||
|
{
|
||||||
|
oldaxes[0] = axes[0];
|
||||||
|
oldaxes[1] = axes[1];
|
||||||
|
}
|
||||||
|
|
||||||
public float[] getAxisValues()
|
public float[] getAxisValues()
|
||||||
{
|
{
|
||||||
float[] iraxes = {0f, 0f, 0f, 0f};
|
float[] iraxes = {0f, 0f, 0f, 0f};
|
||||||
@ -117,4 +152,11 @@ public class InputOverlayPointer
|
|||||||
iraxes[2] = axes[1];
|
iraxes[2] = axes[1];
|
||||||
return iraxes;
|
return iraxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMode(int mode)
|
||||||
|
{
|
||||||
|
mMode = mode;
|
||||||
|
if (mode == MODE_DRAG)
|
||||||
|
updateOldAxes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,9 @@
|
|||||||
android:id="@+id/menu_emulation_ir_group"
|
android:id="@+id/menu_emulation_ir_group"
|
||||||
android:title="@string/emulation_ir_group">
|
android:title="@string/emulation_ir_group">
|
||||||
<menu>
|
<menu>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_emulation_set_ir_mode"
|
||||||
|
android:title="@string/emulation_ir_mode"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_emulation_set_ir_sensitivity"
|
android:id="@+id/menu_emulation_set_ir_sensitivity"
|
||||||
android:title="@string/emulation_ir_sensitivity"/>
|
android:title="@string/emulation_ir_sensitivity"/>
|
||||||
|
@ -433,6 +433,12 @@
|
|||||||
<item>Right Stick</item>
|
<item>Right Stick</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="irModeEntries">
|
||||||
|
<item>Disabled</item>
|
||||||
|
<item>Follow</item>
|
||||||
|
<item>Drag</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="doubleTap">
|
<string-array name="doubleTap">
|
||||||
<item>Button A</item>
|
<item>Button A</item>
|
||||||
<item>Button B</item>
|
<item>Button B</item>
|
||||||
|
@ -517,6 +517,7 @@ It can efficiently compress both junk data and encrypted Wii data.
|
|||||||
<string name="emulation_menu_help">Press Back to access the menu.\nLong press Back to exit emulation.</string>
|
<string name="emulation_menu_help">Press Back to access the menu.\nLong press Back to exit emulation.</string>
|
||||||
<string name="emulation_touch_overlay_reset">Reset Overlay</string>
|
<string name="emulation_touch_overlay_reset">Reset Overlay</string>
|
||||||
<string name="emulation_ir_group">Touch IR Pointer</string>
|
<string name="emulation_ir_group">Touch IR Pointer</string>
|
||||||
|
<string name="emulation_ir_mode">IR Mode</string>
|
||||||
<string name="emulation_ir_sensitivity">IR Sensitivity</string>
|
<string name="emulation_ir_sensitivity">IR Sensitivity</string>
|
||||||
<string name="emulation_choose_doubletap">Double tap button</string>
|
<string name="emulation_choose_doubletap">Double tap button</string>
|
||||||
<string name="emulation_motion_controls">Motion Controls</string>
|
<string name="emulation_motion_controls">Motion Controls</string>
|
||||||
|
@ -38,9 +38,10 @@ bool IsSettingSaveable(const Config::Location& config_location)
|
|||||||
// TODO: Kill the current Android controller mappings system
|
// TODO: Kill the current Android controller mappings system
|
||||||
if (config_location.section == "Android")
|
if (config_location.section == "Android")
|
||||||
{
|
{
|
||||||
static constexpr std::array<const char*, 8> android_setting_saveable = {
|
static constexpr std::array<const char*, 9> android_setting_saveable = {
|
||||||
"ControlScale", "ControlOpacity", "EmulationOrientation", "JoystickRelCenter",
|
"ControlScale", "ControlOpacity", "EmulationOrientation", "JoystickRelCenter",
|
||||||
"LastPlatformTab", "MotionControls", "PhoneRumble", "ShowInputOverlay"};
|
"LastPlatformTab", "MotionControls", "PhoneRumble", "ShowInputOverlay",
|
||||||
|
"IRMode"};
|
||||||
|
|
||||||
return std::any_of(
|
return std::any_of(
|
||||||
android_setting_saveable.cbegin(), android_setting_saveable.cend(),
|
android_setting_saveable.cbegin(), android_setting_saveable.cend(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user