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:
parent
4b60371e64
commit
8c7986eb58
3 changed files with 63 additions and 25 deletions
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
_cemuHookClient.RequestData(clientId, cemuControllerConfig.AltSlot);
|
if (!cemuControllerConfig.MirrorInput)
|
||||||
|
{
|
||||||
|
_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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Reference in a new issue