add touch controls

This commit is contained in:
Karim Mreisi 2015-01-22 08:06:14 +01:00
parent b8141542f8
commit 56a6cee8f2
7 changed files with 770 additions and 6 deletions

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="limelight-android" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> <module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager"> <component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle"> <facet type="android-gradle" name="Android-Gradle">
<configuration> <configuration>
@ -103,18 +103,18 @@
</content> </content>
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" /> <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="androidasync-2.0.2" level="project" />
<orderEntry type="library" exported="" name="bcprov-jdk15on-1.51" level="project" /> <orderEntry type="library" exported="" name="bcprov-jdk15on-1.51" level="project" />
<orderEntry type="library" exported="" name="androidasync-2.0.5" level="project" />
<orderEntry type="library" exported="" name="gson-2.3.1" level="project" /> <orderEntry type="library" exported="" name="gson-2.3.1" level="project" />
<orderEntry type="library" exported="" name="ion-2.0.2" level="project" />
<orderEntry type="library" exported="" name="support-v4-r7" level="project" /> <orderEntry type="library" exported="" name="support-v4-r7" level="project" />
<orderEntry type="library" exported="" name="jmdns-fixed" level="project" /> <orderEntry type="library" exported="" name="jmdns-fixed" level="project" />
<orderEntry type="library" exported="" name="bcpkix-jdk15on-1.51" level="project" /> <orderEntry type="library" exported="" name="bcpkix-jdk15on-1.51" level="project" />
<orderEntry type="library" exported="" name="tinyrtsp" level="project" /> <orderEntry type="library" exported="" name="tinyrtsp" level="project" />
<orderEntry type="library" exported="" name="okhttp-2.1.0" level="project" />
<orderEntry type="library" exported="" name="limelight-common" level="project" /> <orderEntry type="library" exported="" name="limelight-common" level="project" />
<orderEntry type="library" exported="" name="okio-1.1.0" level="project" /> <orderEntry type="library" exported="" name="ion-2.0.5" level="project" />
<orderEntry type="library" exported="" name="okhttp-2.2.0" level="project" />
<orderEntry type="library" exported="" name="jcodec-0.1.9" level="project" /> <orderEntry type="library" exported="" name="jcodec-0.1.9" level="project" />
<orderEntry type="library" exported="" name="okio-1.2.0" level="project" />
</component> </component>
</module> </module>

View File

@ -8,6 +8,7 @@ import com.limelight.binding.input.KeyboardTranslator;
import com.limelight.binding.input.TouchContext; import com.limelight.binding.input.TouchContext;
import com.limelight.binding.input.evdev.EvdevListener; import com.limelight.binding.input.evdev.EvdevListener;
import com.limelight.binding.input.evdev.EvdevWatcher; import com.limelight.binding.input.evdev.EvdevWatcher;
import com.limelight.binding.input.virtual_controller.VirtualController;
import com.limelight.binding.video.ConfigurableDecoderRenderer; import com.limelight.binding.video.ConfigurableDecoderRenderer;
import com.limelight.nvstream.NvConnection; import com.limelight.nvstream.NvConnection;
import com.limelight.nvstream.NvConnectionListener; import com.limelight.nvstream.NvConnectionListener;
@ -41,6 +42,7 @@ import android.view.View.OnTouchListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast; import android.widget.Toast;
@ -56,6 +58,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
private TouchContext[] touchContextMap = new TouchContext[2]; private TouchContext[] touchContextMap = new TouchContext[2];
private ControllerHandler controllerHandler; private ControllerHandler controllerHandler;
private VirtualController virtualController;
private KeyboardTranslator keybTranslator; private KeyboardTranslator keybTranslator;
private PreferenceConfiguration prefConfig; private PreferenceConfiguration prefConfig;
@ -197,7 +200,14 @@ public class Game extends Activity implements SurfaceHolder.Callback,
evdevWatcher = new EvdevWatcher(this); evdevWatcher = new EvdevWatcher(this);
evdevWatcher.start(); evdevWatcher.start();
} }
if (prefConfig.virtualController_enable)
{
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.frameLayout);
virtualController = new VirtualController(conn, frameLayout, getApplicationContext(), getWindowManager());
}
// The connection will be started when the surface gets created // The connection will be started when the surface gets created
sh.addCallback(this); sh.addCallback(this);
} }

View File

