@@ -26,6 +26,7 @@
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.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 @@ protected void onCreate(Bundle savedInstanceState)
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 @@ protected void onCreate(Bundle savedInstanceState)

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 @@ protected void onCreate(Bundle savedInstanceState)
{
setTitle(mSelectedTitle);
}

mPreferences = PreferenceManager.getDefaultSharedPreferences(this);

}

@Override
@@ -348,6 +349,21 @@ protected void restoreState(Bundle savedInstanceState)
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 @@ private void enableFullscreenImmersive()
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 void handleMenuAction(@MenuAction int menuAction)
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 @@ private void chooseController()
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 @@ private void chooseController()
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(
@@ -225,7 +225,6 @@ private void addGeneralSettings(ArrayList<SettingsItem> sl)
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 @@ private void addGeneralSettings(ArrayList<SettingsItem> sl)
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 @@ else if (defaultCpuCore == 4) // AArch64
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));
}
@@ -54,7 +54,6 @@
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";
@@ -571,22 +571,11 @@ private void addWiimoteOverlayControls(String orientation)
}
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));
}
}

@@ -34,7 +34,7 @@
"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;
@@ -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;
}
}
@@ -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"
@@ -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"
@@ -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>
@@ -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>
@@ -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;
@@ -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,
};
@@ -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)
{
@@ -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));
}
@@ -9,6 +9,8 @@

namespace ciface::Android
{
void SetMotionSensorsEnabled(bool accelerometer_enabled, bool gyroscope_enabled);

void PopulateDevices();

class Touchscreen : public Core::Device