mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-20 03:23:07 +00:00
Merge branch 'master' of github.com:limelight-stream/limelight-android
This commit is contained in:
commit
f0f801ba3f
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.limelight"
|
package="com.limelight"
|
||||||
android:versionCode="24"
|
android:versionCode="26"
|
||||||
android:versionName="2.5.0.4" >
|
android:versionName="2.5.1" >
|
||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="16"
|
android:minSdkVersion="16"
|
||||||
|
@ -52,12 +52,13 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
|
|||||||
public static final int discoveryText=0x7f08000b;
|
public static final int discoveryText=0x7f08000b;
|
||||||
public static final int hardwareDec=0x7f080005;
|
public static final int hardwareDec=0x7f080005;
|
||||||
public static final int hostTextView=0x7f080000;
|
public static final int hostTextView=0x7f080000;
|
||||||
public static final int manuallyAddPc=0x7f080013;
|
public static final int manuallyAddPc=0x7f080014;
|
||||||
public static final int pcListView=0x7f080008;
|
public static final int pcListView=0x7f080008;
|
||||||
public static final int rowTextView=0x7f080014;
|
public static final int rowTextView=0x7f080015;
|
||||||
public static final int settingsButton=0x7f08000c;
|
public static final int settingsButton=0x7f08000c;
|
||||||
public static final int softwareDec=0x7f080003;
|
public static final int softwareDec=0x7f080003;
|
||||||
public static final int streamConfigGroup=0x7f08000d;
|
public static final int streamConfigGroup=0x7f08000d;
|
||||||
|
public static final int stretchToFill=0x7f080013;
|
||||||
public static final int surfaceView=0x7f08000a;
|
public static final int surfaceView=0x7f08000a;
|
||||||
}
|
}
|
||||||
public static final class layout {
|
public static final class layout {
|
||||||
|
Binary file not shown.
@ -2,12 +2,13 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#0099cc"
|
android:background="#000"
|
||||||
tools:context=".Game" >
|
tools:context=".Game" >
|
||||||
|
|
||||||
<SurfaceView
|
<SurfaceView
|
||||||
android:id="@+id/surfaceView"
|
android:id="@+id/surfaceView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
android:id="@+id/advancedSettingsButton"
|
android:id="@+id/advancedSettingsButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/streamConfigGroup"
|
android:layout_below="@+id/stretchToFill"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_marginTop="15dp"
|
android:layout_marginTop="15dp"
|
||||||
android:text="Advanced Settings" />
|
android:text="Advanced Settings" />
|
||||||
@ -67,6 +67,14 @@
|
|||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:text="Add PC Manually" />
|
android:text="Add PC Manually" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/stretchToFill"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/streamConfigGroup"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
android:text="Stretch video to fill screen" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
@ -94,8 +94,8 @@ public class AppView extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onDestroy() {
|
||||||
super.onStop();
|
super.onDestroy();
|
||||||
|
|
||||||
Dialog.closeDialogs();
|
Dialog.closeDialogs();
|
||||||
SpinnerDialog.closeDialogs();
|
SpinnerDialog.closeDialogs();
|
||||||
|
@ -32,6 +32,7 @@ import android.view.SurfaceView;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnGenericMotionListener;
|
import android.view.View.OnGenericMotionListener;
|
||||||
import android.view.View.OnTouchListener;
|
import android.view.View.OnTouchListener;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@ -58,6 +59,8 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
private boolean connecting = false;
|
private boolean connecting = false;
|
||||||
private boolean connected = false;
|
private boolean connected = false;
|
||||||
|
|
||||||
|
private boolean stretchToFit;
|
||||||
|
|
||||||
private ConfigurableDecoderRenderer decoderRenderer;
|
private ConfigurableDecoderRenderer decoderRenderer;
|
||||||
|
|
||||||
private WifiManager.WifiLock wifiLock;
|
private WifiManager.WifiLock wifiLock;
|
||||||
@ -76,6 +79,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
public static final String REFRESH_RATE_PREF_STRING = "FPS";
|
public static final String REFRESH_RATE_PREF_STRING = "FPS";
|
||||||
public static final String DECODER_PREF_STRING = "Decoder";
|
public static final String DECODER_PREF_STRING = "Decoder";
|
||||||
public static final String BITRATE_PREF_STRING = "Bitrate";
|
public static final String BITRATE_PREF_STRING = "Bitrate";
|
||||||
|
public static final String STRETCH_PREF_STRING = "Stretch";
|
||||||
|
|
||||||
public static final int BITRATE_DEFAULT_720_30 = 5;
|
public static final int BITRATE_DEFAULT_720_30 = 5;
|
||||||
public static final int BITRATE_DEFAULT_720_60 = 10;
|
public static final int BITRATE_DEFAULT_720_60 = 10;
|
||||||
@ -87,6 +91,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
public static final int DEFAULT_REFRESH_RATE = 60;
|
public static final int DEFAULT_REFRESH_RATE = 60;
|
||||||
public static final int DEFAULT_DECODER = 0;
|
public static final int DEFAULT_DECODER = 0;
|
||||||
public static final int DEFAULT_BITRATE = BITRATE_DEFAULT_720_60;
|
public static final int DEFAULT_BITRATE = BITRATE_DEFAULT_720_60;
|
||||||
|
public static final boolean DEFAULT_STRETCH = false;
|
||||||
|
|
||||||
public static final int FORCE_HARDWARE_DECODER = -1;
|
public static final int FORCE_HARDWARE_DECODER = -1;
|
||||||
public static final int AUTOSELECT_DECODER = 0;
|
public static final int AUTOSELECT_DECODER = 0;
|
||||||
@ -121,13 +126,6 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
// Inflate the content
|
// Inflate the content
|
||||||
setContentView(R.layout.activity_game);
|
setContentView(R.layout.activity_game);
|
||||||
|
|
||||||
// Listen for events on the game surface
|
|
||||||
SurfaceView sv = (SurfaceView) findViewById(R.id.surfaceView);
|
|
||||||
sv.setOnGenericMotionListener(this);
|
|
||||||
sv.setOnTouchListener(this);
|
|
||||||
|
|
||||||
SurfaceHolder sh = sv.getHolder();
|
|
||||||
|
|
||||||
// Start the spinner
|
// Start the spinner
|
||||||
spinner = SpinnerDialog.displayDialog(this, "Establishing Connection", "Starting connection", true);
|
spinner = SpinnerDialog.displayDialog(this, "Establishing Connection", "Starting connection", true);
|
||||||
|
|
||||||
@ -143,16 +141,32 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
drFlags |= VideoDecoderRenderer.FLAG_FORCE_HARDWARE_DECODING;
|
drFlags |= VideoDecoderRenderer.FLAG_FORCE_HARDWARE_DECODING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stretchToFit = prefs.getBoolean(STRETCH_PREF_STRING, DEFAULT_STRETCH);
|
||||||
|
if (stretchToFit) {
|
||||||
|
drFlags |= VideoDecoderRenderer.FLAG_FILL_SCREEN;
|
||||||
|
}
|
||||||
|
|
||||||
int refreshRate, bitrate;
|
int refreshRate, bitrate;
|
||||||
width = prefs.getInt(WIDTH_PREF_STRING, DEFAULT_WIDTH);
|
width = prefs.getInt(WIDTH_PREF_STRING, DEFAULT_WIDTH);
|
||||||
height = prefs.getInt(HEIGHT_PREF_STRING, DEFAULT_HEIGHT);
|
height = prefs.getInt(HEIGHT_PREF_STRING, DEFAULT_HEIGHT);
|
||||||
refreshRate = prefs.getInt(REFRESH_RATE_PREF_STRING, DEFAULT_REFRESH_RATE);
|
refreshRate = prefs.getInt(REFRESH_RATE_PREF_STRING, DEFAULT_REFRESH_RATE);
|
||||||
bitrate = prefs.getInt(BITRATE_PREF_STRING, DEFAULT_BITRATE);
|
bitrate = prefs.getInt(BITRATE_PREF_STRING, DEFAULT_BITRATE);
|
||||||
sh.setFixedSize(width, height);
|
|
||||||
|
|
||||||
Display display = getWindowManager().getDefaultDisplay();
|
Display display = getWindowManager().getDefaultDisplay();
|
||||||
display.getSize(screenSize);
|
display.getSize(screenSize);
|
||||||
|
|
||||||
|
// Listen for events on the game surface
|
||||||
|
SurfaceView sv = (SurfaceView) findViewById(R.id.surfaceView);
|
||||||
|
sv.setOnGenericMotionListener(this);
|
||||||
|
sv.setOnTouchListener(this);
|
||||||
|
|
||||||
|
SurfaceHolder sh = sv.getHolder();
|
||||||
|
|
||||||
|
if (stretchToFit) {
|
||||||
|
// Set the surface to the size of the video
|
||||||
|
sh.setFixedSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
// Warn the user if they're on a metered connection
|
// Warn the user if they're on a metered connection
|
||||||
checkDataConnection();
|
checkDataConnection();
|
||||||
@ -181,6 +195,21 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
sh.addCallback(this);
|
sh.addCallback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resizeSurfaceWithAspectRatio(SurfaceView sv, double vidWidth, double vidHeight)
|
||||||
|
{
|
||||||
|
// Get the visible width of the activity
|
||||||
|
double visibleWidth = getWindow().getDecorView().getWidth();
|
||||||
|
|
||||||
|
ViewGroup.LayoutParams lp = sv.getLayoutParams();
|
||||||
|
|
||||||
|
// Calculate the new size of the SurfaceView
|
||||||
|
lp.width = (int) visibleWidth;
|
||||||
|
lp.height = (int) ((vidHeight / vidWidth) * visibleWidth);
|
||||||
|
|
||||||
|
// Apply the size change
|
||||||
|
sv.setLayoutParams(lp);
|
||||||
|
}
|
||||||
|
|
||||||
private void checkDataConnection()
|
private void checkDataConnection()
|
||||||
{
|
{
|
||||||
ConnectivityManager mgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
ConnectivityManager mgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
@ -233,7 +262,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
int averageDecoderLat = decoderRenderer.getAverageDecoderLatency();
|
int averageDecoderLat = decoderRenderer.getAverageDecoderLatency();
|
||||||
String message = null;
|
String message = null;
|
||||||
if (averageEndToEndLat > 0) {
|
if (averageEndToEndLat > 0) {
|
||||||
message = "Average total frame latency: "+averageEndToEndLat+" ms";
|
message = "Average client-side frame latency: "+averageEndToEndLat+" ms";
|
||||||
if (averageDecoderLat > 0) {
|
if (averageDecoderLat > 0) {
|
||||||
message += " (hardware decoder latency: "+averageDecoderLat+" ms)";
|
message += " (hardware decoder latency: "+averageDecoderLat+" ms)";
|
||||||
}
|
}
|
||||||
@ -270,10 +299,27 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
return modifier;
|
return modifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isSourceFlagSet(int sourcesFlags, int flag) {
|
||||||
|
return (sourcesFlags & flag) == flag;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
if (event.getDevice() != null &&
|
InputDevice dev = event.getDevice();
|
||||||
(event.getDevice().getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC)) {
|
if (dev == null) {
|
||||||
|
return super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
int source = dev.getSources();
|
||||||
|
boolean handled = false;
|
||||||
|
if (isSourceFlagSet(source, InputDevice.SOURCE_DPAD) ||
|
||||||
|
isSourceFlagSet(source, InputDevice.SOURCE_GAMEPAD) ||
|
||||||
|
isSourceFlagSet(source, InputDevice.SOURCE_JOYSTICK))
|
||||||
|
{
|
||||||
|
handled = controllerHandler.handleButtonDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handled) {
|
||||||
short translated = keybTranslator.translate(event.getKeyCode());
|
short translated = keybTranslator.translate(event.getKeyCode());
|
||||||
if (translated == 0) {
|
if (translated == 0) {
|
||||||
return super.onKeyDown(keyCode, event);
|
return super.onKeyDown(keyCode, event);
|
||||||
@ -282,12 +328,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
keybTranslator.sendKeyDown(translated,
|
keybTranslator.sendKeyDown(translated,
|
||||||
getModifierState(event));
|
getModifierState(event));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (!controllerHandler.handleButtonDown(keyCode, event)) {
|
|
||||||
return super.onKeyDown(keyCode, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,22 +343,30 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
h.postDelayed(hideSystemUi, 2000);
|
h.postDelayed(hideSystemUi, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.getDevice() != null &&
|
InputDevice dev = event.getDevice();
|
||||||
(event.getDevice().getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC)) {
|
if (dev == null) {
|
||||||
|
return super.onKeyUp(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
int source = dev.getSources();
|
||||||
|
boolean handled = false;
|
||||||
|
if (isSourceFlagSet(source, InputDevice.SOURCE_DPAD) ||
|
||||||
|
isSourceFlagSet(source, InputDevice.SOURCE_GAMEPAD) ||
|
||||||
|
isSourceFlagSet(source, InputDevice.SOURCE_JOYSTICK))
|
||||||
|
{
|
||||||
|
handled = controllerHandler.handleButtonUp(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handled) {
|
||||||
short translated = keybTranslator.translate(event.getKeyCode());
|
short translated = keybTranslator.translate(event.getKeyCode());
|
||||||
if (translated == 0) {
|
if (translated == 0) {
|
||||||
return super.onKeyUp(keyCode, event);
|
return super.onKeyUp(keyCode, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
keybTranslator.sendKeyUp(translated,
|
keybTranslator.sendKeyUp(translated,
|
||||||
getModifierState(event));
|
getModifierState(event));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (!controllerHandler.handleButtonUp(keyCode, event)) {
|
|
||||||
return super.onKeyUp(keyCode, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -562,6 +611,13 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
public void surfaceCreated(SurfaceHolder holder) {
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
if (!connected && !connecting) {
|
if (!connected && !connecting) {
|
||||||
connecting = true;
|
connecting = true;
|
||||||
|
|
||||||
|
// Resize the surface to match the aspect ratio of the video
|
||||||
|
// This must be done after the surface is created.
|
||||||
|
if (!stretchToFit) {
|
||||||
|
resizeSurfaceWithAspectRatio((SurfaceView) findViewById(R.id.surfaceView), width, height);
|
||||||
|
}
|
||||||
|
|
||||||
conn.start(PlatformBinding.getDeviceName(), holder, drFlags,
|
conn.start(PlatformBinding.getDeviceName(), holder, drFlags,
|
||||||
PlatformBinding.getAudioRenderer(), decoderRenderer);
|
PlatformBinding.getAudioRenderer(), decoderRenderer);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.os.Bundle;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.CheckBox;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
@ -18,6 +19,7 @@ public class StreamSettings extends Activity {
|
|||||||
private Button advancedSettingsButton, addComputerButton;
|
private Button advancedSettingsButton, addComputerButton;
|
||||||
private SharedPreferences prefs;
|
private SharedPreferences prefs;
|
||||||
private RadioButton rbutton720p30, rbutton720p60, rbutton1080p30, rbutton1080p60;
|
private RadioButton rbutton720p30, rbutton720p60, rbutton1080p30, rbutton1080p60;
|
||||||
|
private CheckBox stretchToFill;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
@ -32,6 +34,7 @@ public class StreamSettings extends Activity {
|
|||||||
|
|
||||||
setContentView(R.layout.activity_stream_settings);
|
setContentView(R.layout.activity_stream_settings);
|
||||||
|
|
||||||
|
this.stretchToFill = (CheckBox) findViewById(R.id.stretchToFill);
|
||||||
this.advancedSettingsButton = (Button) findViewById(R.id.advancedSettingsButton);
|
this.advancedSettingsButton = (Button) findViewById(R.id.advancedSettingsButton);
|
||||||
this.addComputerButton = (Button) findViewById(R.id.manuallyAddPc);
|
this.addComputerButton = (Button) findViewById(R.id.manuallyAddPc);
|
||||||
this.rbutton720p30 = (RadioButton) findViewById(R.id.config720p30Selected);
|
this.rbutton720p30 = (RadioButton) findViewById(R.id.config720p30Selected);
|
||||||
@ -44,6 +47,8 @@ public class StreamSettings extends Activity {
|
|||||||
boolean res720p = prefs.getInt(Game.HEIGHT_PREF_STRING, Game.DEFAULT_HEIGHT) == 720;
|
boolean res720p = prefs.getInt(Game.HEIGHT_PREF_STRING, Game.DEFAULT_HEIGHT) == 720;
|
||||||
boolean fps30 = prefs.getInt(Game.REFRESH_RATE_PREF_STRING, Game.DEFAULT_REFRESH_RATE) == 30;
|
boolean fps30 = prefs.getInt(Game.REFRESH_RATE_PREF_STRING, Game.DEFAULT_REFRESH_RATE) == 30;
|
||||||
|
|
||||||
|
stretchToFill.setChecked(prefs.getBoolean(Game.STRETCH_PREF_STRING, Game.DEFAULT_STRETCH));
|
||||||
|
|
||||||
rbutton720p30.setChecked(false);
|
rbutton720p30.setChecked(false);
|
||||||
rbutton720p60.setChecked(false);
|
rbutton720p60.setChecked(false);
|
||||||
rbutton1080p30.setChecked(false);
|
rbutton1080p30.setChecked(false);
|
||||||
@ -119,5 +124,12 @@ public class StreamSettings extends Activity {
|
|||||||
startActivity(i);
|
startActivity(i);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
stretchToFill.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView,
|
||||||
|
boolean isChecked) {
|
||||||
|
prefs.edit().putBoolean(Game.STRETCH_PREF_STRING, isChecked).commit();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,6 +148,10 @@ public class ControllerHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapping.isDpad = (dev.getSources() & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD;
|
||||||
|
mapping.isGamepad = (dev.getSources() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD ||
|
||||||
|
(dev.getSources() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK;
|
||||||
|
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +181,48 @@ public class ControllerHandler {
|
|||||||
leftStickX, leftStickY, rightStickX, rightStickY);
|
leftStickX, leftStickY, rightStickX, rightStickY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int handleRemapping(ControllerMapping mapping, int keyCode) {
|
private static boolean isEventExpected(ControllerMapping mapping, int keyCode) {
|
||||||
|
if (mapping.isDpad) {
|
||||||
|
switch (keyCode) {
|
||||||
|
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_UP:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapping.isGamepad) {
|
||||||
|
switch (keyCode) {
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_MODE:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_START:
|
||||||
|
case KeyEvent.KEYCODE_MENU:
|
||||||
|
case KeyEvent.KEYCODE_BACK:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_SELECT:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_UP:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_B:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_A:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_X:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_Y:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_L1:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_R1:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_THUMBL:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_THUMBR:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_L2:
|
||||||
|
case KeyEvent.KEYCODE_BUTTON_R2:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int handleRemapping(ControllerMapping mapping, int keyCode) {
|
||||||
if (mapping.isDualShock4) {
|
if (mapping.isDualShock4) {
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
case KeyEvent.KEYCODE_BUTTON_Y:
|
case KeyEvent.KEYCODE_BUTTON_Y:
|
||||||
@ -317,6 +362,10 @@ public class ControllerHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isEventExpected(mapping, keyCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// If the button hasn't been down long enough, sleep for a bit before sending the up event
|
// If the button hasn't been down long enough, sleep for a bit before sending the up event
|
||||||
// This allows "instant" button presses (like OUYA's virtual menu button) to work. This
|
// This allows "instant" button presses (like OUYA's virtual menu button) to work. This
|
||||||
// path should not be triggered during normal usage.
|
// path should not be triggered during normal usage.
|
||||||
@ -440,6 +489,10 @@ public class ControllerHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isEventExpected(mapping, keyCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
case KeyEvent.KEYCODE_BUTTON_MODE:
|
case KeyEvent.KEYCODE_BUTTON_MODE:
|
||||||
inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG;
|
inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG;
|
||||||
@ -549,5 +602,7 @@ public class ControllerHandler {
|
|||||||
public float hatYDeadzone;
|
public float hatYDeadzone;
|
||||||
|
|
||||||
public boolean isDualShock4;
|
public boolean isDualShock4;
|
||||||
|
public boolean isDpad;
|
||||||
|
public boolean isGamepad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import java.io.File;
|
|||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -169,6 +170,7 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
long diff = nextFrameTime - System.currentTimeMillis();
|
long diff = nextFrameTime - System.currentTimeMillis();
|
||||||
|
|
||||||
if (diff > WAIT_CEILING_MS) {
|
if (diff > WAIT_CEILING_MS) {
|
||||||
|
LockSupport.parkNanos(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package com.limelight.binding.video;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.locks.LockSupport;
|
||||||
|
|
||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
import com.limelight.nvstream.av.ByteBufferDescriptor;
|
import com.limelight.nvstream.av.ByteBufferDescriptor;
|
||||||
@ -203,6 +204,9 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (outIndex) {
|
switch (outIndex) {
|
||||||
|
case MediaCodec.INFO_TRY_AGAIN_LATER:
|
||||||
|
LockSupport.parkNanos(1);
|
||||||
|
break;
|
||||||
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
|
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
|
||||||
LimeLog.info("Output buffers changed");
|
LimeLog.info("Output buffers changed");
|
||||||
break;
|
break;
|
||||||
|
@ -11,7 +11,7 @@ public class Dialog implements Runnable {
|
|||||||
private Activity activity;
|
private Activity activity;
|
||||||
private boolean endAfterDismiss;
|
private boolean endAfterDismiss;
|
||||||
|
|
||||||
AlertDialog alert;
|
private AlertDialog alert;
|
||||||
|
|
||||||
private static ArrayList<Dialog> rundownDialogs = new ArrayList<Dialog>();
|
private static ArrayList<Dialog> rundownDialogs = new ArrayList<Dialog>();
|
||||||
|
|
||||||
@ -25,13 +25,15 @@ public class Dialog implements Runnable {
|
|||||||
|
|
||||||
public static void closeDialogs()
|
public static void closeDialogs()
|
||||||
{
|
{
|
||||||
for (Dialog d : rundownDialogs) {
|
synchronized (rundownDialogs) {
|
||||||
if (d.alert.isShowing()) {
|
for (Dialog d : rundownDialogs) {
|
||||||
d.alert.dismiss();
|
if (d.alert.isShowing()) {
|
||||||
|
d.alert.dismiss();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rundownDialogs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
rundownDialogs.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void displayDialog(Activity activity, String title, String message, boolean endAfterDismiss)
|
public static void displayDialog(Activity activity, String title, String message, boolean endAfterDismiss)
|
||||||
@ -54,16 +56,21 @@ public class Dialog implements Runnable {
|
|||||||
|
|
||||||
alert.setButton(AlertDialog.BUTTON_NEUTRAL, "OK", new DialogInterface.OnClickListener() {
|
alert.setButton(AlertDialog.BUTTON_NEUTRAL, "OK", new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
alert.dismiss();
|
synchronized (rundownDialogs) {
|
||||||
rundownDialogs.remove(this);
|
rundownDialogs.remove(this);
|
||||||
|
alert.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
if (endAfterDismiss)
|
if (endAfterDismiss) {
|
||||||
activity.finish();
|
activity.finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
rundownDialogs.add(this);
|
synchronized (rundownDialogs) {
|
||||||
alert.show();
|
rundownDialogs.add(this);
|
||||||
|
alert.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,15 @@ public class SpinnerDialog implements Runnable,OnCancelListener {
|
|||||||
|
|
||||||
public static void closeDialogs()
|
public static void closeDialogs()
|
||||||
{
|
{
|
||||||
for (SpinnerDialog d : rundownDialogs) {
|
synchronized (rundownDialogs) {
|
||||||
if (d.progress.isShowing()) {
|
for (SpinnerDialog d : rundownDialogs) {
|
||||||
d.progress.dismiss();
|
if (d.progress.isShowing()) {
|
||||||
|
d.progress.dismiss();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rundownDialogs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
rundownDialogs.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dismiss()
|
public void dismiss()
|
||||||
@ -85,18 +87,27 @@ public class SpinnerDialog implements Runnable,OnCancelListener {
|
|||||||
progress.setCancelable(false);
|
progress.setCancelable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.show();
|
synchronized (rundownDialogs) {
|
||||||
|
rundownDialogs.add(this);
|
||||||
|
progress.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (progress.isShowing()) {
|
synchronized (rundownDialogs) {
|
||||||
progress.dismiss();
|
if (rundownDialogs.remove(this) && progress.isShowing()) {
|
||||||
|
progress.dismiss();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCancel(DialogInterface dialog) {
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
synchronized (rundownDialogs) {
|
||||||
|
rundownDialogs.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
// This will only be called if finish was true, so we don't need to check again
|
// This will only be called if finish was true, so we don't need to check again
|
||||||
activity.finish();
|
activity.finish();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user