@ -0,0 +1,298 @@
package com.limelight.binding.input.virtual_controller;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Karim Mreisi on 30.11.2014.
*/
public class AnalogStick extends View
{
private enum _STICK_STATE
{
NO_MOVEMENT,
MOVED
}
private static final boolean _PRINT_DEBUG_INFORMATION = false;
public interface AnalogStickListener
{
void onMovement(float x, float y);
}
public void addAnalogStickListener (AnalogStickListener listener)
{
listeners.add(listener);
}
private static final void _DBG(String text)
{
if (_PRINT_DEBUG_INFORMATION)
{
System.out.println("AnalogStick: " + text);
}
}
float radius_complete = 0;
float radius_dead_zone = 0;
float radius_analog_stick = 0;
float position_stick_x = 0;
float position_stick_y = 0;
boolean pressed = false;
_STICK_STATE stick_state = _STICK_STATE.NO_MOVEMENT;
List<AnalogStickListener> listeners = new ArrayList<AnalogStickListener>();
public AnalogStick(Context context)
{
super(context);
position_stick_x = getWidth() / 2;
position_stick_y = getHeight() / 2;
stick_state = _STICK_STATE.NO_MOVEMENT;
pressed = false;
}
private float getPercent(float value, int percent)
{
return value / 100 * percent;
}
private int getCorrectWidth()
{
return getWidth() > getHeight() ? getHeight() : getWidth();
}
private double getMovementRadius(float x, float y)
{
if (x == 0)
{
return y > 0 ? y : -y;
}
if (y == 0)
{
return x > 0 ? x : -x;
}
return Math.sqrt(x * x + y * y);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
radius_complete = getPercent(getCorrectWidth() / 2, 90);
radius_dead_zone = getPercent(getCorrectWidth() / 2, 10);
radius_analog_stick = getPercent(getCorrectWidth() / 2, 20);
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas)
{
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(getPercent(getCorrectWidth() / 2, 2));
paint.setColor(Color.YELLOW);
// draw outer circle
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_complete, paint);
// draw dead zone
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_dead_zone, paint);
// draw stick depending on state (no movement, moved, active(out of dead zone))
if (pressed)
{
switch (stick_state)
{
case NO_MOVEMENT:
{
paint.setColor(Color.BLUE);
canvas.drawCircle(position_stick_x, position_stick_y, radius_analog_stick, paint);
break;
}
case MOVED:
{
paint.setColor(Color.CYAN);
canvas.drawCircle(position_stick_x, position_stick_y, radius_analog_stick, paint);
break;
}
}
}
else
{
paint.setColor(Color.RED);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_analog_stick, paint);
}
// set transparent background
canvas.drawColor(Color.TRANSPARENT);
super.onDraw(canvas);
}
private double getAngle(float way_x, float way_y)
{
double angle = 0;
// prevent divisions by zero
if (way_x == 0)
{
if (way_y > 0)
{
angle = 0;
}
else if (way_y < 0)
{
angle = Math.PI;
}
}
else if (way_y == 0)
{
if (way_x > 0)
{
angle = Math.PI * 3/2;
}
else if (way_x < 0)
{
angle = Math.PI * 1/2;
}
}
else
{
if (way_x > 0)
{
if (way_y < 0)
{ // first quadrant
angle = 3 * Math.PI / 2 + Math.atan((double)(-way_y / way_x));
}
else
{ // second quadrant
angle = Math.PI + Math.atan((double)(way_x / way_y));
}
}
else
{
if (way_y > 0)
{ // third quadrant
angle = Math.PI / 2 + Math.atan((double)(way_y / -way_x));
}
else
{ // fourth quadrant
angle = 0 + Math.atan((double) (-way_x / -way_y));
}
}
}
_DBG("angle: " + angle + " way y: "+ way_y + " way x: " + way_x);
return angle;
}
private void moveActionCallback(float x, float y)
{
_DBG("movement x: " + x + " movement y: " + y);
// notify listeners
for (AnalogStickListener listener : listeners)
{
listener.onMovement(x, y);
}
}
private void updatePosition(float x, float y)
{
float way_x = -(getWidth() / 2 - x);
float way_y = -(getHeight() / 2 - y);
float movement_x = 0;
float movement_y = 0;
double movement_radius = getMovementRadius(way_x, way_y);
double movement_angle = getAngle(way_x, way_y);
// chop radius if out of outer circle
if (movement_radius > (radius_complete - radius_analog_stick))
{
movement_radius = radius_complete - radius_analog_stick;
}
float correlated_y = (float)(Math.sin(Math.PI / 2 - movement_angle) * (movement_radius));
float correlated_x = (float)(Math.cos(Math.PI / 2 - movement_angle) * (movement_radius));
float complete = (radius_complete - radius_analog_stick);
movement_x = -(1 / complete) * correlated_x;
movement_y = (1 / complete) * correlated_y;
position_stick_x = getWidth() / 2 - correlated_x;
position_stick_y = getHeight() / 2 - correlated_y;
// check if analog stick is inside of dead zone
if (movement_radius > radius_dead_zone)
{
moveActionCallback(movement_x, movement_y);
stick_state = _STICK_STATE.MOVED;
}
else
{
stick_state = _STICK_STATE.NO_MOVEMENT;
}
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
// get masked (not specific to a pointer) action
int action = event.getActionMasked();
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_MOVE:
{
pressed = true;
break;
}
default:
{
pressed = false;
break;
}
}
if (pressed)
{ // when is pressed calculate new positions (will trigger movement if necessary)
updatePosition(event.getX(), event.getY());
}
else
{ // no longer pressed reset movement
moveActionCallback(0, 0);
}
// to get view refreshed
invalidate();
return true;
}
}

