add virtual controller element abstraction class

This commit is contained in:
Karim Mreisi
2015-01-28 07:12:20 +01:00
39 changed files with 1468 additions and 1087 deletions

View File

@@ -10,6 +10,7 @@ import android.view.MotionEvent;
import com.limelight.LimeLog;
import com.limelight.nvstream.NvConnection;
import com.limelight.nvstream.input.ControllerPacket;
import com.limelight.ui.GameGestures;
import com.limelight.utils.Vector2d;
public class ControllerHandler {
@@ -30,6 +31,9 @@ public class ControllerHandler {
private long lastLbUpTime = 0;
private long lastRbUpTime = 0;
private static final int MAXIMUM_BUMPER_UP_DELAY_MS = 100;
private long startDownTime = 0;
private static final int START_DOWN_TIME_KEYB_MS = 750;
private static final int MINIMUM_BUTTON_DOWN_TIME_MS = 25;
@@ -46,10 +50,12 @@ public class ControllerHandler {
private NvConnection conn;
private double stickDeadzone;
private final ControllerMapping defaultMapping = new ControllerMapping();
private GameGestures gestures;
private boolean hasGameController;
public ControllerHandler(NvConnection conn, int deadzonePercentage) {
public ControllerHandler(NvConnection conn, GameGestures gestures, int deadzonePercentage) {
this.conn = conn;
this.gestures = gestures;
// HACK: For now we're hardcoding a 10% deadzone. Some deadzone
// is required for controller batching support to work.
@@ -513,6 +519,9 @@ public class ControllerHandler {
break;
case KeyEvent.KEYCODE_BUTTON_START:
case KeyEvent.KEYCODE_MENU:
if (SystemClock.uptimeMillis() - startDownTime > ControllerHandler.START_DOWN_TIME_KEYB_MS) {
gestures.showKeyboard();
}
inputMap &= ~ControllerPacket.PLAY_FLAG;
break;
case KeyEvent.KEYCODE_BACK:
@@ -621,6 +630,9 @@ public class ControllerHandler {
break;
case KeyEvent.KEYCODE_BUTTON_START:
case KeyEvent.KEYCODE_MENU:
if (event.getRepeatCount() == 0) {
startDownTime = SystemClock.uptimeMillis();
}
inputMap |= ControllerPacket.PLAY_FLAG;
break;
case KeyEvent.KEYCODE_BACK:

View File

@@ -9,6 +9,7 @@ public class TouchContext {
private int originalTouchX = 0;
private int originalTouchY = 0;
private long originalTouchTime = 0;
private boolean cancelled;
private NvConnection conn;
private int actionIndex;
@@ -56,12 +57,17 @@ public class TouchContext {
originalTouchX = lastTouchX = eventX;
originalTouchY = lastTouchY = eventY;
originalTouchTime = System.currentTimeMillis();
return true;
cancelled = false;
return true;
}
public void touchUpEvent(int eventX, int eventY)
{
if (cancelled) {
return;
}
if (isTap())
{
byte buttonIndex = getMouseButtonIndex();
@@ -81,8 +87,8 @@ public class TouchContext {
}
public boolean touchMoveEvent(int eventX, int eventY)
{
if (eventX != lastTouchX || eventY != lastTouchY)
{
if (eventX != lastTouchX || eventY != lastTouchY)
{
// We only send moves for the primary touch point
if (actionIndex == 0) {
@@ -102,4 +108,12 @@ public class TouchContext {
return true;
}
public void cancelTouch() {
cancelled = true;
}
public boolean isCancelled() {
return cancelled;
}
}

View File

@@ -26,7 +26,7 @@ public class EvdevReader {
// 4.4 and later to do live SELinux policy changes.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
EvdevShell shell = EvdevShell.getInstance();
shell.runCommand("supolicy --live \"allow untrusted_app input_device dir getattr\" " +
shell.runCommand("supolicy --live \"allow untrusted_app input_device dir { getattr read search }\" " +
"\"allow untrusted_app input_device chr_file { open read write ioctl }\"");
}
}

View File

@@ -5,106 +5,56 @@ 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.Date;
import java.util.List;
/**
* Created by Karim Mreisi on 30.11.2014.
*/
public class AnalogStick extends View
public class AnalogStick extends VirtualControllerElement
{
private enum _STICK_STATE
{
NO_MOVEMENT,
MOVED
}
protected static boolean _PRINT_DEBUG_INFORMATION = true;
private enum _CLICK_STATE
{
SINGLE,
DOUBLE
}
float radius_complete = 0;
float radius_dead_zone = 0;
float radius_analog_stick = 0;
float position_stick_x = 0;
float position_stick_y = 0;
private static final boolean _PRINT_DEBUG_INFORMATION = false;
boolean viewPressed = false;
boolean analogStickActive = false;
public interface AnalogStickListener
{
void onMovement(float x, float y);
void onClick();
void onRevoke();
void onDoubleClick();
}
_STICK_STATE stick_state = _STICK_STATE.NO_MOVEMENT;
_CLICK_STATE click_state = _CLICK_STATE.SINGLE;
public void addAnalogStickListener (AnalogStickListener listener)
{
listeners.add(listener);
}
public void setOnTouchListener(OnTouchListener listener)
{
onTouchListener = listener;
}
private static final void _DBG(String text)
{
if (_PRINT_DEBUG_INFORMATION)
{
System.out.println("AnalogStick: " + text);
}
}
private int normalColor = 0xF0888888;
private int pressedColor = 0xF00000FF;
private long timeoutDoubleClick = 250;
private long timeLastClick = 0;
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 viewPressed = false;
boolean analogStickActive = false;
_STICK_STATE stick_state = _STICK_STATE.NO_MOVEMENT;
_CLICK_STATE click_state = _CLICK_STATE.SINGLE;
List<AnalogStickListener> listeners = new ArrayList<AnalogStickListener>();
OnTouchListener onTouchListener = null;
List<AnalogStickListener> listeners = new ArrayList<AnalogStickListener>();
OnTouchListener onTouchListener = null;
private long timeoutDoubleClick = 250;
private long timeLastClick = 0;
public AnalogStick(Context context)
{
super(context);
position_stick_x = getWidth() / 2;
position_stick_y = getHeight() / 2;
stick_state = _STICK_STATE.NO_MOVEMENT;
click_state = _CLICK_STATE.SINGLE;
viewPressed = false;
analogStickActive = false;
position_stick_x = getWidth() / 2;
position_stick_y = getHeight() / 2;
}
public void setColors(int normalColor, int pressedColor)
{
this.normalColor = normalColor;
this.pressedColor = pressedColor;
}
private float getPercent(float value, int percent)
public void addAnalogStickListener(AnalogStickListener listener)
{
return value / 100 * percent;
listeners.add(listener);
}
private int getCorrectWidth()
public void setOnTouchListener(OnTouchListener listener)
{
return getWidth() > getHeight() ? getHeight() : getWidth();
onTouchListener = listener;
}
public void setColors(int normalColor, int pressedColor)
{
this.normalColor = normalColor;
this.pressedColor = pressedColor;
}
private double getMovementRadius(float x, float y)
@@ -119,15 +69,15 @@ public class AnalogStick extends View
return x > 0 ? x : -x;
}
return Math.sqrt(x * x + y * y);
return Math.sqrt(x * x + y * y);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
radius_complete = getPercent(getCorrectWidth() / 2, 95);
radius_dead_zone = getPercent(getCorrectWidth() / 2, 20);
radius_analog_stick = getPercent(getCorrectWidth() / 2, 30);
radius_complete = getPercent(getCorrectWidth() / 2, 95);
radius_dead_zone = getPercent(getCorrectWidth() / 2, 20);
radius_analog_stick = getPercent(getCorrectWidth() / 2, 30);
super.onSizeChanged(w, h, oldw, oldh);
}
@@ -135,29 +85,29 @@ public class AnalogStick extends View
@Override
protected void onDraw(Canvas canvas)
{
// set transparent background
canvas.drawColor(Color.TRANSPARENT);
// set transparent background
canvas.drawColor(Color.TRANSPARENT);
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(getPercent(getCorrectWidth() / 2, 2));
// draw outer circle
if (!viewPressed || click_state == _CLICK_STATE.SINGLE)
{
paint.setColor(normalColor);
}
else
{
paint.setColor(pressedColor);
}
// draw outer circle
if (!viewPressed || click_state == _CLICK_STATE.SINGLE)
{
paint.setColor(normalColor);
}
else
{
paint.setColor(pressedColor);
}
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_complete, paint);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_complete, paint);
paint.setColor(normalColor);
paint.setColor(normalColor);
// draw dead zone
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_dead_zone, paint);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius_dead_zone, paint);
// draw stick depending on state (no movement, moved, active(out of dead zone))
if (analogStickActive)
@@ -209,11 +159,11 @@ public class AnalogStick extends View
{
if (way_x > 0)
{
angle = Math.PI * 3/2;
angle = Math.PI * 3 / 2;
}
else if (way_x < 0)
{
angle = Math.PI * 1/2;
angle = Math.PI * 1 / 2;
}
}
else
@@ -221,30 +171,31 @@ public class AnalogStick extends View
if (way_x > 0)
{
if (way_y < 0)
{ // first quadrant
angle = 3 * Math.PI / 2 + Math.atan((double)(-way_y / way_x));
{ // 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));
{ // 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));
{ // third quadrant
angle = Math.PI / 2 + Math.atan((double) (way_y / -way_x));
}
else
{ // fourth quadrant
{ // fourth quadrant
angle = 0 + Math.atan((double) (-way_x / -way_y));
}
}
}
_DBG("angle: " + angle + " way y: "+ way_y + " way x: " + way_x);
_DBG("angle: " + angle + " way y: " + way_y + " way x: " + way_x);
return angle;
return angle;
}
private void moveActionCallback(float x, float y)
@@ -258,50 +209,49 @@ public class AnalogStick extends View
}
}
private void clickActionCallback()
{
_DBG("click");
// notify listeners
for (AnalogStickListener listener : listeners)
{
listener.onClick();
}
}
private void doubleClickActionCallback()
{
_DBG("double click");
// notify listeners
for (AnalogStickListener listener : listeners)
{
listener.onDoubleClick();
}
}
private void revokeActionCallback()
{
_DBG("revoke");
// notify listeners
for (AnalogStickListener listener : listeners)
{
listener.onRevoke();
}
}
private void updatePosition(float x, float y)
private void clickActionCallback()
{
float way_x = -(getWidth() / 2 - x);
float way_y = -(getHeight() / 2 - y);
_DBG("click");
float movement_x = 0;
float movement_y = 0;
// notify listeners
for (AnalogStickListener listener : listeners)
{
listener.onClick();
}
}
double movement_radius = getMovementRadius(way_x, way_y);
double movement_angle = getAngle(way_x, way_y);
private void doubleClickActionCallback()
{
_DBG("double click");
// notify listeners
for (AnalogStickListener listener : listeners)
{
listener.onDoubleClick();
}
}
private void revokeActionCallback()
{
_DBG("revoke");
// notify listeners
for (AnalogStickListener listener : listeners)
{
listener.onRevoke();
}
}
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))
@@ -309,8 +259,10 @@ public class AnalogStick extends View
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 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);
@@ -336,71 +288,69 @@ public class AnalogStick extends View
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (onTouchListener != null)
{
return onTouchListener.onTouch(this, event);
}
if (onTouchListener != null)
{
return onTouchListener.onTouch(this, event);
}
// get masked (not specific to a pointer) action
int action = event.getActionMasked();
_CLICK_STATE lastClickState = click_state;
boolean wasPressed = analogStickActive;
int action = event.getActionMasked();
_CLICK_STATE lastClickState = click_state;
boolean wasPressed = analogStickActive;
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
{
viewPressed = true;
// check for double click
if (lastClickState == _CLICK_STATE.SINGLE && timeLastClick + timeoutDoubleClick > System.currentTimeMillis())
{
click_state = _CLICK_STATE.DOUBLE;
{
viewPressed = true;
// check for double click
if (lastClickState == _CLICK_STATE.SINGLE && timeLastClick + timeoutDoubleClick > System.currentTimeMillis())
{
click_state = _CLICK_STATE.DOUBLE;
doubleClickActionCallback();
}
else
{
click_state = _CLICK_STATE.SINGLE;
doubleClickActionCallback();
}
else
{
click_state = _CLICK_STATE.SINGLE;
clickActionCallback();
}
clickActionCallback();
}
timeLastClick = System.currentTimeMillis();
break;
}
case MotionEvent.ACTION_MOVE:
{
if (analogStickActive || timeLastClick + timeoutDoubleClick < System.currentTimeMillis())
{
analogStickActive = true;
}
timeLastClick = System.currentTimeMillis();
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_MOVE:
{
analogStickActive = false;
viewPressed = false;
if (analogStickActive || timeLastClick + timeoutDoubleClick < System.currentTimeMillis())
{
analogStickActive = true;
}
revokeActionCallback();
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
{
analogStickActive = false;
viewPressed = false;
revokeActionCallback();
break;
}
}
// no longer pressed reset movement
if (analogStickActive)
{ // when is pressed calculate new positions (will trigger movement if necessary)
{ // when is pressed calculate new positions (will trigger movement if necessary)
updatePosition(event.getX(), event.getY());
}
else
{ // no longer pressed reset movement
if (wasPressed)
{
moveActionCallback(0, 0);
}
else if (wasPressed)
{
moveActionCallback(0, 0);
}
// to get view refreshed
@@ -408,4 +358,28 @@ public class AnalogStick extends View
return true;
}
private enum _STICK_STATE
{
NO_MOVEMENT,
MOVED
}
private enum _CLICK_STATE
{
SINGLE,
DOUBLE
}
public interface AnalogStickListener
{
void onMovement(float x, float y);
void onClick();
void onRevoke();
void onDoubleClick();
}
}

View File

@@ -6,7 +6,6 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
@@ -16,214 +15,181 @@ import java.util.TimerTask;
/**
* Created by Karim on 24.01.2015.
*/
public class DigitalButton extends View
public class DigitalButton extends VirtualControllerElement
{
private class TimerLongClickTimerTask extends TimerTask
{
@Override
public void run()
{
onLongClickCallback();
}
}
private static final boolean _PRINT_DEBUG_INFORMATION = false;
List<DigitalButtonListener> listeners = new ArrayList<DigitalButtonListener>();
OnTouchListener onTouchListener = null;
boolean clicked;
private String text = "";
private int icon = -1;
private long timerLongClickTimeout = 3000;
private Timer timerLongClick = null;
private TimerLongClickTimerTask longClickTimerTask = null;
private int normalColor = 0xF0888888;
private int pressedColor = 0xF00000FF;
private String text = "";
private int icon = -1;
public DigitalButton(Context context)
{
super(context);
clicked = false;
}
private long timerLongClickTimeout = 3000;
private Timer timerLongClick = null;
private TimerLongClickTimerTask longClickTimerTask = null;
public void addDigitalButtonListener(DigitalButtonListener listener)
{
listeners.add(listener);
}
public void setOnTouchListener(OnTouchListener listener)
{
onTouchListener = listener;
}
public interface DigitalButtonListener
{
void onClick();
void onLongClick();
void onRelease();
}
public void setText(String text)
{
this.text = text;
invalidate();
}
public void addDigitalButtonListener(DigitalButtonListener listener)
{
listeners.add(listener);
}
public void setIcon(int id)
{
this.icon = id;
invalidate();
}
public void setColors(int normalColor, int pressedColor)
{
this.normalColor = normalColor;
this.pressedColor = pressedColor;
}
@Override
protected void onDraw(Canvas canvas)
{
// set transparent background
canvas.drawColor(Color.TRANSPARENT);
public void setOnTouchListener(OnTouchListener listener)
{
onTouchListener = listener;
}
Paint paint = new Paint();
private static final void _DBG(String text)
{
if (_PRINT_DEBUG_INFORMATION)
{
System.out.println("DigitalButton: " + text);
}
}
paint.setTextSize(getPercent(getCorrectWidth(), 50));
paint.setTextAlign(Paint.Align.CENTER);
paint.setStrokeWidth(3);
List<DigitalButtonListener> listeners = new ArrayList<DigitalButtonListener>();
OnTouchListener onTouchListener = null;
paint.setColor(clicked ? pressedColor : normalColor);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
1, 1,
getWidth() - 1, getHeight() - 1,
paint
);
boolean clicked;
if (icon != -1)
{
Drawable d = getResources().getDrawable(icon);
d.setBounds(5, 5, getWidth() - 5, getHeight() - 5);
d.draw(canvas);
}
else
{
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText(text,
getPercent(getWidth(), 50), getPercent(getHeight(), 73),
paint);
}
public DigitalButton(Context context)
{
super(context);
super.onDraw(canvas);
}
clicked = false;
}
private void onClickCallback()
{
_DBG("clicked");
public void setText(String text)
{
this.text = text;
// notify listeners
for (DigitalButtonListener listener : listeners)
{
listener.onClick();
}
invalidate();
}
timerLongClick = new Timer();
longClickTimerTask = new TimerLongClickTimerTask();
public void setIcon(int id)
{
this.icon = id;
timerLongClick.schedule(longClickTimerTask, timerLongClickTimeout);
}
invalidate();
}
private void onLongClickCallback()
{
_DBG("long click");
private float getPercent(float value, float percent)
{
return value / 100 * percent;
}
// notify listeners
for (DigitalButtonListener listener : listeners)
{
listener.onLongClick();
}
}
private int getCorrectWidth()
{
return getWidth() > getHeight() ? getHeight() : getWidth();
}
private void onReleaseCallback()
{
_DBG("released");
@Override
protected void onDraw(Canvas canvas)
{
// set transparent background
canvas.drawColor(Color.TRANSPARENT);
// notify listeners
for (DigitalButtonListener listener : listeners)
{
listener.onRelease();
}
Paint paint = new Paint();
timerLongClick.cancel();
longClickTimerTask.cancel();
}
paint.setTextSize(getPercent(getCorrectWidth(), 50));
paint.setTextAlign(Paint.Align.CENTER);
paint.setStrokeWidth(3);
@Override
public boolean onTouchEvent(MotionEvent event)
{
/*
if (onTouchListener != null)
{
return onTouchListener.onTouch(this, event);
}
*/
// get masked (not specific to a pointer) action
int action = event.getActionMasked();
paint.setColor(clicked ? pressedColor : normalColor);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
1, 1,
getWidth() - 1, getHeight() - 1,
paint
);
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
{
clicked = true;
onClickCallback();
if (icon != -1)
{
Drawable d = getResources().getDrawable(icon);
d.setBounds(5, 5, getWidth() - 5, getHeight() - 5);
d.draw(canvas);
}
else
{
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText(text,
getPercent(getWidth(), 50), getPercent(getHeight(), 73),
paint);
}
invalidate();
super.onDraw(canvas);
}
return true;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
{
clicked = false;
onReleaseCallback();
private void onClickCallback()
{
_DBG("clicked");
invalidate();
// notify listeners
for (DigitalButtonListener listener : listeners)
{
listener.onClick();
}
return true;
}
default:
{
}
}
timerLongClick = new Timer();
longClickTimerTask = new TimerLongClickTimerTask();
return true;
}
timerLongClick.schedule(longClickTimerTask, timerLongClickTimeout);
}
public interface DigitalButtonListener
{
void onClick();
private void onLongClickCallback()
{
_DBG("long click");
void onLongClick();
// notify listeners
for (DigitalButtonListener listener : listeners)
{
listener.onLongClick();
}
}
void onRelease();
}
private void onReleaseCallback()
{
_DBG("released");
// notify listeners
for (DigitalButtonListener listener : listeners)
{
listener.onRelease();
}
timerLongClick.cancel();
longClickTimerTask.cancel();
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
/*
if (onTouchListener != null)
{
return onTouchListener.onTouch(this, event);
}
*/
// get masked (not specific to a pointer) action
int action = event.getActionMasked();
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
{
clicked = true;
onClickCallback();
invalidate();
return true;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
{
clicked = false;
onReleaseCallback();
invalidate();
return true;
}
default:
{
}
}
return true;
}
private class TimerLongClickTimerTask extends TimerTask
{
@Override
public void run()
{
onLongClickCallback();
}
}
}

View File

@@ -5,7 +5,6 @@ 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;
@@ -13,273 +12,244 @@ import java.util.List;
/**
* Created by Karim Mreisi on 23.01.2015.
*/
public class DigitalPad extends View
public class DigitalPad extends VirtualControllerElement
{
public final static int DIGITAL_PAD_DIRECTION_NO_DIRECTION = 0;
public final static int DIGITAL_PAD_DIRECTION_LEFT = 1;
public final static int DIGITAL_PAD_DIRECTION_UP = 2;
public final static int DIGITAL_PAD_DIRECTION_RIGHT = 4;
public final static int DIGITAL_PAD_DIRECTION_DOWN = 8;
public final static int DIGITAL_PAD_DIRECTION_NO_DIRECTION = 0;
int direction = DIGITAL_PAD_DIRECTION_NO_DIRECTION;
public final static int DIGITAL_PAD_DIRECTION_LEFT = 1;
public final static int DIGITAL_PAD_DIRECTION_UP = 2;
public final static int DIGITAL_PAD_DIRECTION_RIGHT = 4;
public final static int DIGITAL_PAD_DIRECTION_DOWN = 8;
List<DigitalPadListener> listeners = new ArrayList<DigitalPadListener>();
OnTouchListener onTouchListener = null;
private int normalColor = 0xF0888888;
private int pressedColor = 0xF00000FF;
public DigitalPad(Context context)
{
super(context);
}
private static final boolean _PRINT_DEBUG_INFORMATION = false;
public void addDigitalPadListener(DigitalPadListener listener)
{
listeners.add(listener);
}
public interface DigitalPadListener
{
void onDirectionChange(int direction);
}
public void setOnTouchListener(OnTouchListener listener)
{
onTouchListener = listener;
}
public void addDigitalPadListener (DigitalPadListener listener)
{
listeners.add(listener);
}
@Override
protected void onDraw(Canvas canvas)
{
// set transparent background
canvas.drawColor(Color.TRANSPARENT);
public void setOnTouchListener(OnTouchListener listener)
{
onTouchListener = listener;
}
Paint paint = new Paint();
private static final void _DBG(String text)
{
if (_PRINT_DEBUG_INFORMATION)
{
System.out.println("DigitalPad: " + text);
}
}
paint.setTextSize(getPercent(getCorrectWidth(), 20));
paint.setTextAlign(Paint.Align.CENTER);
paint.setStrokeWidth(3);
List<DigitalPadListener> listeners = new ArrayList<DigitalPadListener>();
OnTouchListener onTouchListener = null;
if (direction == DIGITAL_PAD_DIRECTION_NO_DIRECTION)
{
// draw no direction rect
paint.setStyle(Paint.Style.STROKE);
paint.setColor(normalColor);
canvas.drawRect(
getPercent(getWidth(), 36), getPercent(getHeight(), 36),
getPercent(getWidth(), 63), getPercent(getHeight(), 63),
paint
);
}
int direction;
// draw left rect
paint.setColor(
(direction & DIGITAL_PAD_DIRECTION_LEFT) > 0 ? pressedColor : normalColor);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText("LF",
getPercent(getWidth(), 16.5f), getPercent(getHeight(), 56),
paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
0, getPercent(getHeight(), 33),
getPercent(getWidth(), 33), getPercent(getHeight(), 66),
paint
);
public DigitalPad(Context context)
{
super(context);
// draw left up line
paint.setColor((
(direction & DIGITAL_PAD_DIRECTION_LEFT) > 0 &&
(direction & DIGITAL_PAD_DIRECTION_UP) > 0
) ? pressedColor : normalColor
);
paint.setStyle(Paint.Style.STROKE);
canvas.drawLine(
0, getPercent(getWidth(), 33),
getPercent(getWidth(), 33), 0,
paint
);
direction = DIGITAL_PAD_DIRECTION_NO_DIRECTION;
}
// draw up rect
paint.setColor(
(direction & DIGITAL_PAD_DIRECTION_UP) > 0 ? pressedColor : normalColor);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText("UP",
getPercent(getWidth(), 49.5f), getPercent(getHeight(), 23),
paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
getPercent(getWidth(), 33), 0,
getPercent(getWidth(), 66), getPercent(getHeight(), 33),
paint
);
private float getPercent(float value, float percent)
{
return value / 100 * percent;
}
// draw up right line
paint.setColor((
(direction & DIGITAL_PAD_DIRECTION_UP) > 0 &&
(direction & DIGITAL_PAD_DIRECTION_RIGHT) > 0
) ? pressedColor : normalColor
);
paint.setStyle(Paint.Style.STROKE);
canvas.drawLine(
getPercent(getWidth(), 66), 0,
getPercent(getWidth(), 100), getPercent(getHeight(), 33),
paint
);
private int getCorrectWidth()
{
return getWidth() > getHeight() ? getHeight() : getWidth();
}
// draw right rect
paint.setColor(
(direction & DIGITAL_PAD_DIRECTION_RIGHT) > 0 ? pressedColor : normalColor);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText("RI",
getPercent(getWidth(), 82.5f), getPercent(getHeight(), 56),
paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
getPercent(getWidth(), 66), getPercent(getHeight(), 33),
getPercent(getWidth(), 100), getPercent(getHeight(), 66),
paint
);
public void setColors(int normalColor, int pressedColor)
{
this.normalColor = normalColor;
this.pressedColor = pressedColor;
}
// draw right down line
paint.setColor((
(direction & DIGITAL_PAD_DIRECTION_RIGHT) > 0 &&
(direction & DIGITAL_PAD_DIRECTION_DOWN) > 0
) ? pressedColor : normalColor
);
paint.setStyle(Paint.Style.STROKE);
canvas.drawLine(
getPercent(getWidth(), 100), getPercent(getHeight(), 66),
getPercent(getWidth(), 66), getPercent(getHeight(), 100),
paint
);
@Override
protected void onDraw(Canvas canvas)
{
// set transparent background
canvas.drawColor(Color.TRANSPARENT);
// draw down rect
paint.setColor(
(direction & DIGITAL_PAD_DIRECTION_DOWN) > 0 ? pressedColor : normalColor);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText("DW",
getPercent(getWidth(), 49.5f), getPercent(getHeight(), 89),
paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
getPercent(getWidth(), 33), getPercent(getHeight(), 66),
getPercent(getWidth(), 66), getPercent(getHeight(), 100),
paint
);
Paint paint = new Paint();
// draw down left line
paint.setColor((
(direction & DIGITAL_PAD_DIRECTION_DOWN) > 0 &&
(direction & DIGITAL_PAD_DIRECTION_LEFT) > 0
) ? pressedColor : normalColor
);
paint.setStyle(Paint.Style.STROKE);
canvas.drawLine(
getPercent(getWidth(), 33), getPercent(getHeight(), 100),
getPercent(getWidth(), 0), getPercent(getHeight(), 66),
paint
);
paint.setTextSize(getPercent(getCorrectWidth(), 20));
paint.setTextAlign(Paint.Align.CENTER);
paint.setStrokeWidth(3);
super.onDraw(canvas);
}
if (direction == DIGITAL_PAD_DIRECTION_NO_DIRECTION)
{
// draw no direction rect
paint.setStyle(Paint.Style.STROKE);
paint.setColor(normalColor);
canvas.drawRect(
getPercent(getWidth(), 36), getPercent(getHeight(), 36),
getPercent(getWidth(), 63), getPercent(getHeight(), 63),
paint
);
}
private void newDirectionCallback(int direction)
{
_DBG("direction: " + direction);
// draw left rect
paint.setColor((direction & DIGITAL_PAD_DIRECTION_LEFT) > 0 ? pressedColor : normalColor);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText("LF",
getPercent(getWidth(), 16.5f), getPercent(getHeight(), 56),
paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
0, getPercent(getHeight(), 33),
getPercent(getWidth(), 33), getPercent(getHeight(), 66),
paint
);
// notify listeners
for (DigitalPadListener listener : listeners)
{
listener.onDirectionChange(direction);
}
}
// draw left up line
paint.setColor((
(direction & DIGITAL_PAD_DIRECTION_LEFT) > 0 &&
(direction & DIGITAL_PAD_DIRECTION_UP) > 0
) ? pressedColor : normalColor
);
paint.setStyle(Paint.Style.STROKE);
canvas.drawLine(
0, getPercent(getWidth(), 33),
getPercent(getWidth(), 33), 0,
paint
);
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (onTouchListener != null)
{
return onTouchListener.onTouch(this, event);
}
// draw up rect
paint.setColor((direction & DIGITAL_PAD_DIRECTION_UP) > 0 ? pressedColor : normalColor);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText("UP",
getPercent(getWidth(), 49.5f), getPercent(getHeight(), 23),
paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
getPercent(getWidth(), 33), 0,
getPercent(getWidth(), 66), getPercent(getHeight(), 33),
paint
);
// get masked (not specific to a pointer) action
int action = event.getActionMasked();
// draw up right line
paint.setColor((
(direction & DIGITAL_PAD_DIRECTION_UP) > 0 &&
(direction & DIGITAL_PAD_DIRECTION_RIGHT) > 0
) ? pressedColor : normalColor
);
paint.setStyle(Paint.Style.STROKE);
canvas.drawLine(
getPercent(getWidth(), 66), 0,
getPercent(getWidth(), 100), getPercent(getHeight(), 33),
paint
);
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
{
direction = 0;
// draw right rect
paint.setColor((direction & DIGITAL_PAD_DIRECTION_RIGHT) > 0 ? pressedColor : normalColor);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText("RI",
getPercent(getWidth(), 82.5f), getPercent(getHeight(), 56),
paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
getPercent(getWidth(), 66), getPercent(getHeight(), 33),
getPercent(getWidth(), 100), getPercent(getHeight(), 66),
paint
);
if (event.getX() < getPercent(getWidth(), 33))
{
direction |= DIGITAL_PAD_DIRECTION_LEFT;
}
// draw right down line
paint.setColor((
(direction & DIGITAL_PAD_DIRECTION_RIGHT) > 0 &&
(direction & DIGITAL_PAD_DIRECTION_DOWN) > 0
) ? pressedColor : normalColor
);
paint.setStyle(Paint.Style.STROKE);
canvas.drawLine(
getPercent(getWidth(), 100), getPercent(getHeight(), 66),
getPercent(getWidth(), 66), getPercent(getHeight(), 100),
paint
);
if (event.getX() > getPercent(getWidth(), 66))
{
direction |= DIGITAL_PAD_DIRECTION_RIGHT;
}
// draw down rect
paint.setColor((direction & DIGITAL_PAD_DIRECTION_DOWN) > 0 ? pressedColor : normalColor);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawText("DW",
getPercent(getWidth(), 49.5f), getPercent(getHeight(), 89),
paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(
getPercent(getWidth(), 33), getPercent(getHeight(), 66),
getPercent(getWidth(), 66), getPercent(getHeight(), 100),
paint
);
if (event.getY() > getPercent(getHeight(), 66))
{
direction |= DIGITAL_PAD_DIRECTION_DOWN;
}
// draw down left line
paint.setColor((
(direction & DIGITAL_PAD_DIRECTION_DOWN) > 0 &&
(direction & DIGITAL_PAD_DIRECTION_LEFT) > 0
) ? pressedColor : normalColor
);
paint.setStyle(Paint.Style.STROKE);
canvas.drawLine(
getPercent(getWidth(), 33), getPercent(getHeight(), 100),
getPercent(getWidth(), 0), getPercent(getHeight(), 66),
paint
);
if (event.getY() < getPercent(getHeight(), 33))
{
direction |= DIGITAL_PAD_DIRECTION_UP;
}
super.onDraw(canvas);
}
newDirectionCallback(direction);
private void newDirectionCallback(int direction)
{
_DBG("direction: " + direction);
invalidate();
// notify listeners
for (DigitalPadListener listener : listeners)
{
listener.onDirectionChange(direction);
}
}
return true;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
{
direction = 0;
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (onTouchListener != null)
{
return onTouchListener.onTouch(this, event);
}
newDirectionCallback(direction);
// get masked (not specific to a pointer) action
int action = event.getActionMasked();
invalidate();
switch (action)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
{
direction = 0;
return true;
}
default:
{
}
}
if (event.getX() < getPercent(getWidth(), 33))
{
direction |= DIGITAL_PAD_DIRECTION_LEFT;
}
return true;
}
if (event.getX() > getPercent(getWidth(), 66))
{
direction |= DIGITAL_PAD_DIRECTION_RIGHT;
}
if (event.getY() > getPercent(getHeight(), 66))
{
direction |= DIGITAL_PAD_DIRECTION_DOWN;
}
if (event.getY() < getPercent(getHeight(), 33))
{
direction |= DIGITAL_PAD_DIRECTION_UP;
}
newDirectionCallback(direction);
invalidate();
return true;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
{
direction = 0;
newDirectionCallback(direction);
invalidate();
return true;
}
default:
{
}
}
return true;
}
public interface DigitalPadListener
{
void onDirectionChange(int direction);
}
}

View File

@@ -2,13 +2,9 @@ package com.limelight.binding.input.virtual_controller;
import android.content.Context;
import android.content.Intent;
import android.view.MenuInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.PopupMenu;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.limelight.R;
import com.limelight.nvstream.NvConnection;
@@ -19,183 +15,63 @@ import com.limelight.nvstream.input.ControllerPacket;
*/
public class VirtualController
{
private static final boolean _PRINT_DEBUG_INFORMATION = false;
private static final boolean _PRINT_DEBUG_INFORMATION = false;
NvConnection connection = null;
private Context context = null;
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 static final void _DBG(String text)
{
if (_PRINT_DEBUG_INFORMATION)
{
System.out.println("VirtualController: " + text);
}
}
private FrameLayout frame_layout = null;
private RelativeLayout relative_layout = null;
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 RelativeLayout.LayoutParams layoutParamsButtonStart = null;
private RelativeLayout.LayoutParams layoutParamsButtonSelect = null;
private FrameLayout frame_layout = null;
private RelativeLayout relative_layout = null;
private RelativeLayout.LayoutParams layoutParamsDPad = null;
private RelativeLayout.LayoutParams layoutParamsButtonStart = null;
private RelativeLayout.LayoutParams layoutParamsButtonSelect = null;
private RelativeLayout.LayoutParams layoutParamsButtonA = null;
private RelativeLayout.LayoutParams layoutParamsButtonB = null;
private RelativeLayout.LayoutParams layoutParamsButtonX = null;
private RelativeLayout.LayoutParams layoutParamsButtonY = null;
private RelativeLayout.LayoutParams layoutParamsButtonLT = null;
private RelativeLayout.LayoutParams layoutParamsButtonRT = null;
private RelativeLayout.LayoutParams layoutParamsButtonLB = null;
private RelativeLayout.LayoutParams layoutParamsButtonRB = null;
private RelativeLayout.LayoutParams layoutParamsDPad = null;
private RelativeLayout.LayoutParams layoutParamsStick = null;
private RelativeLayout.LayoutParams layoutParamsStick2 = null;
private RelativeLayout.LayoutParams layoutParamsButtonA = null;
private RelativeLayout.LayoutParams layoutParamsButtonB = null;
private RelativeLayout.LayoutParams layoutParamsButtonX = null;
private RelativeLayout.LayoutParams layoutParamsButtonY = null;
private RelativeLayout.LayoutParams layoutParamsButtonLT = null;
private RelativeLayout.LayoutParams layoutParamsButtonRT = null;
private RelativeLayout.LayoutParams layoutParamsButtonLB = null;
private RelativeLayout.LayoutParams layoutParamsButtonRB = null;
private RelativeLayout.LayoutParams layoutParamsButtonConfigure = null;
private RelativeLayout.LayoutParams layoutParamsStick = null;
private RelativeLayout.LayoutParams layoutParamsStick2 = null;
private DigitalButton buttonStart = null;
private DigitalButton buttonSelect = null;
private RelativeLayout.LayoutParams layoutParamsButtonConfigure = null;
private DigitalPad digitalPad = null;
private DigitalButton buttonStart = null;
private DigitalButton buttonSelect = null;
private DigitalButton buttonA = null;
private DigitalButton buttonB = null;
private DigitalButton buttonX = null;
private DigitalButton buttonY = null;
private DigitalButton buttonLT = null;
private DigitalButton buttonRT = null;
private DigitalButton buttonLB = null;
private DigitalButton buttonRB = null;
private DigitalPad digitalPad = null;
private AnalogStick stick = null;
private AnalogStick stick2 = null;
private DigitalButton buttonA = null;
private DigitalButton buttonB = null;
private DigitalButton buttonX = null;
private DigitalButton buttonY = null;
private DigitalButton buttonLT = null;
private DigitalButton buttonRT = null;
private DigitalButton buttonLB = null;
private DigitalButton buttonRB = null;
private AnalogStick stick = null;
private AnalogStick stick2 = null;
private DigitalButton buttonConfigure = 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, float pos_x, float pos_y)
{
parm.setMargins(
(int)(((float)frame_layout.getWidth() / (float)100 * pos_x) - ((float)parm.width / (float)2)),
(int)(((float)frame_layout.getHeight() / (float)100 * pos_y) - ((float)parm.height / (float)2)),
0,
0
);
}
void refreshLayout()
{
relative_layout.removeAllViews();
layoutParamsDPad = new RelativeLayout.LayoutParams(getPercentageV(30), getPercentageV(30));
layoutParamsStick = new RelativeLayout.LayoutParams(getPercentageV(40), getPercentageV(40));
layoutParamsStick2 = 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));
layoutParamsButtonLT = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonRT = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonLB = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonRB = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonStart = new RelativeLayout.LayoutParams(getPercentageH(12), getPercentageV(8));
layoutParamsButtonSelect = new RelativeLayout.LayoutParams(getPercentageH(12), getPercentageV(8));
layoutParamsButtonConfigure = new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
setPercentilePosition(layoutParamsDPad, 10, 35);
setPercentilePosition(layoutParamsStick, 22, 78);
setPercentilePosition(layoutParamsStick2, 78, 78);
setPercentilePosition(layoutParamsButtonA, 85, 52);
setPercentilePosition(layoutParamsButtonB, 92, 47);
setPercentilePosition(layoutParamsButtonX, 85, 40);
setPercentilePosition(layoutParamsButtonY, 92, 35);
setPercentilePosition(layoutParamsButtonLT, 95, 68);
setPercentilePosition(layoutParamsButtonRT, 95, 80);
setPercentilePosition(layoutParamsButtonLB, 85, 28);
setPercentilePosition(layoutParamsButtonRB, 92, 23);
setPercentilePosition(layoutParamsButtonSelect, 43, 94);
setPercentilePosition(layoutParamsButtonStart, 57, 94);
setPercentilePosition(layoutParamsButtonConfigure, 93, 7);
relative_layout.addView(digitalPad, layoutParamsDPad);
relative_layout.addView(stick, layoutParamsStick);
relative_layout.addView(stick2, layoutParamsStick2);
relative_layout.addView(buttonA, layoutParamsButtonA);
relative_layout.addView(buttonB, layoutParamsButtonB);
relative_layout.addView(buttonX, layoutParamsButtonX);
relative_layout.addView(buttonY, layoutParamsButtonY);
relative_layout.addView(buttonLT, layoutParamsButtonLT);
relative_layout.addView(buttonRT, layoutParamsButtonRT);
relative_layout.addView(buttonLB, layoutParamsButtonLB);
relative_layout.addView(buttonRB, layoutParamsButtonRB);
relative_layout.addView(buttonSelect, layoutParamsButtonSelect);
relative_layout.addView(buttonStart, layoutParamsButtonStart);
relative_layout.addView(buttonConfigure, layoutParamsButtonConfigure);
}
private DigitalButton createDigitalButton(String text, final int key, Context context)
{
DigitalButton button = new DigitalButton(context);
button.setText(text);
button.addDigitalButtonListener(new DigitalButton.DigitalButtonListener() {
@Override
public void onClick() {
inputMap |= key;
sendControllerInputPacket();
}
@Override
public void onLongClick()
{
}
@Override
public void onRelease() {
inputMap &= ~key;
sendControllerInputPacket();
}
});
return button;
}
private DigitalButton buttonConfigure = null;
public VirtualController(final NvConnection conn, FrameLayout layout, final Context context)
{
this.connection = conn;
frame_layout = layout;
this.connection = conn;
this.frame_layout = layout;
this.context = context;
relative_layout = new RelativeLayout(context);
@@ -210,113 +86,113 @@ public class VirtualController
frame_layout.addView(relative_layout);
digitalPad = new DigitalPad(context);
digitalPad.addDigitalPadListener(new DigitalPad.DigitalPadListener()
{
@Override
public void onDirectionChange(int direction)
{
do
{
if (direction == DigitalPad.DIGITAL_PAD_DIRECTION_NO_DIRECTION)
{
inputMap &= ~ControllerPacket.LEFT_FLAG;
inputMap &= ~ControllerPacket.RIGHT_FLAG;
inputMap &= ~ControllerPacket.UP_FLAG;
inputMap &= ~ControllerPacket.DOWN_FLAG;
digitalPad = new DigitalPad(context);
digitalPad.addDigitalPadListener(new DigitalPad.DigitalPadListener()
{
@Override
public void onDirectionChange(int direction)
{
do
{
if (direction == DigitalPad.DIGITAL_PAD_DIRECTION_NO_DIRECTION)
{
inputMap &= ~ControllerPacket.LEFT_FLAG;
inputMap &= ~ControllerPacket.RIGHT_FLAG;
inputMap &= ~ControllerPacket.UP_FLAG;
inputMap &= ~ControllerPacket.DOWN_FLAG;
break;
}
break;
}
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_LEFT) > 0)
{
inputMap |= ControllerPacket.LEFT_FLAG;
}
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_LEFT) > 0)
{
inputMap |= ControllerPacket.LEFT_FLAG;
}
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_RIGHT) > 0)
{
inputMap |= ControllerPacket.RIGHT_FLAG;
}
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_RIGHT) > 0)
{
inputMap |= ControllerPacket.RIGHT_FLAG;
}
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_UP) > 0)
{
inputMap |= ControllerPacket.UP_FLAG;
}
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_UP) > 0)
{
inputMap |= ControllerPacket.UP_FLAG;
}
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_DOWN) > 0)
{
inputMap |= ControllerPacket.DOWN_FLAG;
}
}
while (false);
if ((direction & DigitalPad.DIGITAL_PAD_DIRECTION_DOWN) > 0)
{
inputMap |= ControllerPacket.DOWN_FLAG;
}
}
while (false);
sendControllerInputPacket();
}
});
sendControllerInputPacket();
}
});
buttonX = createDigitalButton("X", ControllerPacket.X_FLAG ,context);
buttonY = createDigitalButton("Y", ControllerPacket.Y_FLAG ,context);
buttonA = createDigitalButton("A", ControllerPacket.A_FLAG ,context);
buttonB = createDigitalButton("B", ControllerPacket.B_FLAG ,context);
buttonX = createDigitalButton("X", ControllerPacket.X_FLAG, context);
buttonY = createDigitalButton("Y", ControllerPacket.Y_FLAG, context);
buttonA = createDigitalButton("A", ControllerPacket.A_FLAG, context);
buttonB = createDigitalButton("B", ControllerPacket.B_FLAG, context);
buttonLT = new DigitalButton(context);
buttonLT.setText("LT");
buttonLT.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
{
@Override
public void onClick()
{
leftTrigger = (byte) (1 * 0xFF);
buttonLT.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
{
@Override
public void onClick()
{
leftTrigger = (byte) (1 * 0xFF);
sendControllerInputPacket();
}
sendControllerInputPacket();
}
@Override
public void onLongClick()
{
@Override
public void onLongClick()
{
}
}
@Override
public void onRelease()
{
leftTrigger = (byte) (0 * 0xFF);
@Override
public void onRelease()
{
leftTrigger = (byte) (0 * 0xFF);
sendControllerInputPacket();
}
});
sendControllerInputPacket();
}
});
buttonRT = new DigitalButton(context);
buttonRT.setText("RT");
buttonRT.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
{
@Override
public void onClick()
{
rightTrigger = (byte) (0xFF);
buttonRT.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
{
@Override
public void onClick()
{
rightTrigger = (byte) (0xFF);
sendControllerInputPacket();
}
sendControllerInputPacket();
}
@Override
public void onLongClick()
{
@Override
public void onLongClick()
{
}
}
@Override
public void onRelease()
{
rightTrigger = (byte) (0);
@Override
public void onRelease()
{
rightTrigger = (byte) (0);
sendControllerInputPacket();
}
});
sendControllerInputPacket();
}
});
buttonLB = createDigitalButton("LB", ControllerPacket.LB_FLAG ,context);
buttonRB = createDigitalButton("RB", ControllerPacket.RB_FLAG ,context);
buttonLB = createDigitalButton("LB", ControllerPacket.LB_FLAG, context);
buttonRB = createDigitalButton("RB", ControllerPacket.RB_FLAG, context);
stick = new AnalogStick(context);
stick = new AnalogStick(context);
stick.addAnalogStickListener(new AnalogStick.AnalogStickListener()
{
@@ -326,30 +202,30 @@ public class VirtualController
leftStickX = (short) (x * 0x7FFE);
leftStickY = (short) (y * 0x7FFE);
_DBG("LEFT STICK MOVEMENT X: "+ leftStickX + " Y: " + leftStickY);
_DBG("LEFT STICK MOVEMENT X: " + leftStickX + " Y: " + leftStickY);
sendControllerInputPacket();
}
@Override
public void onClick()
{
}
@Override
public void onClick()
{
}
@Override
public void onDoubleClick()
{
inputMap |= ControllerPacket.LS_CLK_FLAG;
@Override
public void onDoubleClick()
{
inputMap |= ControllerPacket.LS_CLK_FLAG;
sendControllerInputPacket();
}
sendControllerInputPacket();
}
@Override
public void onRevoke()
{
inputMap &= ~ControllerPacket.LS_CLK_FLAG;
@Override
public void onRevoke()
{
inputMap &= ~ControllerPacket.LS_CLK_FLAG;
sendControllerInputPacket();
}
sendControllerInputPacket();
}
});
stick2 = new AnalogStick(context);
@@ -361,83 +237,229 @@ public class VirtualController
rightStickX = (short) (x * 0x7FFE);
rightStickY = (short) (y * 0x7FFE);
_DBG("RIGHT STICK MOVEMENT X: "+ rightStickX + " Y: " + rightStickY);
_DBG("RIGHT STICK MOVEMENT X: " + rightStickX + " Y: " + rightStickY);
sendControllerInputPacket();
}
@Override
public void onClick()
{
}
@Override
public void onClick()
{
}
@Override
public void onDoubleClick()
{
inputMap |= ControllerPacket.RS_CLK_FLAG;
@Override
public void onDoubleClick()
{
inputMap |= ControllerPacket.RS_CLK_FLAG;
sendControllerInputPacket();
}
sendControllerInputPacket();
}
@Override
public void onRevoke()
{
inputMap &= ~ControllerPacket.RS_CLK_FLAG;
@Override
public void onRevoke()
{
inputMap &= ~ControllerPacket.RS_CLK_FLAG;
sendControllerInputPacket();
}
});
sendControllerInputPacket();
}
});
buttonStart = createDigitalButton("START", ControllerPacket.PLAY_FLAG, context);
buttonSelect = createDigitalButton("SELECT", ControllerPacket.SPECIAL_BUTTON_FLAG, context);
buttonStart = createDigitalButton("START", ControllerPacket.PLAY_FLAG, context);
buttonSelect =
createDigitalButton("SELECT", ControllerPacket.SPECIAL_BUTTON_FLAG, context);
buttonConfigure = new DigitalButton(context);
buttonConfigure.setIcon(R.drawable.settings);
buttonConfigure.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
{
@Override
public void onClick() {
buttonConfigure = new DigitalButton(context);
buttonConfigure.setIcon(R.drawable.settings);
buttonConfigure.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
{
@Override
public void onClick()
{
}
}
@Override
public void onLongClick()
{
Intent virtualControllerConfiguration = new Intent(context,VirtualControllerSettings.class);
@Override
public void onLongClick()
{
openSettingsDialog();
}
virtualControllerConfiguration.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@Override
public void onRelease()
{
context.startActivity(virtualControllerConfiguration);
}
@Override
public void onRelease() {
}
});
}
});
refreshLayout();
}
private static final void _DBG(String text)
{
if (_PRINT_DEBUG_INFORMATION)
{
System.out.println("VirtualController: " + text);
}
}
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, float pos_x, float pos_y)
{
parm.setMargins(
(int) (((float) frame_layout.getWidth() / (float) 100 * pos_x) - ((float) parm.width / (float) 2)),
(int) (((float) frame_layout.getHeight() / (float) 100 * pos_y) - ((float) parm.height / (float) 2)),
0,
0
);
}
public void openSettingsDialog()
{
Intent virtualControllerConfiguration =
new Intent(context, VirtualControllerSettings.class);
virtualControllerConfiguration.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(virtualControllerConfiguration);
}
void refreshLayout()
{
relative_layout.removeAllViews();
layoutParamsDPad =
new RelativeLayout.LayoutParams(getPercentageV(30), getPercentageV(30));
layoutParamsStick =
new RelativeLayout.LayoutParams(getPercentageV(40), getPercentageV(40));
layoutParamsStick2 =
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));
layoutParamsButtonLT =
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonRT =
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonLB =
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonRB =
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
layoutParamsButtonStart =
new RelativeLayout.LayoutParams(getPercentageH(12), getPercentageV(8));
layoutParamsButtonSelect =
new RelativeLayout.LayoutParams(getPercentageH(12), getPercentageV(8));
layoutParamsButtonConfigure =
new RelativeLayout.LayoutParams(getPercentageV(10), getPercentageV(10));
setPercentilePosition(layoutParamsDPad, 10, 35);
setPercentilePosition(layoutParamsStick, 22, 78);
setPercentilePosition(layoutParamsStick2, 78, 78);
setPercentilePosition(layoutParamsButtonA, 85, 52);
setPercentilePosition(layoutParamsButtonB, 92, 47);
setPercentilePosition(layoutParamsButtonX, 85, 40);
setPercentilePosition(layoutParamsButtonY, 92, 35);
setPercentilePosition(layoutParamsButtonLT, 95, 68);
setPercentilePosition(layoutParamsButtonRT, 95, 80);
setPercentilePosition(layoutParamsButtonLB, 85, 28);
setPercentilePosition(layoutParamsButtonRB, 92, 23);
setPercentilePosition(layoutParamsButtonSelect, 43, 94);
setPercentilePosition(layoutParamsButtonStart, 57, 94);
setPercentilePosition(layoutParamsButtonConfigure, 93, 7);
relative_layout.addView(digitalPad, layoutParamsDPad);
relative_layout.addView(stick, layoutParamsStick);
relative_layout.addView(stick2, layoutParamsStick2);
relative_layout.addView(buttonA, layoutParamsButtonA);
relative_layout.addView(buttonB, layoutParamsButtonB);
relative_layout.addView(buttonX, layoutParamsButtonX);
relative_layout.addView(buttonY, layoutParamsButtonY);
relative_layout.addView(buttonLT, layoutParamsButtonLT);
relative_layout.addView(buttonRT, layoutParamsButtonRT);
relative_layout.addView(buttonLB, layoutParamsButtonLB);
relative_layout.addView(buttonRB, layoutParamsButtonRB);
relative_layout.addView(buttonSelect, layoutParamsButtonSelect);
relative_layout.addView(buttonStart, layoutParamsButtonStart);
relative_layout.addView(buttonConfigure, layoutParamsButtonConfigure);
}
private DigitalButton createDigitalButton(String text, final int key, Context context)
{
DigitalButton button = new DigitalButton(context);
button.setText(text);
button.addDigitalButtonListener(new DigitalButton.DigitalButtonListener()
{
@Override
public void onClick()
{
inputMap |= key;
sendControllerInputPacket();
}
@Override
public void onLongClick()
{
}
@Override
public void onRelease()
{
inputMap &= ~key;
sendControllerInputPacket();
}
});
return button;
}
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);
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);
if (connection != null)
{
connection.sendControllerInput(inputMap, leftTrigger, rightTrigger,
leftStickX, leftStickY, rightStickX, rightStickY);
}
}
catch (Exception e)
{
e.printStackTrace();
}
if (connection != null)
{
connection.sendControllerInput(inputMap, leftTrigger, rightTrigger,
leftStickX, leftStickY, rightStickX, rightStickY);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

View File

@@ -1,9 +1,7 @@
package com.limelight.binding.input.virtual_controller;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
@@ -16,29 +14,30 @@ import com.limelight.R;
*/
public class VirtualControllerConfiguration extends Activity
{
VirtualController virtualController;
VirtualController virtualController;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// We don't want a title bar
requestWindowFeature(Window.FEATURE_NO_TITLE);
// We don't want a title bar
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Full-screen and don't let the display go off
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// Full-screen and don't let the display go off
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// Inflate the content
setContentView(R.layout.activity_configure_virtual_controller);
// Inflate the content
setContentView(R.layout.activity_configure_virtual_controller);
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.configure_virtual_controller_frameLayout);
FrameLayout frameLayout =
(FrameLayout) findViewById(R.id.configure_virtual_controller_frameLayout);
// start with configuration constructor
virtualController = new VirtualController(null, frameLayout, this);
// start with configuration constructor
virtualController = new VirtualController(null, frameLayout, this);
Toast.makeText(getApplicationContext(), "Not implemented yet!", Toast.LENGTH_SHORT).show();
}
Toast.makeText(getApplicationContext(), "Not implemented yet!", Toast.LENGTH_SHORT).show();
}
}

