mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-19 02:53:05 +00:00
add touch controls
This commit is contained in:
parent
b8141542f8
commit
56a6cee8f2
10
app/app.iml
10
app/app.iml
@ -1,5 +1,5 @@
|
||||
<?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">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
@ -103,18 +103,18 @@
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
|
||||
<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="androidasync-2.0.5" 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="jmdns-fixed" 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="okhttp-2.1.0" 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="okio-1.2.0" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
@ -8,6 +8,7 @@ import com.limelight.binding.input.KeyboardTranslator;
|
||||
import com.limelight.binding.input.TouchContext;
|
||||
import com.limelight.binding.input.evdev.EvdevListener;
|
||||
import com.limelight.binding.input.evdev.EvdevWatcher;
|
||||
import com.limelight.binding.input.virtual_controller.VirtualController;
|
||||
import com.limelight.binding.video.ConfigurableDecoderRenderer;
|
||||
import com.limelight.nvstream.NvConnection;
|
||||
import com.limelight.nvstream.NvConnectionListener;
|
||||
@ -41,6 +42,7 @@ import android.view.View.OnTouchListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
||||
@ -56,6 +58,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
private TouchContext[] touchContextMap = new TouchContext[2];
|
||||
|
||||
private ControllerHandler controllerHandler;
|
||||
private VirtualController virtualController;
|
||||
private KeyboardTranslator keybTranslator;
|
||||
|
||||
private PreferenceConfiguration prefConfig;
|
||||
@ -198,6 +201,13 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
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
|
||||
sh.addCallback(this);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,9 @@ public class PreferenceConfiguration {
|
||||
private static final String HOST_AUDIO_PREF_STRING = "checkbox_host_audio";
|
||||
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_60 = 10;
|
||||
private static final int BITRATE_DEFAULT_1080_30 = 10;
|
||||
@ -38,6 +41,8 @@ public class PreferenceConfiguration {
|
||||
public int deadzonePercentage;
|
||||
public boolean stretchVideo, enableSops, playHostAudio, disableWarnings;
|
||||
|
||||
public boolean virtualController_enable;
|
||||
|
||||
public static int getDefaultBitrate(String resFpsString) {
|
||||
if (resFpsString.equals("720p30")) {
|
||||
return BITRATE_DEFAULT_720_30;
|
||||
@ -141,6 +146,8 @@ public class PreferenceConfiguration {
|
||||
config.stretchVideo = prefs.getBoolean(STRETCH_PREF_STRING, DEFAULT_STRETCH);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/frameLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".Game" >
|
||||
|
21
limelight_vc.iml
Normal file
21
limelight_vc.iml
Normal 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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user