View File

@ -0,0 +1,427 @@
package com.limelight.binding.input.virtual_controller;
import android.animation.LayoutTransition;
import android.app.ActionBar;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import com.limelight.nvstream.NvConnection;
import com.limelight.nvstream.input.ControllerPacket;
/**
* Created by Karim Mreisi on 30.11.2014.
*/
public class VirtualController
{
private static final boolean _PRINT_DEBUG_INFORMATION = false;
private static final void _DBG(String text)
{
if (_PRINT_DEBUG_INFORMATION)
{
System.out.println("VirtualController: " + text);
}
}
private short inputMap = 0x0000;
private byte leftTrigger = 0x00;
private byte rightTrigger = 0x00;
private short rightStickX = 0x0000;
private short rightStickY = 0x0000;
private short leftStickX = 0x0000;
private short leftStickY = 0x0000;
private FrameLayout frame_layout = null;
private RelativeLayout relative_layout = null;
private RelativeLayout.LayoutParams layoutParamsButtonDPadLeft = null;
private RelativeLayout.LayoutParams layoutParamsButtonDPadRight = null;
private RelativeLayout.LayoutParams layoutParamsButtonDPadUp = null;
private RelativeLayout.LayoutParams layoutParamsButtonDPadDown = null;
private RelativeLayout.LayoutParams layoutParamsButtonA = null;
private RelativeLayout.LayoutParams layoutParamsButtonB = null;
private RelativeLayout.LayoutParams layoutParamsButtonX = null;
private RelativeLayout.LayoutParams layoutParamsButtonY = null;
private RelativeLayout.LayoutParams layoutParamsButtonR1 = null;
private RelativeLayout.LayoutParams layoutParamsButtonR2 = null;
private RelativeLayout.LayoutParams layoutParamsParamsStick = null;
private RelativeLayout.LayoutParams layoutParamsParamsStick2 = null;
private Button buttonStart = null;
private Button buttonSelect = null;
private Button buttonESC = null;
private Button buttonDPadLeft = null;
private Button buttonDPadRight = null;
private Button buttonDPadUp = null;
private Button buttonDPadDown = null;
private Button buttonA = null;
private Button buttonB = null;
private Button buttonX = null;
private Button buttonY = null;
private Button buttonR1 = null;
private Button buttonR2 = null;
private AnalogStick stick = null;
private AnalogStick stick2 = null;
NvConnection connection = null;
private int getPercentageV(int percent)
{
return (int)(((float)frame_layout.getHeight() / (float)100) * (float)percent);
}
private int getPercentageH(int percent)
{
return (int)(((float)frame_layout.getWidth() / (float)100) * (float)percent);
}
private void setPercentilePosition(RelativeLayout.LayoutParams parm, int pos_x, int pos_y)
{
parm.setMargins(
(int)(((float)frame_layout.getWidth() / (float)100 * (float)pos_x) - ((float)parm.width / (float)2)),
(int)(((float)frame_layout.getHeight() / (float)100 * (float)pos_y) - ((float)parm.height / (float)2)),
0,
0
);
}
private void onButtonTouchEvent(View v, MotionEvent event, short key)
{
// get masked (not specific to a pointer) action
int action = event.getActionMasked();
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
{
inputMap |= key;
sendControllerInputPacket();
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
{
inputMap &= ~key;
sendControllerInputPacket();
break;
}
}
}
void refreshLayout()
{
relative_layout.removeAllViews();
layoutParamsButtonDPadLeft = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonDPadRight = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonDPadUp = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonDPadDown = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsParamsStick = new RelativeLayout.LayoutParams(getPercentageV(40), getPercentageV(40));
layoutParamsParamsStick2 = new RelativeLayout.LayoutParams(getPercentageV(40), getPercentageV(40));
layoutParamsButtonA = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonB = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonX = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonY = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonR1 = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonR2 = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
setPercentilePosition(layoutParamsButtonDPadLeft, 5, 45);
setPercentilePosition(layoutParamsButtonDPadRight, 15, 45);
setPercentilePosition(layoutParamsButtonDPadUp, 10, 35);
setPercentilePosition(layoutParamsButtonDPadDown, 10, 55);
setPercentilePosition(layoutParamsParamsStick, 22, 78);
setPercentilePosition(layoutParamsParamsStick2, 78, 78);
setPercentilePosition(layoutParamsButtonA, 85, 52);
setPercentilePosition(layoutParamsButtonB, 92, 47);
setPercentilePosition(layoutParamsButtonX, 85, 40);
setPercentilePosition(layoutParamsButtonY, 92, 35);
setPercentilePosition(layoutParamsButtonR1, 95, 68);
setPercentilePosition(layoutParamsButtonR2, 95, 80);
relative_layout.addView(buttonDPadLeft, layoutParamsButtonDPadLeft);
relative_layout.addView(buttonDPadRight, layoutParamsButtonDPadRight);
relative_layout.addView(buttonDPadUp, layoutParamsButtonDPadUp);
relative_layout.addView(buttonDPadDown, layoutParamsButtonDPadDown);
relative_layout.addView(stick, layoutParamsParamsStick);
relative_layout.addView(stick2, layoutParamsParamsStick2);
relative_layout.addView(buttonA, layoutParamsButtonA);
relative_layout.addView(buttonB, layoutParamsButtonB);
relative_layout.addView(buttonX, layoutParamsButtonX);
relative_layout.addView(buttonY, layoutParamsButtonY);
relative_layout.addView(buttonR1, layoutParamsButtonR1);
relative_layout.addView(buttonR2, layoutParamsButtonR2);
}
public VirtualController(final NvConnection conn, FrameLayout layout, Context context, WindowManager window_manager)
{
this.connection = conn;
frame_layout = layout;
relative_layout = new RelativeLayout(context);
relative_layout.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
{
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
{
refreshLayout();
}
});
frame_layout.addView(relative_layout);
buttonDPadLeft = new Button(context);
buttonDPadLeft.setText("LF");
buttonDPadLeft.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
onButtonTouchEvent(v, event, ControllerPacket.LEFT_FLAG);
return false;
}
});
buttonDPadRight = new Button(context);
buttonDPadRight.setText("RI");
buttonDPadRight.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
onButtonTouchEvent(v, event, ControllerPacket.RIGHT_FLAG);
return false;
}
});
buttonDPadUp = new Button(context);
buttonDPadUp.setText("UP");
buttonDPadUp.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
onButtonTouchEvent(v, event, ControllerPacket.UP_FLAG);
return false;
}
});
buttonDPadDown = new Button(context);
buttonDPadDown.setText("DW");
buttonDPadDown.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
onButtonTouchEvent(v, event, ControllerPacket.DOWN_FLAG);
return false;
}
});
buttonX = new Button(context);
buttonX.setText("X");
buttonX.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
onButtonTouchEvent(v, event, ControllerPacket.X_FLAG);
return false;
}
});
buttonY = new Button(context);
buttonY.setText("Y");
buttonY.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
onButtonTouchEvent(v, event, ControllerPacket.Y_FLAG);
return false;
}
});
buttonA = new Button(context);
buttonA.setText("A");
buttonA.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
onButtonTouchEvent(v, event, ControllerPacket.A_FLAG);
return false;
}
});
buttonB = new Button(context);
buttonB.setText("B");
buttonB.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
onButtonTouchEvent(v, event, ControllerPacket.B_FLAG);
return false;
}
});
buttonR1 = new Button(context);
buttonR1.setText("LT");
buttonR1.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
// get masked (not specific to a pointer) action
int action = event.getActionMasked();
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
{
leftTrigger = (byte)(1 * 0xFF);
sendControllerInputPacket();
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
{
leftTrigger = (byte)(0 * 0xFF);
sendControllerInputPacket();
break;
}
}
return false;
}
});
buttonR2 = new Button(context);
buttonR2.setText("RT");
buttonR2.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
// get masked (not specific to a pointer) action
int action = event.getActionMasked();
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
{
rightTrigger = (byte)(1 * 0xFF);
sendControllerInputPacket();
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
{
rightTrigger = (byte)(0 * 0xFF);
sendControllerInputPacket();
break;
}
}
return false;
}
});
stick = new AnalogStick(context);
stick.addAnalogStickListener(new AnalogStick.AnalogStickListener()
{
@Override
public void onMovement(float x, float y)
{
leftStickX = (short) (x * 0x7FFE);
leftStickY = (short) (y * 0x7FFE);
_DBG("LEFT STICK MOVEMENT X: "+ leftStickX + " Y: " + leftStickY);
sendControllerInputPacket();
}
});
stick2 = new AnalogStick(context);
stick2.addAnalogStickListener(new AnalogStick.AnalogStickListener()
{
@Override
public void onMovement(float x, float y)
{
rightStickX = (short) (x * 0x7FFE);
rightStickY = (short) (y * 0x7FFE);
_DBG("RIGHT STICK MOVEMENT X: "+ rightStickX + " Y: " + rightStickY);
sendControllerInputPacket();
}
});
refreshLayout();
}
private void sendControllerInputPacket()
{
try
{
_DBG("INPUT_MAP + " + inputMap);
_DBG("LEFT_TRIGGER " + leftTrigger);
_DBG("RIGHT_TRIGGER " + rightTrigger);
_DBG("LEFT STICK X: " + leftStickX + " Y: " + leftStickY);
_DBG("RIGHT STICK X: " + rightStickX + " Y: " + rightStickY);
_DBG("RIGHT STICK X: " + rightStickX + " Y: " + rightStickY);
connection.sendControllerInput(inputMap, leftTrigger, rightTrigger,
leftStickX, leftStickY, rightStickX, rightStickY);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

View File

@ -14,6 +14,9 @@ public class PreferenceConfiguration {
private static final String HOST_AUDIO_PREF_STRING = "checkbox_host_audio"; private static final String HOST_AUDIO_PREF_STRING = "checkbox_host_audio";
private static final String DEADZONE_PREF_STRING = "seekbar_deadzone"; private static final String DEADZONE_PREF_STRING = "seekbar_deadzone";
private static final String VIRTUAL_CONTROLLER_ENABLE = "virtual_controller_checkbox_enable";
private static final Boolean VIRTUAL_CONTROLLER_ENABLE_DEFAULT = true;
private static final int BITRATE_DEFAULT_720_30 = 5; private static final int BITRATE_DEFAULT_720_30 = 5;
private static final int BITRATE_DEFAULT_720_60 = 10; private static final int BITRATE_DEFAULT_720_60 = 10;
private static final int BITRATE_DEFAULT_1080_30 = 10; private static final int BITRATE_DEFAULT_1080_30 = 10;
@ -38,6 +41,8 @@ public class PreferenceConfiguration {
public int deadzonePercentage; public int deadzonePercentage;
public boolean stretchVideo, enableSops, playHostAudio, disableWarnings; public boolean stretchVideo, enableSops, playHostAudio, disableWarnings;
public boolean virtualController_enable;
public static int getDefaultBitrate(String resFpsString) { public static int getDefaultBitrate(String resFpsString) {
if (resFpsString.equals("720p30")) { if (resFpsString.equals("720p30")) {
return BITRATE_DEFAULT_720_30; return BITRATE_DEFAULT_720_30;
@ -141,6 +146,8 @@ public class PreferenceConfiguration {
config.stretchVideo = prefs.getBoolean(STRETCH_PREF_STRING, DEFAULT_STRETCH); config.stretchVideo = prefs.getBoolean(STRETCH_PREF_STRING, DEFAULT_STRETCH);
config.playHostAudio = prefs.getBoolean(HOST_AUDIO_PREF_STRING, DEFAULT_HOST_AUDIO); config.playHostAudio = prefs.getBoolean(HOST_AUDIO_PREF_STRING, DEFAULT_HOST_AUDIO);
config.virtualController_enable = prefs.getBoolean(VIRTUAL_CONTROLLER_ENABLE, VIRTUAL_CONTROLLER_ENABLE_DEFAULT);
return config; return config;
} }
} }

View File

@ -1,5 +1,6 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/frameLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".Game" > tools:context=".Game" >

21
limelight_vc.iml Normal file
View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/classes/main" />
<output-test url="file://$MODULE_DIR$/build/classes/test" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>