Skip to content

Commit

Permalink
Control: Change internal interfaces to batch-process input axis updates
Browse files Browse the repository at this point in the history
These naturally come in bunches on many platforms like Android, so lay
some groundwork to also handle them in bunches to minimize locking in
the future.

Linux buildfix
  • Loading branch information
hrydgard committed Aug 31, 2023
1 parent 3e6788d commit 80a99a6
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 103 deletions.
2 changes: 1 addition & 1 deletion Common/System/NativeApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ bool NativeIsRestarting();
// input latency - assuming your main loop is architected properly (NativeFrame called from a different thread than input event handling).
void NativeTouch(const TouchInput &touch);
bool NativeKey(const KeyInput &key);
void NativeAxis(const AxisInput &axis);
void NativeAxis(const AxisInput *axis, size_t count);

// Called when it's process a frame, including rendering. If the device can keep up, this
// will be called sixty times per second. Main thread.
Expand Down
58 changes: 29 additions & 29 deletions Common/VR/PPSSPPVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ static bool vrMirroring[VR_MIRRORING_COUNT];
static int vrMirroringVariant = 0;
static XrView vrView[2];

static void (*NativeAxis)(const AxisInput &axis);
static bool (*NativeKey)(const KeyInput &key);
static void (*NativeTouch)(const TouchInput &touch);
static void (*cbNativeAxis)(const AxisInput *axis, size_t count);
static bool (*cbNativeKey)(const KeyInput &key);
static void (*cbNativeTouch)(const TouchInput &touch);