View File

@@ -0,0 +1,45 @@
package com.limelight.binding.input.virtual_controller;
import android.content.Context;
import android.view.View;
/**
* Created by Karim on 27.01.2015.
*/
public abstract class VirtualControllerElement extends View
{
protected static boolean _PRINT_DEBUG_INFORMATION = false;
protected int normalColor = 0xF0888888;
protected int pressedColor = 0xF00000FF;
protected VirtualControllerElement(Context context)
{
super(context);
}
protected static final void _DBG(String text)
{
if (_PRINT_DEBUG_INFORMATION)
{
System.out.println("DigitalButton: " + text);
}
}
public void setColors(int normalColor, int pressedColor)
{
this.normalColor = normalColor;
this.pressedColor = pressedColor;
invalidate();
}
protected final float getPercent(float value, float percent)
{
return value / 100 * percent;
}
protected final int getCorrectWidth()
{
return getWidth() > getHeight() ? getHeight() : getWidth();
}
}

View File

@@ -2,46 +2,28 @@ package com.limelight.binding.input.virtual_controller;
import android.app.Activity;
import android.os.Bundle;
import android.view.MenuInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.PopupMenu;
import android.widget.Toast;
import com.limelight.R;
import org.apache.http.util.VersionInfo;
/**
* Created by Karim on 26.01.2015.
*/
public class VirtualControllerSettings extends Activity
{
private static VirtualController controller = null;
private static View view = null;
private VirtualController controller = null;
static void setController(VirtualController value)
{
controller = value;
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// We don't want a title bar
requestWindowFeature(Window.FEATURE_NO_TITLE);
static void setView(View value)
{
view = value;
}
// Inflate the content
setContentView(R.layout.activity_virtual_controller_settings);
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// We don't want a title bar
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Inflate the content
setContentView(R.layout.activity_virtual_controller_settings);
Toast.makeText(getApplicationContext(), "Not implemented yet!", Toast.LENGTH_SHORT).show();
}
Toast.makeText(getApplicationContext(), "Not implemented yet!", Toast.LENGTH_SHORT).show();
}
}