[Android-overlay] Add the new overlay icons. Support configuring them. Disable hardfloat since it has issues since Dalvik doesn't understand passing floats due to ABI differences.

This commit is contained in:
Ryan Houdek 2013-11-29 18:37:33 -06:00
parent 7f85c3215b
commit 49eef423a8
45 changed files with 115 additions and 94 deletions

View file

@ -289,10 +289,6 @@ if(ANDROID)
set(USE_WAYLAND 0)
set(USE_UPNP 0)
set(USE_GLES3 1)
if(ANDROID_NDK_ABI_NAME STREQUAL "armeabi-v7a")
message("Enabling hard-float")
add_definitions(-mhard-float)
endif()
endif()
# For now GLES and EGL are tied to each other.

View file

@ -18,8 +18,8 @@ C-Stick/Left = `Axis 17`
C-Stick/Right = `Axis 18`
C-Stick/Modifier = Control_L
C-Stick/Modifier/Range = 50.000000
Triggers/L = `Axis 18`
Triggers/R = `Axis 19`
Triggers/L = `Button 18`
Triggers/R = `Button 19`
D-Pad/Up = `Button 6`
D-Pad/Down = `Button 7`
D-Pad/Left = `Button 8`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -37,6 +37,7 @@ public final class EmulationActivity extends Activity
private float screenWidth;
private float screenHeight;
private SharedPreferences sharedPrefs;
public static WindowManager wm;
@Override
public void onCreate(Bundle savedInstanceState)
@ -45,7 +46,7 @@ public final class EmulationActivity extends Activity
// Retrieve screen dimensions.
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = getWindowManager();
wm = getWindowManager();
wm.getDefaultDisplay().getMetrics(displayMetrics);
this.screenHeight = displayMetrics.heightPixels;
this.screenWidth = displayMetrics.widthPixels;

View file