/*
================================================================================
Expand Down Expand Up @@ -205,10 +205,10 @@ void GetVRResolutionPerEye(int* width, int* height) {
}
}

void SetVRCallbacks(void (*axis)(const AxisInput &axis), bool(*key)(const KeyInput &key), void (*touch)(const TouchInput &touch)) {
NativeAxis = axis;
NativeKey = key;
NativeTouch = touch;
void SetVRCallbacks(void (*axis)(const AxisInput *axis, size_t count), bool(*key)(const KeyInput &key), void (*touch)(const TouchInput &touch)) {
cbNativeAxis = axis;
cbNativeKey = key;
cbNativeTouch = touch;
}

/*
Expand All @@ -226,20 +226,20 @@ void SetVRAppMode(VRAppMode mode) {
void UpdateVRInput(bool haptics, float dp_xscale, float dp_yscale) {
//axis
if (pspKeys[(int)VIRTKEY_VR_CAMERA_ADJUST]) {
AxisInput axis = {};
AxisInput axis[2] = {};
axis[0].deviceId = DEVICE_ID_DEFAULT;
axis[1].deviceId = DEVICE_ID_DEFAULT;
for (int j = 0; j < 2; j++) {
XrVector2f joystick = IN_VRGetJoystickState(j);
axis.deviceId = DEVICE_ID_DEFAULT;

//horizontal
axis.axisId = j == 0 ? JOYSTICK_AXIS_X : JOYSTICK_AXIS_Z;
axis.value = joystick.x;
NativeAxis(axis);
axis[0].axisId = j == 0 ? JOYSTICK_AXIS_X : JOYSTICK_AXIS_Z;
axis[0].value = joystick.x;

//vertical
axis.axisId = j == 0 ? JOYSTICK_AXIS_Y : JOYSTICK_AXIS_RZ;
axis.value = -joystick.y;
NativeAxis(axis);
axis[1].axisId = j == 0 ? JOYSTICK_AXIS_Y : JOYSTICK_AXIS_RZ;
axis[1].value = -joystick.y;
cbNativeAxis(axis, 2);
}
}

Expand All @@ -261,12 +261,12 @@ void UpdateVRInput(bool haptics, float dp_xscale, float dp_yscale) {
if (pressed && haptics) {
INVR_Vibrate(100, j, 1000);
}
NativeKey(keyInput);
cbNativeKey(keyInput);
m.pressed = pressed;
m.repeat = 0;
} else if (pressed && (m.repeat > 30)) {
keyInput.flags |= KEY_IS_REPEAT;
NativeKey(keyInput);
cbNativeKey(keyInput);
m.repeat = 0;
} else {
m.repeat++;
Expand All @@ -289,39 +289,39 @@ void UpdateVRInput(bool haptics, float dp_xscale, float dp_yscale) {
keyInput.flags = activate ? KEY_DOWN : KEY_UP;
keyInput.keyCode = NKCODE_EXT_MOTION_UP;
keyInput.deviceId = controllerIds[j];
if (controllerMotion[j][0] != activate) NativeKey(keyInput);
if (controllerMotion[j][0] != activate) cbNativeKey(keyInput);
controllerMotion[j][0] = activate;

//down
activate = position.y < -limit * 1.5f;
keyInput.flags = activate ? KEY_DOWN : KEY_UP;
keyInput.keyCode = NKCODE_EXT_MOTION_DOWN;
keyInput.deviceId = controllerIds[j];
if (controllerMotion[j][1] != activate) NativeKey(keyInput);
if (controllerMotion[j][1] != activate) cbNativeKey(keyInput);
controllerMotion[j][1] = activate;

//left
activate = position.x < -limit * (j == 0 ? 1.0f : 0.25f);
keyInput.flags = activate ? KEY_DOWN : KEY_UP;
keyInput.keyCode = NKCODE_EXT_MOTION_LEFT;
keyInput.deviceId = controllerIds[j];
if (controllerMotion[j][2] != activate) NativeKey(keyInput);
if (controllerMotion[j][2] != activate) cbNativeKey(keyInput);
controllerMotion[j][2] = activate;

//right
activate = position.x > limit * (j == 1 ? 1.0f : 0.25f);
keyInput.flags = activate ? KEY_DOWN : KEY_UP;
keyInput.keyCode = NKCODE_EXT_MOTION_RIGHT;
keyInput.deviceId = controllerIds[j];
if (controllerMotion[j][3] != activate) NativeKey(keyInput);
if (controllerMotion[j][3] != activate) cbNativeKey(keyInput);
controllerMotion[j][3] = activate;

//forward
activate = position.z < -limit;
keyInput.flags = activate ? KEY_DOWN : KEY_UP;
keyInput.keyCode = NKCODE_EXT_MOTION_FORWARD;
keyInput.deviceId = controllerIds[j];
if (controllerMotion[j][4] != activate) NativeKey(keyInput);
if (controllerMotion[j][4] != activate) cbNativeKey(keyInput);
controllerMotion[j][4] = activate;
}
}
Expand Down Expand Up @@ -358,15 +358,15 @@ void UpdateVRInput(bool haptics, float dp_xscale, float dp_yscale) {
activate = !disable && yaw < -limit;
keyInput.flags = activate ? KEY_DOWN : KEY_UP;
keyInput.keyCode = NKCODE_EXT_ROTATION_LEFT;
if (hmdMotion[2] != activate) NativeKey(keyInput);
if (hmdMotion[2] != activate) cbNativeKey(keyInput);
if (isVR && activate) hmdMotionDiff[1] += limit;
hmdMotion[2] = activate;

//right
activate = !disable && yaw > limit;
keyInput.flags = activate ? KEY_DOWN : KEY_UP;
keyInput.keyCode = NKCODE_EXT_ROTATION_RIGHT;
if (hmdMotion[3] != activate) NativeKey(keyInput);
if (hmdMotion[3] != activate) cbNativeKey(keyInput);
if (isVR && activate) hmdMotionDiff[1] -= limit;
hmdMotion[3] = activate;
}
Expand Down Expand Up @@ -449,9 +449,9 @@ void UpdateVRInput(bool haptics, float dp_xscale, float dp_yscale) {
if (mousePressed != pressed) {
if (pressed) {
touch.flags = TOUCH_DOWN;
NativeTouch(touch);
cbNativeTouch(touch);
touch.flags = TOUCH_UP;
NativeTouch(touch);
cbNativeTouch(touch);
}
mousePressed = pressed;
}
Expand All @@ -463,10 +463,10 @@ void UpdateVRInput(bool haptics, float dp_xscale, float dp_yscale) {
float scroll = -IN_VRGetJoystickState(j).y;
keyInput.flags = scroll < -0.5f ? KEY_DOWN : KEY_UP;
keyInput.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
NativeKey(keyInput);
cbNativeKey(keyInput);
keyInput.flags = scroll > 0.5f ? KEY_DOWN : KEY_UP;
keyInput.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
NativeKey(keyInput);
cbNativeKey(keyInput);
}
} else {
VR_SetConfig(VR_CONFIG_MOUSE_SIZE, 0);
Expand Down Expand Up @@ -525,7 +525,7 @@ bool UpdateVRKeys(const KeyInput &key) {
for (auto& pspKey : pspKeys) {
if (pspKey.second) {
keyUp.keyCode = (InputKeyCode)pspKey.first;
NativeKey(keyUp);
cbNativeKey(keyUp);
}
}
pspKeys[VIRTKEY_VR_CAMERA_ADJUST] = true;
Expand Down
4 changes: 3 additions & 1 deletion Common/VR/PPSSPPVR.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <cstddef>

struct AxisInput;
struct TouchInput;
struct KeyInput;
Expand Down Expand Up @@ -30,7 +32,7 @@ bool IsVREnabled();
void InitVROnAndroid(void* vm, void* activity, const char* system, int version, const char* name);
void EnterVR(bool firstStart, void* vulkanContext);
void GetVRResolutionPerEye(int* width, int* height);
void SetVRCallbacks(void(*axis)(const AxisInput &axis), bool(*key)(const KeyInput &key), void(*touch)(const TouchInput &touch));
void SetVRCallbacks(void(*axis)(const AxisInput *axis, size_t count), bool(*key)(const KeyInput &key), void(*touch)(const TouchInput &touch));

// VR input integration
void SetVRAppMode(VRAppMode mode);
Expand Down
24 changes: 11 additions & 13 deletions Qt/QtMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,20 +731,18 @@ void MainUI::updateAccelerometer() {
// TODO: Toggle it depending on whether it is enabled
QAccelerometerReading *reading = acc->reading();
if (reading) {
AxisInput axis;
axis.deviceId = DEVICE_ID_ACCELEROMETER;

axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_X;
axis.value = reading->x();
NativeAxis(axis);

axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Y;
axis.value = reading->y();
NativeAxis(axis);
AxisInput axis[3];
for (int i = 0; i < 3; i++) {
axis[i].deviceId = DEVICE_ID_ACCELEROMETER;
}

axis.axisId = JOYSTICK_AXIS_ACCELEROMETER_Z;
axis.value = reading->z();
NativeAxis(axis);
axis[0].axisId = JOYSTICK_AXIS_ACCELEROMETER_X;
axis[0].value = reading->x();
axis[1].axisId = JOYSTICK_AXIS_ACCELEROMETER_Y;
axis[1].value = reading->y();
axis[2].axisId = JOYSTICK_AXIS_ACCELEROMETER_Z;
axis[2].value = reading->z();
NativeAxis(axis, 3);
}
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion SDL/SDLJoystick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ void SDLJoystick::ProcessInput(const SDL_Event &event){
if (axis.value > 1.0f) axis.value = 1.0f;
if (axis.value < -1.0f) axis.value = -1.0f;
axis.deviceId = DEVICE_ID_PAD_0 + getDeviceIndex(event.caxis.which);
NativeAxis(axis);
NativeAxis(&axis, 1);
break;
case SDL_CONTROLLERDEVICEREMOVED:
// for removal events, "which" is the instance ID for SDL_CONTROLLERDEVICEREMOVED
Expand Down
17 changes: 8 additions & 9 deletions SDL/SDLMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -724,17 +724,16 @@ struct InputStateTracker {
float scaleFactor_x = g_display.dpi_scale_x * 0.1 * g_Config.fMouseSensitivity;
float scaleFactor_y = g_display.dpi_scale_y * 0.1 * g_Config.fMouseSensitivity;

AxisInput axisX, axisY;
axisX.axisId = JOYSTICK_AXIS_MOUSE_REL_X;
axisX.deviceId = DEVICE_ID_MOUSE;
axisX.value = std::max(-1.0f, std::min(1.0f, mouseDeltaX * scaleFactor_x));
axisY.axisId = JOYSTICK_AXIS_MOUSE_REL_Y;
axisY.deviceId = DEVICE_ID_MOUSE;
axisY.value = std::max(-1.0f, std::min(1.0f, mouseDeltaY * scaleFactor_y));
AxisInput axis[2];
axis[0].axisId = JOYSTICK_AXIS_MOUSE_REL_X;
axis[0].deviceId = DEVICE_ID_MOUSE;
axis[0].value = std::max(-1.0f, std::min(1.0f, mouseDeltaX * scaleFactor_x));
axis[1].axisId = JOYSTICK_AXIS_MOUSE_REL_Y;
axis[1].deviceId = DEVICE_ID_MOUSE;
axis[1].value = std::max(-1.0f, std::min(1.0f, mouseDeltaY * scaleFactor_y));

if (GetUIState() == UISTATE_INGAME || g_Config.bMapMouse) {
NativeAxis(axisX);
NativeAxis(axisY);
NativeAxis(axis, 2);
}
mouseDeltaX *= g_Config.fMouseSmoothing;
mouseDeltaY *= g_Config.fMouseSmoothing;
Expand Down
29 changes: 16 additions & 13 deletions UI/NativeApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1319,7 +1319,7 @@ bool NativeKey(const KeyInput &key) {
return retval;
}

void NativeAxis(const AxisInput &axis) {
static void ProcessOneAxisEvent(const AxisInput &axis) {
// VR actions
if (IsVREnabled() && !UpdateVRAxis(axis)) {
return;
Expand All @@ -1330,28 +1330,31 @@ void NativeAxis(const AxisInput &axis) {
return;
}

using namespace TiltEventProcessor;

// only do special handling of tilt events if tilt is enabled.
HLEPlugins::PluginDataAxis[axis.axisId] = axis.value;
g_screenManager->axis(axis);
}

if (g_Config.iTiltInputType == TILT_NULL) {
// if tilt events are disabled, don't do anything special.
return;
}

void NativeAxis(const AxisInput *axes, size_t count) {
// figure out what the current tilt orientation is by checking the axis event
// This is static, since we need to remember where we last were (in terms of orientation)
static float tiltX;
static float tiltY;
static float tiltZ;

switch (axis.axisId) {
case JOYSTICK_AXIS_ACCELEROMETER_X: tiltX = axis.value; break;
case JOYSTICK_AXIS_ACCELEROMETER_Y: tiltY = axis.value; break;
case JOYSTICK_AXIS_ACCELEROMETER_Z: tiltZ = axis.value; break;
for (size_t i = 0; i < count; i++) {
ProcessOneAxisEvent(axes[i]);
switch (axes[i].axisId) {
case JOYSTICK_AXIS_ACCELEROMETER_X: tiltX = axes[i].value; break;
case JOYSTICK_AXIS_ACCELEROMETER_Y: tiltY = axes[i].value; break;
case JOYSTICK_AXIS_ACCELEROMETER_Z: tiltZ = axes[i].value; break;
default: break;
}
}

if (g_Config.iTiltInputType == TILT_NULL) {
// if tilt events are disabled, don't do anything special.
return;
}

// create the base coordinate tilt system from the calibration data.
Expand All @@ -1371,7 +1374,7 @@ void NativeAxis(const AxisInput &axis) {
// see [http://developer.android.com/guide/topics/sensors/sensors_overview.html] for details
bool landscape = g_display.dp_yres < g_display.dp_xres;
// now transform out current tilt to the calibrated coordinate system
ProcessTilt(landscape, tiltBaseAngleY, tiltX, tiltY, tiltZ,
TiltEventProcessor::ProcessTilt(landscape, tiltBaseAngleY, tiltX, tiltY, tiltZ,
g_Config.bInvertTiltX, g_Config.bInvertTiltY,
xSensitivity, ySensitivity);
}
Expand Down
3 changes: 2 additions & 1 deletion Windows/DinputDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ void SendNativeAxis(InputDeviceID deviceId, int value, int &lastValue, InputAxis
axis.deviceId = deviceId;
axis.axisId = axisId;
axis.value = (float)value * (1.0f / 10000.0f); // Convert axis to normalised float
NativeAxis(axis);
NativeAxis(&axis, 1);

lastValue = value;
}
Expand Down Expand Up @@ -241,6 +241,7 @@ int DinputDevice::UpdateState() {
ApplyButtons(js);

if (analog) {
// TODO: Use the batched interface.
AxisInput axis;
axis.deviceId = DEVICE_ID_PAD_0 + pDevNum;

Expand Down
17 changes: 8 additions & 9 deletions Windows/WindowsHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,16 @@ void WindowsInputManager::PollControllers() {

float mx = std::max(-1.0f, std::min(1.0f, mouseDeltaX_ * scaleFactor_x));
float my = std::max(-1.0f, std::min(1.0f, mouseDeltaY_ * scaleFactor_y));
AxisInput axisX{}, axisY{};
axisX.axisId = JOYSTICK_AXIS_MOUSE_REL_X;
axisX.deviceId = DEVICE_ID_MOUSE;
axisX.value = mx;
axisY.axisId = JOYSTICK_AXIS_MOUSE_REL_Y;
axisY.deviceId = DEVICE_ID_MOUSE;
axisY.value = my;
AxisInput axis[2];
axis[0].axisId = JOYSTICK_AXIS_MOUSE_REL_X;
axis[0].deviceId = DEVICE_ID_MOUSE;
axis[0].value = mx;
axis[1].axisId = JOYSTICK_AXIS_MOUSE_REL_Y;
axis[1].deviceId = DEVICE_ID_MOUSE;
axis[1].value = my;

if (GetUIState() == UISTATE_INGAME || g_Config.bMapMouse) {
NativeAxis(axisX);
NativeAxis(axisY);
NativeAxis(axis, 2);
}
}

Expand Down
17 changes: 12 additions & 5 deletions Windows/XinputDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,17 @@ void XinputDevice::UpdatePad(int pad, const XINPUT_STATE &state, XINPUT_VIBRATIO
ApplyButtons(pad, state);
ApplyVibration(pad, vibration);

AxisInput axis;
axis.deviceId = (InputDeviceID)(DEVICE_ID_XINPUT_0 + pad);
AxisInput axis[6];
int axisCount = 0;
for (int i = 0; i < ARRAY_SIZE(axis); i++) {
axis[i].deviceId = (InputDeviceID)(DEVICE_ID_XINPUT_0 + pad);
}
auto sendAxis = [&](InputAxis axisId, float value, int axisIndex) {
if (value != prevAxisValue_[pad][axisIndex]) {
prevAxisValue_[pad][axisIndex] = value;
axis.axisId = axisId;
axis.value = value;
NativeAxis(axis);
axis[axisCount].axisId = axisId;
axis[axisCount].value = value;
axisCount++;
}
};

Expand All @@ -242,6 +245,10 @@ void XinputDevice::UpdatePad(int pad, const XINPUT_STATE &state, XINPUT_VIBRATIO
sendAxis(JOYSTICK_AXIS_RTRIGGER, (float)state.Gamepad.bRightTrigger / 255.0f, 5);
}

if (axisCount) {
NativeAxis(axis, axisCount);
}

prevState[pad] = state;
check_delay[pad] = 0;
}
Expand Down
Loading

0 comments on commit 80a99a6

Please sign in to comment.