Skip to content

Commit

Permalink
Merge pull request #18029 from hrydgard/input-batch-axis-update
Browse files Browse the repository at this point in the history
Control: Change internal interfaces to batch-process input axis updates
  • Loading branch information
hrydgard committed Aug 31, 2023
2 parents 7a3eab9 + 80a99a6 commit 0fb1ea3
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
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
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
@@ -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
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
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
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
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
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
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
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

0 comments on commit 0fb1ea3

Please sign in to comment.