@ -9,18 +9,25 @@ package org.dolphinemu.dolphinemu.emulation.overlay;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.*;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.NativeLibrary.ButtonState;
import org.dolphinemu.dolphinemu.NativeLibrary.ButtonType;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.emulation.EmulationActivity;
import java.util.HashSet;
import java.util.Set;
@ -34,6 +41,18 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<InputOverlayDrawableButton>();
private final Set<InputOverlayDrawableJoystick> overlayJoysticks = new HashSet<InputOverlayDrawableJoystick>();
public static Bitmap resizeBitmap(WindowManager wm, Context context, Bitmap bitmap, float scale) {
// Retrieve screen dimensions.
DisplayMetrics displayMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(displayMetrics);
Bitmap bitmapResized = Bitmap.createScaledBitmap(bitmap,
(int)(displayMetrics.heightPixels * scale),
(int)(displayMetrics.heightPixels * scale),
false);
return bitmapResized;
}
/**
* Constructor
*
@ -45,11 +64,15 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
super(context, attrs);
// Add all the overlay items to the HashSet.
overlayButtons.add(initializeOverlayButton(context, R.drawable.button_a, ButtonType.BUTTON_A));
overlayButtons.add(initializeOverlayButton(context, R.drawable.button_b, ButtonType.BUTTON_B));
overlayButtons.add(initializeOverlayButton(context, R.drawable.button_start, ButtonType.BUTTON_START));
overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_a, ButtonType.BUTTON_A));
overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_b, ButtonType.BUTTON_B));
overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_x, ButtonType.BUTTON_X));
overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_y, ButtonType.BUTTON_Y));
overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_start, ButtonType.BUTTON_START));
overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_l, ButtonType.TRIGGER_L));
overlayButtons.add(initializeOverlayButton(context, R.drawable.gcpad_r, ButtonType.TRIGGER_R));
overlayJoysticks.add(initializeOverlayJoystick(context,
R.drawable.joy_outer, R.drawable.joy_inner,
R.drawable.gcpad_joystick_range, R.drawable.gcpad_joystick,
ButtonType.STICK_MAIN));
// Set the on touch listener.
@ -88,30 +111,11 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
// TODO: Refactor this so we detect either Axis movements or button presses so we don't run two loops all the time.
//
int buttonState = (event.getAction() == MotionEvent.ACTION_DOWN) ? ButtonState.PRESSED : ButtonState.RELEASED;
// Check if there was a touch within the bounds of a drawable.
for (InputOverlayDrawableButton button : overlayButtons)
{
// Check if there was a touch within the bounds of a drawable.
if (button.getBounds().contains((int)event.getX(), (int)event.getY()))
{
switch (button.getId())
{
case ButtonType.BUTTON_A:
NativeLibrary.onTouchEvent(0, ButtonType.BUTTON_A, buttonState);
break;
NativeLibrary.onTouchEvent(0, button.getId(), buttonState);
case ButtonType.BUTTON_B:
NativeLibrary.onTouchEvent(0, ButtonType.BUTTON_B, buttonState);
break;
case ButtonType.BUTTON_START:
NativeLibrary.onTouchEvent(0, ButtonType.BUTTON_START, buttonState);
break;
default:
break;
}
}
}
for (InputOverlayDrawableJoystick joystick : overlayJoysticks)
{
@ -120,9 +124,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
float[] axises = joystick.getAxisValues();
for (int a = 0; a < 4; ++a)
{
NativeLibrary.onTouchAxisEvent(0, axisIDs[a], axises[a]);
}
}
return true;
@ -168,7 +170,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(context);
// Initialize the InputOverlayDrawableButton.
final Bitmap bitmap = BitmapFactory.decodeResource(res, resId);
final Bitmap bitmap = resizeBitmap(EmulationActivity.wm, context, BitmapFactory.decodeResource(res, resId), 0.20f);
final InputOverlayDrawableButton overlayDrawable = new InputOverlayDrawableButton(res, bitmap, buttonId);
// String ID of the Drawable. This is what is passed into SharedPreferences
@ -212,7 +214,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(context);
// Initialize the InputOverlayDrawableJoystick.
final Bitmap bitmapOuter = BitmapFactory.decodeResource(res, resOuter);
final Bitmap bitmapOuter = resizeBitmap(EmulationActivity.wm, context, BitmapFactory.decodeResource(res, resOuter), 0.30f);
final Bitmap bitmapInner = BitmapFactory.decodeResource(res, resInner);
// String ID of the Drawable. This is what is passed into SharedPreferences
@ -226,7 +228,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
// Now set the bounds for the InputOverlayDrawableJoystick.
// This will dictate where on the screen (and the what the size) the InputOverlayDrawableJoystick will be.
int outerSize = bitmapOuter.getWidth() + 256;
int outerSize = bitmapOuter.getWidth();
Rect outerRect = new Rect(drawableX, drawableY, drawableX + outerSize, drawableY + outerSize);
Rect innerRect = new Rect(0, 0, outerSize / 4, outerSize / 4);

View file

@ -80,6 +80,7 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable
}
}
}
if (trackid == -1)
return;
float touchX = event.getX();
@ -101,27 +102,15 @@ public final class InputOverlayDrawableJoystick extends BitmapDrawable
public float[] getAxisValues()
{
float[] joyaxises = new float[4];
float[] joyaxises = {0f, 0f, 0f, 0f};
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;
}

View file

@ -6,6 +6,7 @@
package org.dolphinemu.dolphinemu.settings.input.overlayconfig;
import android.view.WindowManager;
import org.dolphinemu.dolphinemu.R;
import android.app.Activity;
@ -22,16 +23,28 @@ public final class OverlayConfigActivity extends Activity
{
super.onCreate(savedInstanceState);
WindowManager wm = getWindowManager();
// Initialize all of the buttons to add.
final OverlayConfigButton buttonA = new OverlayConfigButton(this, "button_a", R.drawable.button_a);
final OverlayConfigButton buttonB = new OverlayConfigButton(this, "button_b", R.drawable.button_b);
final OverlayConfigButton buttonS = new OverlayConfigButton(this, "button_start", R.drawable.button_start);
final OverlayConfigButton buttonA = new OverlayConfigButton(wm, this, "gcpad_a", R.drawable.gcpad_a);
final OverlayConfigButton buttonB = new OverlayConfigButton(wm, this, "gcpad_b", R.drawable.gcpad_b);
final OverlayConfigButton buttonX = new OverlayConfigButton(wm, this, "gcpad_x", R.drawable.gcpad_x);
final OverlayConfigButton buttonY = new OverlayConfigButton(wm, this, "gcpad_y", R.drawable.gcpad_y);
final OverlayConfigButton buttonS = new OverlayConfigButton(wm, this, "gcpad_start", R.drawable.gcpad_start);
final OverlayConfigButton buttonL = new OverlayConfigButton(wm, this, "gcpad_l", R.drawable.gcpad_l);
final OverlayConfigButton buttonR = new OverlayConfigButton(wm, this, "gcpad_r", R.drawable.gcpad_r);
final OverlayConfigButton joystick = new OverlayConfigButton(wm, this, "gcpad_joystick_range", R.drawable.gcpad_joystick_range);
// Add the buttons to the layout
final RelativeLayout configLayout = new RelativeLayout(this);
configLayout.addView(buttonA);
configLayout.addView(buttonB);
configLayout.addView(buttonX);
configLayout.addView(buttonY);
configLayout.addView(buttonS);
configLayout.addView(buttonL);
configLayout.addView(buttonR);
configLayout.addView(joystick);
// Now set the layout
setContentView(configLayout);

View file

@ -8,11 +8,17 @@ package org.dolphinemu.dolphinemu.settings.input.overlayconfig;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Button;
import org.dolphinemu.dolphinemu.R;
/**
* A movable {@link Button} for use within the
@ -36,6 +42,18 @@ public final class OverlayConfigButton extends Button implements OnTouchListener
// float buttonY = sPrefs.getFloat(buttonId+"-Y", -1f);
//
private final String buttonId;
private Drawable resizeDrawable(WindowManager wm, Context context, Drawable image, float scale) {
// Retrieve screen dimensions.
DisplayMetrics displayMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(displayMetrics);
Bitmap b = ((BitmapDrawable)image).getBitmap();
Bitmap bitmapResized = Bitmap.createScaledBitmap(b,
(int)(displayMetrics.heightPixels * scale),
(int)(displayMetrics.heightPixels * scale),
false);
return new BitmapDrawable(context.getResources(), bitmapResized);
}
/**
* Constructor
@ -44,7 +62,7 @@ public final class OverlayConfigButton extends Button implements OnTouchListener
* @param buttonId the String ID for this button.
* @param drawableId the Drawable ID for the image to represent this OverlayConfigButton.
*/
public OverlayConfigButton(Context context, String buttonId, int drawableId)
public OverlayConfigButton(WindowManager wm, Context context, String buttonId, int drawableId)
{
super(context);
@ -55,7 +73,9 @@ public final class OverlayConfigButton extends Button implements OnTouchListener
setOnTouchListener(this);
// Set the button's icon that represents it.
setBackground(context.getResources().getDrawable(drawableId));
setBackground(resizeDrawable(wm, context,
context.getResources().getDrawable(drawableId),
drawableId == R.drawable.gcpad_joystick_range ? 0.30f : 0.20f));
// Get the SharedPreferences instance.
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);

