Compare commits

..

5 Commits

Author SHA1 Message Date
darko1979
bed516bfda Implement rotate stick 90 degrees clockwise (#3084)
* Implement swapping sticks

* Rotate 90 degrees clockwise

Co-authored-by: matesic.darko@gmail.com <Darkman1979>
2022-03-12 18:23:48 +01:00
gdkchan
69b05f9918 Fix GetUserDisableCount NRE (#3187) 2022-03-12 18:12:12 +01:00
gdkchan
fb7c80e928 Limit number of events that can be retrieved from GetDisplayVSyncEvent (#3188)
* Limit number of events that can be retrieved from GetDisplayVSyncEvent

* Cleaning

* Rename openDisplayInfos -> openDisplays
2022-03-12 17:56:19 +01:00
merry
bb2f9df0a1 KThread: Fix GetPsr mask (#3180)
* ExecutionContext: GetPstate / SetPstate

* Put it in NativeContext

* KThread: Fix GetPsr mask

* ExecutionContext: Turn methods into Pstate property

* Address nit
2022-03-11 03:16:32 +01:00
Mary
54bfaa125d amadeus: Fix wrong Span usage in CopyHistories (#3181)
Fix a copypasta from the original Amadeus PR causing invalid
CopyHistories output.

Also added a missing size check.

This fix a crash in Mononoke Slashdown
2022-03-07 09:49:29 +01:00
16 changed files with 114 additions and 29 deletions

View File

@@ -43,6 +43,12 @@ namespace ARMeilleure.State
public long TpidrEl0 { get; set; }
public long Tpidr { get; set; }
public uint Pstate
{
get => _nativeContext.GetPstate();
set => _nativeContext.SetPstate(value);
}
public FPCR Fpcr { get; set; }
public FPSR Fpsr { get; set; }
public FPCR StandardFpcrValue => (Fpcr & (FPCR.Ahp)) | FPCR.Dn | FPCR.Fz;

View File

@@ -95,6 +95,25 @@ namespace ARMeilleure.State
GetStorage().Flags[(int)flag] = value ? 1u : 0u;
}
public unsafe uint GetPstate()
{
uint value = 0;
for (int flag = 0; flag < RegisterConsts.FlagsCount; flag++)
{
value |= GetStorage().Flags[flag] != 0 ? 1u << flag : 0u;
}
return value;
}
public unsafe void SetPstate(uint value)
{
for (int flag = 0; flag < RegisterConsts.FlagsCount; flag++)
{
uint bit = 1u << flag;
GetStorage().Flags[flag] = (value & bit) == bit ? 1u : 0u;
}
}
public unsafe bool GetFPStateFlag(FPState flag)
{
if ((uint)flag >= RegisterConsts.FpFlagsCount)

View File

@@ -149,11 +149,21 @@ namespace Ryujinx.Audio.Renderer.Server.Performance
Span<byte> targetSpan = performanceOutput.Slice(nextOffset);
// NOTE: We check for the space for two headers for the final blank header.
int requiredSpace = Unsafe.SizeOf<THeader>() + Unsafe.SizeOf<TEntry>() * inputHeader.GetEntryCount()
+ Unsafe.SizeOf<TEntryDetail>() * inputHeader.GetEntryDetailCount()
+ Unsafe.SizeOf<THeader>();
if (targetSpan.Length < requiredSpace)
{
break;
}
ref THeader outputHeader = ref MemoryMarshal.Cast<byte, THeader>(targetSpan)[0];
nextOffset += Unsafe.SizeOf<THeader>();
Span<TEntry> outputEntries = MemoryMarshal.Cast<byte, TEntry>(targetSpan.Slice(nextOffset));
Span<TEntry> outputEntries = MemoryMarshal.Cast<byte, TEntry>(performanceOutput.Slice(nextOffset));
int totalProcessingTime = 0;
@@ -175,7 +185,7 @@ namespace Ryujinx.Audio.Renderer.Server.Performance
}
}
Span<TEntryDetail> outputEntriesDetail = MemoryMarshal.Cast<byte, TEntryDetail>(targetSpan.Slice(nextOffset));
Span<TEntryDetail> outputEntriesDetail = MemoryMarshal.Cast<byte, TEntryDetail>(performanceOutput.Slice(nextOffset));
int effectiveEntryDetailCount = 0;

View File

@@ -5,6 +5,7 @@
public Stick Joystick { get; set; }
public bool InvertStickX { get; set; }
public bool InvertStickY { get; set; }
public bool Rotate90CW { get; set; }
public Button StickButton { get; set; }
}
}

View File

@@ -751,7 +751,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
KThread currentThread = KernelStatic.GetCurrentThread();
if (currentThread.Owner != null &&
if (currentThread.Context.Running &&
currentThread.Owner != null &&
currentThread.GetUserDisableCount() != 0 &&
currentThread.Owner.PinnedThreads[currentThread.CurrentCore] == null)
{

View File

@@ -658,10 +658,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
private static uint GetPsr(ARMeilleure.State.ExecutionContext context)
{
return (context.GetPstateFlag(ARMeilleure.State.PState.NFlag) ? (1U << (int)ARMeilleure.State.PState.NFlag) : 0U) |
(context.GetPstateFlag(ARMeilleure.State.PState.ZFlag) ? (1U << (int)ARMeilleure.State.PState.ZFlag) : 0U) |
(context.GetPstateFlag(ARMeilleure.State.PState.CFlag) ? (1U << (int)ARMeilleure.State.PState.CFlag) : 0U) |
(context.GetPstateFlag(ARMeilleure.State.PState.VFlag) ? (1U << (int)ARMeilleure.State.PState.VFlag) : 0U);
return context.Pstate & 0xFF0FFE20;
}
private ThreadContext GetCurrentContext()
@@ -1371,7 +1368,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
PreferredCore = _originalPreferredCore;
AffinityMask = _originalAffinityMask;
if (AffinityMask != affinityMask)
{
if ((AffinityMask & 1UL << ActiveCore) != 0)

View File

@@ -16,7 +16,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
if (serviceType != ViServiceType.Application)
{
return ResultCode.InvalidRange;
return ResultCode.PermissionDenied;
}
MakeObject(context, new IApplicationDisplayService(serviceType));

View File

@@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
if (serviceType != ViServiceType.Manager)
{
return ResultCode.InvalidRange;
return ResultCode.PermissionDenied;
}
MakeObject(context, new IApplicationDisplayService(serviceType));

View File

@@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
if (serviceType != ViServiceType.System)
{
return ResultCode.InvalidRange;
return ResultCode.PermissionDenied;
}
MakeObject(context, new IApplicationDisplayService(serviceType));

View File

@@ -9,7 +9,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
InvalidArguments = (1 << ErrorCodeShift) | ModuleId,
InvalidLayerSize = (4 << ErrorCodeShift) | ModuleId,
InvalidRange = (5 << ErrorCodeShift) | ModuleId,
PermissionDenied = (5 << ErrorCodeShift) | ModuleId,
InvalidScalingMode = (6 << ErrorCodeShift) | ModuleId,
InvalidValue = (7 << ErrorCodeShift) | ModuleId,
AlreadyOpened = (9 << ErrorCodeShift) | ModuleId

View File

@@ -1,7 +1,6 @@
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory;
using Ryujinx.Cpu;
using Ryujinx.HLE.HOS.Applets;
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common;
@@ -22,16 +21,21 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{
private readonly ViServiceType _serviceType;
private readonly List<DisplayInfo> _displayInfo;
private readonly Dictionary<ulong, DisplayInfo> _openDisplayInfo;
private class DisplayState
{
public int RetrievedEventsCount;
}
private readonly List<DisplayInfo> _displayInfo;
private readonly Dictionary<ulong, DisplayState> _openDisplays;
private int _vsyncEventHandle;
public IApplicationDisplayService(ViServiceType serviceType)
{
_serviceType = serviceType;
_displayInfo = new List<DisplayInfo>();
_openDisplayInfo = new Dictionary<ulong, DisplayInfo>();
_serviceType = serviceType;
_displayInfo = new List<DisplayInfo>();
_openDisplays = new Dictionary<ulong, DisplayState>();
void AddDisplayInfo(string name, bool layerLimitEnabled, ulong layerLimitMax, ulong width, ulong height)
{
@@ -64,7 +68,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
// FIXME: Should be _serviceType != ViServiceType.Application but guests crashes if we do this check.
if (_serviceType > ViServiceType.System)
{
return ResultCode.InvalidRange;
return ResultCode.PermissionDenied;
}
MakeObject(context, new HOSBinderDriverServer());
@@ -79,7 +83,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
// FIXME: Should be _serviceType == ViServiceType.System but guests crashes if we do this check.
if (_serviceType > ViServiceType.System)
{
return ResultCode.InvalidRange;
return ResultCode.PermissionDenied;
}
MakeObject(context, new ISystemDisplayService(this));
@@ -93,7 +97,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{
if (_serviceType > ViServiceType.System)
{
return ResultCode.InvalidRange;
return ResultCode.PermissionDenied;
}
MakeObject(context, new IManagerDisplayService(this));
@@ -107,7 +111,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{
if (_serviceType > ViServiceType.System)
{
return ResultCode.InvalidRange;
return ResultCode.PermissionDenied;
}
MakeObject(context, new HOSBinderDriverServer());
@@ -174,7 +178,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
return ResultCode.InvalidValue;
}
if (!_openDisplayInfo.TryAdd((ulong)displayId, _displayInfo[displayId]))
if (!_openDisplays.TryAdd((ulong)displayId, new DisplayState()))
{
return ResultCode.AlreadyOpened;
}
@@ -190,7 +194,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{
ulong displayId = context.RequestData.ReadUInt64();
if (!_openDisplayInfo.Remove(displayId))
if (!_openDisplays.Remove(displayId))
{
return ResultCode.InvalidValue;
}
@@ -454,11 +458,16 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{
ulong displayId = context.RequestData.ReadUInt64();
if (!_openDisplayInfo.ContainsKey(displayId))
if (!_openDisplays.TryGetValue(displayId, out DisplayState displayState))
{
return ResultCode.InvalidValue;
}
if (displayState.RetrievedEventsCount > 0)
{
return ResultCode.PermissionDenied;
}
if (_vsyncEventHandle == 0)
{
if (context.Process.HandleTable.GenerateHandle(context.Device.System.VsyncEvent.ReadableEvent, out _vsyncEventHandle) != KernelResult.Success)
@@ -467,6 +476,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
}
}
displayState.RetrievedEventsCount++;
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_vsyncEventHandle);
return ResultCode.Success;

View File

@@ -220,6 +220,7 @@ namespace Ryujinx.Headless.SDL2
StickButton = ConfigGamepadInputId.LeftStick,
InvertStickX = false,
InvertStickY = false,
Rotate90CW = false,
},
RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
@@ -241,6 +242,7 @@ namespace Ryujinx.Headless.SDL2
StickButton = ConfigGamepadInputId.RightStick,
InvertStickX = false,
InvertStickY = false,
Rotate90CW = false,
},
Motion = new StandardMotionConfigController

View File

@@ -350,6 +350,14 @@ namespace Ryujinx.Input.SDL2
{
resultY = -resultY;
}
if ((inputId == StickInputId.Left && _configuration.LeftJoyconStick.Rotate90CW) ||
(inputId == StickInputId.Right && _configuration.RightJoyconStick.Rotate90CW))
{
float temp = resultX;
resultX = resultY;
resultY = -temp;
}
}
return (resultX, resultY);

View File

@@ -283,10 +283,7 @@ namespace Ryujinx.Tests.Cpu
}
uint finalCpsr = test.FinalRegs[15];
for (int i = 0; i < 32; i++)
{
Assert.That(GetContext().GetPstateFlag((PState)i), Is.EqualTo((finalCpsr & (1u << i)) != 0));
}
Assert.That(GetContext().Pstate, Is.EqualTo(finalCpsr));
}
protected void SetWorkingMemory(uint offset, byte[] data)

View File

@@ -73,6 +73,7 @@ namespace Ryujinx.Ui.Windows
[GUI] ToggleButton _lStick;
[GUI] CheckButton _invertLStickX;
[GUI] CheckButton _invertLStickY;
[GUI] CheckButton _rotateL90CW;
[GUI] ToggleButton _lStickUp;
[GUI] ToggleButton _lStickDown;
[GUI] ToggleButton _lStickLeft;
@@ -88,6 +89,7 @@ namespace Ryujinx.Ui.Windows
[GUI] ToggleButton _rStick;
[GUI] CheckButton _invertRStickX;
[GUI] CheckButton _invertRStickY;
[GUI] CheckButton _rotateR90CW;
[GUI] ToggleButton _rStickUp;
[GUI] ToggleButton _rStickDown;
[GUI] ToggleButton _rStickLeft;
@@ -490,6 +492,7 @@ namespace Ryujinx.Ui.Windows
_lStick.Label = controllerConfig.LeftJoyconStick.Joystick.ToString();
_invertLStickX.Active = controllerConfig.LeftJoyconStick.InvertStickX;
_invertLStickY.Active = controllerConfig.LeftJoyconStick.InvertStickY;
_rotateL90CW.Active = controllerConfig.LeftJoyconStick.Rotate90CW;
_lStickButton.Label = controllerConfig.LeftJoyconStick.StickButton.ToString();
_dpadUp.Label = controllerConfig.LeftJoycon.DpadUp.ToString();
_dpadDown.Label = controllerConfig.LeftJoycon.DpadDown.ToString();
@@ -503,6 +506,7 @@ namespace Ryujinx.Ui.Windows
_rStick.Label = controllerConfig.RightJoyconStick.Joystick.ToString();
_invertRStickX.Active = controllerConfig.RightJoyconStick.InvertStickX;
_invertRStickY.Active = controllerConfig.RightJoyconStick.InvertStickY;
_rotateR90CW.Active = controllerConfig.RightJoyconStick.Rotate90CW;
_rStickButton.Label = controllerConfig.RightJoyconStick.StickButton.ToString();
_a.Label = controllerConfig.RightJoycon.ButtonA.ToString();
_b.Label = controllerConfig.RightJoycon.ButtonB.ToString();
@@ -718,6 +722,7 @@ namespace Ryujinx.Ui.Windows
Joystick = lStick,
InvertStickY = _invertLStickY.Active,
StickButton = lStickButton,
Rotate90CW = _rotateL90CW.Active,
},
RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
{
@@ -737,6 +742,7 @@ namespace Ryujinx.Ui.Windows
Joystick = rStick,
InvertStickY = _invertRStickY.Active,
StickButton = rStickButton,
Rotate90CW = _rotateR90CW.Active,
},
Motion = motionConfig,
Rumble = new RumbleConfigController
@@ -1056,6 +1062,7 @@ namespace Ryujinx.Ui.Windows
StickButton = ConfigGamepadInputId.LeftStick,
InvertStickX = false,
InvertStickY = false,
Rotate90CW = false,
},
RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
@@ -1077,6 +1084,7 @@ namespace Ryujinx.Ui.Windows
StickButton = ConfigGamepadInputId.RightStick,
InvertStickX = false,
InvertStickY = false,
Rotate90CW = false,
},
Motion = new StandardMotionConfigController

View File

@@ -740,6 +740,19 @@
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="_rotateL90CW">
<property name="label" translatable="yes">Rotate 90° Clockwise</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
@@ -1697,6 +1710,19 @@
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="_rotateR90CW">
<property name="label" translatable="yes">Rotate 90° Clockwise</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>