summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
authorJMC47 <JMC4789@gmail.com>2019-01-24 20:02:23 -0500
committerGitHub <noreply@github.com>2019-01-24 20:02:23 -0500
commitddb1fbf7017644666f0670d3d8de1b05787c8f96 (patch)
tree68930de37be124b0f1d8f92db9c393aad7de9cb7 /Source/Android/app/src/main/java
parentf64b30156f83a4d3c70c2cc0ebd649967788f990 (diff)
parente15af5077f8c9605248a58e3172c8c1c45bd8589 (diff)
Merge pull request #7500 from zackhow/pointer
Android: Add IR pointer control to touch overlay
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java17
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java190
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java3
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java19
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java121
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.java1
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableDpad.java1
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableJoystick.java14
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java135
9 files changed, 456 insertions, 45 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
index 6574d22199..442a4e8644 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
@@ -397,6 +397,8 @@ public final class NativeLibrary
*/
public static native void RefreshWiimotes();
+ public static native void ReloadWiimoteConfig();
+
private static boolean alertResult = false;
public static boolean displayAlertMsg(final String caption, final String text,
@@ -490,4 +492,19 @@ public final class NativeLibrary
sEmulationActivity.clear();
}
+
+ public static void updateTouchPointer()
+ {
+ final EmulationActivity emulationActivity = sEmulationActivity.get();
+ if (emulationActivity == null)
+ {
+ Log.warning("[NativeLibrary] EmulationActivity is null.");
+ }
+ else
+ {
+ emulationActivity.runOnUiThread(emulationActivity::initInputPointer);
+ }
+ }
+
+ public static native float GetGameAspectRatio();
}
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 f5309869d5..cf75b127e0 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
@@ -2,6 +2,7 @@ package org.dolphinemu.dolphinemu.activities;
import android.app.AlertDialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
@@ -38,6 +39,8 @@ import org.dolphinemu.dolphinemu.fragments.MenuFragment;
import org.dolphinemu.dolphinemu.fragments.SaveLoadStateFragment;
import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
+import org.dolphinemu.dolphinemu.overlay.InputOverlay;
+import org.dolphinemu.dolphinemu.overlay.InputOverlayPointer;
import org.dolphinemu.dolphinemu.ui.main.MainActivity;
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
import org.dolphinemu.dolphinemu.ui.platform.Platform;
@@ -74,12 +77,14 @@ public final class EmulationActivity extends AppCompatActivity
private boolean activityRecreated;
private String mSelectedTitle;
+ private String mSelectedGameId;
private int mPlatform;
private String[] mPaths;
private boolean backPressedOnce = false;
public static final String EXTRA_SELECTED_GAMES = "SelectedGames";
public static final String EXTRA_SELECTED_TITLE = "SelectedTitle";
+ public static final String EXTRA_SELECTED_GAMEID = "SelectedGameId";
public static final String EXTRA_PLATFORM = "Platform";
@Retention(SOURCE)
@@ -91,7 +96,7 @@ 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_ACTION_RESET_OVERLAY, MENU_SET_IR_SENSITIVITY, MENU_ACTION_CHOOSE_DOUBLETAP})
public @interface MenuAction
{
}
@@ -123,6 +128,8 @@ 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;
private static SparseIntArray buttonsActionsMap = new SparseIntArray();
@@ -165,6 +172,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_set_ir_sensitivity,
+ EmulationActivity.MENU_SET_IR_SENSITIVITY);
+ buttonsActionsMap.append(R.id.menu_emulation_choose_doubletap,
+ EmulationActivity.MENU_ACTION_CHOOSE_DOUBLETAP);
}
private static String[] scanForSecondDisc(GameFile gameFile)
@@ -182,6 +193,7 @@ public final class EmulationActivity extends AppCompatActivity
launcher.putExtra(EXTRA_SELECTED_GAMES, scanForSecondDisc(gameFile));
launcher.putExtra(EXTRA_SELECTED_TITLE, gameFile.getTitle());
+ launcher.putExtra(EXTRA_SELECTED_GAMEID, gameFile.getGameId());
launcher.putExtra(EXTRA_PLATFORM, gameFile.getPlatform());
activity.startActivityForResult(launcher, MainPresenter.REQUEST_EMULATE_GAME);
}
@@ -201,6 +213,7 @@ public final class EmulationActivity extends AppCompatActivity
Intent gameToEmulate = getIntent();
mPaths = gameToEmulate.getStringArrayExtra(EXTRA_SELECTED_GAMES);
mSelectedTitle = gameToEmulate.getStringExtra(EXTRA_SELECTED_TITLE);
+ mSelectedGameId = gameToEmulate.getStringExtra(EXTRA_SELECTED_GAMEID);
mPlatform = gameToEmulate.getIntExtra(EXTRA_PLATFORM, 0);
activityRecreated = false;
}
@@ -294,6 +307,7 @@ public final class EmulationActivity extends AppCompatActivity
}
outState.putStringArray(EXTRA_SELECTED_GAMES, mPaths);
outState.putString(EXTRA_SELECTED_TITLE, mSelectedTitle);
+ outState.putString(EXTRA_SELECTED_GAMEID, mSelectedGameId);
outState.putInt(EXTRA_PLATFORM, mPlatform);
super.onSaveInstanceState(outState);
}
@@ -302,6 +316,7 @@ public final class EmulationActivity extends AppCompatActivity
{
mPaths = savedInstanceState.getStringArray(EXTRA_SELECTED_GAMES);
mSelectedTitle = savedInstanceState.getString(EXTRA_SELECTED_TITLE);
+ mSelectedGameId = savedInstanceState.getString(EXTRA_SELECTED_GAMEID);
mPlatform = savedInstanceState.getInt(EXTRA_PLATFORM);
}
@@ -578,6 +593,14 @@ public final class EmulationActivity extends AppCompatActivity
FileBrowserHelper.openFilePicker(this, REQUEST_CHANGE_DISC);
return;
+ case MENU_SET_IR_SENSITIVITY:
+ setIRSensitivity();
+ return;
+
+ case MENU_ACTION_CHOOSE_DOUBLETAP:
+ chooseDoubleTapButton();
+ return;
+
case MENU_ACTION_EXIT:
// ATV menu is built using a fragment, this will pop that fragment before emulation ends.
if (TvUtil.isLeanback(getApplicationContext()))
@@ -708,6 +731,39 @@ public final class EmulationActivity extends AppCompatActivity
alertDialog.show();
}
+ public void chooseDoubleTapButton()
+ {
+ final SharedPreferences.Editor editor = mPreferences.edit();
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+
+ int currentController =
+ mPreferences.getInt("wiiController", InputOverlay.OVERLAY_WIIMOTE_NUNCHUCK);
+
+ int currentValue = mPreferences.getInt("doubleTapButton",
+ InputOverlayPointer.DOUBLE_TAP_OPTIONS.get(InputOverlayPointer.DOUBLE_TAP_A));
+
+ int buttonList = currentController == InputOverlay.OVERLAY_WIIMOTE_CLASSIC ?
+ R.array.doubleTapWithClassic : R.array.doubleTap;
+
+ if (currentController != InputOverlay.OVERLAY_WIIMOTE_CLASSIC &&
+ currentValue == InputOverlay.OVERLAY_WIIMOTE_CLASSIC)
+ {
+ currentValue = InputOverlay.OVERLAY_WIIMOTE;
+ }
+
+ builder.setSingleChoiceItems(buttonList, currentValue, (DialogInterface dialog, int which) ->
+ editor.putInt("doubleTapButton", InputOverlayPointer.DOUBLE_TAP_OPTIONS.get(which)));
+
+ builder.setPositiveButton(getString(R.string.ok), (dialogInterface, i) ->
+ {
+ editor.commit();
+ mEmulationFragment.initInputPointer();
+ });
+
+ AlertDialog alertDialog = builder.create();
+ alertDialog.show();
+ }
+
private void adjustScale()
{
LayoutInflater inflater = LayoutInflater.from(this);
@@ -785,6 +841,132 @@ public final class EmulationActivity extends AppCompatActivity
}
+ private void setIRSensitivity()
+ {
+ int irHeight = Integer.valueOf(
+ mPreferences.getString(SettingsFile.KEY_WIIBIND_IR_HEIGHT + mSelectedGameId, "50"));
+
+ LayoutInflater inflater = LayoutInflater.from(this);
+ View view = inflater.inflate(R.layout.dialog_ir_sensitivity, null);
+
+ TextView mTextSliderValueHeight = (TextView) view.findViewById(R.id.text_ir_height);
+ TextView units = (TextView) view.findViewById(R.id.text_ir_height_units);
+ SeekBar seekbarHeight = view.findViewById(R.id.seekbar_height);
+
+ mTextSliderValueHeight.setText(String.valueOf(irHeight));
+ units.setText(getString(R.string.height));
+ seekbarHeight.setMax(100);
+ seekbarHeight.setProgress(irHeight);
+ seekbarHeight.setKeyProgressIncrement(5);
+ seekbarHeight.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
+ {
+ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
+ {
+ mTextSliderValueHeight.setText(String.valueOf(progress));
+ }
+
+ @Override public void onStartTrackingTouch(SeekBar seekBar)
+ {
+ // Do nothing
+ }
+
+ @Override public void onStopTrackingTouch(SeekBar seekBar)
+ {
+ // Do nothing
+ }
+ });
+
+ int irWidth = Integer.valueOf(
+ mPreferences.getString(SettingsFile.KEY_WIIBIND_IR_WIDTH + mSelectedGameId, "50"));
+
+ TextView mTextSliderValueWidth = (TextView) view.findViewById(R.id.text_ir_width);
+ TextView unitsWidth = (TextView) view.findViewById(R.id.text_ir_width_units);
+ SeekBar seekbarWidth = view.findViewById(R.id.seekbar_width);
+
+ mTextSliderValueWidth.setText(String.valueOf(irWidth));
+ unitsWidth.setText(getString(R.string.width));
+ seekbarWidth.setMax(100);
+ seekbarWidth.setProgress(irWidth);
+ seekbarWidth.setKeyProgressIncrement(5);
+ seekbarWidth.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
+ {
+ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
+ {
+ mTextSliderValueWidth.setText(String.valueOf(progress));
+ }
+
+ @Override public void onStartTrackingTouch(SeekBar seekBar)
+ {
+ // Do nothing
+ }
+
+ @Override public void onStopTrackingTouch(SeekBar seekBar)
+ {
+ // Do nothing
+ }
+ });
+
+
+ int irCenter = Integer.valueOf(
+ mPreferences.getString(SettingsFile.KEY_WIIBIND_IR_CENTER + mSelectedGameId, "50"));
+
+ TextView mTextSliderValueCenter = (TextView) view.findViewById(R.id.text_ir_center);
+ TextView unitsCenter = (TextView) view.findViewById(R.id.text_ir_center_units);
+ SeekBar seekbarCenter = view.findViewById(R.id.seekbar_center);
+
+ mTextSliderValueCenter.setText(String.valueOf(irCenter));
+ unitsCenter.setText(getString(R.string.center));
+ seekbarCenter.setMax(100);
+ seekbarCenter.setProgress(irCenter);
+ seekbarCenter.setKeyProgressIncrement(5);
+ seekbarCenter.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
+ {
+ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
+ {
+ mTextSliderValueCenter.setText(String.valueOf(progress));
+ }
+
+ @Override public void onStartTrackingTouch(SeekBar seekBar)
+ {
+ // Do nothing
+ }
+
+ @Override public void onStopTrackingTouch(SeekBar seekBar)
+ {
+ // Do nothing
+ }
+ });
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(getString(R.string.emulation_ir_sensitivity));
+ builder.setView(view);
+ builder.setPositiveButton(R.string.ok, (dialogInterface, i) ->
+ {
+ SettingsFile.saveSingleCustomSetting(mSelectedGameId, Settings.SECTION_CONTROLS,
+ SettingsFile.KEY_WIIBIND_IR_HEIGHT, mTextSliderValueHeight.getText().toString());
+ SettingsFile.saveSingleCustomSetting(mSelectedGameId, Settings.SECTION_CONTROLS,
+ SettingsFile.KEY_WIIBIND_IR_WIDTH, mTextSliderValueWidth.getText().toString());
+ SettingsFile.saveSingleCustomSetting(mSelectedGameId, Settings.SECTION_CONTROLS,
+ SettingsFile.KEY_WIIBIND_IR_CENTER, mTextSliderValueCenter.getText().toString());
+
+ NativeLibrary.ReloadWiimoteConfig();
+
+ SharedPreferences.Editor editor = mPreferences.edit();
+ editor.putString(SettingsFile.KEY_WIIBIND_IR_HEIGHT + mSelectedGameId,
+ mTextSliderValueHeight.getText().toString());
+ editor.putString(SettingsFile.KEY_WIIBIND_IR_WIDTH + mSelectedGameId,
+ mTextSliderValueWidth.getText().toString());
+ editor.putString(SettingsFile.KEY_WIIBIND_IR_CENTER + mSelectedGameId,
+ mTextSliderValueCenter.getText().toString());
+ editor.apply();
+ });
+ builder.setNegativeButton(R.string.cancel, (dialogInterface, i) ->
+ {
+ // Do nothing
+ });
+ builder.show();
+ }
+
private void resetOverlay()
{
new AlertDialog.Builder(this)
@@ -882,4 +1064,10 @@ public final class EmulationActivity extends AppCompatActivity
{
return mSettings;
}
+
+ public void initInputPointer()
+ {
+ if (deviceHasTouchScreen())
+ mEmulationFragment.initInputPointer();
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java
index 0dd027cd80..df51a38e04 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java
@@ -151,6 +151,9 @@ public final class SettingsFile
public static final String KEY_WIIBIND_IR_FORWARD = "IRForward_";
public static final String KEY_WIIBIND_IR_BACKWARD = "IRBackward_";
public static final String KEY_WIIBIND_IR_HIDE = "IRHide_";
+ public static final String KEY_WIIBIND_IR_HEIGHT = "IRHeight";
+ public static final String KEY_WIIBIND_IR_WIDTH = "IRWidth";
+ public static final String KEY_WIIBIND_IR_CENTER = "IRCenter";
public static final String KEY_WIIBIND_SWING_UP = "SwingUp_";
public static final String KEY_WIIBIND_SWING_DOWN = "SwingDown_";
public static final String KEY_WIIBIND_SWING_LEFT = "SwingLeft_";
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 dc888d74d4..f817414add 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
@@ -102,14 +102,6 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
surfaceView.getHolder().addCallback(this);
mInputOverlay = contents.findViewById(R.id.surface_input_overlay);
- if (mInputOverlay != null)
- {
- // If the input overlay was previously disabled, then don't show it.
- if (!mPreferences.getBoolean("showInputOverlay", true))
- {
- mInputOverlay.setVisibility(View.GONE);
- }
- }
Button doneButton = contents.findViewById(R.id.done_control_config);
if (doneButton != null)
@@ -199,18 +191,19 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
// If the overlay is currently set to INVISIBLE
if (!mPreferences.getBoolean("showInputOverlay", false))
{
- // Set it to VISIBLE
- mInputOverlay.setVisibility(View.VISIBLE);
editor.putBoolean("showInputOverlay", true);
}
else
{
- // Set it to INVISIBLE
- mInputOverlay.setVisibility(View.GONE);
editor.putBoolean("showInputOverlay", false);
}
+ editor.commit();
+ mInputOverlay.refreshControls();
+ }
- editor.apply();
+ public void initInputPointer()
+ {
+ mInputOverlay.initTouchPointer();
}
public void refreshInputOverlay()
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 de29e00ed5..c679838d3b 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
@@ -40,9 +40,16 @@ import java.util.Set;
*/
public final class InputOverlay extends SurfaceView implements OnTouchListener
{
+ public static final int OVERLAY_GAMECUBE = 0;
+ public static final int OVERLAY_WIIMOTE = 1;
+ public static final int OVERLAY_WIIMOTE_SIDEWAYS = 2;
+ public static final int OVERLAY_WIIMOTE_NUNCHUCK = 3;
+ public static final int OVERLAY_WIIMOTE_CLASSIC = 4;
+
private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<>();
private final Set<InputOverlayDrawableDpad> overlayDpads = new HashSet<>();
private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<>();
+ private InputOverlayPointer overlayPointer;
private boolean mIsInEditMode = false;
private InputOverlayDrawableButton mButtonBeingConfigured;
@@ -85,6 +92,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
mPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
if (!mPreferences.getBoolean("OverlayInitV2", false))
defaultOverlay();
+
// Load the controls.
refreshControls();
@@ -98,6 +106,27 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
requestFocus();
}
+ public void initTouchPointer()
+ {
+ // Refresh before starting the pointer
+ refreshControls();
+
+ if (!EmulationActivity.isGameCubeGame())
+ {
+ int doubleTapButton = mPreferences.getInt("doubleTapButton",
+ InputOverlayPointer.DOUBLE_TAP_OPTIONS.get(InputOverlayPointer.DOUBLE_TAP_A));
+
+ if (mPreferences.getInt("wiiController", OVERLAY_WIIMOTE_NUNCHUCK) !=
+ InputOverlay.OVERLAY_WIIMOTE_CLASSIC &&
+ doubleTapButton == InputOverlayPointer.DOUBLE_TAP_CLASSIC_A)
+ {
+ doubleTapButton = InputOverlayPointer.DOUBLE_TAP_A;
+ }
+
+ overlayPointer = new InputOverlayPointer(this.getContext(), doubleTapButton);
+ }
+ }
+
@Override
public void draw(Canvas canvas)
{
@@ -128,6 +157,8 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
}
int pointerIndex = event.getActionIndex();
+ // Tracks if any button/joystick is pressed down
+ boolean pressed = false;
for (InputOverlayDrawableButton button : overlayButtons)
{
@@ -142,6 +173,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
{
button.setPressedState(true);
button.setTrackId(event.getPointerId(pointerIndex));
+ pressed = true;
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
ButtonState.PRESSED);
}
@@ -154,6 +186,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
button.setPressedState(false);
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, button.getId(),
ButtonState.RELEASED);
+ button.setTrackId(-1);
}
break;
}
@@ -166,35 +199,47 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
- case MotionEvent.ACTION_MOVE:
- // Up, Down, Left, Right
- boolean[] pressed = {false, false, false, false};
// If a pointer enters the bounds of a button, press that button.
if (dpad.getBounds()
.contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex)))
{
+ dpad.setTrackId(event.getPointerId(pointerIndex));
+ pressed = true;
+ }
+ case MotionEvent.ACTION_MOVE:
+ if (dpad.getTrackId() == event.getPointerId(pointerIndex))
+ {
+ // Up, Down, Left, Right
+ boolean[] dpadPressed = {false, false, false, false};
+
if (dpad.getBounds().top + (dpad.getHeight() / 3) > (int) event.getY(pointerIndex))
- pressed[0] = true;
+ dpadPressed[0] = true;
if (dpad.getBounds().bottom - (dpad.getHeight() / 3) < (int) event.getY(pointerIndex))
- pressed[1] = true;
+ dpadPressed[1] = true;
if (dpad.getBounds().left + (dpad.getWidth() / 3) > (int) event.getX(pointerIndex))
- pressed[2] = true;
+ dpadPressed[2] = true;
if (dpad.getBounds().right - (dpad.getWidth() / 3) < (int) event.getX(pointerIndex))
- pressed[3] = true;
+ dpadPressed[3] = true;
// Release the buttons first, then press
- for (int i = 0; i < pressed.length; i++)
- if (!pressed[i])
+ for (int i = 0; i < dpadPressed.length; i++)
+ {
+ if (!dpadPressed[i])
+ {
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
ButtonState.RELEASED);
+ }
+ }
// Press buttons
- for (int i = 0; i < pressed.length; i++)
- if (pressed[i])
+ for (int i = 0; i < dpadPressed.length; i++)
+ {
+ if (dpadPressed[i])
+ {
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
ButtonState.PRESSED);
-
- setDpadState(dpad, pressed[0], pressed[1], pressed[2], pressed[3]);
- dpad.setTrackId(event.getPointerId(pointerIndex));
+ }
+ }
+ setDpadState(dpad, dpadPressed[0], dpadPressed[1], dpadPressed[2], dpadPressed[3]);
}
break;
case MotionEvent.ACTION_UP:
@@ -208,6 +253,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
NativeLibrary.onGamePadEvent(NativeLibrary.TouchScreenDevice, dpad.getId(i),
ButtonState.RELEASED);
}
+ dpad.setTrackId(-1);
}
break;
}
@@ -215,7 +261,11 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
for (InputOverlayDrawableJoystick joystick : overlayJoysticks)
{
- joystick.TrackEvent(event);
+ if (joystick.TrackEvent(event))
+ {
+ if (joystick.getTrackId() != -1)
+ pressed = true;
+ }
int[] axisIDs = joystick.getAxisIDs();
float[] axises = joystick.getAxisValues();
@@ -225,6 +275,18 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
}
}
+ // No button/joystick pressed, safe to move pointer
+ if (!pressed && overlayPointer != null)
+ {
+ overlayPointer.onTouch(event);
+ float[] axises = overlayPointer.getAxisValues();
+
+ NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice, ButtonType.WIIMOTE_IR + 2,
+ axises[0]);
+ NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice, ButtonType.WIIMOTE_IR + 4,
+ axises[1]);
+ }
+
invalidate();
return true;
@@ -617,21 +679,24 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ?
"-Portrait" : "";
- // Add all the enabled overlay items back to the HashSet.
- if (EmulationActivity.isGameCubeGame() || mPreferences.getInt("wiiController", 3) == 0)
+ if (mPreferences.getBoolean("showInputOverlay", true))
{
- addGameCubeOverlayControls(orientation);
- }
- else if (mPreferences.getInt("wiiController", 3) == 4)
- {
- addClassicOverlayControls(orientation);
- }
- else
- {
- addWiimoteOverlayControls(orientation);
- if (mPreferences.getInt("wiiController", 3) == 3)
+ // Add all the enabled overlay items back to the HashSet.
+ if (EmulationActivity.isGameCubeGame() || mPreferences.getInt("wiiController", 3) == 0)
+ {
+ addGameCubeOverlayControls(orientation);
+ }
+ else if (mPreferences.getInt("wiiController", 3) == 4)
+ {
+ addClassicOverlayControls(orientation);
+ }
+ else
{
- addNunchukOverlayControls(orientation);
+ addWiimoteOverlayControls(orientation);
+ if (mPreferences.getInt("wiiController", 3) == 3)
+ {
+ addNunchukOverlayControls(orientation);
+ }
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.java
index 96b4aeca0a..266cd273c4 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.java
@@ -41,6 +41,7 @@ public final class InputOverlayDrawableButton
public InputOverlayDrawableButton(Resources res, Bitmap defaultStateBitmap,
Bitmap pressedStateBitmap, int buttonType)
{
+ mTrackId = -1;
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap);
mPressedStateBitmap = new BitmapDrawable(res, pressedStateBitmap);
mButtonType = buttonType;
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableDpad.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableDpad.java
index fd60f1fc98..5aa8c4846d 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableDpad.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableDpad.java
@@ -60,6 +60,7 @@ public final class InputOverlayDrawableDpad
int buttonUp, int buttonDown,
int buttonLeft, int buttonRight)
{
+ mTrackId = -1;
mDefaultStateBitmap = new BitmapDrawable(res, defaultStateBitmap);
mPressedOneDirectionStateBitmap = new BitmapDrawable(res, pressedOneDirectionStateBitmap);
mPressedTwoDirectionsStateBitmap = new BitmapDrawable(res, pressedTwoDirectionsStateBitmap);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableJoystick.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableJoystick.java
index a54d01c7cf..55f6347096 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableJoystick.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableJoystick.java
@@ -94,10 +94,11 @@ public final class InputOverlayDrawableJoystick
mBoundsBoxBitmap.draw(canvas);
}
- public void TrackEvent(MotionEvent event)
+ public boolean TrackEvent(MotionEvent event)
{
boolean reCenter = mPreferences.getBoolean("joystickRelCenter", true);
int pointerIndex = event.getActionIndex();
+ boolean pressed = false;
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
@@ -105,7 +106,7 @@ public final class InputOverlayDrawableJoystick
case MotionEvent.ACTION_POINTER_DOWN:
if (getBounds().contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex)))
{
- mPressedState = true;
+ mPressedState = pressed = true;
mOuterBitmap.setAlpha(0);
mBoundsBoxBitmap.setAlpha(255);
if (reCenter)
@@ -121,6 +122,7 @@ public final class InputOverlayDrawableJoystick
case MotionEvent.ACTION_POINTER_UP:
if (trackId == event.getPointerId(pointerIndex))
{
+ pressed = true;
mPressedState = false;
axises[0] = axises[1] = 0.0f;
mOuterBitmap.setAlpha(255);
@@ -136,7 +138,7 @@ public final class InputOverlayDrawableJoystick
}
if (trackId == -1)
- return;
+ return pressed;
for (int i = 0; i < event.getPointerCount(); i++)
{
@@ -158,6 +160,7 @@ public final class InputOverlayDrawableJoystick
SetInnerBounds();
}
}
+ return pressed;
}
public boolean onConfigureTouch(MotionEvent event)
@@ -274,4 +277,9 @@ public final class InputOverlayDrawableJoystick
{
return mHeight;
}
+
+ public int getTrackId()
+ {
+ return trackId;
+ }
}
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
new file mode 100644
index 0000000000..492cf186eb
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayPointer.java
@@ -0,0 +1,135 @@
+package org.dolphinemu.dolphinemu.overlay;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Handler;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.MotionEvent;
+
+import org.dolphinemu.dolphinemu.NativeLibrary;
+
+import java.util.ArrayList;
+
+public class InputOverlayPointer
+{
+ public static final int DOUBLE_TAP_A = 0;
+ public static final int DOUBLE_TAP_B = 1;
+ public static final int DOUBLE_TAP_2 = 2;
+ public static final int DOUBLE_TAP_CLASSIC_A = 3;
+
+ private final float[] axes = {0f, 0f};
+
+ private float maxHeight;
+ private float maxWidth;
+ private float aspectAdjusted;
+ private boolean xAdjusted;
+ private boolean doubleTap = false;
+ private int doubleTapButton;
+ private int trackId = -1;
+
+ public static ArrayList<Integer> DOUBLE_TAP_OPTIONS = new ArrayList<>();
+
+ static
+ {
+ DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.WIIMOTE_BUTTON_A);
+ DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.WIIMOTE_BUTTON_B);
+ DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.WIIMOTE_BUTTON_2);
+ DOUBLE_TAP_OPTIONS.add(NativeLibrary.ButtonType.CLASSIC_BUTTON_A);
+ }
+
+ public InputOverlayPointer(Context context, int button)
+ {
+ Display display = ((Activity) context).getWindowManager().getDefaultDisplay();
+ DisplayMetrics outMetrics = new DisplayMetrics();
+ display.getMetrics(outMetrics);
+ doubleTapButton = button;
+
+ Integer y = outMetrics.heightPixels;
+ Integer x = outMetrics.widthPixels;
+
+ // Adjusting for device's black bars.
+ Float deviceAR = (float) x / y;
+ Float gameAR = NativeLibrary.GetGameAspectRatio();
+ aspectAdjusted = gameAR / deviceAR;
+
+ if (gameAR < deviceAR) // Black bars on left/right
+ {
+ xAdjusted = true;
+ Integer gameX = Math.round((float) y * gameAR);
+ Integer buffer = (x - gameX);
+
+ maxWidth = (float) (x - buffer) / 2;
+ maxHeight = (float) y / 2;
+ }
+ else // Bars on top/bottom
+ {
+ xAdjusted = false;
+ Integer gameY = Math.round((float) x * gameAR);
+ Integer buffer = (y - gameY);
+
+ maxWidth = (float) x / 2;
+ maxHeight = (float) (y - buffer) / 2;
+ }
+ }
+
+ public boolean onTouch(MotionEvent event)
+ {
+ int pointerIndex = event.getActionIndex();
+
+ switch (event.getAction() & MotionEvent.ACTION_MASK)
+ {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_POINTER_DOWN:
+ trackId = event.getPointerId(pointerIndex);
+ touchPress();
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_UP:
+ if (trackId == event.getPointerId(pointerIndex))
+ trackId = -1;
+ break;
+ }
+
+ if (trackId == -1)
+ return false;
+
+ int x = (int) event.getX(event.findPointerIndex(trackId));
+ int y = (int) event.getY(event.findPointerIndex(trackId));
+ if (xAdjusted)
+ {
+ axes[0] = (y - maxHeight) / maxHeight;
+ axes[1] = ((x * aspectAdjusted) - maxWidth) / maxWidth;
+ }
+ else
+ {
+ axes[0] = ((y * aspectAdjusted) - maxHeight) / maxHeight;
+ axes[1] = (x - maxWidth) / maxWidth;
+ }
+ return false;
+ }
+
+ private void touchPress()
+ {
+ 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);
+ }
+ }
+
+ public float[] getAxisValues()
+ {
+ float[] ir = {0f, 0f};
+ ir[0] = axes[0];
+ ir[1] = axes[1];
+ return axes;
+ }
+}