View file

@ -86,8 +86,8 @@ namespace ButtonManager
m_axises[std::make_pair(a, STICK_C_DOWN)] = new Axis();
m_axises[std::make_pair(a, STICK_C_LEFT)] = new Axis();
m_axises[std::make_pair(a, STICK_C_RIGHT)] = new Axis();
m_axises[std::make_pair(a, TRIGGER_L)] = new Axis();
m_axises[std::make_pair(a, TRIGGER_R)] = new Axis();
m_buttons[std::make_pair(a, TRIGGER_L)] = new Button();
m_buttons[std::make_pair(a, TRIGGER_R)] = new Button();
}
// Init our controller bindings
IniFile ini;
@ -137,19 +137,17 @@ namespace ButtonManager
}
float GetAxisValue(int padID, ButtonType axis)
{
float value = 0.0f;
value = m_axises[std::make_pair(padID, axis)]->AxisValue();
float value = m_axises[std::make_pair(padID, axis)]->AxisValue();
auto it = m_controllers.begin();
if (it == m_controllers.end())
return value;
return it->second->AxisValue(padID, axis);
}
void TouchEvent(int padID, int button, int action)
void TouchEvent(int padID, ButtonType button, int action)
{
m_buttons[std::make_pair(padID, button)]->SetState(action ? BUTTON_PRESSED : BUTTON_RELEASED);
}
void TouchAxisEvent(int padID, int axis, float value)
void TouchAxisEvent(int padID, ButtonType axis, float value)
{
m_axises[std::make_pair(padID, axis)]->SetValue(value);
}
@ -188,35 +186,39 @@ namespace ButtonManager
// InputDevice
void InputDevice::PressEvent(ButtonType button, int action)
{
m_buttons[m_binds[button]->m_bind] = action == 0 ? true : false;
if (_binds.find(button) == _binds.end())
return;
_buttons[_binds[button]->_bind] = action == 0 ? true : false;
}
void InputDevice::AxisEvent(ButtonType axis, float value)
{
m_axises[m_binds[axis]->m_bind] = value;
if (_binds.find(axis) == _binds.end())
return;
_axises[_binds[axis]->_bind] = value;
}
bool InputDevice::ButtonValue(int padID, ButtonType button)
{
auto it = m_binds.find(button);
if (it == m_binds.end())
auto it = _binds.find(button);
if (it == _binds.end())
return false;
if (it->second->m_padID != padID)
if (it->second->_padID != padID)
return false;
if (it->second->m_bindtype == BIND_BUTTON)
return m_buttons[it->second->m_bind];
if (it->second->_bindtype == BIND_BUTTON)
return _buttons[it->second->_bind];
else
return AxisValue(padID, button);
}
float InputDevice::AxisValue(int padID, ButtonType axis)
{
auto it = m_binds.find(axis);
if (it == m_binds.end())
auto it = _binds.find(axis);
if (it == _binds.end())
return 0.0f;
if (it->second->m_padID != padID)
if (it->second->_padID != padID)
return 0.0f;
if (it->second->m_bindtype == BIND_BUTTON)
if (it->second->_bindtype == BIND_BUTTON)
return ButtonValue(padID, axis);
else
return m_axises[it->second->m_bind] * it->second->m_neg;
return _axises[it->second->_bind] * it->second->_neg;
}
}

