Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Common/Input/InputState.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ enum {
TOUCH_RELEASE_ALL = 1 << 6, // Useful for app focus switches when events may be lost.
TOUCH_HOVER = 1 << 7,

// These are the Android getToolType() codes, shifted by 10.
// These are the Android getToolType() codes, shifted by 10. Unused currently.
TOUCH_TOOL_MASK = 7 << 10,
TOUCH_TOOL_UNKNOWN = 0 << 10,
TOUCH_TOOL_FINGER = 1 << 10,
Expand Down
2 changes: 1 addition & 1 deletion Common/UI/ViewGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,7 @@ std::string GridLayoutList::DescribeText() const {
}

TabHolder::TabHolder(Orientation orientation, float stripSize, LayoutParams *layoutParams)
: LinearLayout(Opposite(orientation), layoutParams), stripSize_(stripSize) {
: LinearLayout(Opposite(orientation), layoutParams) {
SetSpacing(0.0f);
if (orientation == ORIENT_HORIZONTAL) {
tabStrip_ = new ChoiceStrip(orientation, new LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
Expand Down
1 change: 0 additions & 1 deletion Common/UI/ViewGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ class TabHolder : public LinearLayout {
ScrollView *tabScroll_ = nullptr;
AnchorLayout *contents_ = nullptr;

float stripSize_;
int currentTab_ = 0;
std::vector<View *> tabs_;
std::vector<AnchorTranslateTween *> tabTweens_;
Expand Down
4 changes: 2 additions & 2 deletions Qt/QtMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ bool MainUI::event(QEvent *e) {
case Qt::LeftButton:
input.x = ((QMouseEvent*)e)->pos().x() * g_display.dpi_scale * xscale;
input.y = ((QMouseEvent*)e)->pos().y() * g_display.dpi_scale * yscale;
input.flags = (e->type() == QEvent::MouseButtonPress) ? TOUCH_DOWN : TOUCH_UP;
input.flags = ((e->type() == QEvent::MouseButtonPress) ? TOUCH_DOWN : TOUCH_UP) | TOUCH_MOUSE;
input.id = 0;
NativeTouch(input);
break;
Expand All @@ -636,7 +636,7 @@ bool MainUI::event(QEvent *e) {
case QEvent::MouseMove:
input.x = ((QMouseEvent*)e)->pos().x() * g_display.dpi_scale * xscale;
input.y = ((QMouseEvent*)e)->pos().y() * g_display.dpi_scale * yscale;
input.flags = TOUCH_MOVE;
input.flags = TOUCH_MOVE | TOUCH_MOUSE;
input.id = 0;
NativeTouch(input);
break;
Expand Down
12 changes: 5 additions & 7 deletions UI/DevScreens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,11 @@ bool TouchTestScreen::key(const KeyInput &key) {
}

void TouchTestScreen::axis(const AxisInput &axis) {
if (axis.deviceId == DEVICE_ID_MOUSE && (axis.axisId == JOYSTICK_AXIS_MOUSE_REL_X || axis.axisId == JOYSTICK_AXIS_MOUSE_REL_Y)) {
// These spam a lot, don't log for now.
return;
}

char buf[512];
snprintf(buf, sizeof(buf), "Axis: %s (%d) (value %1.3f) Device ID: %d",
KeyMap::GetAxisName(axis.axisId).c_str(), axis.axisId, axis.value, axis.deviceId);
Expand Down Expand Up @@ -1311,12 +1316,6 @@ void TouchTestScreen::DrawForeground(UIContext &dc) {
truncate_cpy(extra_debug, Android_GetInputDeviceDebugString().c_str());
#endif

// Hm, why don't we print all the info on Android?
#if PPSSPP_PLATFORM(ANDROID)
snprintf(buffer, sizeof(buffer),
"display_res: %dx%d\n",
(int)System_GetPropertyInt(SYSPROP_DISPLAY_XRES), (int)System_GetPropertyInt(SYSPROP_DISPLAY_YRES));
#else
snprintf(buffer, sizeof(buffer),
"display_res: %dx%d\n"
"dp_res: %dx%d pixel_res: %dx%d\n"
Expand All @@ -1329,7 +1328,6 @@ void TouchTestScreen::DrawForeground(UIContext &dc) {
g_display.dpi_scale_real,
delta * 1000.0, 1.0 / delta,
extra_debug);
#endif

// On Android, also add joystick debug data.
dc.DrawTextShadow(buffer, bounds.centerX(), bounds.y + 20.0f, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII);
Expand Down
1 change: 1 addition & 0 deletions android/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<uses-feature android:name="android.hardware.location.network" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.type.pc" android:required="false" />

<!-- I tried using android:maxSdkVersion="29" on WRITE/READ_EXTERNAL_STORAGE, but that made
it so that in legacy mode, you can't ask for permission anymore. So removed that. -->
Expand Down
64 changes: 64 additions & 0 deletions android/jni/app-android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1242,6 +1242,70 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_joystickAxis(
env->ReleaseFloatArrayElements(values, valueBuffer, JNI_ABORT); // ABORT just means we don't want changes copied back!
}

extern "C" jboolean Java_org_ppsspp_ppsspp_NativeApp_mouse(
JNIEnv *env, jclass, jfloat x, jfloat y, int button, int action) {
if (!renderer_inited)
return false;
TouchInput input{};

static float last_x = 0.0f;
static float last_y = 0.0f;

if (x == -1.0f) {
x = last_x;
} else {
last_x = x;
}
if (y == -1.0f) {
y = last_y;
} else {
last_y = y;
}

x *= g_display.dpi_scale;
y *= g_display.dpi_scale;

if (button == 0) {
// It's a pure mouse move.
input.flags = TOUCH_MOUSE | TOUCH_MOVE;
input.x = x;
input.y = y;
input.id = 0;
} else {
input.buttons = button;
input.x = x;
input.y = y;
switch (action) {
case 1:
input.flags = TOUCH_MOUSE | TOUCH_DOWN;
break;
case 2:
input.flags = TOUCH_MOUSE | TOUCH_UP;
break;
}
input.id = 0;
}
INFO_LOG(Log::System, "New-style mouse event: %f %f %d %d -> x: %f y: %f buttons: %d flags: %04x", x, y, button, action, input.x, input.y, input.buttons, input.flags);
NativeTouch(input);

// Also send mouse button key events, for binding.
if (button) {
KeyInput input{};
input.deviceId = DEVICE_ID_MOUSE;
switch (button) {
case 1: input.keyCode = NKCODE_EXT_MOUSEBUTTON_1; break;
case 2: input.keyCode = NKCODE_EXT_MOUSEBUTTON_2; break;
case 3: input.keyCode = NKCODE_EXT_MOUSEBUTTON_3; break;
default: WARN_LOG(Log::System, "Unexpected mouse button %d", button);
}
input.flags = action == 1 ? KEY_DOWN : KEY_UP;
if (input.keyCode != 0) {
NativeKey(input);
}
}
return true;
}

extern "C" jboolean Java_org_ppsspp_ppsspp_NativeApp_mouseWheelEvent(
JNIEnv *env, jclass, jfloat x, jfloat y) {
if (!renderer_inited)
Expand Down
1 change: 1 addition & 0 deletions android/src/org/ppsspp/ppsspp/InputDeviceState.java
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ public boolean onJoystickMotion(MotionEvent event) {
Log.i(TAG, "Not a joystick event: source = " + event.getSource());
return false;
}
Log.i(TAG, "onjoystick");
int count = 0;
for (int i = 0; i < mAxes.length; i++) {
int axisId = mAxes[i];
Expand Down
2 changes: 1 addition & 1 deletion android/src/org/ppsspp/ppsspp/MogaHack.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public static void init(Controller controller, Context context) {
// Convert implicit intent to explicit intent, see http://stackoverflow.com/a/26318757
Intent intent = new Intent(IControllerService.class.getName());
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentServices(intent, 0);
if (resolveInfos == null || resolveInfos.size() != 1) {
if (resolveInfos.size() != 1) {
// What? this doesn't do anything.
// Log.e("MogaHack", "Somebody is trying to intercept our intent. Disabling MOGA controller for security.");
}
Expand Down
115 changes: 82 additions & 33 deletions android/src/org/ppsspp/ppsspp/NativeActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ public abstract class NativeActivity extends Activity {

private Vibrator vibrator;

private boolean isXperiaPlay;

// This is to avoid losing the game/menu state etc when we are just
// switched-away from or rotated etc.
private boolean shuttingDown;
Expand Down Expand Up @@ -136,6 +134,15 @@ public abstract class NativeActivity extends Activity {
public static final int REQUEST_CODE_CAMERA_PERMISSION = 3;
public static final int REQUEST_CODE_MICROPHONE_PERMISSION = 4;

// Once we received a "modern" mouse event, we stop listening to old style mouse
// button events.
public static boolean useModernMouseEvents = false;

// Workaround for bizarre behavior on Pocophone where we get modern events
// for the left mouse button, but wacky BACK keyboard event with source == mouse
// for the right mouse button.
public static boolean useModernMouseEventsB2 = false;

// Functions for the app activity to override to change behaviour.

public native void registerCallbacks();
Expand Down Expand Up @@ -275,7 +282,7 @@ private static ArrayList<String> getSdCardPaths(final Context context) {
for (String var : varNames) {
Log.i(TAG, "getSdCardPaths: Checking env " + var);
String secStore = System.getenv("SECONDARY_STORAGE");
if (secStore != null && secStore.length() > 0) {
if (secStore != null && !secStore.isEmpty()) {
list = new ArrayList<String>();
list.add(secStore);
break;
Expand Down Expand Up @@ -399,8 +406,6 @@ public void Initialize() {
// All other device types are treated the same.
}

isXperiaPlay = IsXperiaPlay();

String extStorageState = Environment.getExternalStorageState();
String extStorageDir = Environment.getExternalStorageDirectory().getAbsolutePath();
File externalFiles = this.getExternalFilesDir(null);
Expand Down Expand Up @@ -573,10 +578,8 @@ private void updateSystemUiVisibility() {
// Need API 11 to check for existence of a vibrator? Zany.
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void checkForVibrator() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if (!vibrator.hasVibrator()) {
vibrator = null;
}
if (!vibrator.hasVibrator()) {
vibrator = null;
}
}

Expand Down Expand Up @@ -780,7 +783,7 @@ protected void onDestroy() {
do {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
} catch (InterruptedException ignored) {
}
tries--;
} while (nativeRenderer.isRenderingFrame() && tries > 0);
Expand Down Expand Up @@ -973,7 +976,7 @@ protected String getInputDeviceDebugString() {
for (InputDeviceState input : inputPlayers) {
buffer += input.getDebugString();
}
if (buffer.length() == 0) {
if (buffer.isEmpty()) {
buffer = "(no devices)";
}
return buffer;
Expand All @@ -982,15 +985,29 @@ protected String getInputDeviceDebugString() {
}
}

public boolean IsXperiaPlay() {
return android.os.Build.MODEL.equals("R800a") || android.os.Build.MODEL.equals("R800i") || android.os.Build.MODEL.equals("R800x") || android.os.Build.MODEL.equals("R800at") || android.os.Build.MODEL.equals("SO-01D") || android.os.Build.MODEL.equals("zeus");
}

// We grab the keys before onKeyDown/... even see them. This is also better because it lets us
// distinguish devices.
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1 && !isXperiaPlay) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
Log.i(TAG, "key event" + event.getSource());
if (NativeSurfaceView.isFromSource(event, InputDevice.SOURCE_MOUSE)) {
Log.i(TAG, "Forwarding key event from mouse: " + event.getKeyCode());
Log.i(TAG, "usemodernb2: " + useModernMouseEventsB2);
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && !useModernMouseEventsB2) {
// Probably a right click
switch (event.getAction()) {
case KeyEvent.ACTION_DOWN:
NativeApp.mouse(-1, -1, 2, 1);
break;
case KeyEvent.ACTION_UP:
NativeApp.mouse(-1, -1, 2, 2);
break;
}
}
return true;
}

InputDeviceState state = getInputDeviceState(event);
if (state == null) {
return super.dispatchKeyEvent(event);
Expand Down Expand Up @@ -1022,12 +1039,14 @@ public boolean dispatchKeyEvent(KeyEvent event) {
if (!passThrough) {
switch (event.getAction()) {
case KeyEvent.ACTION_DOWN:
Log.i(TAG, "KeyEvent Down");
if (state.onKeyDown(event)) {
return true;
}
break;

case KeyEvent.ACTION_UP:
Log.i(TAG, "KeyEvent Up");
if (state.onKeyUp(event)) {
return true;
}
Expand Down Expand Up @@ -1055,23 +1074,24 @@ public static String getInputDesc(InputDevice input) {

@TargetApi(Build.VERSION_CODES.N)
void sendMouseDelta(float dx, float dy) {
NativeApp.mouseDelta(dx, dy);
// Ignore zero deltas.
if (Math.abs(dx) > 0.001 || Math.abs(dx) > 0.001) {
NativeApp.mouseDelta(dx, dy);
}
}

@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public boolean onGenericMotionEvent(MotionEvent event) {
// Log.d(TAG, "onGenericMotionEvent: " + event);
// Log.i(TAG, "NativeActivity onGenericMotionEvent: " + event);
if (InputDeviceState.inputSourceIsJoystick(event.getSource())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
InputDeviceState state = getInputDeviceState(event);
if (state == null) {
Log.w(TAG, "Joystick event but failed to get input device state.");
return super.onGenericMotionEvent(event);
}
state.onJoystickMotion(event);
return true;
InputDeviceState state = getInputDeviceState(event);
if (state == null) {
Log.w(TAG, "Joystick event but failed to get input device state.");
return super.onGenericMotionEvent(event);
}
state.onJoystickMotion(event);
return true;
}

if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
Expand All @@ -1081,15 +1101,44 @@ public boolean onGenericMotionEvent(MotionEvent event) {
float dy = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
sendMouseDelta(dx, dy);
}
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
Log.i(TAG, "Erroneous move event"); // should be in touch events
return true;
case MotionEvent.ACTION_HOVER_MOVE:
Log.i(TAG, "Action Hover Move");
// process the mouse hover movement...
NativeApp.mouse(event.getX(), event.getY(), 0, 0);
return true;
case MotionEvent.ACTION_SCROLL:
float scrollX = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
float scrollY = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
Log.i(TAG, "Action Scroll: " + scrollX + " " + scrollY);
NativeApp.mouseWheelEvent(scrollX, scrollY);
return true;
}
}
}

switch (event.getAction()) {
case MotionEvent.ACTION_HOVER_MOVE:
// process the mouse hover movement...
return true;
case MotionEvent.ACTION_SCROLL:
NativeApp.mouseWheelEvent(event.getAxisValue(MotionEvent.AXIS_HSCROLL), event.getAxisValue(MotionEvent.AXIS_VSCROLL));
return true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int button = event.getActionButton();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_BUTTON_PRESS: {
Log.i(TAG, "action button press: button: " + button);
useModernMouseEvents = true;
if (button > 1) {
useModernMouseEventsB2 = true;
}
NativeApp.mouse(event.getX(), event.getY(), button, 1);
return true;
}
case MotionEvent.ACTION_BUTTON_RELEASE: {
Log.i(TAG, "action button release: button: " + button);
NativeApp.mouse(event.getX(), event.getY(), button, 2);
return true;
}
default:
break;
}
}
return super.onGenericMotionEvent(event);
Expand Down
1 change: 1 addition & 0 deletions android/src/org/ppsspp/ppsspp/NativeApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class NativeApp {

public static native void accelerometer(float x, float y, float z);

public static native void mouse(float x, float y, int button, int action);
public static native void mouseDelta(float x, float y);
public static native void sendMessageFromJava(String msg, String arg);
public static native void sendRequestResult(int seqID, boolean result, String value, int iValue);
Expand Down
Loading
Loading