[Android-overlay] Support touch screen axises in native. Have a non-configurable main joystick on screen at this point.
This commit is contained in:
parent
9d3d568ae4
commit
feedee5c23
|
@ -59,6 +59,14 @@ public final class NativeLibrary
|
||||||
*/
|
*/
|
||||||
public static native void onTouchEvent(int Button, int Action);
|
public static native void onTouchEvent(int Button, int Action);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles touch events.
|
||||||
|
*
|
||||||
|
* @param Button Key code identifying which button was pressed.
|
||||||
|
* @param Action Mask for the action being performed.
|
||||||
|
*/
|
||||||
|
public static native void onTouchAxisEvent(int Axis, float loc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles button press events for a gamepad.
|
* Handles button press events for a gamepad.
|
||||||
*
|
*
|
||||||
|
|
|
@ -6,36 +6,41 @@
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.emulation.overlay;
|
package org.dolphinemu.dolphinemu.emulation.overlay;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import android.content.Context;
|
||||||
import java.util.Set;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.*;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnTouchListener;
|
||||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||||
import org.dolphinemu.dolphinemu.NativeLibrary.ButtonState;
|
import org.dolphinemu.dolphinemu.NativeLibrary.ButtonState;
|
||||||
import org.dolphinemu.dolphinemu.NativeLibrary.ButtonType;
|
import org.dolphinemu.dolphinemu.NativeLibrary.ButtonType;
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
|
||||||
import android.content.Context;
|
import java.util.HashSet;
|
||||||
import android.content.SharedPreferences;
|
import java.util.Set;
|
||||||
import android.content.res.Resources;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import android.graphics.Bitmap;
|
import java.util.concurrent.Semaphore;
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.SurfaceView;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnTouchListener;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the interactive input overlay on top of the
|
* Draws the interactive input overlay on top of the
|
||||||
* {@link NativeGLSurfaceView} that is rendering emulation.
|
* {@link NativeGLSurfaceView} that is rendering emulation.
|
||||||
*/
|
*/
|
||||||
public final class InputOverlay extends SurfaceView implements OnTouchListener
|
public final class InputOverlay extends SurfaceView implements OnTouchListener, Runnable
|
||||||
{
|
{
|
||||||
private final Set<InputOverlayDrawable> overlayItems = new HashSet<InputOverlayDrawable>();
|
private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<InputOverlayDrawableButton>();
|
||||||
|
private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<InputOverlayDrawableJoystick>();
|
||||||
|
Semaphore _sema;
|
||||||
|
|
||||||
|
SurfaceHolder surfaceHolder;
|
||||||
|
Thread thread = null;
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
|
@ -47,9 +52,13 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
|
||||||
// Add all the overlay items to the HashSet.
|
// Add all the overlay items to the HashSet.
|
||||||
overlayItems.add(initializeOverlayDrawable(context, R.drawable.button_a, ButtonType.BUTTON_A));
|
overlayButtons.add(initializeOverlayButton(context, R.drawable.button_a, ButtonType.BUTTON_A));
|
||||||
overlayItems.add(initializeOverlayDrawable(context, R.drawable.button_b, ButtonType.BUTTON_B));
|
overlayButtons.add(initializeOverlayButton(context, R.drawable.button_b, ButtonType.BUTTON_B));
|
||||||
overlayItems.add(initializeOverlayDrawable(context, R.drawable.button_start, ButtonType.BUTTON_START));
|
overlayButtons.add(initializeOverlayButton(context, R.drawable.button_start, ButtonType.BUTTON_START));
|
||||||
|
overlayJoysticks.add(initializeOverlayJoystick(context,
|
||||||
|
R.drawable.joy_outer, R.drawable.joy_inner,
|
||||||
|
ButtonType.STICK_MAIN_UP, ButtonType.STICK_MAIN_DOWN,
|
||||||
|
ButtonType.STICK_MAIN_LEFT, ButtonType.STICK_MAIN_RIGHT));
|
||||||
|
|
||||||
// Set the on touch listener.
|
// Set the on touch listener.
|
||||||
setOnTouchListener(this);
|
setOnTouchListener(this);
|
||||||
|
@ -59,8 +68,42 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
|
|
||||||
// Request focus for the overlay so it has priority on presses.
|
// Request focus for the overlay so it has priority on presses.
|
||||||
requestFocus();
|
requestFocus();
|
||||||
}
|
_sema = new Semaphore(0);
|
||||||
|
|
||||||
|
surfaceHolder = getHolder();
|
||||||
|
surfaceHolder.setFormat(PixelFormat.TRANSPARENT);
|
||||||
|
thread = new Thread(this);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
private boolean Draw()
|
||||||
|
{
|
||||||
|
if(surfaceHolder.getSurface().isValid()){
|
||||||
|
// Draw everything
|
||||||
|
Canvas canvas = surfaceHolder.lockCanvas();
|
||||||
|
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
||||||
|
for (InputOverlayDrawableButton item : overlayButtons)
|
||||||
|
item.draw(canvas);
|
||||||
|
for (InputOverlayDrawableJoystick item : overlayJoysticks)
|
||||||
|
item.Draw(canvas);
|
||||||
|
surfaceHolder.unlockCanvasAndPost(canvas);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
boolean didFirstPost = false;
|
||||||
|
while(!didFirstPost)
|
||||||
|
if (Draw())
|
||||||
|
didFirstPost = true;
|
||||||
|
while(true){
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_sema.acquire();
|
||||||
|
Draw();
|
||||||
|
} catch (InterruptedException ex) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View v, MotionEvent event)
|
public boolean onTouch(View v, MotionEvent event)
|
||||||
{
|
{
|
||||||
|
@ -69,7 +112,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
// The reason it won't work is that when moving an axis, you would get the event MotionEvent.ACTION_MOVE.
|
// The reason it won't work is that when moving an axis, you would get the event MotionEvent.ACTION_MOVE.
|
||||||
int buttonState = (event.getAction() == MotionEvent.ACTION_DOWN) ? ButtonState.PRESSED : ButtonState.RELEASED;
|
int buttonState = (event.getAction() == MotionEvent.ACTION_DOWN) ? ButtonState.PRESSED : ButtonState.RELEASED;
|
||||||
|
|
||||||
for (InputOverlayDrawable item : overlayItems)
|
for (InputOverlayDrawableButton item : overlayButtons)
|
||||||
{
|
{
|
||||||
// Check if there was a touch within the bounds of a drawable.
|
// Check if there was a touch within the bounds of a drawable.
|
||||||
if (item.getBounds().contains((int)event.getX(), (int)event.getY()))
|
if (item.getBounds().contains((int)event.getX(), (int)event.getY()))
|
||||||
|
@ -93,24 +136,22 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (InputOverlayDrawableJoystick item : overlayJoysticks)
|
||||||
|
{
|
||||||
|
item.TrackEvent(event);
|
||||||
|
int[] axisIDs = item.getAxisIDs();
|
||||||
|
float[] axises = item.getAxisValues();
|
||||||
|
|
||||||
|
for (int a = 0; a < 4; ++a)
|
||||||
|
NativeLibrary.onTouchAxisEvent(axisIDs[a], axises[a]);
|
||||||
|
}
|
||||||
|
_sema.release();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDraw(Canvas canvas)
|
|
||||||
{
|
|
||||||
super.onDraw(canvas);
|
|
||||||
|
|
||||||
// Draw all overlay items.
|
|
||||||
for (InputOverlayDrawable item : overlayItems)
|
|
||||||
{
|
|
||||||
item.draw(canvas);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an InputOverlayDrawable, given by resId, with all of the
|
* Initializes an InputOverlayDrawableButton, given by resId, with all of the
|
||||||
* parameters set for it to be properly shown on the InputOverlay.
|
* parameters set for it to be properly shown on the InputOverlay.
|
||||||
* <p>
|
* <p>
|
||||||
* This works due to the way the X and Y coordinates are stored within
|
* This works due to the way the X and Y coordinates are stored within
|
||||||
|
@ -130,47 +171,76 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>
|
* <p>
|
||||||
* Technically no modifications should need to be performed on the returned
|
* Technically no modifications should need to be performed on the returned
|
||||||
* InputOverlayDrawable. Simply add it to the HashSet of overlay items and wait
|
* InputOverlayDrawableButton. Simply add it to the HashSet of overlay items and wait
|
||||||
* for Android to call the onDraw method.
|
* for Android to call the onDraw method.
|
||||||
*
|
*
|
||||||
* @param context The current {@link Context}.
|
* @param context The current {@link Context}.
|
||||||
* @param resId The resource ID of the {@link Drawable} to get the {@link Bitmap} of.
|
* @param resId The resource ID of the {@link Drawable} to get the {@link Bitmap} of.
|
||||||
* @param buttonId Identifier for determining what type of button the initialized InputOverlayDrawable represents.
|
* @param buttonId Identifier for determining what type of button the initialized InputOverlayDrawableButton represents.
|
||||||
*
|
*
|
||||||
* @return An {@link InputOverlayDrawable} with the correct drawing bounds set.
|
* @return An {@link InputOverlayDrawableButton} with the correct drawing bounds set.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static InputOverlayDrawable initializeOverlayDrawable(Context context, int resId, int buttonId)
|
private static InputOverlayDrawableButton initializeOverlayButton(Context context, int resId, int buttonId)
|
||||||
{
|
{
|
||||||
// Resources handle for fetching the initial Drawable resource.
|
// Resources handle for fetching the initial Drawable resource.
|
||||||
final Resources res = context.getResources();
|
final Resources res = context.getResources();
|
||||||
|
|
||||||
// SharedPreference to retrieve the X and Y coordinates for the InputOverlayDrawable.
|
// SharedPreference to retrieve the X and Y coordinates for the InputOverlayDrawableButton.
|
||||||
final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
// Initialize the InputOverlayDrawable.
|
// Initialize the InputOverlayDrawableButton.
|
||||||
final Bitmap bitmap = BitmapFactory.decodeResource(res, resId);
|
final Bitmap bitmap = BitmapFactory.decodeResource(res, resId);
|
||||||
final InputOverlayDrawable overlayDrawable = new InputOverlayDrawable(res, bitmap, buttonId);
|
final InputOverlayDrawableButton overlayDrawable = new InputOverlayDrawableButton(res, bitmap, buttonId);
|
||||||
|
|
||||||
// String ID of the Drawable. This is what is passed into SharedPreferences
|
// String ID of the Drawable. This is what is passed into SharedPreferences
|
||||||
// to check whether or not a value has been set.
|
// to check whether or not a value has been set.
|
||||||
final String drawableId = res.getResourceEntryName(resId);
|
final String drawableId = res.getResourceEntryName(resId);
|
||||||
|
|
||||||
// The X and Y coordinates of the InputOverlayDrawable on the InputOverlay.
|
// The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay.
|
||||||
// These were set in the input overlay configuration menu.
|
// These were set in the input overlay configuration menu.
|
||||||
int drawableX = (int) sPrefs.getFloat(drawableId+"-X", 0f);
|
int drawableX = (int) sPrefs.getFloat(drawableId+"-X", 0f);
|
||||||
int drawableY = (int) sPrefs.getFloat(drawableId+"-Y", 0f);
|
int drawableY = (int) sPrefs.getFloat(drawableId+"-Y", 0f);
|
||||||
|
|
||||||
// Intrinsic width and height of the InputOverlayDrawable.
|
// Intrinsic width and height of the InputOverlayDrawableButton.
|
||||||
// For any who may not know, intrinsic width/height
|
// For any who may not know, intrinsic width/height
|
||||||
// are the original unmodified width and height of the image.
|
// are the original unmodified width and height of the image.
|
||||||
int intrinWidth = overlayDrawable.getIntrinsicWidth();
|
int intrinWidth = overlayDrawable.getIntrinsicWidth();
|
||||||
int intrinHeight = overlayDrawable.getIntrinsicHeight();
|
int intrinHeight = overlayDrawable.getIntrinsicHeight();
|
||||||
|
|
||||||
// Now set the bounds for the InputOverlayDrawable.
|
// Now set the bounds for the InputOverlayDrawableButton.
|
||||||
// This will dictate where on the screen (and the what the size) the InputOverlayDrawable will be.
|
// This will dictate where on the screen (and the what the size) the InputOverlayDrawableButton will be.
|
||||||
overlayDrawable.setBounds(drawableX, drawableY, drawableX+intrinWidth, drawableY+intrinHeight);
|
overlayDrawable.setBounds(drawableX, drawableY, drawableX+intrinWidth, drawableY+intrinHeight);
|
||||||
|
|
||||||
|
return overlayDrawable;
|
||||||
|
}
|
||||||
|
private static InputOverlayDrawableJoystick initializeOverlayJoystick(Context context, int resOuter, int resInner, int axisUp, int axisDown, int axisLeft, int axisRight)
|
||||||
|
{
|
||||||
|
// Resources handle for fetching the initial Drawable resource.
|
||||||
|
final Resources res = context.getResources();
|
||||||
|
|
||||||
|
// SharedPreference to retrieve the X and Y coordinates for the InputOverlayDrawableButton.
|
||||||
|
final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
|
// Initialize the InputOverlayDrawableButton.
|
||||||
|
final Bitmap bitmapOuter = BitmapFactory.decodeResource(res, resOuter);
|
||||||
|
final Bitmap bitmapInner = BitmapFactory.decodeResource(res, resInner);
|
||||||
|
|
||||||
|
// Now set the bounds for the InputOverlayDrawableButton.
|
||||||
|
// This will dictate where on the screen (and the what the size) the InputOverlayDrawableButton will be.
|
||||||
|
int outerSize = bitmapOuter.getWidth() + 256;
|
||||||
|
int X = 0;
|
||||||
|
int Y = 0;
|
||||||
|
Rect outerRect = new Rect(X, Y, X + outerSize, Y + outerSize);
|
||||||
|
Rect innerRect = new Rect(0, 0, outerSize / 4, outerSize / 4);
|
||||||
|
|
||||||
|
final InputOverlayDrawableJoystick overlayDrawable
|
||||||
|
= new InputOverlayDrawableJoystick(res,
|
||||||
|
bitmapOuter, bitmapInner,
|
||||||
|
outerRect, innerRect,
|
||||||
|
axisUp, axisDown, axisLeft, axisRight);
|
||||||
|
|
||||||
|
|
||||||
return overlayDrawable;
|
return overlayDrawable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import android.graphics.drawable.BitmapDrawable;
|
||||||
* Custom {@link BitmapDrawable} that is capable
|
* Custom {@link BitmapDrawable} that is capable
|
||||||
* of storing it's own ID.
|
* of storing it's own ID.
|
||||||
*/
|
*/
|
||||||
public class InputOverlayDrawable extends BitmapDrawable
|
public class InputOverlayDrawableButton extends BitmapDrawable
|
||||||
{
|
{
|
||||||
// The ID identifying what type of button this Drawable represents.
|
// The ID identifying what type of button this Drawable represents.
|
||||||
private int buttonType;
|
private int buttonType;
|
||||||
|
@ -26,7 +26,7 @@ public class InputOverlayDrawable extends BitmapDrawable
|
||||||
* @param bitmap {@link Bitmap} to use with this Drawable.
|
* @param bitmap {@link Bitmap} to use with this Drawable.
|
||||||
* @param buttonType Identifier for this type of button.
|
* @param buttonType Identifier for this type of button.
|
||||||
*/
|
*/
|
||||||
public InputOverlayDrawable(Resources res, Bitmap bitmap, int buttonType)
|
public InputOverlayDrawableButton(Resources res, Bitmap bitmap, int buttonType)
|
||||||
{
|
{
|
||||||
super(res, bitmap);
|
super(res, bitmap);
|
||||||
|
|
||||||
|
@ -34,9 +34,9 @@ public class InputOverlayDrawable extends BitmapDrawable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets this InputOverlayDrawable's button ID.
|
* Gets this InputOverlayDrawableButton's button ID.
|
||||||
*
|
*
|
||||||
* @return this InputOverlayDrawable's button ID.
|
* @return this InputOverlayDrawableButton's button ID.
|
||||||
*/
|
*/
|
||||||
public int getId()
|
public int getId()
|
||||||
{
|
{
|
|
@ -0,0 +1,140 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2013 Dolphin Emulator Project
|
||||||
|
* Licensed under GPLv2
|
||||||
|
* Refer to the license.txt file included.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.emulation.overlay;
|
||||||
|
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom {@link android.graphics.drawable.BitmapDrawable} that is capable
|
||||||
|
* of storing it's own ID.
|
||||||
|
*/
|
||||||
|
public class InputOverlayDrawableJoystick extends BitmapDrawable
|
||||||
|
{
|
||||||
|
// The ID identifying what type of button this Drawable represents.
|
||||||
|
private int axisIDs[] = {0, 0, 0, 0};
|
||||||
|
private float axises[] = {0f, 0f};
|
||||||
|
private int trackid = -1;
|
||||||
|
private BitmapDrawable ringInner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param res {@link android.content.res.Resources} instance.
|
||||||
|
* @param bitmapOuter {@link android.graphics.Bitmap} to use with this Drawable.
|
||||||
|
* @param axisUp Identifier for this type of axis.
|
||||||
|
* @param axisDown Identifier for this type of axis.
|
||||||
|
* @param axisLeft Identifier for this type of axis.
|
||||||
|
* @param axisRight Identifier for this type of axis.
|
||||||
|
*/
|
||||||
|
public InputOverlayDrawableJoystick(Resources res,
|
||||||
|
Bitmap bitmapOuter, Bitmap bitmapInner,
|
||||||
|
Rect rectOuter, Rect rectInner,
|
||||||
|
int axisUp, int axisDown, int axisLeft, int axisRight)
|
||||||
|
{
|
||||||
|
super(res, bitmapOuter);
|
||||||
|
this.setBounds(rectOuter);
|
||||||
|
|
||||||
|
this.ringInner = new BitmapDrawable(res, bitmapInner);
|
||||||
|
this.ringInner.setBounds(rectInner);
|
||||||
|
SetInnerBounds();
|
||||||
|
this.axisIDs[0] = axisUp;
|
||||||
|
this.axisIDs[1] = axisDown;
|
||||||
|
this.axisIDs[2] = axisLeft;
|
||||||
|
this.axisIDs[3] = axisRight;
|
||||||
|
}
|
||||||
|
public void Draw(Canvas canvas)
|
||||||
|
{
|
||||||
|
this.draw(canvas);
|
||||||
|
ringInner.draw(canvas);
|
||||||
|
}
|
||||||
|
public void TrackEvent(MotionEvent event)
|
||||||
|
{
|
||||||
|
int pointerIndex = event.getActionIndex();
|
||||||
|
if (trackid == -1)
|
||||||
|
{
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_DOWN)
|
||||||
|
if(getBounds().contains((int)event.getX(), (int)event.getY()))
|
||||||
|
trackid = event.getPointerId(pointerIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_UP)
|
||||||
|
{
|
||||||
|
if (trackid == event.getPointerId(pointerIndex))
|
||||||
|
{
|
||||||
|
axises[0] = axises[1] = 0.0f;
|
||||||
|
SetInnerBounds();
|
||||||
|
trackid = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (trackid == -1)
|
||||||
|
return;
|
||||||
|
float touchX = event.getX();
|
||||||
|
float touchY = event.getY();
|
||||||
|
float maxY = this.getBounds().bottom;
|
||||||
|
float maxX = this.getBounds().right;
|
||||||
|
touchX -= this.getBounds().centerX();
|
||||||
|
maxX -= this.getBounds().centerX();
|
||||||
|
touchY -= this.getBounds().centerY();
|
||||||
|
maxY -= this.getBounds().centerY();
|
||||||
|
final float AxisX = touchX / maxX;
|
||||||
|
final float AxisY = touchY/maxY;
|
||||||
|
|
||||||
|
this.axises[0] = AxisY;
|
||||||
|
this.axises[1] = AxisX;
|
||||||
|
|
||||||
|
SetInnerBounds();
|
||||||
|
}
|
||||||
|
public float[] getAxisValues()
|
||||||
|
{
|
||||||
|
float[] joyaxises = new float[4];
|
||||||
|
if (axises[0] >= 0.0f)
|
||||||
|
{
|
||||||
|
joyaxises[0] = 0.0f;
|
||||||
|
joyaxises[1] = Math.min(axises[0], 1.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
joyaxises[0] = Math.min(Math.abs(axises[0]), 1.0f);
|
||||||
|
joyaxises[1] = 0.0f;
|
||||||
|
}
|
||||||
|
if (axises[1] >= 0.0)
|
||||||
|
{
|
||||||
|
joyaxises[2] = 0.0f;
|
||||||
|
joyaxises[3] = Math.min(axises[1], 1.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
joyaxises[2] = Math.min(Math.abs(axises[1]), 1.0f);
|
||||||
|
joyaxises[3] = 0.0f;
|
||||||
|
}
|
||||||
|
return joyaxises;
|
||||||
|
}
|
||||||
|
public int[] getAxisIDs()
|
||||||
|
{
|
||||||
|
return axisIDs;
|
||||||
|
}
|
||||||
|
private void SetInnerBounds()
|
||||||
|
{
|
||||||
|
float floatX = this.getBounds().centerX();
|
||||||
|
float floatY = this.getBounds().centerY();
|
||||||
|
floatY += axises[0] * (this.getBounds().height() / 2);
|
||||||
|
floatX += axises[1] * (this.getBounds().width() / 2);
|
||||||
|
int X = (int)(floatX);
|
||||||
|
int Y = (int)(floatY);
|
||||||
|
int width = this.ringInner.getBounds().width() / 2;
|
||||||
|
int height = this.ringInner.getBounds().height() / 2;
|
||||||
|
this.ringInner.setBounds(X - width, Y - height,
|
||||||
|
X + width, Y + height);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ extern void DrawButton(GLuint tex, float *coords);
|
||||||
namespace ButtonManager
|
namespace ButtonManager
|
||||||
{
|
{
|
||||||
std::unordered_map<int, Button*> m_buttons;
|
std::unordered_map<int, Button*> m_buttons;
|
||||||
|
std::unordered_map<int, Axis*> m_axises;
|
||||||
std::unordered_map<std::string, InputDevice*> m_controllers;
|
std::unordered_map<std::string, InputDevice*> m_controllers;
|
||||||
const char *configStrings[] = { "InputA",
|
const char *configStrings[] = { "InputA",
|
||||||
"InputB",
|
"InputB",
|
||||||
|
@ -74,6 +75,16 @@ namespace ButtonManager
|
||||||
m_buttons[BUTTON_LEFT] = new Button();
|
m_buttons[BUTTON_LEFT] = new Button();
|
||||||
m_buttons[BUTTON_RIGHT] = new Button();
|
m_buttons[BUTTON_RIGHT] = new Button();
|
||||||
|
|
||||||
|
m_axises[STICK_MAIN_UP] = new Axis();
|
||||||
|
m_axises[STICK_MAIN_DOWN] = new Axis();
|
||||||
|
m_axises[STICK_MAIN_LEFT] = new Axis();
|
||||||
|
m_axises[STICK_MAIN_RIGHT] = new Axis();
|
||||||
|
m_axises[STICK_C_UP] = new Axis();
|
||||||
|
m_axises[STICK_C_DOWN] = new Axis();
|
||||||
|
m_axises[STICK_C_LEFT] = new Axis();
|
||||||
|
m_axises[STICK_C_RIGHT] = new Axis();
|
||||||
|
m_axises[TRIGGER_L] = new Axis();
|
||||||
|
m_axises[TRIGGER_R] = new Axis();
|
||||||
|
|
||||||
// Init our controller bindings
|
// Init our controller bindings
|
||||||
IniFile ini;
|
IniFile ini;
|
||||||
|
@ -118,16 +129,22 @@ namespace ButtonManager
|
||||||
}
|
}
|
||||||
float GetAxisValue(ButtonType axis)
|
float GetAxisValue(ButtonType axis)
|
||||||
{
|
{
|
||||||
|
float value = 0.0f;
|
||||||
|
value = m_axises[axis]->AxisValue();
|
||||||
|
|
||||||
auto it = m_controllers.begin();
|
auto it = m_controllers.begin();
|
||||||
if (it == m_controllers.end())
|
if (it == m_controllers.end())
|
||||||
return 0.0f;
|
return value;
|
||||||
return it->second->AxisValue(axis);
|
return it->second->AxisValue(axis);
|
||||||
}
|
}
|
||||||
void TouchEvent(int button, int action)
|
void TouchEvent(int button, int action)
|
||||||
{
|
{
|
||||||
m_buttons[button]->SetState(action ? BUTTON_PRESSED : BUTTON_RELEASED);
|
m_buttons[button]->SetState(action ? BUTTON_PRESSED : BUTTON_RELEASED);
|
||||||
}
|
}
|
||||||
|
void TouchAxisEvent(int axis, float value)
|
||||||
|
{
|
||||||
|
m_axises[axis]->SetValue(value);
|
||||||
|
}
|
||||||
void GamepadEvent(std::string dev, int button, int action)
|
void GamepadEvent(std::string dev, int button, int action)
|
||||||
{
|
{
|
||||||
auto it = m_controllers.find(dev);
|
auto it = m_controllers.find(dev);
|
||||||
|
@ -160,11 +177,6 @@ namespace ButtonManager
|
||||||
m_buttons.clear();
|
m_buttons.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawButtons()
|
|
||||||
{
|
|
||||||
// XXX: Make platform specific drawing
|
|
||||||
}
|
|
||||||
|
|
||||||
// InputDevice
|
// InputDevice
|
||||||
void InputDevice::PressEvent(int button, int action)
|
void InputDevice::PressEvent(int button, int action)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,7 +67,18 @@ namespace ButtonManager
|
||||||
void SetState(ButtonState state) { m_state = state; }
|
void SetState(ButtonState state) { m_state = state; }
|
||||||
bool Pressed() { return m_state == BUTTON_PRESSED; }
|
bool Pressed() { return m_state == BUTTON_PRESSED; }
|
||||||
|
|
||||||
~Button() { }
|
~Button() {}
|
||||||
|
};
|
||||||
|
class Axis
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float m_value;
|
||||||
|
public:
|
||||||
|
Axis() : m_value(0.0f) {}
|
||||||
|
void SetValue(float value) { m_value = value; }
|
||||||
|
float AxisValue() { return m_value; }
|
||||||
|
|
||||||
|
~Axis() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sBind
|
struct sBind
|
||||||
|
@ -107,10 +118,10 @@ namespace ButtonManager
|
||||||
};
|
};
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void DrawButtons();
|
|
||||||
bool GetButtonPressed(ButtonType button);
|
bool GetButtonPressed(ButtonType button);
|
||||||
float GetAxisValue(ButtonType axis);
|
float GetAxisValue(ButtonType axis);
|
||||||
void TouchEvent(int button, int action);
|
void TouchEvent(int button, int action);
|
||||||
|
void TouchAxisEvent(int axis, float value);
|
||||||
void GamepadEvent(std::string dev, int button, int action);
|
void GamepadEvent(std::string dev, int button, int action);
|
||||||
void GamepadAxisEvent(std::string dev, int axis, float value);
|
void GamepadAxisEvent(std::string dev, int axis, float value);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
|
@ -241,6 +241,10 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onTouchEvent
|
||||||
{
|
{
|
||||||
ButtonManager::TouchEvent(Button, Action);
|
ButtonManager::TouchEvent(Button, Action);
|
||||||
}
|
}
|
||||||
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onTouchAxisEvent(JNIEnv *env, jobject obj, jint Button, jfloat Action)
|
||||||
|
{
|
||||||
|
ButtonManager::TouchAxisEvent(Button, Action);
|
||||||
|
}
|
||||||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadEvent(JNIEnv *env, jobject obj, jstring jDevice, jint Button, jint Action)
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadEvent(JNIEnv *env, jobject obj, jstring jDevice, jint Button, jint Action)
|
||||||
{
|
{
|
||||||
const char *Device = env->GetStringUTFChars(jDevice, NULL);
|
const char *Device = env->GetStringUTFChars(jDevice, NULL);
|
||||||
|
@ -375,15 +379,6 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *
|
||||||
VideoBackend::ActivateBackend(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoBackend);
|
VideoBackend::ActivateBackend(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoBackend);
|
||||||
WiimoteReal::LoadSettings();
|
WiimoteReal::LoadSettings();
|
||||||
|
|
||||||
// Load our Android specific settings
|
|
||||||
IniFile ini;
|
|
||||||
bool onscreencontrols = true;
|
|
||||||
ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string("Dolphin.ini"));
|
|
||||||
ini.Get("Android", "ScreenControls", &onscreencontrols, true);
|
|
||||||
|
|
||||||
if (onscreencontrols)
|
|
||||||
OSD::AddCallback(OSD::OSD_ONFRAME, ButtonManager::DrawButtons);
|
|
||||||
|
|
||||||
// No use running the loop when booting fails
|
// No use running the loop when booting fails
|
||||||
if ( BootManager::BootCore( g_filename.c_str() ) )
|
if ( BootManager::BootCore( g_filename.c_str() ) )
|
||||||
while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
|
while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
|
||||||
|
|
Loading…
Reference in New Issue