Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support using android device's gyros as mouse, for aiming assist #1200

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA"/>
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA"/>

<uses-feature
android:name="android.hardware.sensor.gyroscope"
android:required="true" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
Expand Down
31 changes: 30 additions & 1 deletion app/src/main/java/com/limelight/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.input.InputManager;
import android.hardware.SensorEventListener;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
Expand All @@ -77,6 +80,7 @@
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import android.widget.Toast;
import android.hardware.SensorManager;

import java.io.ByteArrayInputStream;
import java.lang.reflect.InvocationTargetException;
Expand All @@ -90,7 +94,7 @@
public class Game extends Activity implements SurfaceHolder.Callback,
OnGenericMotionListener, OnTouchListener, NvConnectionListener, EvdevListener,
OnSystemUiVisibilityChangeListener, GameGestures, StreamView.InputCallbacks,
PerfOverlayListener, UsbDriverService.UsbDriverStateListener, View.OnKeyListener {
PerfOverlayListener, UsbDriverService.UsbDriverStateListener, View.OnKeyListener, SensorEventListener {
private int lastButtonState = 0;

// Only 2 touches are supported
Expand Down Expand Up @@ -152,6 +156,11 @@ public class Game extends Activity implements SurfaceHolder.Callback,
private WifiManager.WifiLock lowLatencyWifiLock;

private boolean connectedToUsbDriverService = false;

private SensorManager sensorManager;
private Sensor gameRotationVectorSensor;
private float gyroSensitivity;

private ServiceConnection usbDriverServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Expand Down Expand Up @@ -179,9 +188,27 @@ public void onServiceDisconnected(ComponentName componentName) {
public static final String EXTRA_APP_HDR = "HDR";
public static final String EXTRA_SERVER_CERT = "ServerCert";

@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
float dx = event.values[0];
float dy = event.values[1];

short x = (short) (dx * -gyroSensitivity);
short y = (short) (dy * gyroSensitivity);
conn.sendMouseMove(x, y);
}
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
this.gameRotationVectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

UiHelper.setLocale(this);

Expand Down Expand Up @@ -533,6 +560,8 @@ public void notifyCrash(Exception e) {

// The connection will be started when the surface gets created
streamView.getHolder().addCallback(this);
sensorManager.registerListener(this, gameRotationVectorSensor, SensorManager.SENSOR_DELAY_GAME);
gyroSensitivity = (float)prefConfig.gyroSensitivity;
}

private void setPreferredOrientationForCurrentDisplay() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class PreferenceConfiguration {
private static final String DISABLE_TOASTS_PREF_STRING = "checkbox_disable_warnings";
private static final String HOST_AUDIO_PREF_STRING = "checkbox_host_audio";
private static final String DEADZONE_PREF_STRING = "seekbar_deadzone";
private static final String GYROASSIST_PREF_STRING = "gyro_sensitivity";
private static final String OSC_OPACITY_PREF_STRING = "seekbar_osc_opacity";
private static final String LANGUAGE_PREF_STRING = "list_languages";
private static final String SMALL_ICONS_PREF_STRING = "checkbox_small_icon_mode";
Expand Down Expand Up @@ -57,6 +58,7 @@ public class PreferenceConfiguration {
private static final boolean DEFAULT_DISABLE_TOASTS = false;
private static final boolean DEFAULT_HOST_AUDIO = false;
private static final int DEFAULT_DEADZONE = 7;
private static final int DEFAULT_GYROASSIST = 10;
private static final int DEFAULT_OPACITY = 90;
public static final String DEFAULT_LANGUAGE = "default";
private static final boolean DEFAULT_MULTI_CONTROLLER = true;
Expand Down Expand Up @@ -104,6 +106,7 @@ public class PreferenceConfiguration {
public int bitrate;
public int videoFormat;
public int deadzonePercentage;
public float gyroSensitivity;
public int oscOpacity;
public boolean stretchVideo, enableSops, playHostAudio, disableWarnings;
public String language;
Expand Down Expand Up @@ -479,6 +482,7 @@ else if (audioConfig.equals("51")) {
config.framePacing = getFramePacingValue(context);

config.deadzonePercentage = prefs.getInt(DEADZONE_PREF_STRING, DEFAULT_DEADZONE);
config.gyroSensitivity = prefs.getInt(GYROASSIST_PREF_STRING, DEFAULT_GYROASSIST);

config.oscOpacity = prefs.getInt(OSC_OPACITY_PREF_STRING, DEFAULT_OPACITY);

Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@
<string name="title_seekbar_deadzone">Adjust analog stick deadzone</string>
<string name="summary_seekbar_deadzone">Note: Some games can enforce a larger deadzone than what Moonlight is configured to use.</string>
<string name="suffix_seekbar_deadzone">%</string>
<string name="title_gyro_sensitivity">Adjust gyro assist sensitivity</string>
<string name="summary_gyro_sensitivity">This enables using the phone gyros for aiminig/mouse control</string>
<string name="suffix_gyro_sensitivity">%</string>
<string name="title_checkbox_xb1_driver">Xbox 360/One USB gamepad driver</string>
<string name="summary_checkbox_xb1_driver">Enables a built-in USB driver for devices without native Xbox controller support</string>
<string name="title_checkbox_usb_bind_all">Override native Xbox gamepad support</string>
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@
android:summary="@string/summary_seekbar_deadzone"
android:text="@string/suffix_seekbar_deadzone"
android:title="@string/title_seekbar_deadzone"/>
<com.limelight.preferences.SeekBarPreference
android:key="gyro_sensitivity"
android:defaultValue="10"
android:max="100"
android:min="0"
android:summary="@string/summary_gyro_sensitivity"
android:text="@string/suffix_gyro_sensitivity"
android:title="@string/title_gyro_sensitivity"/>
<CheckBoxPreference
android:key="checkbox_touchscreen_trackpad"
android:title="@string/title_checkbox_touchscreen_trackpad"
Expand Down