Ensure right joycon motion data is set (#2488)

* motion fix

* mirror motion data on right joycon in pair mode when using native motion source

* fix

* addressed comments
This commit is contained in:
emmauss 2021-07-23 23:01:36 +00:00 committed by GitHub
parent 4b60371e64
commit 8c7986eb58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 25 deletions

View file

@ -569,7 +569,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
UpdateUnusedSixInputIfNotEqual(ref lifo, ref currentNpad.JoyRightSixAxisSensor); UpdateUnusedSixInputIfNotEqual(ref lifo, ref currentNpad.JoyRightSixAxisSensor);
} }
if (!needUpdateRight) if (!needUpdateRight && !isRightPair)
{ {
SixAxisSensorState emptyState = new SixAxisSensorState(); SixAxisSensorState emptyState = new SixAxisSensorState();

View file

@ -208,7 +208,8 @@ namespace Ryujinx.Input.HLE
private bool _isValid; private bool _isValid;
private string _id; private string _id;
private MotionInput _motionInput; private MotionInput _leftMotionInput;
private MotionInput _rightMotionInput;
private IGamepad _gamepad; private IGamepad _gamepad;
private InputConfig _config; private InputConfig _config;
@ -259,7 +260,7 @@ namespace Ryujinx.Input.HLE
else else
{ {
// Non-controller doesn't have motions. // Non-controller doesn't have motions.
_motionInput = null; _leftMotionInput = null;
} }
_config = config; _config = config;
@ -274,11 +275,11 @@ namespace Ryujinx.Input.HLE
{ {
if (motionConfig.MotionBackend != MotionInputBackendType.CemuHook) if (motionConfig.MotionBackend != MotionInputBackendType.CemuHook)
{ {
_motionInput = new MotionInput(); _leftMotionInput = new MotionInput();
} }
else else
{ {
_motionInput = null; _leftMotionInput = null;
} }
} }
@ -300,7 +301,12 @@ namespace Ryujinx.Input.HLE
accelerometer = new Vector3(accelerometer.X, -accelerometer.Z, accelerometer.Y); accelerometer = new Vector3(accelerometer.X, -accelerometer.Z, accelerometer.Y);
gyroscope = new Vector3(gyroscope.X, gyroscope.Z, gyroscope.Y); gyroscope = new Vector3(gyroscope.X, gyroscope.Z, gyroscope.Y);
_motionInput.Update(accelerometer, gyroscope, (ulong)PerformanceCounter.ElapsedNanoseconds / 1000, controllerConfig.Motion.Sensitivity, (float)controllerConfig.Motion.GyroDeadzone); _leftMotionInput.Update(accelerometer, gyroscope, (ulong)PerformanceCounter.ElapsedNanoseconds / 1000, controllerConfig.Motion.Sensitivity, (float)controllerConfig.Motion.GyroDeadzone);
if (controllerConfig.ControllerType == ConfigControllerType.JoyconPair)
{
_rightMotionInput = _leftMotionInput;
}
} }
} }
else if (controllerConfig.Motion.MotionBackend == MotionInputBackendType.CemuHook && controllerConfig.Motion is CemuHookMotionConfigController cemuControllerConfig) else if (controllerConfig.Motion.MotionBackend == MotionInputBackendType.CemuHook && controllerConfig.Motion is CemuHookMotionConfigController cemuControllerConfig)
@ -310,16 +316,22 @@ namespace Ryujinx.Input.HLE
// First of all ensure we are registered // First of all ensure we are registered
_cemuHookClient.RegisterClient(clientId, cemuControllerConfig.DsuServerHost, cemuControllerConfig.DsuServerPort); _cemuHookClient.RegisterClient(clientId, cemuControllerConfig.DsuServerHost, cemuControllerConfig.DsuServerPort);
// Then request data // Then request and retrieve the data
_cemuHookClient.RequestData(clientId, cemuControllerConfig.Slot); _cemuHookClient.RequestData(clientId, cemuControllerConfig.Slot);
_cemuHookClient.TryGetData(clientId, cemuControllerConfig.Slot, out _leftMotionInput);
if (controllerConfig.ControllerType == ConfigControllerType.JoyconPair && !cemuControllerConfig.MirrorInput) if (controllerConfig.ControllerType == ConfigControllerType.JoyconPair)
{
if (!cemuControllerConfig.MirrorInput)
{ {
_cemuHookClient.RequestData(clientId, cemuControllerConfig.AltSlot); _cemuHookClient.RequestData(clientId, cemuControllerConfig.AltSlot);
_cemuHookClient.TryGetData(clientId, cemuControllerConfig.AltSlot, out _rightMotionInput);
}
else
{
_rightMotionInput = _leftMotionInput;
}
} }
// Finally, get motion input data
_cemuHookClient.TryGetData(clientId, cemuControllerConfig.Slot, out _motionInput);
} }
} }
} }
@ -327,7 +339,7 @@ namespace Ryujinx.Input.HLE
{ {
// Reset states // Reset states
State = default; State = default;
_motionInput = null; _leftMotionInput = null;
} }
} }
@ -395,20 +407,32 @@ namespace Ryujinx.Input.HLE
return state; return state;
} }
public SixAxisInput GetHLEMotionState() public SixAxisInput GetHLEMotionState(bool isJoyconRightPair = false)
{ {
float[] orientationForHLE = new float[9]; float[] orientationForHLE = new float[9];
Vector3 gyroscope; Vector3 gyroscope;
Vector3 accelerometer; Vector3 accelerometer;
Vector3 rotation; Vector3 rotation;
if (_motionInput != null) MotionInput motionInput = _leftMotionInput;
{
gyroscope = Truncate(_motionInput.Gyroscrope * 0.0027f, 3);
accelerometer = Truncate(_motionInput.Accelerometer, 3);
rotation = Truncate(_motionInput.Rotation * 0.0027f, 3);
Matrix4x4 orientation = _motionInput.GetOrientation(); if (isJoyconRightPair)
{
if (_rightMotionInput == null)
{
return default;
}
motionInput = _rightMotionInput;
}
if (motionInput != null)
{
gyroscope = Truncate(motionInput.Gyroscrope * 0.0027f, 3);
accelerometer = Truncate(motionInput.Accelerometer, 3);
rotation = Truncate(motionInput.Rotation * 0.0027f, 3);
Matrix4x4 orientation = motionInput.GetOrientation();
orientationForHLE[0] = Math.Clamp(orientation.M11, -1f, 1f); orientationForHLE[0] = Math.Clamp(orientation.M11, -1f, 1f);
orientationForHLE[1] = Math.Clamp(orientation.M12, -1f, 1f); orientationForHLE[1] = Math.Clamp(orientation.M12, -1f, 1f);

View file

@ -1,5 +1,6 @@
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Configuration.Hid.Controller.Motion;
using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.HLE.HOS.Services.Hid; using Ryujinx.HLE.HOS.Services.Hid;
using System; using System;
@ -163,10 +164,12 @@ namespace Ryujinx.Input.HLE
foreach (InputConfig inputConfig in _inputConfig) foreach (InputConfig inputConfig in _inputConfig)
{ {
GamepadInput inputState = default; GamepadInput inputState = default;
SixAxisInput motionState = default; (SixAxisInput, SixAxisInput) motionState = default;
NpadController controller = _controllers[(int)inputConfig.PlayerIndex]; NpadController controller = _controllers[(int)inputConfig.PlayerIndex];
bool isJoyconPair = false;
// Do we allow input updates and is a controller connected? // Do we allow input updates and is a controller connected?
if (!_blockInputUpdates && controller != null) if (!_blockInputUpdates && controller != null)
{ {
@ -179,7 +182,11 @@ namespace Ryujinx.Input.HLE
inputState.Buttons |= _device.Hid.UpdateStickButtons(inputState.LStick, inputState.RStick); inputState.Buttons |= _device.Hid.UpdateStickButtons(inputState.LStick, inputState.RStick);
motionState = controller.GetHLEMotionState(); isJoyconPair = inputConfig.ControllerType == Common.Configuration.Hid.ControllerType.JoyconPair;
var altMotionState = isJoyconPair ? controller.GetHLEMotionState(true) : default;
motionState = (controller.GetHLEMotionState(), altMotionState);
if (_enableKeyboard) if (_enableKeyboard)
{ {
@ -189,14 +196,21 @@ namespace Ryujinx.Input.HLE
else else
{ {
// Ensure that orientation isn't null // Ensure that orientation isn't null
motionState.Orientation = new float[9]; motionState.Item1.Orientation = new float[9];
} }
inputState.PlayerId = (Ryujinx.HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex; inputState.PlayerId = (Ryujinx.HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex;
motionState.PlayerId = (Ryujinx.HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex; motionState.Item1.PlayerId = (Ryujinx.HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex;
hleInputStates.Add(inputState); hleInputStates.Add(inputState);
hleMotionStates.Add(motionState); hleMotionStates.Add(motionState.Item1);
if (isJoyconPair && !motionState.Item2.Equals(default))
{
motionState.Item2.PlayerId = (Ryujinx.HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex;
hleMotionStates.Add(motionState.Item2);
}
} }
_device.Hid.Npads.Update(hleInputStates); _device.Hid.Npads.Update(hleInputStates);