Merge pull request #8439 from JosJuice/android-native-motion-controls

Android: Native motion controls
This commit is contained in:
Anthony 2019-11-27 15:40:43 -08:00 committed by GitHub
commit 155016531f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 468 additions and 48 deletions

View File

@ -4,6 +4,12 @@
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false"/>
<uses-feature
android:name="android.hardware.sensor.accelerometer"
android:required="false"/>
<uses-feature
android:name="android.hardware.sensor.gyroscope"
android:required="false"/>
<uses-feature
android:name="android.hardware.gamepad"
android:required="false"/>

View File

@ -99,7 +99,7 @@ Guitar/Stick/Down = `Axis 411`
Guitar/Stick/Left = `Axis 412`
Guitar/Stick/Right = `Axis 413`
Guitar/Stick/Radius = 100,000000
Guitar/Whammy/Bar = `Axis = 414`
Guitar/Whammy/Bar = `Axis 414`
Drums/Buttons/- = `Button 500`
Drums/Buttons/+ = `Button 501`
Drums/Pads/Red = `Button 502`
@ -135,6 +135,18 @@ Turntable/Stick/Radius = 100,000000
Turntable/Effect/Dial = `Axis 621`
Turntable/Crossfade/Left = `Axis 623`
Turntable/Crossfade/Right = `Axis 624`
IMUAccelerometer/Left = `Axis 625`
IMUAccelerometer/Right = `Axis 626`
IMUAccelerometer/Forward = `Axis 627`
IMUAccelerometer/Backward = `Axis 628`
IMUAccelerometer/Up = `Axis 629`
IMUAccelerometer/Down = `Axis 630`
IMUGyroscope/Pitch Up = `Axis 631`
IMUGyroscope/Pitch Down = `Axis 632`
IMUGyroscope/Roll Left = `Axis 633`
IMUGyroscope/Roll Right = `Axis 634`
IMUGyroscope/Yaw Left = `Axis 635`
IMUGyroscope/Yaw Right = `Axis 636`
Source = 1
Rumble/Motor = `Rumble 700`
[Wiimote2]
@ -238,7 +250,7 @@ Guitar/Stick/Down = `Axis 411`
Guitar/Stick/Left = `Axis 412`
Guitar/Stick/Right = `Axis 413`
Guitar/Stick/Radius = 100,000000
Guitar/Whammy/Bar = `Axis = 414`
Guitar/Whammy/Bar = `Axis 414`
Drums/Buttons/- = `Button 500`
Drums/Buttons/+ = `Button 501`
Drums/Pads/Red = `Button 502`
@ -274,6 +286,18 @@ Turntable/Stick/Radius = 100,000000
Turntable/Effect/Dial = `Axis 621`
Turntable/Crossfade/Left = `Axis 623`
Turntable/Crossfade/Right = `Axis 624`
IMUAccelerometer/Left = `Axis 625`
IMUAccelerometer/Right = `Axis 626`
IMUAccelerometer/Forward = `Axis 627`
IMUAccelerometer/Backward = `Axis 628`
IMUAccelerometer/Up = `Axis 629`
IMUAccelerometer/Down = `Axis 630`
IMUGyroscope/Pitch Up = `Axis 631`
IMUGyroscope/Pitch Down = `Axis 632`
IMUGyroscope/Roll Left = `Axis 633`
IMUGyroscope/Roll Right = `Axis 634`
IMUGyroscope/Yaw Left = `Axis 635`
IMUGyroscope/Yaw Right = `Axis 636`
Source = 0
Rumble/Motor = `Rumble 700`
[Wiimote3]
@ -377,7 +401,7 @@ Guitar/Stick/Down = `Axis 411`
Guitar/Stick/Left = `Axis 412`
Guitar/Stick/Right = `Axis 413`
Guitar/Stick/Radius = 100,000000
Guitar/Whammy/Bar = `Axis = 414`
Guitar/Whammy/Bar = `Axis 414`
Drums/Buttons/- = `Button 500`
Drums/Buttons/+ = `Button 501`
Drums/Pads/Red = `Button 502`
@ -413,6 +437,18 @@ Turntable/Stick/Radius = 100,000000
Turntable/Effect/Dial = `Axis 621`
Turntable/Crossfade/Left = `Axis 623`
Turntable/Crossfade/Right = `Axis 624`
IMUAccelerometer/Left = `Axis 625`
IMUAccelerometer/Right = `Axis 626`
IMUAccelerometer/Forward = `Axis 627`
IMUAccelerometer/Backward = `Axis 628`
IMUAccelerometer/Up = `Axis 629`
IMUAccelerometer/Down = `Axis 630`
IMUGyroscope/Pitch Up = `Axis 631`
IMUGyroscope/Pitch Down = `Axis 632`
IMUGyroscope/Roll Left = `Axis 633`
IMUGyroscope/Roll Right = `Axis 634`
IMUGyroscope/Yaw Left = `Axis 635`
IMUGyroscope/Yaw Right = `Axis 636`
Source = 0
Rumble/Motor = `Rumble 700`
[Wiimote4]
@ -516,7 +552,7 @@ Guitar/Stick/Down = `Axis 411`
Guitar/Stick/Left = `Axis 412`
Guitar/Stick/Right = `Axis 413`
Guitar/Stick/Radius = 100,000000
Guitar/Whammy/Bar = `Axis = 414`
Guitar/Whammy/Bar = `Axis 414`
Drums/Buttons/- = `Button 500`
Drums/Buttons/+ = `Button 501`
Drums/Pads/Red = `Button 502`
@ -552,5 +588,17 @@ Turntable/Stick/Radius = 100,000000
Turntable/Effect/Dial = `Axis 621`
Turntable/Crossfade/Left = `Axis 623`
Turntable/Crossfade/Right = `Axis 624`
IMUAccelerometer/Left = `Axis 625`
IMUAccelerometer/Right = `Axis 626`
IMUAccelerometer/Forward = `Axis 627`
IMUAccelerometer/Backward = `Axis 628`
IMUAccelerometer/Up = `Axis 629`
IMUAccelerometer/Down = `Axis 630`
IMUGyroscope/Pitch Up = `Axis 631`
IMUGyroscope/Pitch Down = `Axis 632`
IMUGyroscope/Roll Left = `Axis 633`
IMUGyroscope/Roll Right = `Axis 634`
IMUGyroscope/Yaw Left = `Axis 635`
IMUGyroscope/Yaw Right = `Axis 636`
Source = 0
Rumble/Motor = `Rumble 700`

