Merge pull request #7500 from zackhow/pointer
Android: Add IR pointer control to touch overlay
This commit is contained in:
commit
ddb1fbf701
|
@ -1,5 +1,10 @@
|
|||
# RMCE01, RMCJ01, RMCK01, RMCP01 - Mario Kart Wii
|
||||
|
||||
[Controls]
|
||||
IRHeight = 50
|
||||
IRWidth = 30
|
||||
IRCenter = 50
|
||||
|
||||
[Core]
|
||||
# Values set here will override the main Dolphin settings.
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
# RMGE01, RMGJ01, RMGK01, RMGP01 - SUPER MARIO GALAXY
|
||||
|
||||
[Controls]
|
||||
IRHeight = 50
|
||||
IRWidth = 30
|
||||
IRCenter = 50
|
||||
|
||||
[Core]
|
||||
# Values set here will override the main Dolphin settings.
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# RODE01, RODJ01, RODK01, RODP01 - WarioWare: Smooth Moves
|
||||
[Controls]
|
||||
IRHeight = 71
|
||||
IRWidth = 64
|
||||
IRCenter = 99
|
||||
|
||||
[Core]
|
||||
# Values set here will override the main Dolphin settings.
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# RUUE01, RUUJ01, RUUK01, RUUP01 - Animal Crossing Wii
|
||||
[Controls]
|
||||
IRHeight = 50
|
||||
IRWidth = 30
|
||||
IRCenter = 50
|
||||
|
||||
[Core]
|
||||
# Values set here will override the main Dolphin settings.
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# RZDE01, RZDJ01, RZDK01, RZDP01 - The Legend of Zelda: Twilight Princess [Wii]
|
||||
[Controls]
|
||||
IRHeight = 39
|
||||
IRWidth = 37
|
||||
IRCenter = 91
|
||||
|
||||
[Core]
|
||||
# Values set here will override the main Dolphin settings.
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# SB4E01, SB4J01, SB4P01 - Super Mario Galaxy 2
|
||||
[Controls]
|
||||
IRHeight = 50
|
||||
IRWidth = 30
|
||||
IRCenter = 50
|
||||
|
||||
[Core]
|
||||
# Values set here will override the main Dolphin settings.
|
||||
|
|
|
@ -18,6 +18,9 @@ IR/Right = `Axis 115`
|
|||
IR/Forward = `Axis 116`
|
||||
IR/Backward = `Axis 117`
|
||||
IR/Hide = `Button 118`
|
||||
IR/Height = 50
|
||||
IR/Width = 30
|
||||
IR/Center = 50
|
||||
Swing/Up = `Axis 120`
|
||||
Swing/Down = `Axis 121`
|
||||
Swing/Left = `Axis 122`
|
||||
|
@ -154,6 +157,9 @@ IR/Right = `Axis 115`
|
|||
IR/Forward = `Axis 116`
|
||||
IR/Backward = `Axis 117`
|
||||
IR/Hide = `Button 118`
|
||||
IR/Height = 50
|
||||
IR/Width = 30
|
||||
IR/Center = 50
|
||||
Swing/Up = `Axis 120`
|
||||
Swing/Down = `Axis 121`
|
||||
Swing/Left = `Axis 122`
|
||||
|
@ -290,6 +296,9 @@ IR/Right = `Axis 115`
|
|||
IR/Forward = `Axis 116`
|
||||
IR/Backward = `Axis 117`
|
||||
IR/Hide = `Button 118`
|
||||
IR/Height = 50
|
||||
IR/Width = 30
|
||||
IR/Center = 50
|
||||
Swing/Up = `Axis 120`
|
||||
Swing/Down = `Axis 121`
|
||||
Swing/Left = `Axis 122`
|
||||
|
@ -426,6 +435,9 @@ IR/Right = `Axis 115`
|
|||
IR/Forward = `Axis 116`
|
||||
IR/Backward = `Axis 117`
|
||||
IR/Hide = `Button 118`
|
||||
IR/Height = 50
|
||||
IR/Width = 30
|
||||
IR/Center = 50
|
||||
Swing/Up = `Axis 120`
|
||||
Swing/Down = `Axis 121`
|
||||
Swing/Left = `Axis 122`
|
||||
|
|
|
@ -18,6 +18,9 @@ IR/Right = `Axis 115`
|
|||
IR/Forward = `Axis 116`
|
||||
IR/Backward = `Axis 117`
|
||||
IR/Hide = `Button 118`
|
||||
IR/Height = 50
|
||||
IR/Width = 30
|
||||
IR/Center = 50
|
||||
Swing/Up = `Axis 120`
|
||||
Swing/Down = `Axis 121`
|
||||
Swing/Left = `Axis 122`
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_";
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
addNunchukOverlayControls(orientation);
|
||||
addGameCubeOverlayControls(orientation);
|
||||
}
|
||||
else if (mPreferences.getInt("wiiController", 3) == 4)
|
||||
{
|
||||
addClassicOverlayControls(orientation);
|
||||
}
|
||||
else
|
||||
{
|
||||
addWiimoteOverlayControls(orientation);
|
||||
if (mPreferences.getInt("wiiController", 3) == 3)
|
||||
{
|
||||
addNunchukOverlayControls(orientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/seekbar_width"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/text_ir_width"
|
||||
android:layout_marginBottom="@dimen/spacing_medlarge"
|
||||
android:layout_marginLeft="@dimen/spacing_large"
|
||||
android:layout_marginRight="@dimen/spacing_large"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_ir_width"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="@dimen/spacing_medlarge"
|
||||
android:layout_marginTop="@dimen/spacing_medlarge"
|
||||
tools:text="75"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_ir_width_units"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/text_ir_width"
|
||||
android:layout_toEndOf="@+id/text_ir_width"
|
||||
tools:text="%"/>
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/seekbar_height"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/text_ir_height"
|
||||
android:layout_marginBottom="@dimen/spacing_medlarge"
|
||||
android:layout_marginLeft="@dimen/spacing_large"
|
||||
android:layout_marginRight="@dimen/spacing_large"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_ir_height"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="@dimen/spacing_medlarge"
|
||||
android:layout_marginTop="@dimen/spacing_medlarge"
|
||||
tools:text="75"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_ir_height_units"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/text_ir_height"
|
||||
android:layout_toEndOf="@+id/text_ir_height"
|
||||
tools:text="%"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/seekbar_center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/text_ir_center"
|
||||
android:layout_marginBottom="@dimen/spacing_medlarge"
|
||||
android:layout_marginLeft="@dimen/spacing_large"
|
||||
android:layout_marginRight="@dimen/spacing_large"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_ir_center"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="@dimen/spacing_medlarge"
|
||||
android:layout_marginTop="@dimen/spacing_medlarge"
|
||||
tools:text="75"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_ir_center_units"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/text_ir_center"
|
||||
android:layout_toEndOf="@+id/text_ir_center"
|
||||
tools:text="%"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -112,7 +112,21 @@
|
|||
<item
|
||||
android:id="@+id/menu_emulation_choose_controller"
|
||||
android:title="@string/emulation_choose_controller"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_emulation_ir_group"
|
||||
android:title="@string/emulation_ir_group"
|
||||
app:showAsAction="never">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/menu_emulation_set_ir_sensitivity"
|
||||
android:title="@string/emulation_ir_sensitivity"
|
||||
app:showAsAction="ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/menu_emulation_choose_doubletap"
|
||||
android:title="@string/emulation_choose_doubletap"
|
||||
app:showAsAction="ifRoom"/>
|
||||
</menu>
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/menu_emulation_reset_overlay"
|
||||
android:title="@string/emulation_touch_overlay_reset"/>
|
||||
|
|
|
@ -306,6 +306,19 @@
|
|||
<item>Right Stick</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="doubleTap">
|
||||
<item>Button A</item>
|
||||
<item>Button B</item>
|
||||
<item>Button 2</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="doubleTapWithClassic">
|
||||
<item>Button A</item>
|
||||
<item>Button B</item>
|
||||
<item>Button 2</item>
|
||||
<item>Classic A</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="gameSettingsMenusGC">
|
||||
<item>Core Settings</item>
|
||||
<item>GFX Settings</item>
|
||||
|
|
|
@ -298,6 +298,9 @@
|
|||
<string name="emulation_controller_changed">You may have to reload the game after changing extensions.</string>
|
||||
<string name="emulation_touch_button_help">Swipe down from the top of the screen to access the menu.</string>
|
||||
<string name="emulation_touch_overlay_reset">Reset Overlay</string>
|
||||
<string name="emulation_ir_group">Touch IR Pointer</string>
|
||||
<string name="emulation_ir_sensitivity">IR Sensitivity</string>
|
||||
<string name="emulation_choose_doubletap">Double tap button</string>
|
||||
|
||||
<!-- GC Adapter Menu-->
|
||||
<string name="gc_adapter_rumble">Enable Vibration</string>
|
||||
|
@ -322,4 +325,10 @@
|
|||
<string name="homescreen_favorites">Favorites</string>
|
||||
|
||||
<string name="select_dir">Select This Directory</string>
|
||||
|
||||
<!-- Misc -->
|
||||
<string name="height">Height</string>
|
||||
<string name="width">Width</string>
|
||||
<string name="center">Center</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -12,6 +12,7 @@ static JavaVM* s_java_vm;
|
|||
|
||||
static jclass s_native_library_class;
|
||||
static jmethodID s_display_alert_msg;
|
||||
static jmethodID s_get_update_touch_pointer;
|
||||
|
||||
static jclass s_game_file_class;
|
||||
static jfieldID s_game_file_pointer;
|
||||
|
@ -41,6 +42,11 @@ jmethodID GetDisplayAlertMsg()
|
|||
return s_display_alert_msg;
|
||||
}
|
||||
|
||||
jmethodID GetUpdateTouchPointer()
|
||||
{
|
||||
return s_get_update_touch_pointer;
|
||||
}
|
||||
|
||||
jclass GetAnalyticsClass()
|
||||
{
|
||||
return s_analytics_class;
|
||||
|
@ -98,6 +104,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||
s_native_library_class = reinterpret_cast<jclass>(env->NewGlobalRef(native_library_class));
|
||||
s_display_alert_msg = env->GetStaticMethodID(s_native_library_class, "displayAlertMsg",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Z)Z");
|
||||
s_get_update_touch_pointer =
|
||||
env->GetStaticMethodID(IDCache::GetNativeLibraryClass(), "updateTouchPointer", "()V");
|
||||
|
||||
const jclass game_file_class = env->FindClass("org/dolphinemu/dolphinemu/model/GameFile");
|
||||
s_game_file_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_file_class));
|
||||
|
|
|
@ -14,6 +14,7 @@ JavaVM* GetJavaVM();
|
|||
|
||||
jclass GetNativeLibraryClass();
|
||||
jmethodID GetDisplayAlertMsg();
|
||||
jmethodID GetUpdateTouchPointer();
|
||||
|
||||
jclass GetAnalyticsClass();
|
||||
jmethodID GetSendAnalyticsReport();
|
||||
|
|
|
@ -107,6 +107,11 @@ void Host_UpdateMainFrame()
|
|||
|
||||
void Host_RequestRenderWindowSize(int width, int height)
|
||||
{
|
||||
// Update touch pointer
|
||||
JNIEnv* env;
|
||||
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
||||
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetUpdateTouchPointer());
|
||||
IDCache::GetJavaVM()->DetachCurrentThread();
|
||||
}
|
||||
|
||||
bool Host_UINeedsControllerState()
|
||||
|
@ -564,6 +569,13 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestr
|
|||
s_surf = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_NativeLibrary_GetGameAspectRatio(JNIEnv* env, jobject obj)
|
||||
{
|
||||
return g_renderer->CalculateDrawAspectRatio();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_RefreshWiimotes(JNIEnv* env,
|
||||
jobject obj)
|
||||
{
|
||||
|
@ -571,6 +583,12 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_RefreshWiimo
|
|||
WiimoteReal::Refresh();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ReloadWiimoteConfig(JNIEnv* env,
|
||||
jobject obj)
|
||||
{
|
||||
Wiimote::LoadConfig();
|
||||
}
|
||||
|
||||
static void Run(const std::vector<std::string>& paths, bool first_open,
|
||||
std::optional<std::string> savestate_path = {}, bool delete_savestate = false)
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@ private:
|
|||
{
|
||||
public:
|
||||
std::string GetName() const;
|
||||
bool IsDetectable() override { return false; }
|
||||
Axis(int padID, ButtonManager::ButtonType index, float neg = 1.0f)
|
||||
: _padID(padID), _index(index), _neg(neg)
|
||||
{
|
||||
|
|
|
@ -33,6 +33,11 @@ bool InputConfig::LoadConfig(bool isGC)
|
|||
std::string profile[MAX_BBMOTES];
|
||||
std::string path;
|
||||
|
||||
#if defined(ANDROID)
|
||||
bool use_ir_config = false;
|
||||
std::string ir_values[3];
|
||||
#endif
|
||||
|
||||
if (SConfig::GetInstance().GetGameID() != "00000000")
|
||||
{
|
||||
std::string type;
|
||||
|
@ -73,6 +78,18 @@ bool InputConfig::LoadConfig(bool isGC)
|
|||
}
|
||||
}
|
||||
}
|
||||
#if defined(ANDROID)
|
||||
// For use on android touchscreen IR pointer
|
||||
// Check for IR values
|
||||
if (control_section->Exists("IRWidth") && control_section->Exists("IRHeight") &&
|
||||
control_section->Exists("IRCenter"))
|
||||
{
|
||||
use_ir_config = true;
|
||||
control_section->Get("IRWidth", &ir_values[0]);
|
||||
control_section->Get("IRHeight", &ir_values[1]);
|
||||
control_section->Get("IRCenter", &ir_values[2]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (inifile.Load(File::GetUserPath(D_CONFIG_IDX) + m_ini_name + ".ini"))
|
||||
|
@ -80,6 +97,7 @@ bool InputConfig::LoadConfig(bool isGC)
|
|||
int n = 0;
|
||||
for (auto& controller : m_controllers)
|
||||
{
|
||||
IniFile::Section config;
|
||||
// Load settings from ini
|
||||
if (useProfile[n])
|
||||
{
|
||||
|
@ -91,13 +109,22 @@ bool InputConfig::LoadConfig(bool isGC)
|
|||
|
||||
IniFile profile_ini;
|
||||
profile_ini.Load(profile[n]);
|
||||
controller->LoadConfig(profile_ini.GetOrCreateSection("Profile"));
|
||||
config = *profile_ini.GetOrCreateSection("Profile");
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->LoadConfig(inifile.GetOrCreateSection(controller->GetName()));
|
||||
config = *inifile.GetOrCreateSection(controller->GetName());
|
||||
}
|
||||
|
||||
#if defined(ANDROID)
|
||||
// Only set for wii pads
|
||||
if (!isGC && use_ir_config)
|
||||
{
|
||||
config.Set("IR/Width", ir_values[0]);
|
||||
config.Set("IR/Height", ir_values[1]);
|
||||
config.Set("IR/Center", ir_values[2]);
|
||||
}
|
||||
#endif
|
||||
controller->LoadConfig(&config);
|
||||
// Update refs
|
||||
controller->UpdateReferences(g_controller_interface);
|
||||
|
||||
|
|
Loading…
Reference in New Issue