diff --git a/Source/Android/app/src/main/AndroidManifest.xml b/Source/Android/app/src/main/AndroidManifest.xml
index 0ba4bc2b51..f9554dbc73 100644
--- a/Source/Android/app/src/main/AndroidManifest.xml
+++ b/Source/Android/app/src/main/AndroidManifest.xml
@@ -4,6 +4,12 @@
+
+
diff --git a/Source/Android/app/src/main/assets/WiimoteNew.ini b/Source/Android/app/src/main/assets/WiimoteNew.ini
index 2ebd9d61d9..933c63e3ed 100644
--- a/Source/Android/app/src/main/assets/WiimoteNew.ini
+++ b/Source/Android/app/src/main/assets/WiimoteNew.ini
@@ -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`
diff --git a/Source/Android/app/src/main/assets/WiimoteProfile.ini b/Source/Android/app/src/main/assets/WiimoteProfile.ini
index 2546736d13..33e51c94d6 100644
--- a/Source/Android/app/src/main/assets/WiimoteProfile.ini
+++ b/Source/Android/app/src/main/assets/WiimoteProfile.ini
@@ -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`
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 1c748a5cea..171946a226 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
@@ -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);
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 1b5661b9a0..68562e9969 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
@@ -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(
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
index 271d556a4b..3c3f2f294f 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
@@ -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));
}
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 6f7bf15be8..8de9bf5281 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
@@ -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";
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 40e4a3d6ed..e2c6c1978c 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
@@ -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));
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java
index eeb3a78855..7742ac90ae 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java
@@ -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;
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/MotionListener.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/MotionListener.java
new file mode 100644
index 0000000000..31d1641aba
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/MotionListener.java
@@ -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;
+ }
+}
diff --git a/Source/Android/app/src/main/res/menu/menu_emulation.xml b/Source/Android/app/src/main/res/menu/menu_emulation.xml
index cfa126c4c9..6f0abbeae7 100644
--- a/Source/Android/app/src/main/res/menu/menu_emulation.xml
+++ b/Source/Android/app/src/main/res/menu/menu_emulation.xml
@@ -113,6 +113,11 @@
+
+
+
+
-
+
+
- Wii Controller Settings
- Clear Game Settings
+
+
+ - Landscape
+ - Portrait
+ - Auto
+
+
+ - 0
+ - 1
+ - -1
+
+
+
+ - Use Device Sensors (With Pointer Emulation)
+ - Use Device Sensors (Without Pointer Emulation)
+ - Don\'t Use Device Sensors
+
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index f1346dfdde..1e7ef2114a 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -318,6 +318,8 @@
Touch IR Pointer
IR Sensitivity
Double tap button
+ Screen Orientation
+ Motion Controls
Enable Vibration
diff --git a/Source/Android/jni/ButtonManager.cpp b/Source/Android/jni/ButtonManager.cpp
index 1ba6de758e..bd02525db4 100644
--- a/Source/Android/jni/ButtonManager.cpp
+++ b/Source/Android/jni/ButtonManager.cpp
@@ -18,7 +18,7 @@ namespace ButtonManager
namespace
{
constexpr char touchScreenKey[] = "Touchscreen";
-constexpr std::array configStrings{{
+constexpr std::array configStrings{{
// GC
"InputA",
"InputB",
@@ -168,11 +168,24 @@ constexpr std::array configStrings{{
"TurntableEffDial",
"TurntableCrossLeft",
"TurntableCrossRight",
+ // Wiimote IMU
+ "WiimoteAccelLeft",
+ "WiimoteAccelRight",
+ "WiimoteAccelForward",
+ "WiimoteAccelBackward",
+ "WiimoteAccelUp",
+ "WiimoteAccelDown",
+ "WiimoteGyroPitchUp",
+ "WiimoteGyroPitchDown",
+ "WiimoteGyroRollLeft",
+ "WiimoteGyroRollRight",
+ "WiimoteGyroYawLeft",
+ "WiimoteGyroYawRight",
// Rumble
"Rumble",
}};
-constexpr std::array configTypes{{
+constexpr std::array configTypes{{
// GC
BUTTON_A,
BUTTON_B,
@@ -322,6 +335,19 @@ constexpr std::array 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;
diff --git a/Source/Android/jni/ButtonManager.h b/Source/Android/jni/ButtonManager.h
index b7fd2f7647..71722c54d6 100644
--- a/Source/Android/jni/ButtonManager.h
+++ b/Source/Android/jni/ButtonManager.h
@@ -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,
};
diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp
index aa197f7e5e..d998097fee 100644
--- a/Source/Android/jni/MainAndroid.cpp
+++ b/Source/Android/jni/MainAndroid.cpp
@@ -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)
{
diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp
index 910b7553c9..21537cba15 100644
--- a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp
@@ -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));
}
diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.h b/Source/Core/InputCommon/ControllerInterface/Android/Android.h
index 82a1a47954..c9e7ddc0a9 100644
--- a/Source/Core/InputCommon/ControllerInterface/Android/Android.h
+++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.h
@@ -9,6 +9,8 @@
namespace ciface::Android
{
+void SetMotionSensorsEnabled(bool accelerometer_enabled, bool gyroscope_enabled);
+
void PopulateDevices();
class Touchscreen : public Core::Device