View File

@ -99,7 +99,7 @@ Guitar/Stick/Down = `Axis 411`
Guitar/Stick/Left = `Axis 412`
Guitar/Stick/Right = `Axis 413`
Guitar/Stick/Radius = 100,000000
Guitar/Whammy/Bar = `Axis = 414`
Guitar/Whammy/Bar = `Axis 414`
Drums/Buttons/- = `Button 500`
Drums/Buttons/+ = `Button 501`
Drums/Pads/Red = `Button 502`
@ -135,4 +135,16 @@ Turntable/Stick/Radius = 100,000000
Turntable/Effect/Dial = `Axis 621`
Turntable/Crossfade/Left = `Axis 623`
Turntable/Crossfade/Right = `Axis 624`
IMUAccelerometer/Left = `Axis 625`
IMUAccelerometer/Right = `Axis 626`
IMUAccelerometer/Forward = `Axis 627`
IMUAccelerometer/Backward = `Axis 628`
IMUAccelerometer/Up = `Axis 629`
IMUAccelerometer/Down = `Axis 630`
IMUGyroscope/Pitch Up = `Axis 631`
IMUGyroscope/Pitch Down = `Axis 632`
IMUGyroscope/Roll Left = `Axis 633`
IMUGyroscope/Roll Right = `Axis 634`
IMUGyroscope/Yaw Left = `Axis 635`
IMUGyroscope/Yaw Right = `Axis 636`
Rumble/Motor = `Rumble 700`

View File