View file

@ -85,13 +85,13 @@ namespace ButtonManager
struct sBind
{
const int m_padID;
const ButtonType m_buttontype;
const BindType m_bindtype;
const int m_bind;
const float m_neg;
const int _padID;
const ButtonType _buttontype;
const BindType _bindtype;
const int _bind;
const float _neg;
sBind(int padID, ButtonType buttontype, BindType bindtype, int bind, float neg)
: m_padID(padID), m_buttontype(buttontype), m_bindtype(bindtype), m_bind(bind), m_neg(neg)
: _padID(padID), _buttontype(buttontype), _bindtype(bindtype), _bind(bind), _neg(neg)
{}
};
@ -99,21 +99,19 @@ namespace ButtonManager
class InputDevice
{
private:
std::string m_dev;
std::map<int, bool> m_buttons;
std::map<int, float> m_axises;
std::map<ButtonType, sBind*> m_binds;
const std::string _dev;
std::map<int, bool> _buttons;
std::map<int, float> _axises;
std::map<ButtonType, sBind*> _binds;
public:
InputDevice(std::string dev)
{
m_dev = dev;
}
: _dev(dev) {}
~InputDevice()
{
for (auto it = m_binds.begin(); it != m_binds.end(); ++it)
for (auto it = _binds.begin(); it != _binds.end(); ++it)
delete it->second;
}
void AddBind(sBind *bind) { m_binds[bind->m_buttontype] = bind; }
void AddBind(sBind *bind) { _binds[bind->_buttontype] = bind; }
void PressEvent(ButtonType button, int action);
void AxisEvent(ButtonType axis, float value);
bool ButtonValue(int padID, ButtonType button);
@ -123,8 +121,8 @@ namespace ButtonManager
void Init();
bool GetButtonPressed(int padID, ButtonType button);
float GetAxisValue(int padID, ButtonType axis);
void TouchEvent(int padID, int button, int action);
void TouchAxisEvent(int padID, int axis, float value);
void TouchEvent(int padID, ButtonType button, int action);
void TouchAxisEvent(int padID, ButtonType axis, float value);
void GamepadEvent(std::string dev, ButtonType button, int action);
void GamepadAxisEvent(std::string dev, ButtonType axis, float value);
void Shutdown();

View file

@ -239,11 +239,11 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulatio
}
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onTouchEvent(JNIEnv *env, jobject obj, jint padID, jint Button, jint Action)
{
ButtonManager::TouchEvent(padID, Button, Action);
ButtonManager::TouchEvent(padID, (ButtonManager::ButtonType)Button, Action);
}
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onTouchAxisEvent(JNIEnv *env, jobject obj, jint padID, jint Button, jfloat Action)
{
ButtonManager::TouchAxisEvent(padID, Button, Action);
ButtonManager::TouchAxisEvent(padID, (ButtonManager::ButtonType)Button, Action);
}
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadEvent(JNIEnv *env, jobject obj, jstring jDevice, jint Button, jint Action)
{