@ -196,6 +196,18 @@ public final class NativeLibrary
public static final int TURNTABLE_CROSSFADE = 622;
public static final int TURNTABLE_CROSSFADE_LEFT = 623;
public static final int TURNTABLE_CROSSFADE_RIGHT = 624;
public static final int WIIMOTE_ACCEL_LEFT = 625;
public static final int WIIMOTE_ACCEL_RIGHT = 626;
public static final int WIIMOTE_ACCEL_FORWARD = 627;
public static final int WIIMOTE_ACCEL_BACKWARD = 628;
public static final int WIIMOTE_ACCEL_UP = 629;
public static final int WIIMOTE_ACCEL_DOWN = 630;
public static final int WIIMOTE_GYRO_PITCH_UP = 631;
public static final int WIIMOTE_GYRO_PITCH_DOWN = 632;
public static final int WIIMOTE_GYRO_ROLL_LEFT = 633;
public static final int WIIMOTE_GYRO_ROLL_RIGHT = 634;
public static final int WIIMOTE_GYRO_YAW_LEFT = 635;
public static final int WIIMOTE_GYRO_YAW_RIGHT = 636;
}
/**
@ -254,6 +266,9 @@ public final class NativeLibrary
Rumble.checkRumble(padID, state);
}
public static native void SetMotionSensorsEnabled(boolean accelerometerEnabled,
boolean gyroscopeEnabled);
public static native void NewGameIniFile();
public static native void LoadGameIniFile(String gameId);

View File

@ -26,6 +26,7 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
@ -49,6 +50,7 @@ import org.dolphinemu.dolphinemu.utils.ControllerMappingHelper;
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
import org.dolphinemu.dolphinemu.utils.Java_GCAdapter;
import org.dolphinemu.dolphinemu.utils.Java_WiimoteAdapter;
import org.dolphinemu.dolphinemu.utils.MotionListener;
import org.dolphinemu.dolphinemu.utils.Rumble;
import org.dolphinemu.dolphinemu.utils.TvUtil;
@ -67,6 +69,7 @@ public final class EmulationActivity extends AppCompatActivity
private EmulationFragment mEmulationFragment;
private SharedPreferences mPreferences;
private MotionListener mMotionListener;
private ControllerMappingHelper mControllerMappingHelper;
private Settings mSettings;
@ -97,7 +100,8 @@ public final class EmulationActivity extends AppCompatActivity
MENU_ACTION_SAVE_SLOT6, MENU_ACTION_LOAD_SLOT1, MENU_ACTION_LOAD_SLOT2,
MENU_ACTION_LOAD_SLOT3, MENU_ACTION_LOAD_SLOT4, MENU_ACTION_LOAD_SLOT5,
MENU_ACTION_LOAD_SLOT6, MENU_ACTION_EXIT, MENU_ACTION_CHANGE_DISC,
MENU_ACTION_RESET_OVERLAY, MENU_SET_IR_SENSITIVITY, MENU_ACTION_CHOOSE_DOUBLETAP})
MENU_ACTION_RESET_OVERLAY, MENU_SET_IR_SENSITIVITY, MENU_ACTION_CHOOSE_DOUBLETAP,
MENU_ACTION_SCREEN_ORIENTATION, MENU_ACTION_MOTION_CONTROLS})
public @interface MenuAction
{
}
@ -131,6 +135,8 @@ public final class EmulationActivity extends AppCompatActivity
public static final int MENU_ACTION_RESET_OVERLAY = 26;
public static final int MENU_SET_IR_SENSITIVITY = 27;
public static final int MENU_ACTION_CHOOSE_DOUBLETAP = 28;
public static final int MENU_ACTION_SCREEN_ORIENTATION = 29;
public static final int MENU_ACTION_MOTION_CONTROLS = 30;
private static SparseIntArray buttonsActionsMap = new SparseIntArray();
@ -177,6 +183,10 @@ public final class EmulationActivity extends AppCompatActivity
EmulationActivity.MENU_SET_IR_SENSITIVITY);
buttonsActionsMap.append(R.id.menu_emulation_choose_doubletap,
EmulationActivity.MENU_ACTION_CHOOSE_DOUBLETAP);
buttonsActionsMap.append(R.id.menu_screen_orientation,
EmulationActivity.MENU_ACTION_SCREEN_ORIENTATION);
buttonsActionsMap.append(R.id.menu_emulation_motion_controls,
EmulationActivity.MENU_ACTION_MOTION_CONTROLS);
}
private static String[] scanForSecondDisc(GameFile gameFile)
@ -252,13 +262,18 @@ public final class EmulationActivity extends AppCompatActivity
restoreState(savedInstanceState);
}
mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
mSettings = new Settings();
mSettings.loadSettings(null);
updateOrientation();
// TODO: The accurate way to find out which console we're emulating is to
// first launch emulation and then ask the core which console we're emulating
sIsGameCubeGame = Platform.fromNativeInt(mPlatform) == Platform.GAMECUBE;
mDeviceHasTouchScreen = getPackageManager().hasSystemFeature("android.hardware.touchscreen");
mMotionListener = new MotionListener(this);
mControllerMappingHelper = new ControllerMappingHelper();
int themeId;
@ -295,17 +310,6 @@ public final class EmulationActivity extends AppCompatActivity
setContentView(R.layout.activity_emulation);
BooleanSetting lockLandscapeSetting =
(BooleanSetting) mSettings.getSection(Settings.SECTION_INI_CORE)
.getSetting(SettingsFile.KEY_LOCK_LANDSCAPE);
boolean lockLandscape = lockLandscapeSetting == null || lockLandscapeSetting.getValue();
// Force landscape if set
if (mDeviceHasTouchScreen && lockLandscape)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
// Find or create the EmulationFragment
mEmulationFragment = (EmulationFragment) getSupportFragmentManager()
.findFragmentById(R.id.frame_emulation_fragment);
@ -321,9 +325,6 @@ public final class EmulationActivity extends AppCompatActivity
{
setTitle(mSelectedTitle);
}
mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
}
@Override
@ -348,6 +349,21 @@ public final class EmulationActivity extends AppCompatActivity
mPlatform = savedInstanceState.getInt(EXTRA_PLATFORM);
}
@Override
protected void onResume()
{
super.onResume();
if (!sIsGameCubeGame && mPreferences.getInt("motionControlsEnabled", 0) != 2)
mMotionListener.enable();
}
@Override
protected void onPause()
{
super.onPause();
mMotionListener.disable();
}
@Override
protected void onStop()
{
@ -414,6 +430,12 @@ public final class EmulationActivity extends AppCompatActivity
View.SYSTEM_UI_FLAG_IMMERSIVE);
}
private void updateOrientation()
{
setRequestedOrientation(mPreferences.getInt("emulationActivityOrientation",
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE));
}
private void toggleMenu()
{
boolean result = getSupportFragmentManager().popBackStackImmediate(
@ -629,6 +651,14 @@ public final class EmulationActivity extends AppCompatActivity
chooseDoubleTapButton();
return;
case MENU_ACTION_SCREEN_ORIENTATION:
chooseOrientation();
return;
case MENU_ACTION_MOTION_CONTROLS:
showMotionControlsOptions();
return;
case MENU_ACTION_EXIT:
// ATV menu is built using a fragment, this will pop that fragment before emulation ends.
if (TvUtil.isLeanback(getApplicationContext()))
@ -852,6 +882,8 @@ public final class EmulationActivity extends AppCompatActivity
editor.putInt("wiiController", indexSelected);
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Extension",
getResources().getStringArray(R.array.controllersValues)[indexSelected]);
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1",
"Options/Sideways Wiimote", indexSelected == 2 ? "True" : "False");
NativeLibrary.ReloadWiimoteConfig();
});
builder.setPositiveButton(getString(R.string.ok), (dialogInterface, i) ->
@ -864,6 +896,63 @@ public final class EmulationActivity extends AppCompatActivity
alertDialog.show();
}
private void showMotionControlsOptions()
{
final SharedPreferences.Editor editor = mPreferences.edit();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.emulation_motion_controls);
builder.setSingleChoiceItems(R.array.motionControlsEntries,
mPreferences.getInt("motionControlsEnabled", 0),
(dialog, indexSelected) ->
{
editor.putInt("motionControlsEnabled", indexSelected);
if (indexSelected != 2)
mMotionListener.enable();
else
mMotionListener.disable();
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "IMUIR/Enabled",
indexSelected != 1 ? "True" : "False");
NativeLibrary.ReloadWiimoteConfig();
});
builder.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> editor.apply());
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
private void chooseOrientation()
{
final int[] orientationValues = getResources().getIntArray(R.array.orientationValues);
int initialChoice = mPreferences.getInt("emulationActivityOrientation",
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
int initialIndex = -1;
for (int i = 0; i < orientationValues.length; i++)
{
if (orientationValues[i] == initialChoice)
initialIndex = i;
}
final SharedPreferences.Editor editor = mPreferences.edit();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.emulation_screen_orientation);
builder.setSingleChoiceItems(R.array.orientationEntries, initialIndex,
(dialog, indexSelected) ->
{
int orientation = orientationValues[indexSelected];
editor.putInt("emulationActivityOrientation", orientation);
});
builder.setPositiveButton(getString(R.string.ok), (dialogInterface, i) ->
{
editor.apply();
updateOrientation();
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
private void setIRSensitivity()
{
int ir_pitch = Integer.valueOf(

View File

@ -225,7 +225,6 @@ public final class SettingsFragmentPresenter
Setting autoDiscChange = null;
Setting analytics = null;
Setting enableSaveState;
Setting lockToLandscape;
SettingSection coreSection = mSettings.getSection(Settings.SECTION_INI_CORE);
SettingSection dspSection = mSettings.getSection(Settings.SECTION_INI_DSP);
@ -241,7 +240,6 @@ public final class SettingsFragmentPresenter
autoDiscChange = coreSection.getSetting(SettingsFile.KEY_AUTO_DISC_CHANGE);
analytics = analyticsSection.getSetting(SettingsFile.KEY_ANALYTICS_ENABLED);
enableSaveState = coreSection.getSetting(SettingsFile.KEY_ENABLE_SAVE_STATES);
lockToLandscape = coreSection.getSetting(SettingsFile.KEY_LOCK_LANDSCAPE);
// TODO: Having different emuCoresEntries/emuCoresValues for each architecture is annoying.
// The proper solution would be to have one emuCoresEntries and one emuCoresValues
@ -288,12 +286,6 @@ public final class SettingsFragmentPresenter
sl.add(new CheckBoxSetting(SettingsFile.KEY_ENABLE_SAVE_STATES, Settings.SECTION_INI_CORE,
R.string.enable_save_states, R.string.enable_save_states_description, false,
enableSaveState));
if (!TvUtil.isLeanback(DolphinApplication.getAppContext()))
{
sl.add(new CheckBoxSetting(SettingsFile.KEY_LOCK_LANDSCAPE, Settings.SECTION_INI_CORE,
R.string.lock_emulation_landscape, R.string.lock_emulation_landscape_desc, true,
lockToLandscape));
}
sl.add(new CheckBoxSetting(SettingsFile.KEY_ANALYTICS_ENABLED, Settings.SECTION_ANALYTICS,
R.string.analytics, 0, false, analytics));
}

View File

@ -54,7 +54,6 @@ public final class SettingsFile
public static final String KEY_SLOT_A_DEVICE = "SlotA";
public static final String KEY_SLOT_B_DEVICE = "SlotB";
public static final String KEY_ENABLE_SAVE_STATES = "EnableSaveStates";
public static final String KEY_LOCK_LANDSCAPE = "LockLandscape";
public static final String KEY_ANALYTICS_ENABLED = "Enabled";
public static final String KEY_ANALYTICS_PERMISSION_ASKED = "PermissionAsked";

View File

@ -571,22 +571,11 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
}
if (mPreferences.getBoolean("buttonToggleWii7", true))
{
if (mPreferences.getInt("wiiController", 3) == 2)
{
overlayDpads.add(initializeOverlayDpad(getContext(), R.drawable.gcwii_dpad,
R.drawable.gcwii_dpad_pressed_one_direction,
R.drawable.gcwii_dpad_pressed_two_directions,
ButtonType.WIIMOTE_RIGHT, ButtonType.WIIMOTE_LEFT,
ButtonType.WIIMOTE_UP, ButtonType.WIIMOTE_DOWN, orientation));
}
else
{
overlayDpads.add(initializeOverlayDpad(getContext(), R.drawable.gcwii_dpad,
R.drawable.gcwii_dpad_pressed_one_direction,
R.drawable.gcwii_dpad_pressed_two_directions,
ButtonType.WIIMOTE_UP, ButtonType.WIIMOTE_DOWN,
ButtonType.WIIMOTE_LEFT, ButtonType.WIIMOTE_RIGHT, orientation));
}
overlayDpads.add(initializeOverlayDpad(getContext(), R.drawable.gcwii_dpad,
R.drawable.gcwii_dpad_pressed_one_direction,
R.drawable.gcwii_dpad_pressed_two_directions,
ButtonType.WIIMOTE_UP, ButtonType.WIIMOTE_DOWN,
ButtonType.WIIMOTE_LEFT, ButtonType.WIIMOTE_RIGHT, orientation));
}
}

View File

@ -34,7 +34,7 @@ public final class DirectoryInitialization
"org.dolphinemu.dolphinemu.DIRECTORY_INITIALIZATION";
public static final String EXTRA_STATE = "directoryState";
private static final Integer WiimoteNewVersion = 2;
private static final int WiimoteNewVersion = 3; // Last changed in PR 8439
private static volatile DirectoryInitializationState directoryState = null;
private static String userPath;
private static String internalPath;

View File

@ -0,0 +1,126 @@
package org.dolphinemu.dolphinemu.utils;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.Surface;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.NativeLibrary.ButtonType;
public class MotionListener implements SensorEventListener
{
private final Activity mActivity;
private final SensorManager mSensorManager;
private final Sensor mAccelSensor;
private final Sensor mGyroSensor;
private boolean mEnabled = false;
// The same sampling period as for Wii Remotes
private static final int SAMPLING_PERIOD_US = 1000000 / 200;
public MotionListener(Activity activity)
{
mActivity = activity;
mSensorManager = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mGyroSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
}
@Override
public void onSensorChanged(SensorEvent sensorEvent)
{
float x, y;
float z = sensorEvent.values[2];
int orientation = mActivity.getWindowManager().getDefaultDisplay().getRotation();
switch (orientation)
{
default:
case Surface.ROTATION_0:
x = -sensorEvent.values[0];
y = -sensorEvent.values[1];
break;
case Surface.ROTATION_90:
x = sensorEvent.values[1];
y = -sensorEvent.values[0];
break;
case Surface.ROTATION_180:
x = sensorEvent.values[0];
y = sensorEvent.values[1];
break;
case Surface.ROTATION_270:
x = -sensorEvent.values[1];
y = sensorEvent.values[0];
break;
}
if (sensorEvent.sensor == mAccelSensor)
{
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_ACCEL_LEFT, x);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_ACCEL_RIGHT, x);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_ACCEL_FORWARD, y);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_ACCEL_BACKWARD, y);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_ACCEL_UP, z);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_ACCEL_DOWN, z);
}
if (sensorEvent.sensor == mGyroSensor)
{
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_GYRO_PITCH_UP, x);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_GYRO_PITCH_DOWN, x);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_GYRO_ROLL_LEFT, y);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_GYRO_ROLL_RIGHT, y);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_GYRO_YAW_LEFT, z);
NativeLibrary.onGamePadMoveEvent(NativeLibrary.TouchScreenDevice,
ButtonType.WIIMOTE_GYRO_YAW_RIGHT, z);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i)
{
// We don't care about this
}
public void enable()
{
if (mEnabled)
return;
if (mAccelSensor != null)
mSensorManager.registerListener(this, mAccelSensor, SAMPLING_PERIOD_US);
if (mGyroSensor != null)
mSensorManager.registerListener(this, mGyroSensor, SAMPLING_PERIOD_US);
NativeLibrary.SetMotionSensorsEnabled(mAccelSensor != null, mGyroSensor != null);
mEnabled = true;
}
public void disable()
{
if (!mEnabled)
return;
mSensorManager.unregisterListener(this);
NativeLibrary.SetMotionSensorsEnabled(false, false);
mEnabled = false;
}
}

View File

@ -113,6 +113,11 @@
</menu>
</item>
<item
android:id="@+id/menu_screen_orientation"
app:showAsAction="never"
android:title="@string/emulation_screen_orientation"/>
<item
android:id="@+id/menu_change_disc"
app:showAsAction="never"

View File

@ -112,6 +112,10 @@
<item
android:id="@+id/menu_emulation_choose_controller"
android:title="@string/emulation_choose_controller"/>
<item
android:id="@+id/menu_emulation_motion_controls"
android:title="@string/emulation_motion_controls"/>
<item
android:id="@+id/menu_emulation_ir_group"
android:title="@string/emulation_ir_group"
@ -133,6 +137,11 @@
</menu>
</item>
<item
android:id="@+id/menu_screen_orientation"
app:showAsAction="never"
android:title="@string/emulation_screen_orientation"/>
<item
android:id="@+id/menu_change_disc"
app:showAsAction="never"

View File

@ -350,4 +350,21 @@
<item>Wii Controller Settings</item>
<item>Clear Game Settings</item>
</string-array>
<string-array name="orientationEntries">
<item>Landscape</item>
<item>Portrait</item>
<item>Auto</item>
</string-array>
<integer-array name="orientationValues">
<item>0</item>
<item>1</item>
<item>-1</item>
</integer-array>
<string-array name="motionControlsEntries">
<item>Use Device Sensors (With Pointer Emulation)</item>
<item>Use Device Sensors (Without Pointer Emulation)</item>
<item>Don\'t Use Device Sensors</item>
</string-array>
</resources>

View File

@ -318,6 +318,8 @@
<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>
<string name="emulation_screen_orientation">Screen Orientation</string>
<string name="emulation_motion_controls">Motion Controls</string>
<!-- GC Adapter Menu-->
<string name="gc_adapter_rumble">Enable Vibration</string>

View File

@ -18,7 +18,7 @@ namespace ButtonManager
namespace
{
constexpr char touchScreenKey[] = "Touchscreen";
constexpr std::array<const char*, 143> configStrings{{
constexpr std::array<const char*, 155> configStrings{{
// GC
"InputA",
"InputB",
@ -168,11 +168,24 @@ constexpr std::array<const char*, 143> configStrings{{
"TurntableEffDial",
"TurntableCrossLeft",
"TurntableCrossRight",
// Wiimote IMU
"WiimoteAccelLeft",
"WiimoteAccelRight",
"WiimoteAccelForward",
"WiimoteAccelBackward",
"WiimoteAccelUp",
"WiimoteAccelDown",
"WiimoteGyroPitchUp",
"WiimoteGyroPitchDown",
"WiimoteGyroRollLeft",
"WiimoteGyroRollRight",
"WiimoteGyroYawLeft",
"WiimoteGyroYawRight",
// Rumble
"Rumble",
}};
constexpr std::array<ButtonType, 143> configTypes{{
constexpr std::array<ButtonType, 155> configTypes{{
// GC
BUTTON_A,
BUTTON_B,
@ -322,6 +335,19 @@ constexpr std::array<ButtonType, 143> configTypes{{
TURNTABLE_EFFECT_DIAL,
TURNTABLE_CROSSFADE_LEFT,
TURNTABLE_CROSSFADE_RIGHT,
// Wiimote IMU
WIIMOTE_ACCEL_LEFT,
WIIMOTE_ACCEL_RIGHT,
WIIMOTE_ACCEL_FORWARD,
WIIMOTE_ACCEL_BACKWARD,
WIIMOTE_ACCEL_UP,
WIIMOTE_ACCEL_DOWN,
WIIMOTE_GYRO_PITCH_UP,
WIIMOTE_GYRO_PITCH_DOWN,
WIIMOTE_GYRO_ROLL_LEFT,
WIIMOTE_GYRO_ROLL_RIGHT,
WIIMOTE_GYRO_YAW_LEFT,
WIIMOTE_GYRO_YAW_RIGHT,
// Rumble
RUMBLE,
}};
@ -562,6 +588,29 @@ void Init(const std::string& gameId)
new sBind(a, TURNTABLE_CROSSFADE_LEFT, BIND_AXIS, TURNTABLE_CROSSFADE_LEFT, -1.0f));
AddBind(touchScreenKey,
new sBind(a, TURNTABLE_CROSSFADE_RIGHT, BIND_AXIS, TURNTABLE_CROSSFADE_RIGHT, 1.0f));
// Wiimote IMU
AddBind(touchScreenKey, new sBind(a, WIIMOTE_ACCEL_LEFT, BIND_AXIS, WIIMOTE_ACCEL_LEFT, 1.0f));
AddBind(touchScreenKey,
new sBind(a, WIIMOTE_ACCEL_RIGHT, BIND_AXIS, WIIMOTE_ACCEL_RIGHT, -1.0f));
AddBind(touchScreenKey,
new sBind(a, WIIMOTE_ACCEL_FORWARD, BIND_AXIS, WIIMOTE_ACCEL_FORWARD, -1.0f));
AddBind(touchScreenKey,
new sBind(a, WIIMOTE_ACCEL_BACKWARD, BIND_AXIS, WIIMOTE_ACCEL_BACKWARD, 1.0f));
AddBind(touchScreenKey, new sBind(a, WIIMOTE_ACCEL_UP, BIND_AXIS, WIIMOTE_ACCEL_UP, 1.0f));
AddBind(touchScreenKey, new sBind(a, WIIMOTE_ACCEL_DOWN, BIND_AXIS, WIIMOTE_ACCEL_DOWN, -1.0f));
AddBind(touchScreenKey,
new sBind(a, WIIMOTE_GYRO_PITCH_UP, BIND_AXIS, WIIMOTE_GYRO_PITCH_UP, -1.0f));
AddBind(touchScreenKey,
new sBind(a, WIIMOTE_GYRO_PITCH_DOWN, BIND_AXIS, WIIMOTE_GYRO_PITCH_DOWN, 1.0f));
AddBind(touchScreenKey,
new sBind(a, WIIMOTE_GYRO_ROLL_LEFT, BIND_AXIS, WIIMOTE_GYRO_ROLL_LEFT, 1.0f));
AddBind(touchScreenKey,
new sBind(a, WIIMOTE_GYRO_ROLL_RIGHT, BIND_AXIS, WIIMOTE_GYRO_ROLL_RIGHT, -1.0f));
AddBind(touchScreenKey,
new sBind(a, WIIMOTE_GYRO_YAW_LEFT, BIND_AXIS, WIIMOTE_GYRO_YAW_LEFT, 1.0f));
AddBind(touchScreenKey,
new sBind(a, WIIMOTE_GYRO_YAW_RIGHT, BIND_AXIS, WIIMOTE_GYRO_YAW_RIGHT, -1.0f));
}
// Init our controller bindings
IniFile ini;

View File

@ -176,6 +176,19 @@ enum ButtonType
TURNTABLE_CROSSFADE = 622, // To Be Used on Java Side
TURNTABLE_CROSSFADE_LEFT = 623,
TURNTABLE_CROSSFADE_RIGHT = 624,
// Wiimote IMU
WIIMOTE_ACCEL_LEFT = 625,
WIIMOTE_ACCEL_RIGHT = 626,
WIIMOTE_ACCEL_FORWARD = 627,
WIIMOTE_ACCEL_BACKWARD = 628,
WIIMOTE_ACCEL_UP = 629,
WIIMOTE_ACCEL_DOWN = 630,
WIIMOTE_GYRO_PITCH_UP = 631,
WIIMOTE_GYRO_PITCH_DOWN = 632,
WIIMOTE_GYRO_ROLL_LEFT = 633,
WIIMOTE_GYRO_ROLL_RIGHT = 634,
WIIMOTE_GYRO_YAW_LEFT = 635,
WIIMOTE_GYRO_YAW_RIGHT = 636,
// Rumble
RUMBLE = 700,
};

View File

@ -47,6 +47,8 @@
#include "DiscIO/Enums.h"
#include "DiscIO/Volume.h"
#include "InputCommon/ControllerInterface/Android/Android.h"
#include "UICommon/UICommon.h"
#include "VideoCommon/OnScreenDisplay.h"
@ -200,6 +202,8 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePa
JNIEnv* env, jobject obj, jstring jDevice, jint Button, jint Action);
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadMoveEvent(
JNIEnv* env, jobject obj, jstring jDevice, jint Axis, jfloat Value);
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetMotionSensorsEnabled(
JNIEnv* env, jobject obj, jboolean accelerometer_enabled, jboolean gyroscope_enabled);
JNIEXPORT jstring JNICALL
Java_org_dolphinemu_dolphinemu_NativeLibrary_GetVersionString(JNIEnv* env, jobject obj);
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetGitRevision(JNIEnv* env,
@ -308,6 +312,12 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadMov
ButtonManager::GamepadAxisEvent(GetJString(env, jDevice), Axis, Value);
}
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetMotionSensorsEnabled(
JNIEnv* env, jobject obj, jboolean accelerometer_enabled, jboolean gyroscope_enabled)
{
ciface::Android::SetMotionSensorsEnabled(accelerometer_enabled, gyroscope_enabled);
}
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetVersionString(JNIEnv* env,
jobject obj)
{

View File

@ -10,6 +10,21 @@
namespace ciface::Android
{
static bool s_accelerometer_enabled = false;
static bool s_gyroscope_enabled = false;
void SetMotionSensorsEnabled(bool accelerometer_enabled, bool gyroscope_enabled)
{
const bool any_changes =
s_accelerometer_enabled != accelerometer_enabled || s_gyroscope_enabled != gyroscope_enabled;
s_accelerometer_enabled = accelerometer_enabled;
s_gyroscope_enabled = gyroscope_enabled;
if (any_changes)
g_controller_interface.RefreshDevices();
}
void PopulateDevices()
{
for (int i = 0; i < 8; ++i)
@ -185,6 +200,28 @@ Touchscreen::Touchscreen(int padID) : _padID(padID)
AddInput(new Axis(_padID, ButtonManager::TURNTABLE_CROSSFADE_RIGHT));
AddInput(new Axis(_padID, ButtonManager::TURNTABLE_EFFECT_DIAL));
// Wiimote IMU
// Only add inputs if we actually can receive data from the relevant sensor.
// Whether inputs exist affects what WiimoteEmu gets when calling ControlReference::BoundCount.
if (s_accelerometer_enabled)
{
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_ACCEL_LEFT));
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_ACCEL_RIGHT));
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_ACCEL_FORWARD));
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_ACCEL_BACKWARD));
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_ACCEL_UP));
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_ACCEL_DOWN));
}
if (s_gyroscope_enabled)
{
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_GYRO_PITCH_UP));
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_GYRO_PITCH_DOWN));
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_GYRO_ROLL_LEFT));
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_GYRO_ROLL_RIGHT));
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_GYRO_YAW_LEFT));
AddInput(new Axis(_padID, ButtonManager::WIIMOTE_GYRO_YAW_RIGHT));
}
// Rumble
AddOutput(new Motor(_padID, ButtonManager::RUMBLE));
}

View File

@ -9,6 +9,8 @@
namespace ciface::Android
{
void SetMotionSensorsEnabled(bool accelerometer_enabled, bool gyroscope_enabled);
void PopulateDevices();
class Touchscreen : public Core::Device