Compare commits

..

3 Commits

Author SHA1 Message Date
0a75b73fa4 [Ryujinx.Memory] Address dotnet-format issues (#5386)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1069 warnings

* Address remaining dotnet format analyzer warnings

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Address review feedback

* Assign Decommit to ReplacePlaceholder

* Run final dotnet format pass

* Organize imports again

* Add trailing commas

* Add missing newline
2023-06-28 18:34:00 +02:00
46b7c905f5 [Ryujinx.Input] Address dotnet-format issues (#5384)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Remove redundant code, convert to auto-properties and fix naming rule violations

* Remove bogus change

* Address review feedback
2023-06-28 18:23:00 +02:00
40f2bd37e3 [Ryujinx.Graphics.OpenGL] Address dotnet-format issues (#5372)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Address or silence dotnet format IDE1006 warnings

* Fix IDE0090 after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Address review feedback
2023-06-28 18:10:55 +02:00
82 changed files with 640 additions and 606 deletions

View File

@ -9,12 +9,12 @@ namespace Ryujinx.Graphics.OpenGL
{ {
[ThreadStatic] [ThreadStatic]
public static bool InBackground; public static bool InBackground;
private Thread _thread; private readonly Thread _thread;
private bool _running; private bool _running;
private AutoResetEvent _signal; private readonly AutoResetEvent _signal;
private Queue<Action> _work; private readonly Queue<Action> _work;
private ObjectPool<ManualResetEventSlim> _invokePool; private readonly ObjectPool<ManualResetEventSlim> _invokePool;
private readonly IOpenGLContext _backgroundContext; private readonly IOpenGLContext _backgroundContext;
public BackgroundContextWorker(IOpenGLContext backgroundContext) public BackgroundContextWorker(IOpenGLContext backgroundContext)
@ -88,4 +88,4 @@ namespace Ryujinx.Graphics.OpenGL
_signal.Dispose(); _signal.Dispose();
} }
} }
} }

View File

@ -63,10 +63,18 @@ namespace Ryujinx.Graphics.OpenGL
switch (type) switch (type)
{ {
case DebugType.DebugTypeError : Logger.Error?.Print(LogClass.Gpu, $"{severity}: {msg}\nCallStack={Environment.StackTrace}", "GLERROR"); break; case DebugType.DebugTypeError:
case DebugType.DebugTypePerformance: Logger.Warning?.Print(LogClass.Gpu, $"{severity}: {msg}", "GLPERF"); break; Logger.Error?.Print(LogClass.Gpu, $"{severity}: {msg}\nCallStack={Environment.StackTrace}", "GLERROR");
case DebugType.DebugTypePushGroup : Logger.Info?.Print(LogClass.Gpu, $"{{ ({id}) {severity}: {msg}", "GLINFO"); break; break;
case DebugType.DebugTypePopGroup : Logger.Info?.Print(LogClass.Gpu, $"}} ({id}) {severity}: {msg}", "GLINFO"); break; case DebugType.DebugTypePerformance:
Logger.Warning?.Print(LogClass.Gpu, $"{severity}: {msg}", "GLPERF");
break;
case DebugType.DebugTypePushGroup:
Logger.Info?.Print(LogClass.Gpu, $"{{ ({id}) {severity}: {msg}", "GLINFO");
break;
case DebugType.DebugTypePopGroup:
Logger.Info?.Print(LogClass.Gpu, $"}} ({id}) {severity}: {msg}", "GLINFO");
break;
default: default:
if (source == DebugSource.DebugSourceApplication) if (source == DebugSource.DebugSourceApplication)
{ {

View File

@ -65,16 +65,12 @@ void main()
if (x0 > x1) if (x0 > x1)
{ {
float temp = s0; (s1, s0) = (s0, s1);
s0 = s1;
s1 = temp;
} }
if (y0 > y1) if (y0 > y1)
{ {
float temp = t0; (t1, t0) = (t0, t1);
t0 = t1;
t1 = temp;
} }
GL.Uniform1(_uniformSrcX0Location, s0); GL.Uniform1(_uniformSrcX0Location, s0);

View File

@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects
} }
} }
public FsrScalingFilter(OpenGLRenderer renderer, IPostProcessingEffect filter) public FsrScalingFilter(OpenGLRenderer renderer)
{ {
Initialize(); Initialize();
@ -174,4 +174,4 @@ namespace Ryujinx.Graphics.OpenGL.Effects
GL.ActiveTexture((TextureUnit)previousUnit); GL.ActiveTexture((TextureUnit)previousUnit);
} }
} }
} }

View File

@ -78,4 +78,4 @@ namespace Ryujinx.Graphics.OpenGL.Effects
return textureView; return textureView;
} }
} }
} }

View File

@ -3,9 +3,9 @@ using System;
namespace Ryujinx.Graphics.OpenGL.Effects namespace Ryujinx.Graphics.OpenGL.Effects
{ {
internal interface IPostProcessingEffect : IDisposable internal interface IPostProcessingEffect : IDisposable
{ {
const int LocalGroupSize = 64; const int LocalGroupSize = 64;
TextureView Run(TextureView view, int width, int height); TextureView Run(TextureView view, int width, int height);
} }
} }

View File

@ -15,4 +15,4 @@ namespace Ryujinx.Graphics.OpenGL.Effects
Extents2D source, Extents2D source,
Extents2D destination); Extents2D destination);
} }
} }

View File

@ -1,5 +1,4 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using System;
namespace Ryujinx.Graphics.OpenGL.Effects namespace Ryujinx.Graphics.OpenGL.Effects
{ {

View File

@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
private int[] _neighbourShaderPrograms; private int[] _neighbourShaderPrograms;
private TextureStorage _edgeOutputTexture; private TextureStorage _edgeOutputTexture;
private TextureStorage _blendOutputTexture; private TextureStorage _blendOutputTexture;
private string[] _qualities; private readonly string[] _qualities;
private int _inputUniform; private int _inputUniform;
private int _outputUniform; private int _outputUniform;
private int _samplerAreaUniform; private int _samplerAreaUniform;

View File

@ -4,42 +4,42 @@ namespace Ryujinx.Graphics.OpenGL
{ {
readonly struct FormatInfo readonly struct FormatInfo
{ {
public int Components { get; } public int Components { get; }
public bool Normalized { get; } public bool Normalized { get; }
public bool Scaled { get; } public bool Scaled { get; }
public PixelInternalFormat PixelInternalFormat { get; } public PixelInternalFormat PixelInternalFormat { get; }
public PixelFormat PixelFormat { get; } public PixelFormat PixelFormat { get; }
public PixelType PixelType { get; } public PixelType PixelType { get; }
public bool IsCompressed { get; } public bool IsCompressed { get; }
public FormatInfo( public FormatInfo(
int components, int components,
bool normalized, bool normalized,
bool scaled, bool scaled,
All pixelInternalFormat, All pixelInternalFormat,
PixelFormat pixelFormat, PixelFormat pixelFormat,
PixelType pixelType) PixelType pixelType)
{ {
Components = components; Components = components;
Normalized = normalized; Normalized = normalized;
Scaled = scaled; Scaled = scaled;
PixelInternalFormat = (PixelInternalFormat)pixelInternalFormat; PixelInternalFormat = (PixelInternalFormat)pixelInternalFormat;
PixelFormat = pixelFormat; PixelFormat = pixelFormat;
PixelType = pixelType; PixelType = pixelType;
IsCompressed = false; IsCompressed = false;
} }
public FormatInfo(int components, bool normalized, bool scaled, All pixelFormat) public FormatInfo(int components, bool normalized, bool scaled, All pixelFormat)
{ {
Components = components; Components = components;
Normalized = normalized; Normalized = normalized;
Scaled = scaled; Scaled = scaled;
PixelInternalFormat = 0; PixelInternalFormat = 0;
PixelFormat = (PixelFormat)pixelFormat; PixelFormat = (PixelFormat)pixelFormat;
PixelType = 0; PixelType = 0;
IsCompressed = true; IsCompressed = true;
} }
} }
} }

View File

@ -4,10 +4,10 @@ using System;
namespace Ryujinx.Graphics.OpenGL namespace Ryujinx.Graphics.OpenGL
{ {
struct FormatTable readonly struct FormatTable
{ {
private static FormatInfo[] _table; private static readonly FormatInfo[] _table;
private static SizedInternalFormat[] _tableImage; private static readonly SizedInternalFormat[] _tableImage;
static FormatTable() static FormatTable()
{ {
@ -16,6 +16,7 @@ namespace Ryujinx.Graphics.OpenGL
_table = new FormatInfo[tableSize]; _table = new FormatInfo[tableSize];
_tableImage = new SizedInternalFormat[tableSize]; _tableImage = new SizedInternalFormat[tableSize];
#pragma warning disable IDE0055 // Disable formatting
Add(Format.R8Unorm, new FormatInfo(1, true, false, All.R8, PixelFormat.Red, PixelType.UnsignedByte)); Add(Format.R8Unorm, new FormatInfo(1, true, false, All.R8, PixelFormat.Red, PixelType.UnsignedByte));
Add(Format.R8Snorm, new FormatInfo(1, true, false, All.R8Snorm, PixelFormat.Red, PixelType.Byte)); Add(Format.R8Snorm, new FormatInfo(1, true, false, All.R8Snorm, PixelFormat.Red, PixelType.Byte));
Add(Format.R8Uint, new FormatInfo(1, false, false, All.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte)); Add(Format.R8Uint, new FormatInfo(1, false, false, All.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte));
@ -200,6 +201,7 @@ namespace Ryujinx.Graphics.OpenGL
Add(Format.R10G10B10A2Unorm, (SizedInternalFormat)All.Rgb10A2); Add(Format.R10G10B10A2Unorm, (SizedInternalFormat)All.Rgb10A2);
Add(Format.R10G10B10A2Uint, (SizedInternalFormat)All.Rgb10A2ui); Add(Format.R10G10B10A2Uint, (SizedInternalFormat)All.Rgb10A2ui);
Add(Format.R11G11B10Float, (SizedInternalFormat)All.R11fG11fB10f); Add(Format.R11G11B10Float, (SizedInternalFormat)All.R11fG11fB10f);
#pragma warning restore IDE0055
} }
private static void Add(Format format, FormatInfo info) private static void Add(Format format, FormatInfo info)

View File

@ -105,7 +105,7 @@ namespace Ryujinx.Graphics.OpenGL
_colorsCount = colorsCount; _colorsCount = colorsCount;
} }
private void SetDrawBuffersImpl(int colorsCount) private static void SetDrawBuffersImpl(int colorsCount)
{ {
DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[colorsCount]; DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[colorsCount];

View File

@ -5,30 +5,30 @@ namespace Ryujinx.Graphics.OpenGL
{ {
static class HwCapabilities static class HwCapabilities
{ {
private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new Lazy<bool>(() => HasExtension("GL_NV_alpha_to_coverage_dither_control")); private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new(() => HasExtension("GL_NV_alpha_to_coverage_dither_control"));
private static readonly Lazy<bool> _supportsAstcCompression = new Lazy<bool>(() => HasExtension("GL_KHR_texture_compression_astc_ldr")); private static readonly Lazy<bool> _supportsAstcCompression = new(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
private static readonly Lazy<bool> _supportsBlendEquationAdvanced = new Lazy<bool>(() => HasExtension("GL_NV_blend_equation_advanced")); private static readonly Lazy<bool> _supportsBlendEquationAdvanced = new(() => HasExtension("GL_NV_blend_equation_advanced"));
private static readonly Lazy<bool> _supportsDrawTexture = new Lazy<bool>(() => HasExtension("GL_NV_draw_texture")); private static readonly Lazy<bool> _supportsDrawTexture = new(() => HasExtension("GL_NV_draw_texture"));
private static readonly Lazy<bool> _supportsFragmentShaderInterlock = new Lazy<bool>(() => HasExtension("GL_ARB_fragment_shader_interlock")); private static readonly Lazy<bool> _supportsFragmentShaderInterlock = new(() => HasExtension("GL_ARB_fragment_shader_interlock"));
private static readonly Lazy<bool> _supportsFragmentShaderOrdering = new Lazy<bool>(() => HasExtension("GL_INTEL_fragment_shader_ordering")); private static readonly Lazy<bool> _supportsFragmentShaderOrdering = new(() => HasExtension("GL_INTEL_fragment_shader_ordering"));
private static readonly Lazy<bool> _supportsGeometryShaderPassthrough = new Lazy<bool>(() => HasExtension("GL_NV_geometry_shader_passthrough")); private static readonly Lazy<bool> _supportsGeometryShaderPassthrough = new(() => HasExtension("GL_NV_geometry_shader_passthrough"));
private static readonly Lazy<bool> _supportsImageLoadFormatted = new Lazy<bool>(() => HasExtension("GL_EXT_shader_image_load_formatted")); private static readonly Lazy<bool> _supportsImageLoadFormatted = new(() => HasExtension("GL_EXT_shader_image_load_formatted"));
private static readonly Lazy<bool> _supportsIndirectParameters = new Lazy<bool>(() => HasExtension("GL_ARB_indirect_parameters")); private static readonly Lazy<bool> _supportsIndirectParameters = new(() => HasExtension("GL_ARB_indirect_parameters"));
private static readonly Lazy<bool> _supportsParallelShaderCompile = new Lazy<bool>(() => HasExtension("GL_ARB_parallel_shader_compile")); private static readonly Lazy<bool> _supportsParallelShaderCompile = new(() => HasExtension("GL_ARB_parallel_shader_compile"));
private static readonly Lazy<bool> _supportsPolygonOffsetClamp = new Lazy<bool>(() => HasExtension("GL_EXT_polygon_offset_clamp")); private static readonly Lazy<bool> _supportsPolygonOffsetClamp = new(() => HasExtension("GL_EXT_polygon_offset_clamp"));
private static readonly Lazy<bool> _supportsQuads = new Lazy<bool>(SupportsQuadsCheck); private static readonly Lazy<bool> _supportsQuads = new(SupportsQuadsCheck);
private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new Lazy<bool>(() => HasExtension("GL_ARB_seamless_cubemap_per_texture")); private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new(() => HasExtension("GL_ARB_seamless_cubemap_per_texture"));
private static readonly Lazy<bool> _supportsShaderBallot = new Lazy<bool>(() => HasExtension("GL_ARB_shader_ballot")); private static readonly Lazy<bool> _supportsShaderBallot = new(() => HasExtension("GL_ARB_shader_ballot"));
private static readonly Lazy<bool> _supportsShaderViewportLayerArray = new Lazy<bool>(() => HasExtension("GL_ARB_shader_viewport_layer_array")); private static readonly Lazy<bool> _supportsShaderViewportLayerArray = new(() => HasExtension("GL_ARB_shader_viewport_layer_array"));
private static readonly Lazy<bool> _supportsViewportArray2 = new Lazy<bool>(() => HasExtension("GL_NV_viewport_array2")); private static readonly Lazy<bool> _supportsViewportArray2 = new(() => HasExtension("GL_NV_viewport_array2"));
private static readonly Lazy<bool> _supportsTextureCompressionBptc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_bptc")); private static readonly Lazy<bool> _supportsTextureCompressionBptc = new(() => HasExtension("GL_EXT_texture_compression_bptc"));
private static readonly Lazy<bool> _supportsTextureCompressionRgtc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_rgtc")); private static readonly Lazy<bool> _supportsTextureCompressionRgtc = new(() => HasExtension("GL_EXT_texture_compression_rgtc"));
private static readonly Lazy<bool> _supportsTextureCompressionS3tc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_s3tc")); private static readonly Lazy<bool> _supportsTextureCompressionS3tc = new(() => HasExtension("GL_EXT_texture_compression_s3tc"));
private static readonly Lazy<bool> _supportsTextureShadowLod = new Lazy<bool>(() => HasExtension("GL_EXT_texture_shadow_lod")); private static readonly Lazy<bool> _supportsTextureShadowLod = new(() => HasExtension("GL_EXT_texture_shadow_lod"));
private static readonly Lazy<bool> _supportsViewportSwizzle = new Lazy<bool>(() => HasExtension("GL_NV_viewport_swizzle")); private static readonly Lazy<bool> _supportsViewportSwizzle = new(() => HasExtension("GL_NV_viewport_swizzle"));
private static readonly Lazy<int> _maximumComputeSharedMemorySize = new Lazy<int>(() => GetLimit(All.MaxComputeSharedMemorySize)); private static readonly Lazy<int> _maximumComputeSharedMemorySize = new(() => GetLimit(All.MaxComputeSharedMemorySize));
private static readonly Lazy<int> _storageBufferOffsetAlignment = new Lazy<int>(() => GetLimit(All.ShaderStorageBufferOffsetAlignment)); private static readonly Lazy<int> _storageBufferOffsetAlignment = new(() => GetLimit(All.ShaderStorageBufferOffsetAlignment));
public enum GpuVendor public enum GpuVendor
{ {
@ -40,45 +40,44 @@ namespace Ryujinx.Graphics.OpenGL
Nvidia Nvidia
} }
private static readonly Lazy<GpuVendor> _gpuVendor = new Lazy<GpuVendor>(GetGpuVendor); private static readonly Lazy<GpuVendor> _gpuVendor = new(GetGpuVendor);
private static bool _isAMD => _gpuVendor.Value == GpuVendor.AmdWindows || _gpuVendor.Value == GpuVendor.AmdUnix; private static bool IsIntel => _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix;
private static bool _isIntel => _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix;
public static GpuVendor Vendor => _gpuVendor.Value; public static GpuVendor Vendor => _gpuVendor.Value;
private static Lazy<float> _maxSupportedAnisotropy = new Lazy<float>(GL.GetFloat((GetPName)All.MaxTextureMaxAnisotropy)); private static readonly Lazy<float> _maxSupportedAnisotropy = new(GL.GetFloat((GetPName)All.MaxTextureMaxAnisotropy));
public static bool UsePersistentBufferForFlush => _gpuVendor.Value == GpuVendor.AmdWindows || _gpuVendor.Value == GpuVendor.Nvidia; public static bool UsePersistentBufferForFlush => _gpuVendor.Value == GpuVendor.AmdWindows || _gpuVendor.Value == GpuVendor.Nvidia;
public static bool SupportsAlphaToCoverageDitherControl => _supportsAlphaToCoverageDitherControl.Value; public static bool SupportsAlphaToCoverageDitherControl => _supportsAlphaToCoverageDitherControl.Value;
public static bool SupportsAstcCompression => _supportsAstcCompression.Value; public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
public static bool SupportsBlendEquationAdvanced => _supportsBlendEquationAdvanced.Value; public static bool SupportsBlendEquationAdvanced => _supportsBlendEquationAdvanced.Value;
public static bool SupportsDrawTexture => _supportsDrawTexture.Value; public static bool SupportsDrawTexture => _supportsDrawTexture.Value;
public static bool SupportsFragmentShaderInterlock => _supportsFragmentShaderInterlock.Value; public static bool SupportsFragmentShaderInterlock => _supportsFragmentShaderInterlock.Value;
public static bool SupportsFragmentShaderOrdering => _supportsFragmentShaderOrdering.Value; public static bool SupportsFragmentShaderOrdering => _supportsFragmentShaderOrdering.Value;
public static bool SupportsGeometryShaderPassthrough => _supportsGeometryShaderPassthrough.Value; public static bool SupportsGeometryShaderPassthrough => _supportsGeometryShaderPassthrough.Value;
public static bool SupportsImageLoadFormatted => _supportsImageLoadFormatted.Value; public static bool SupportsImageLoadFormatted => _supportsImageLoadFormatted.Value;
public static bool SupportsIndirectParameters => _supportsIndirectParameters.Value; public static bool SupportsIndirectParameters => _supportsIndirectParameters.Value;
public static bool SupportsParallelShaderCompile => _supportsParallelShaderCompile.Value; public static bool SupportsParallelShaderCompile => _supportsParallelShaderCompile.Value;
public static bool SupportsPolygonOffsetClamp => _supportsPolygonOffsetClamp.Value; public static bool SupportsPolygonOffsetClamp => _supportsPolygonOffsetClamp.Value;
public static bool SupportsQuads => _supportsQuads.Value; public static bool SupportsQuads => _supportsQuads.Value;
public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value; public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value;
public static bool SupportsShaderBallot => _supportsShaderBallot.Value; public static bool SupportsShaderBallot => _supportsShaderBallot.Value;
public static bool SupportsShaderViewportLayerArray => _supportsShaderViewportLayerArray.Value; public static bool SupportsShaderViewportLayerArray => _supportsShaderViewportLayerArray.Value;
public static bool SupportsViewportArray2 => _supportsViewportArray2.Value; public static bool SupportsViewportArray2 => _supportsViewportArray2.Value;
public static bool SupportsTextureCompressionBptc => _supportsTextureCompressionBptc.Value; public static bool SupportsTextureCompressionBptc => _supportsTextureCompressionBptc.Value;
public static bool SupportsTextureCompressionRgtc => _supportsTextureCompressionRgtc.Value; public static bool SupportsTextureCompressionRgtc => _supportsTextureCompressionRgtc.Value;
public static bool SupportsTextureCompressionS3tc => _supportsTextureCompressionS3tc.Value; public static bool SupportsTextureCompressionS3tc => _supportsTextureCompressionS3tc.Value;
public static bool SupportsTextureShadowLod => _supportsTextureShadowLod.Value; public static bool SupportsTextureShadowLod => _supportsTextureShadowLod.Value;
public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value; public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value;
public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.AmdWindows && _gpuVendor.Value != GpuVendor.IntelWindows; public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.AmdWindows && _gpuVendor.Value != GpuVendor.IntelWindows;
public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia; public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia;
public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.AmdWindows || _isIntel; public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.AmdWindows || IsIntel;
public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value; public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value; public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value;
public static float MaximumSupportedAnisotropy => _maxSupportedAnisotropy.Value; public static float MaximumSupportedAnisotropy => _maxSupportedAnisotropy.Value;
@ -139,4 +138,4 @@ namespace Ryujinx.Graphics.OpenGL
return GL.GetError() == ErrorCode.NoError; return GL.GetError() == ErrorCode.NoError;
} }
} }
} }

View File

@ -100,4 +100,4 @@ namespace Ryujinx.Graphics.OpenGL.Image
_entries.Clear(); _entries.Clear();
} }
} }
} }

View File

@ -39,8 +39,8 @@ namespace Ryujinx.Graphics.OpenGL.Image
GL.SamplerParameter(Handle, SamplerParameterName.TextureBorderColor, borderColor); GL.SamplerParameter(Handle, SamplerParameterName.TextureBorderColor, borderColor);
} }
GL.SamplerParameter(Handle, SamplerParameterName.TextureMinLod, info.MinLod); GL.SamplerParameter(Handle, SamplerParameterName.TextureMinLod, info.MinLod);
GL.SamplerParameter(Handle, SamplerParameterName.TextureMaxLod, info.MaxLod); GL.SamplerParameter(Handle, SamplerParameterName.TextureMaxLod, info.MaxLod);
GL.SamplerParameter(Handle, SamplerParameterName.TextureLodBias, info.MipLodBias); GL.SamplerParameter(Handle, SamplerParameterName.TextureLodBias, info.MipLodBias);
GL.SamplerParameter(Handle, SamplerParameterName.TextureMaxAnisotropyExt, info.MaxAnisotropy); GL.SamplerParameter(Handle, SamplerParameterName.TextureMaxAnisotropyExt, info.MaxAnisotropy);

View File

@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
class TextureBuffer : TextureBase, ITexture class TextureBuffer : TextureBase, ITexture
{ {
private OpenGLRenderer _renderer; private readonly OpenGLRenderer _renderer;
private int _bufferOffset; private int _bufferOffset;
private int _bufferSize; private int _bufferSize;
private int _bufferCount; private int _bufferCount;
@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
var dataSpan = data.AsSpan(); var dataSpan = data.AsSpan();
Buffer.SetData(_buffer, _bufferOffset, dataSpan.Slice(0, Math.Min(dataSpan.Length, _bufferSize))); Buffer.SetData(_buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]);
} }
public void SetData(SpanOrArray<byte> data, int layer, int level) public void SetData(SpanOrArray<byte> data, int layer, int level)

View File

@ -26,13 +26,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
public void Copy( public void Copy(
TextureView src, TextureView src,
TextureView dst, TextureView dst,
Extents2D srcRegion, Extents2D srcRegion,
Extents2D dstRegion, Extents2D dstRegion,
bool linearFilter, bool linearFilter,
int srcLayer = 0, int srcLayer = 0,
int dstLayer = 0, int dstLayer = 0,
int srcLevel = 0, int srcLevel = 0,
int dstLevel = 0) int dstLevel = 0)
{ {
int levels = Math.Min(src.Info.Levels - srcLevel, dst.Info.Levels - dstLevel); int levels = Math.Min(src.Info.Levels - srcLevel, dst.Info.Levels - dstLevel);
int layers = Math.Min(src.Info.GetLayers() - srcLayer, dst.Info.GetLayers() - dstLayer); int layers = Math.Min(src.Info.GetLayers() - srcLayer, dst.Info.GetLayers() - dstLayer);
@ -43,15 +43,15 @@ namespace Ryujinx.Graphics.OpenGL.Image
public void Copy( public void Copy(
TextureView src, TextureView src,
TextureView dst, TextureView dst,
Extents2D srcRegion, Extents2D srcRegion,
Extents2D dstRegion, Extents2D dstRegion,
bool linearFilter, bool linearFilter,
int srcLayer, int srcLayer,
int dstLayer, int dstLayer,
int srcLevel, int srcLevel,
int dstLevel, int dstLevel,
int layers, int layers,
int levels) int levels)
{ {
TextureView srcConverted = src.Format.IsBgr() != dst.Format.IsBgr() ? BgraSwap(src) : src; TextureView srcConverted = src.Format.IsBgr() != dst.Format.IsBgr() ? BgraSwap(src) : src;

View File

@ -1,5 +1,4 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
@ -81,9 +80,6 @@ void main()
public void CopyIncompatibleFormats(ITextureInfo src, ITextureInfo dst, int srcLayer, int dstLayer, int srcLevel, int dstLevel, int depth, int levels) public void CopyIncompatibleFormats(ITextureInfo src, ITextureInfo dst, int srcLayer, int dstLayer, int srcLevel, int dstLevel, int depth, int levels)
{ {
TextureCreateInfo srcInfo = src.Info;
TextureCreateInfo dstInfo = dst.Info;
int srcBpp = src.Info.BytesPerPixel; int srcBpp = src.Info.BytesPerPixel;
int dstBpp = dst.Info.BytesPerPixel; int dstBpp = dst.Info.BytesPerPixel;
@ -176,7 +172,7 @@ void main()
return GetShader(ComputeShaderWidening, _wideningProgramHandles, componentSize, srcComponentsCount, dstComponentsCount); return GetShader(ComputeShaderWidening, _wideningProgramHandles, componentSize, srcComponentsCount, dstComponentsCount);
} }
private int GetShader( private static int GetShader(
string code, string code,
Dictionary<int, int> programHandles, Dictionary<int, int> programHandles,
int componentSize, int componentSize,

View File

@ -94,8 +94,8 @@ void main()
}"; }";
private readonly OpenGLRenderer _renderer; private readonly OpenGLRenderer _renderer;
private int[] _msToNonMSProgramHandles; private readonly int[] _msToNonMSProgramHandles;
private int[] _nonMSToMSProgramHandles; private readonly int[] _nonMSToMSProgramHandles;
public TextureCopyMS(OpenGLRenderer renderer) public TextureCopyMS(OpenGLRenderer renderer)
{ {
@ -219,7 +219,7 @@ void main()
return GetShader(ComputeShaderNonMSToMS, _nonMSToMSProgramHandles, bytesPerPixel); return GetShader(ComputeShaderNonMSToMS, _nonMSToMSProgramHandles, bytesPerPixel);
} }
private int GetShader(string code, int[] programHandles, int bytesPerPixel) private static int GetShader(string code, int[] programHandles, int bytesPerPixel)
{ {
int index = BitOperations.Log2((uint)bytesPerPixel); int index = BitOperations.Log2((uint)bytesPerPixel);

View File

@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
public TextureStorage(OpenGLRenderer renderer, TextureCreateInfo info, float scaleFactor) public TextureStorage(OpenGLRenderer renderer, TextureCreateInfo info, float scaleFactor)
{ {
_renderer = renderer; _renderer = renderer;
Info = info; Info = info;
Handle = GL.GenTexture(); Handle = GL.GenTexture();
ScaleFactor = scaleFactor; ScaleFactor = scaleFactor;

View File

@ -88,9 +88,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
// Swap B <-> R for BGRA formats, as OpenGL has no support for them // Swap B <-> R for BGRA formats, as OpenGL has no support for them
// and we need to manually swap the components on read/write on the GPU. // and we need to manually swap the components on read/write on the GPU.
int temp = swizzleRgba[0]; (swizzleRgba[2], swizzleRgba[0]) = (swizzleRgba[0], swizzleRgba[2]);
swizzleRgba[0] = swizzleRgba[2];
swizzleRgba[2] = temp;
} }
GL.TexParameter(target, TextureParameterName.TextureSwizzleRgba, swizzleRgba); GL.TexParameter(target, TextureParameterName.TextureSwizzleRgba, swizzleRgba);
@ -186,8 +184,8 @@ namespace Ryujinx.Graphics.OpenGL.Image
// This approach uses blit, which causes a resolution loss since some samples will be lost // This approach uses blit, which causes a resolution loss since some samples will be lost
// in the process. // in the process.
Extents2D srcRegion = new Extents2D(0, 0, Width, Height); Extents2D srcRegion = new(0, 0, Width, Height);
Extents2D dstRegion = new Extents2D(0, 0, destinationView.Width, destinationView.Height); Extents2D dstRegion = new(0, 0, destinationView.Width, destinationView.Height);
if (destinationView.Target.IsMultisample()) if (destinationView.Target.IsMultisample())
{ {

View File

@ -21,13 +21,13 @@ namespace Ryujinx.Graphics.OpenGL
public IWindow Window => _window; public IWindow Window => _window;
private TextureCopy _textureCopy; private readonly TextureCopy _textureCopy;
private TextureCopy _backgroundTextureCopy; private readonly TextureCopy _backgroundTextureCopy;
internal TextureCopy TextureCopy => BackgroundContextWorker.InBackground ? _backgroundTextureCopy : _textureCopy; internal TextureCopy TextureCopy => BackgroundContextWorker.InBackground ? _backgroundTextureCopy : _textureCopy;
internal TextureCopyIncompatible TextureCopyIncompatible { get; } internal TextureCopyIncompatible TextureCopyIncompatible { get; }
internal TextureCopyMS TextureCopyMS { get; } internal TextureCopyMS TextureCopyMS { get; }
private Sync _sync; private readonly Sync _sync;
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured; public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
@ -222,9 +222,9 @@ namespace Ryujinx.Graphics.OpenGL
private void PrintGpuInformation() private void PrintGpuInformation()
{ {
GpuVendor = GL.GetString(StringName.Vendor); GpuVendor = GL.GetString(StringName.Vendor);
GpuRenderer = GL.GetString(StringName.Renderer); GpuRenderer = GL.GetString(StringName.Renderer);
GpuVersion = GL.GetString(StringName.Version); GpuVersion = GL.GetString(StringName.Version);
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})"); Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
} }

View File

@ -11,10 +11,10 @@ namespace Ryujinx.Graphics.OpenGL
{ {
class PersistentBuffers : IDisposable class PersistentBuffers : IDisposable
{ {
private PersistentBuffer _main = new PersistentBuffer(); private readonly PersistentBuffer _main = new();
private PersistentBuffer _background = new PersistentBuffer(); private readonly PersistentBuffer _background = new();
private Dictionary<BufferHandle, IntPtr> _maps = new Dictionary<BufferHandle, IntPtr>(); private readonly Dictionary<BufferHandle, IntPtr> _maps = new();
public PersistentBuffer Default => BackgroundContextWorker.InBackground ? _background : _main; public PersistentBuffer Default => BackgroundContextWorker.InBackground ? _background : _main;
@ -91,7 +91,7 @@ namespace Ryujinx.Graphics.OpenGL
return _dataMap; return _dataMap;
} }
private void Sync() private static void Sync()
{ {
GL.MemoryBarrier(MemoryBarrierFlags.ClientMappedBufferBarrierBit); GL.MemoryBarrier(MemoryBarrierFlags.ClientMappedBufferBarrierBit);
@ -133,7 +133,7 @@ namespace Ryujinx.Graphics.OpenGL
Sync(); Sync();
return new ReadOnlySpan<byte>(_bufferMap.ToPointer(), size).Slice(offset); return new ReadOnlySpan<byte>(_bufferMap.ToPointer(), size)[offset..];
} }
public unsafe ReadOnlySpan<byte> GetBufferData(BufferHandle buffer, int offset, int size) public unsafe ReadOnlySpan<byte> GetBufferData(BufferHandle buffer, int offset, int size)

View File

@ -44,11 +44,11 @@ namespace Ryujinx.Graphics.OpenGL
private CounterQueueEvent _activeConditionalRender; private CounterQueueEvent _activeConditionalRender;
private Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount]; private readonly Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount];
private Vector4<float>[] _renderScale = new Vector4<float>[73]; private readonly Vector4<float>[] _renderScale = new Vector4<float>[73];
private int _fragmentScaleCount; private int _fragmentScaleCount;
private (TextureBase, Format)[] _images; private readonly (TextureBase, Format)[] _images;
private TextureBase _unit0Texture; private TextureBase _unit0Texture;
private Sampler _unit0Sampler; private Sampler _unit0Sampler;
@ -260,7 +260,7 @@ namespace Ryujinx.Graphics.OpenGL
PostDraw(); PostDraw();
} }
private void DrawQuadsImpl( private static void DrawQuadsImpl(
int vertexCount, int vertexCount,
int instanceCount, int instanceCount,
int firstVertex, int firstVertex,
@ -285,7 +285,7 @@ namespace Ryujinx.Graphics.OpenGL
quadsCount); quadsCount);
} }
private void DrawQuadStripImpl( private static void DrawQuadStripImpl(
int vertexCount, int vertexCount,
int instanceCount, int instanceCount,
int firstVertex, int firstVertex,
@ -366,8 +366,12 @@ namespace Ryujinx.Graphics.OpenGL
switch (_elementsType) switch (_elementsType)
{ {
case DrawElementsType.UnsignedShort: indexElemSize = 2; break; case DrawElementsType.UnsignedShort:
case DrawElementsType.UnsignedInt: indexElemSize = 4; break; indexElemSize = 2;
break;
case DrawElementsType.UnsignedInt:
indexElemSize = 4;
break;
} }
IntPtr indexBaseOffset = _indexBaseOffset + firstIndex * indexElemSize; IntPtr indexBaseOffset = _indexBaseOffset + firstIndex * indexElemSize;
@ -1471,7 +1475,7 @@ namespace Ryujinx.Graphics.OpenGL
GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit); GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit);
} }
private void SetBuffers(ReadOnlySpan<BufferAssignment> buffers, bool isStorage) private static void SetBuffers(ReadOnlySpan<BufferAssignment> buffers, bool isStorage)
{ {
BufferRangeTarget target = isStorage ? BufferRangeTarget.ShaderStorageBuffer : BufferRangeTarget.UniformBuffer; BufferRangeTarget target = isStorage ? BufferRangeTarget.ShaderStorageBuffer : BufferRangeTarget.UniformBuffer;
@ -1701,11 +1705,9 @@ namespace Ryujinx.Graphics.OpenGL
public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual) public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
{ {
if (value is CounterQueueEvent) // Compare an event and a constant value.
if (value is CounterQueueEvent evt)
{ {
// Compare an event and a constant value.
CounterQueueEvent evt = (CounterQueueEvent)value;
// Easy host conditional rendering when the check matches what GL can do: // Easy host conditional rendering when the check matches what GL can do:
// - Event is of type samples passed. // - Event is of type samples passed.
// - Result is not a combination of multiple queries. // - Result is not a combination of multiple queries.

View File

@ -123,7 +123,7 @@ namespace Ryujinx.Graphics.OpenGL
if (log.Length > MaxShaderLogLength) if (log.Length > MaxShaderLogLength)
{ {
log = log.Substring(0, MaxShaderLogLength) + "..."; log = log[..MaxShaderLogLength] + "...";
} }
Logger.Warning?.Print(LogClass.Gpu, $"Shader linking failed: \n{log}"); Logger.Warning?.Print(LogClass.Gpu, $"Shader linking failed: \n{log}");

View File

@ -14,9 +14,9 @@ namespace Ryujinx.Graphics.OpenGL.Queries
public int Query { get; } public int Query { get; }
private int _buffer; private readonly int _buffer;
private IntPtr _bufferMap; private readonly IntPtr _bufferMap;
private QueryTarget _type; private readonly QueryTarget _type;
public BufferedQuery(QueryTarget type) public BufferedQuery(QueryTarget type)
{ {
@ -64,7 +64,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
} }
} }
private bool WaitingForValue(long data) private static bool WaitingForValue(long data)
{ {
return data == DefaultValue || return data == DefaultValue ||
((ulong)data & HighMask) == (unchecked((ulong)DefaultValue) & HighMask); ((ulong)data & HighMask) == (unchecked((ulong)DefaultValue) & HighMask);

View File

@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private readonly Pipeline _pipeline; private readonly Pipeline _pipeline;
private Queue<CounterQueueEvent> _events = new Queue<CounterQueueEvent>(); private readonly Queue<CounterQueueEvent> _events = new();
private CounterQueueEvent _current; private CounterQueueEvent _current;
private ulong _accumulatedCounter; private ulong _accumulatedCounter;
@ -23,12 +23,12 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private readonly object _lock = new(); private readonly object _lock = new();
private Queue<BufferedQuery> _queryPool; private readonly Queue<BufferedQuery> _queryPool;
private AutoResetEvent _queuedEvent = new AutoResetEvent(false); private readonly AutoResetEvent _queuedEvent = new(false);
private AutoResetEvent _wakeSignal = new AutoResetEvent(false); private readonly AutoResetEvent _wakeSignal = new(false);
private AutoResetEvent _eventConsumed = new AutoResetEvent(false); private readonly AutoResetEvent _eventConsumed = new(false);
private Thread _consumerThread; private readonly Thread _consumerThread;
internal CounterQueue(Pipeline pipeline, CounterType type) internal CounterQueue(Pipeline pipeline, CounterType type)
{ {
@ -148,14 +148,13 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private static QueryTarget GetTarget(CounterType type) private static QueryTarget GetTarget(CounterType type)
{ {
switch (type) return type switch
{ {
case CounterType.SamplesPassed: return QueryTarget.SamplesPassed; CounterType.SamplesPassed => QueryTarget.SamplesPassed,
case CounterType.PrimitivesGenerated: return QueryTarget.PrimitivesGenerated; CounterType.PrimitivesGenerated => QueryTarget.PrimitivesGenerated,
case CounterType.TransformFeedbackPrimitivesWritten: return QueryTarget.TransformFeedbackPrimitivesWritten; CounterType.TransformFeedbackPrimitivesWritten => QueryTarget.TransformFeedbackPrimitivesWritten,
} _ => QueryTarget.SamplesPassed,
};
return QueryTarget.SamplesPassed;
} }
public void Flush(bool blocking) public void Flush(bool blocking)

View File

@ -18,8 +18,8 @@ namespace Ryujinx.Graphics.OpenGL.Queries
public ulong DrawIndex { get; } public ulong DrawIndex { get; }
private CounterQueue _queue; private readonly CounterQueue _queue;
private BufferedQuery _counter; private readonly BufferedQuery _counter;
private bool _hostAccessReserved = false; private bool _hostAccessReserved = false;
private int _refCount = 1; // Starts with a reference from the counter queue. private int _refCount = 1; // Starts with a reference from the counter queue.

View File

@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
{ {
class Counters : IDisposable class Counters : IDisposable
{ {
private CounterQueue[] _counterQueues; private readonly CounterQueue[] _counterQueues;
public Counters() public Counters()
{ {
@ -54,4 +54,4 @@ namespace Ryujinx.Graphics.OpenGL.Queries
} }
} }
} }
} }

View File

@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.OpenGL
private const int DisposedLiveFrames = 2; private const int DisposedLiveFrames = 2;
private readonly object _lock = new(); private readonly object _lock = new();
private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new Dictionary<TextureCreateInfo, List<DisposedTexture>>(); private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new();
/// <summary> /// <summary>
/// Add a texture that is not being used anymore to the resource pool to be used later. /// Add a texture that is not being used anymore to the resource pool to be used later.
@ -32,8 +32,7 @@ namespace Ryujinx.Graphics.OpenGL
{ {
lock (_lock) lock (_lock)
{ {
List<DisposedTexture> list; if (!_textures.TryGetValue(view.Info, out List<DisposedTexture> list))
if (!_textures.TryGetValue(view.Info, out list))
{ {
list = new List<DisposedTexture>(); list = new List<DisposedTexture>();
_textures.Add(view.Info, list); _textures.Add(view.Info, list);
@ -59,8 +58,7 @@ namespace Ryujinx.Graphics.OpenGL
{ {
lock (_lock) lock (_lock)
{ {
List<DisposedTexture> list; if (!_textures.TryGetValue(info, out List<DisposedTexture> list))
if (!_textures.TryGetValue(info, out list))
{ {
return null; return null;
} }

View File

@ -15,13 +15,13 @@ namespace Ryujinx.Graphics.OpenGL
} }
private ulong _firstHandle = 0; private ulong _firstHandle = 0;
private ClientWaitSyncFlags _syncFlags => HwCapabilities.RequiresSyncFlush ? ClientWaitSyncFlags.None : ClientWaitSyncFlags.SyncFlushCommandsBit; private static ClientWaitSyncFlags SyncFlags => HwCapabilities.RequiresSyncFlush ? ClientWaitSyncFlags.None : ClientWaitSyncFlags.SyncFlushCommandsBit;
private List<SyncHandle> _handles = new List<SyncHandle>(); private readonly List<SyncHandle> _handles = new();
public void Create(ulong id) public void Create(ulong id)
{ {
SyncHandle handle = new SyncHandle SyncHandle handle = new()
{ {
ID = id, ID = id,
Handle = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None) Handle = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None)
@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.OpenGL
if (handle.ID > lastHandle) if (handle.ID > lastHandle)
{ {
WaitSyncStatus syncResult = GL.ClientWaitSync(handle.Handle, _syncFlags, 0); WaitSyncStatus syncResult = GL.ClientWaitSync(handle.Handle, SyncFlags, 0);
if (syncResult == WaitSyncStatus.AlreadySignaled) if (syncResult == WaitSyncStatus.AlreadySignaled)
{ {
@ -101,8 +101,8 @@ namespace Ryujinx.Graphics.OpenGL
return; return;
} }
WaitSyncStatus syncResult = GL.ClientWaitSync(result.Handle, _syncFlags, 1000000000); WaitSyncStatus syncResult = GL.ClientWaitSync(result.Handle, SyncFlags, 1000000000);
if (syncResult == WaitSyncStatus.TimeoutExpired) if (syncResult == WaitSyncStatus.TimeoutExpired)
{ {
Logger.Error?.PrintMsg(LogClass.Gpu, $"GL Sync Object {result.ID} failed to signal within 1000ms. Continuing..."); Logger.Error?.PrintMsg(LogClass.Gpu, $"GL Sync Object {result.ID} failed to signal within 1000ms. Continuing...");
@ -123,9 +123,12 @@ namespace Ryujinx.Graphics.OpenGL
first = _handles.FirstOrDefault(); first = _handles.FirstOrDefault();
} }
if (first == null) break; if (first == null)
{
break;
}
WaitSyncStatus syncResult = GL.ClientWaitSync(first.Handle, _syncFlags, 0); WaitSyncStatus syncResult = GL.ClientWaitSync(first.Handle, SyncFlags, 0);
if (syncResult == WaitSyncStatus.AlreadySignaled) if (syncResult == WaitSyncStatus.AlreadySignaled)
{ {
@ -140,7 +143,8 @@ namespace Ryujinx.Graphics.OpenGL
first.Handle = IntPtr.Zero; first.Handle = IntPtr.Zero;
} }
} }
} else }
else
{ {
// This sync handle and any following have not been reached yet. // This sync handle and any following have not been reached yet.
break; break;

View File

@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.OpenGL
private uint _vertexBuffersLimited; private uint _vertexBuffersLimited;
private BufferRange _indexBuffer; private BufferRange _indexBuffer;
private BufferHandle _tempIndexBuffer; private readonly BufferHandle _tempIndexBuffer;
private BufferHandle _tempVertexBuffer; private BufferHandle _tempVertexBuffer;
private int _tempVertexBufferSize; private int _tempVertexBufferSize;
@ -102,7 +102,7 @@ namespace Ryujinx.Graphics.OpenGL
} }
int offset = attrib.Offset; int offset = attrib.Offset;
int size = fmtInfo.Components; int size = fmtInfo.Components;
bool isFloat = fmtInfo.PixelType == PixelType.Float || bool isFloat = fmtInfo.PixelType == PixelType.Float ||
fmtInfo.PixelType == PixelType.HalfFloat; fmtInfo.PixelType == PixelType.HalfFloat;

View File

@ -375,7 +375,7 @@ namespace Ryujinx.Graphics.OpenGL
if (_scalingFilter is not FsrScalingFilter) if (_scalingFilter is not FsrScalingFilter)
{ {
_scalingFilter?.Dispose(); _scalingFilter?.Dispose();
_scalingFilter = new FsrScalingFilter(_renderer, _antiAliasing); _scalingFilter = new FsrScalingFilter(_renderer);
} }
_isLinear = false; _isLinear = false;
_scalingFilter.Level = _scalingFilterLevel; _scalingFilter.Level = _scalingFilterLevel;
@ -417,4 +417,4 @@ namespace Ryujinx.Graphics.OpenGL
_updateScalingFilter = true; _updateScalingFilter = true;
} }
} }
} }

View File

@ -10,15 +10,15 @@ namespace Ryujinx.Input.Assigner
/// </summary> /// </summary>
public class GamepadButtonAssigner : IButtonAssigner public class GamepadButtonAssigner : IButtonAssigner
{ {
private IGamepad _gamepad; private readonly IGamepad _gamepad;
private GamepadStateSnapshot _currState; private GamepadStateSnapshot _currState;
private GamepadStateSnapshot _prevState; private GamepadStateSnapshot _prevState;
private JoystickButtonDetector _detector; private readonly JoystickButtonDetector _detector;
private bool _forStick; private readonly bool _forStick;
public GamepadButtonAssigner(IGamepad gamepad, float triggerThreshold, bool forStick) public GamepadButtonAssigner(IGamepad gamepad, float triggerThreshold, bool forStick)
{ {
@ -35,7 +35,7 @@ namespace Ryujinx.Input.Assigner
{ {
_currState = _gamepad.GetStateSnapshot(); _currState = _gamepad.GetStateSnapshot();
_prevState = _currState; _prevState = _currState;
} }
} }
public void ReadInput() public void ReadInput()
@ -116,7 +116,7 @@ namespace Ryujinx.Input.Assigner
private class JoystickButtonDetector private class JoystickButtonDetector
{ {
private Dictionary<GamepadButtonInputId, InputSummary> _stats; private readonly Dictionary<GamepadButtonInputId, InputSummary> _stats;
public JoystickButtonDetector() public JoystickButtonDetector()
{ {
@ -135,9 +135,8 @@ namespace Ryujinx.Input.Assigner
public void AddInput(GamepadButtonInputId button, float value) public void AddInput(GamepadButtonInputId button, float value)
{ {
InputSummary inputSummary;
if (!_stats.TryGetValue(button, out inputSummary)) if (!_stats.TryGetValue(button, out InputSummary inputSummary))
{ {
inputSummary = new InputSummary(); inputSummary = new InputSummary();
_stats.Add(button, inputSummary); _stats.Add(button, inputSummary);
@ -148,7 +147,7 @@ namespace Ryujinx.Input.Assigner
public override string ToString() public override string ToString()
{ {
StringWriter writer = new StringWriter(); StringWriter writer = new();
foreach (var kvp in _stats) foreach (var kvp in _stats)
{ {

View File

@ -33,4 +33,4 @@ namespace Ryujinx.Input.Assigner
/// <returns>The pressed button that was read</returns> /// <returns>The pressed button that was read</returns>
string GetPressedButton(); string GetPressedButton();
} }
} }

View File

@ -5,7 +5,7 @@ namespace Ryujinx.Input.Assigner
/// </summary> /// </summary>
public class KeyboardKeyAssigner : IButtonAssigner public class KeyboardKeyAssigner : IButtonAssigner
{ {
private IKeyboard _keyboard; private readonly IKeyboard _keyboard;
private KeyboardStateSnapshot _keyboardState; private KeyboardStateSnapshot _keyboardState;
@ -47,4 +47,4 @@ namespace Ryujinx.Input.Assigner
return !ShouldCancel() ? keyPressed : ""; return !ShouldCancel() ? keyPressed : "";
} }
} }
} }

View File

@ -52,6 +52,6 @@
SingleLeftTrigger1, SingleLeftTrigger1,
SingleRightTrigger1, SingleRightTrigger1,
Count Count,
} }
} }

View File

@ -23,6 +23,6 @@ namespace Ryujinx.Input
/// Motion /// Motion
/// <remarks>Also named sixaxis</remarks> /// <remarks>Also named sixaxis</remarks>
/// </summary> /// </summary>
Motion Motion,
} }
} }

View File

@ -25,7 +25,7 @@ namespace Ryujinx.Input.HLE
{ {
return new NpadManager(KeyboardDriver, GamepadDriver, MouseDriver); return new NpadManager(KeyboardDriver, GamepadDriver, MouseDriver);
} }
public TouchScreenManager CreateTouchScreenManager() public TouchScreenManager CreateTouchScreenManager()
{ {
if (MouseDriver == null) if (MouseDriver == null)
@ -48,6 +48,7 @@ namespace Ryujinx.Input.HLE
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
Dispose(true); Dispose(true);
} }
} }

View File

@ -8,7 +8,6 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using CemuHookClient = Ryujinx.Input.Motion.CemuHook.Client; using CemuHookClient = Ryujinx.Input.Motion.CemuHook.Client;
using ConfigControllerType = Ryujinx.Common.Configuration.Hid.ControllerType; using ConfigControllerType = Ryujinx.Common.Configuration.Hid.ControllerType;
@ -28,29 +27,28 @@ namespace Ryujinx.Input.HLE
} }
} }
private static readonly HLEButtonMappingEntry[] _hleButtonMapping = new HLEButtonMappingEntry[] private static readonly HLEButtonMappingEntry[] _hleButtonMapping = {
{ new(GamepadButtonInputId.A, ControllerKeys.A),
new HLEButtonMappingEntry(GamepadButtonInputId.A, ControllerKeys.A), new(GamepadButtonInputId.B, ControllerKeys.B),
new HLEButtonMappingEntry(GamepadButtonInputId.B, ControllerKeys.B), new(GamepadButtonInputId.X, ControllerKeys.X),
new HLEButtonMappingEntry(GamepadButtonInputId.X, ControllerKeys.X), new(GamepadButtonInputId.Y, ControllerKeys.Y),
new HLEButtonMappingEntry(GamepadButtonInputId.Y, ControllerKeys.Y), new(GamepadButtonInputId.LeftStick, ControllerKeys.LStick),
new HLEButtonMappingEntry(GamepadButtonInputId.LeftStick, ControllerKeys.LStick), new(GamepadButtonInputId.RightStick, ControllerKeys.RStick),
new HLEButtonMappingEntry(GamepadButtonInputId.RightStick, ControllerKeys.RStick), new(GamepadButtonInputId.LeftShoulder, ControllerKeys.L),
new HLEButtonMappingEntry(GamepadButtonInputId.LeftShoulder, ControllerKeys.L), new(GamepadButtonInputId.RightShoulder, ControllerKeys.R),
new HLEButtonMappingEntry(GamepadButtonInputId.RightShoulder, ControllerKeys.R), new(GamepadButtonInputId.LeftTrigger, ControllerKeys.Zl),
new HLEButtonMappingEntry(GamepadButtonInputId.LeftTrigger, ControllerKeys.Zl), new(GamepadButtonInputId.RightTrigger, ControllerKeys.Zr),
new HLEButtonMappingEntry(GamepadButtonInputId.RightTrigger, ControllerKeys.Zr), new(GamepadButtonInputId.DpadUp, ControllerKeys.DpadUp),
new HLEButtonMappingEntry(GamepadButtonInputId.DpadUp, ControllerKeys.DpadUp), new(GamepadButtonInputId.DpadDown, ControllerKeys.DpadDown),
new HLEButtonMappingEntry(GamepadButtonInputId.DpadDown, ControllerKeys.DpadDown), new(GamepadButtonInputId.DpadLeft, ControllerKeys.DpadLeft),
new HLEButtonMappingEntry(GamepadButtonInputId.DpadLeft, ControllerKeys.DpadLeft), new(GamepadButtonInputId.DpadRight, ControllerKeys.DpadRight),
new HLEButtonMappingEntry(GamepadButtonInputId.DpadRight, ControllerKeys.DpadRight), new(GamepadButtonInputId.Minus, ControllerKeys.Minus),
new HLEButtonMappingEntry(GamepadButtonInputId.Minus, ControllerKeys.Minus), new(GamepadButtonInputId.Plus, ControllerKeys.Plus),
new HLEButtonMappingEntry(GamepadButtonInputId.Plus, ControllerKeys.Plus),
new HLEButtonMappingEntry(GamepadButtonInputId.SingleLeftTrigger0, ControllerKeys.SlLeft), new(GamepadButtonInputId.SingleLeftTrigger0, ControllerKeys.SlLeft),
new HLEButtonMappingEntry(GamepadButtonInputId.SingleRightTrigger0, ControllerKeys.SrLeft), new(GamepadButtonInputId.SingleRightTrigger0, ControllerKeys.SrLeft),
new HLEButtonMappingEntry(GamepadButtonInputId.SingleLeftTrigger1, ControllerKeys.SlRight), new(GamepadButtonInputId.SingleLeftTrigger1, ControllerKeys.SlRight),
new HLEButtonMappingEntry(GamepadButtonInputId.SingleRightTrigger1, ControllerKeys.SrRight), new(GamepadButtonInputId.SingleRightTrigger1, ControllerKeys.SrRight),
}; };
private class HLEKeyboardMappingEntry private class HLEKeyboardMappingEntry
@ -65,150 +63,147 @@ namespace Ryujinx.Input.HLE
} }
} }
private static readonly HLEKeyboardMappingEntry[] KeyMapping = new HLEKeyboardMappingEntry[] private static readonly HLEKeyboardMappingEntry[] _keyMapping = {
{ new(Key.A, 0x4),
new HLEKeyboardMappingEntry(Key.A, 0x4), new(Key.B, 0x5),
new HLEKeyboardMappingEntry(Key.B, 0x5), new(Key.C, 0x6),
new HLEKeyboardMappingEntry(Key.C, 0x6), new(Key.D, 0x7),
new HLEKeyboardMappingEntry(Key.D, 0x7), new(Key.E, 0x8),
new HLEKeyboardMappingEntry(Key.E, 0x8), new(Key.F, 0x9),
new HLEKeyboardMappingEntry(Key.F, 0x9), new(Key.G, 0xA),
new HLEKeyboardMappingEntry(Key.G, 0xA), new(Key.H, 0xB),
new HLEKeyboardMappingEntry(Key.H, 0xB), new(Key.I, 0xC),
new HLEKeyboardMappingEntry(Key.I, 0xC), new(Key.J, 0xD),
new HLEKeyboardMappingEntry(Key.J, 0xD), new(Key.K, 0xE),
new HLEKeyboardMappingEntry(Key.K, 0xE), new(Key.L, 0xF),
new HLEKeyboardMappingEntry(Key.L, 0xF), new(Key.M, 0x10),
new HLEKeyboardMappingEntry(Key.M, 0x10), new(Key.N, 0x11),
new HLEKeyboardMappingEntry(Key.N, 0x11), new(Key.O, 0x12),
new HLEKeyboardMappingEntry(Key.O, 0x12), new(Key.P, 0x13),
new HLEKeyboardMappingEntry(Key.P, 0x13), new(Key.Q, 0x14),
new HLEKeyboardMappingEntry(Key.Q, 0x14), new(Key.R, 0x15),
new HLEKeyboardMappingEntry(Key.R, 0x15), new(Key.S, 0x16),
new HLEKeyboardMappingEntry(Key.S, 0x16), new(Key.T, 0x17),
new HLEKeyboardMappingEntry(Key.T, 0x17), new(Key.U, 0x18),
new HLEKeyboardMappingEntry(Key.U, 0x18), new(Key.V, 0x19),
new HLEKeyboardMappingEntry(Key.V, 0x19), new(Key.W, 0x1A),
new HLEKeyboardMappingEntry(Key.W, 0x1A), new(Key.X, 0x1B),
new HLEKeyboardMappingEntry(Key.X, 0x1B), new(Key.Y, 0x1C),
new HLEKeyboardMappingEntry(Key.Y, 0x1C), new(Key.Z, 0x1D),
new HLEKeyboardMappingEntry(Key.Z, 0x1D),
new HLEKeyboardMappingEntry(Key.Number1, 0x1E), new(Key.Number1, 0x1E),
new HLEKeyboardMappingEntry(Key.Number2, 0x1F), new(Key.Number2, 0x1F),
new HLEKeyboardMappingEntry(Key.Number3, 0x20), new(Key.Number3, 0x20),
new HLEKeyboardMappingEntry(Key.Number4, 0x21), new(Key.Number4, 0x21),
new HLEKeyboardMappingEntry(Key.Number5, 0x22), new(Key.Number5, 0x22),
new HLEKeyboardMappingEntry(Key.Number6, 0x23), new(Key.Number6, 0x23),
new HLEKeyboardMappingEntry(Key.Number7, 0x24), new(Key.Number7, 0x24),
new HLEKeyboardMappingEntry(Key.Number8, 0x25), new(Key.Number8, 0x25),
new HLEKeyboardMappingEntry(Key.Number9, 0x26), new(Key.Number9, 0x26),
new HLEKeyboardMappingEntry(Key.Number0, 0x27), new(Key.Number0, 0x27),
new HLEKeyboardMappingEntry(Key.Enter, 0x28), new(Key.Enter, 0x28),
new HLEKeyboardMappingEntry(Key.Escape, 0x29), new(Key.Escape, 0x29),
new HLEKeyboardMappingEntry(Key.BackSpace, 0x2A), new(Key.BackSpace, 0x2A),
new HLEKeyboardMappingEntry(Key.Tab, 0x2B), new(Key.Tab, 0x2B),
new HLEKeyboardMappingEntry(Key.Space, 0x2C), new(Key.Space, 0x2C),
new HLEKeyboardMappingEntry(Key.Minus, 0x2D), new(Key.Minus, 0x2D),
new HLEKeyboardMappingEntry(Key.Plus, 0x2E), new(Key.Plus, 0x2E),
new HLEKeyboardMappingEntry(Key.BracketLeft, 0x2F), new(Key.BracketLeft, 0x2F),
new HLEKeyboardMappingEntry(Key.BracketRight, 0x30), new(Key.BracketRight, 0x30),
new HLEKeyboardMappingEntry(Key.BackSlash, 0x31), new(Key.BackSlash, 0x31),
new HLEKeyboardMappingEntry(Key.Tilde, 0x32), new(Key.Tilde, 0x32),
new HLEKeyboardMappingEntry(Key.Semicolon, 0x33), new(Key.Semicolon, 0x33),
new HLEKeyboardMappingEntry(Key.Quote, 0x34), new(Key.Quote, 0x34),
new HLEKeyboardMappingEntry(Key.Grave, 0x35), new(Key.Grave, 0x35),
new HLEKeyboardMappingEntry(Key.Comma, 0x36), new(Key.Comma, 0x36),
new HLEKeyboardMappingEntry(Key.Period, 0x37), new(Key.Period, 0x37),
new HLEKeyboardMappingEntry(Key.Slash, 0x38), new(Key.Slash, 0x38),
new HLEKeyboardMappingEntry(Key.CapsLock, 0x39), new(Key.CapsLock, 0x39),
new HLEKeyboardMappingEntry(Key.F1, 0x3a), new(Key.F1, 0x3a),
new HLEKeyboardMappingEntry(Key.F2, 0x3b), new(Key.F2, 0x3b),
new HLEKeyboardMappingEntry(Key.F3, 0x3c), new(Key.F3, 0x3c),
new HLEKeyboardMappingEntry(Key.F4, 0x3d), new(Key.F4, 0x3d),
new HLEKeyboardMappingEntry(Key.F5, 0x3e), new(Key.F5, 0x3e),
new HLEKeyboardMappingEntry(Key.F6, 0x3f), new(Key.F6, 0x3f),
new HLEKeyboardMappingEntry(Key.F7, 0x40), new(Key.F7, 0x40),
new HLEKeyboardMappingEntry(Key.F8, 0x41), new(Key.F8, 0x41),
new HLEKeyboardMappingEntry(Key.F9, 0x42), new(Key.F9, 0x42),
new HLEKeyboardMappingEntry(Key.F10, 0x43), new(Key.F10, 0x43),
new HLEKeyboardMappingEntry(Key.F11, 0x44), new(Key.F11, 0x44),
new HLEKeyboardMappingEntry(Key.F12, 0x45), new(Key.F12, 0x45),
new HLEKeyboardMappingEntry(Key.PrintScreen, 0x46), new(Key.PrintScreen, 0x46),
new HLEKeyboardMappingEntry(Key.ScrollLock, 0x47), new(Key.ScrollLock, 0x47),
new HLEKeyboardMappingEntry(Key.Pause, 0x48), new(Key.Pause, 0x48),
new HLEKeyboardMappingEntry(Key.Insert, 0x49), new(Key.Insert, 0x49),
new HLEKeyboardMappingEntry(Key.Home, 0x4A), new(Key.Home, 0x4A),
new HLEKeyboardMappingEntry(Key.PageUp, 0x4B), new(Key.PageUp, 0x4B),
new HLEKeyboardMappingEntry(Key.Delete, 0x4C), new(Key.Delete, 0x4C),
new HLEKeyboardMappingEntry(Key.End, 0x4D), new(Key.End, 0x4D),
new HLEKeyboardMappingEntry(Key.PageDown, 0x4E), new(Key.PageDown, 0x4E),
new HLEKeyboardMappingEntry(Key.Right, 0x4F), new(Key.Right, 0x4F),
new HLEKeyboardMappingEntry(Key.Left, 0x50), new(Key.Left, 0x50),
new HLEKeyboardMappingEntry(Key.Down, 0x51), new(Key.Down, 0x51),
new HLEKeyboardMappingEntry(Key.Up, 0x52), new(Key.Up, 0x52),
new HLEKeyboardMappingEntry(Key.NumLock, 0x53), new(Key.NumLock, 0x53),
new HLEKeyboardMappingEntry(Key.KeypadDivide, 0x54), new(Key.KeypadDivide, 0x54),
new HLEKeyboardMappingEntry(Key.KeypadMultiply, 0x55), new(Key.KeypadMultiply, 0x55),
new HLEKeyboardMappingEntry(Key.KeypadSubtract, 0x56), new(Key.KeypadSubtract, 0x56),
new HLEKeyboardMappingEntry(Key.KeypadAdd, 0x57), new(Key.KeypadAdd, 0x57),
new HLEKeyboardMappingEntry(Key.KeypadEnter, 0x58), new(Key.KeypadEnter, 0x58),
new HLEKeyboardMappingEntry(Key.Keypad1, 0x59), new(Key.Keypad1, 0x59),
new HLEKeyboardMappingEntry(Key.Keypad2, 0x5A), new(Key.Keypad2, 0x5A),
new HLEKeyboardMappingEntry(Key.Keypad3, 0x5B), new(Key.Keypad3, 0x5B),
new HLEKeyboardMappingEntry(Key.Keypad4, 0x5C), new(Key.Keypad4, 0x5C),
new HLEKeyboardMappingEntry(Key.Keypad5, 0x5D), new(Key.Keypad5, 0x5D),
new HLEKeyboardMappingEntry(Key.Keypad6, 0x5E), new(Key.Keypad6, 0x5E),
new HLEKeyboardMappingEntry(Key.Keypad7, 0x5F), new(Key.Keypad7, 0x5F),
new HLEKeyboardMappingEntry(Key.Keypad8, 0x60), new(Key.Keypad8, 0x60),
new HLEKeyboardMappingEntry(Key.Keypad9, 0x61), new(Key.Keypad9, 0x61),
new HLEKeyboardMappingEntry(Key.Keypad0, 0x62), new(Key.Keypad0, 0x62),
new HLEKeyboardMappingEntry(Key.KeypadDecimal, 0x63), new(Key.KeypadDecimal, 0x63),
new HLEKeyboardMappingEntry(Key.F13, 0x68), new(Key.F13, 0x68),
new HLEKeyboardMappingEntry(Key.F14, 0x69), new(Key.F14, 0x69),
new HLEKeyboardMappingEntry(Key.F15, 0x6A), new(Key.F15, 0x6A),
new HLEKeyboardMappingEntry(Key.F16, 0x6B), new(Key.F16, 0x6B),
new HLEKeyboardMappingEntry(Key.F17, 0x6C), new(Key.F17, 0x6C),
new HLEKeyboardMappingEntry(Key.F18, 0x6D), new(Key.F18, 0x6D),
new HLEKeyboardMappingEntry(Key.F19, 0x6E), new(Key.F19, 0x6E),
new HLEKeyboardMappingEntry(Key.F20, 0x6F), new(Key.F20, 0x6F),
new HLEKeyboardMappingEntry(Key.F21, 0x70), new(Key.F21, 0x70),
new HLEKeyboardMappingEntry(Key.F22, 0x71), new(Key.F22, 0x71),
new HLEKeyboardMappingEntry(Key.F23, 0x72), new(Key.F23, 0x72),
new HLEKeyboardMappingEntry(Key.F24, 0x73), new(Key.F24, 0x73),
new HLEKeyboardMappingEntry(Key.ControlLeft, 0xE0), new(Key.ControlLeft, 0xE0),
new HLEKeyboardMappingEntry(Key.ShiftLeft, 0xE1), new(Key.ShiftLeft, 0xE1),
new HLEKeyboardMappingEntry(Key.AltLeft, 0xE2), new(Key.AltLeft, 0xE2),
new HLEKeyboardMappingEntry(Key.WinLeft, 0xE3), new(Key.WinLeft, 0xE3),
new HLEKeyboardMappingEntry(Key.ControlRight, 0xE4), new(Key.ControlRight, 0xE4),
new HLEKeyboardMappingEntry(Key.ShiftRight, 0xE5), new(Key.ShiftRight, 0xE5),
new HLEKeyboardMappingEntry(Key.AltRight, 0xE6), new(Key.AltRight, 0xE6),
new HLEKeyboardMappingEntry(Key.WinRight, 0xE7), new(Key.WinRight, 0xE7),
}; };
private static readonly HLEKeyboardMappingEntry[] KeyModifierMapping = new HLEKeyboardMappingEntry[] private static readonly HLEKeyboardMappingEntry[] _keyModifierMapping = {
{ new(Key.ControlLeft, 0),
new HLEKeyboardMappingEntry(Key.ControlLeft, 0), new(Key.ShiftLeft, 1),
new HLEKeyboardMappingEntry(Key.ShiftLeft, 1), new(Key.AltLeft, 2),
new HLEKeyboardMappingEntry(Key.AltLeft, 2), new(Key.WinLeft, 3),
new HLEKeyboardMappingEntry(Key.WinLeft, 3), new(Key.ControlRight, 4),
new HLEKeyboardMappingEntry(Key.ControlRight, 4), new(Key.ShiftRight, 5),
new HLEKeyboardMappingEntry(Key.ShiftRight, 5), new(Key.AltRight, 6),
new HLEKeyboardMappingEntry(Key.AltRight, 6), new(Key.WinRight, 7),
new HLEKeyboardMappingEntry(Key.WinRight, 7), new(Key.CapsLock, 8),
new HLEKeyboardMappingEntry(Key.CapsLock, 8), new(Key.ScrollLock, 9),
new HLEKeyboardMappingEntry(Key.ScrollLock, 9), new(Key.NumLock, 10),
new HLEKeyboardMappingEntry(Key.NumLock, 10),
}; };
private bool _isValid; private bool _isValid;
private string _id;
private MotionInput _leftMotionInput; private MotionInput _leftMotionInput;
private MotionInput _rightMotionInput; private MotionInput _rightMotionInput;
@ -219,14 +214,14 @@ namespace Ryujinx.Input.HLE
public IGamepadDriver GamepadDriver { get; private set; } public IGamepadDriver GamepadDriver { get; private set; }
public GamepadStateSnapshot State { get; private set; } public GamepadStateSnapshot State { get; private set; }
public string Id => _id; public string Id { get; private set; }
private CemuHookClient _cemuHookClient; private readonly CemuHookClient _cemuHookClient;
public NpadController(CemuHookClient cemuHookClient) public NpadController(CemuHookClient cemuHookClient)
{ {
State = default; State = default;
_id = null; Id = null;
_isValid = false; _isValid = false;
_cemuHookClient = cemuHookClient; _cemuHookClient = cemuHookClient;
} }
@ -237,8 +232,8 @@ namespace Ryujinx.Input.HLE
_gamepad?.Dispose(); _gamepad?.Dispose();
_id = config.Id; Id = config.Id;
_gamepad = GamepadDriver.GetGamepad(_id); _gamepad = GamepadDriver.GetGamepad(Id);
_isValid = _gamepad != null; _isValid = _gamepad != null;
UpdateUserConfiguration(config); UpdateUserConfiguration(config);
@ -278,7 +273,7 @@ namespace Ryujinx.Input.HLE
if (motionConfig.MotionBackend != MotionInputBackendType.CemuHook) if (motionConfig.MotionBackend != MotionInputBackendType.CemuHook)
{ {
_leftMotionInput = new MotionInput(); _leftMotionInput = new MotionInput();
} }
else else
{ {
_leftMotionInput = null; _leftMotionInput = null;
@ -347,7 +342,7 @@ namespace Ryujinx.Input.HLE
public GamepadInput GetHLEInputState() public GamepadInput GetHLEInputState()
{ {
GamepadInput state = new GamepadInput(); GamepadInput state = new();
// First update all buttons // First update all buttons
foreach (HLEButtonMappingEntry entry in _hleButtonMapping) foreach (HLEButtonMappingEntry entry in _hleButtonMapping)
@ -366,13 +361,13 @@ namespace Ryujinx.Input.HLE
state.LStick = new JoystickPosition state.LStick = new JoystickPosition
{ {
Dx = ClampAxis(leftAxisX), Dx = ClampAxis(leftAxisX),
Dy = ClampAxis(leftAxisY) Dy = ClampAxis(leftAxisY),
}; };
state.RStick = new JoystickPosition state.RStick = new JoystickPosition
{ {
Dx = ClampAxis(rightAxisX), Dx = ClampAxis(rightAxisX),
Dy = ClampAxis(rightAxisY) Dy = ClampAxis(rightAxisY),
}; };
} }
else if (_config is StandardControllerInputConfig controllerConfig) else if (_config is StandardControllerInputConfig controllerConfig)
@ -391,16 +386,16 @@ namespace Ryujinx.Input.HLE
private static JoystickPosition ApplyDeadzone(float x, float y, float deadzone) private static JoystickPosition ApplyDeadzone(float x, float y, float deadzone)
{ {
float magnitudeClamped = Math.Min(MathF.Sqrt(x * x + y * y), 1f); float magnitudeClamped = Math.Min(MathF.Sqrt(x * x + y * y), 1f);
if (magnitudeClamped <= deadzone) if (magnitudeClamped <= deadzone)
{ {
return new JoystickPosition() {Dx = 0, Dy = 0}; return new JoystickPosition { Dx = 0, Dy = 0 };
} }
return new JoystickPosition() return new JoystickPosition
{ {
Dx = ClampAxis((x / magnitudeClamped) * ((magnitudeClamped - deadzone) / (1 - deadzone))), Dx = ClampAxis((x / magnitudeClamped) * ((magnitudeClamped - deadzone) / (1 - deadzone))),
Dy = ClampAxis((y / magnitudeClamped) * ((magnitudeClamped - deadzone) / (1 - deadzone))) Dy = ClampAxis((y / magnitudeClamped) * ((magnitudeClamped - deadzone) / (1 - deadzone))),
}; };
} }
@ -428,7 +423,7 @@ namespace Ryujinx.Input.HLE
return new JoystickPosition return new JoystickPosition
{ {
Dx = (int)point.X, Dx = (int)point.X,
Dy = (int)point.Y Dy = (int)point.Y,
}; };
} }
@ -476,12 +471,12 @@ namespace Ryujinx.Input.HLE
rotation = new Vector3(); rotation = new Vector3();
} }
return new SixAxisInput() return new SixAxisInput
{ {
Accelerometer = accelerometer, Accelerometer = accelerometer,
Gyroscope = gyroscope, Gyroscope = gyroscope,
Rotation = rotation, Rotation = rotation,
Orientation = orientationForHLE Orientation = orientationForHLE,
}; };
} }
@ -502,20 +497,20 @@ namespace Ryujinx.Input.HLE
{ {
KeyboardStateSnapshot keyboardState = keyboard.GetKeyboardStateSnapshot(); KeyboardStateSnapshot keyboardState = keyboard.GetKeyboardStateSnapshot();
KeyboardInput hidKeyboard = new KeyboardInput KeyboardInput hidKeyboard = new()
{ {
Modifier = 0, Modifier = 0,
Keys = new ulong[0x4] Keys = new ulong[0x4],
}; };
foreach (HLEKeyboardMappingEntry entry in KeyMapping) foreach (HLEKeyboardMappingEntry entry in _keyMapping)
{ {
ulong value = keyboardState.IsPressed(entry.TargetKey) ? 1UL : 0UL; ulong value = keyboardState.IsPressed(entry.TargetKey) ? 1UL : 0UL;
hidKeyboard.Keys[entry.Target / 0x40] |= (value << (entry.Target % 0x40)); hidKeyboard.Keys[entry.Target / 0x40] |= (value << (entry.Target % 0x40));
} }
foreach (HLEKeyboardMappingEntry entry in KeyModifierMapping) foreach (HLEKeyboardMappingEntry entry in _keyModifierMapping)
{ {
int value = keyboardState.IsPressed(entry.TargetKey) ? 1 : 0; int value = keyboardState.IsPressed(entry.TargetKey) ? 1 : 0;
@ -539,6 +534,7 @@ namespace Ryujinx.Input.HLE
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
Dispose(true); Dispose(true);
} }

View File

@ -7,13 +7,15 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using CemuHookClient = Ryujinx.Input.Motion.CemuHook.Client; using CemuHookClient = Ryujinx.Input.Motion.CemuHook.Client;
using ControllerType = Ryujinx.Common.Configuration.Hid.ControllerType;
using PlayerIndex = Ryujinx.HLE.HOS.Services.Hid.PlayerIndex;
using Switch = Ryujinx.HLE.Switch; using Switch = Ryujinx.HLE.Switch;
namespace Ryujinx.Input.HLE namespace Ryujinx.Input.HLE
{ {
public class NpadManager : IDisposable public class NpadManager : IDisposable
{ {
private CemuHookClient _cemuHookClient; private readonly CemuHookClient _cemuHookClient;
private readonly object _lock = new(); private readonly object _lock = new();
@ -21,7 +23,7 @@ namespace Ryujinx.Input.HLE
private const int MaxControllers = 9; private const int MaxControllers = 9;
private NpadController[] _controllers; private readonly NpadController[] _controllers;
private readonly IGamepadDriver _keyboardDriver; private readonly IGamepadDriver _keyboardDriver;
private readonly IGamepadDriver _gamepadDriver; private readonly IGamepadDriver _gamepadDriver;
@ -51,7 +53,7 @@ namespace Ryujinx.Input.HLE
{ {
lock (_lock) lock (_lock)
{ {
List<InputConfig> validInputs = new List<InputConfig>(); List<InputConfig> validInputs = new();
foreach (var inputConfigEntry in _inputConfig) foreach (var inputConfigEntry in _inputConfig)
{ {
if (_controllers[(int)inputConfigEntry.PlayerIndex] != null) if (_controllers[(int)inputConfigEntry.PlayerIndex] != null)
@ -96,10 +98,8 @@ namespace Ryujinx.Input.HLE
{ {
return controller.UpdateDriverConfiguration(targetDriver, config); return controller.UpdateDriverConfiguration(targetDriver, config);
} }
else
{ return controller.GamepadDriver != null;
return controller.GamepadDriver != null;
}
} }
public void ReloadConfiguration(List<InputConfig> inputConfig, bool enableKeyboard, bool enableMouse) public void ReloadConfiguration(List<InputConfig> inputConfig, bool enableKeyboard, bool enableMouse)
@ -112,11 +112,11 @@ namespace Ryujinx.Input.HLE
_controllers[i] = null; _controllers[i] = null;
} }
List<InputConfig> validInputs = new List<InputConfig>(); List<InputConfig> validInputs = new();
foreach (InputConfig inputConfigEntry in inputConfig) foreach (InputConfig inputConfigEntry in inputConfig)
{ {
NpadController controller = new NpadController(_cemuHookClient); NpadController controller = new(_cemuHookClient);
bool isValid = DriverConfigurationUpdate(ref controller, inputConfigEntry); bool isValid = DriverConfigurationUpdate(ref controller, inputConfigEntry);
@ -131,9 +131,9 @@ namespace Ryujinx.Input.HLE
} }
} }
_inputConfig = inputConfig; _inputConfig = inputConfig;
_enableKeyboard = enableKeyboard; _enableKeyboard = enableKeyboard;
_enableMouse = enableMouse; _enableMouse = enableMouse;
_device.Hid.RefreshInputConfig(validInputs); _device.Hid.RefreshInputConfig(validInputs);
} }
@ -167,8 +167,8 @@ namespace Ryujinx.Input.HLE
{ {
lock (_lock) lock (_lock)
{ {
List<GamepadInput> hleInputStates = new List<GamepadInput>(); List<GamepadInput> hleInputStates = new();
List<SixAxisInput> hleMotionStates = new List<SixAxisInput>(NpadDevices.MaxControllers); List<SixAxisInput> hleMotionStates = new(NpadDevices.MaxControllers);
KeyboardInput? hleKeyboardInput = null; KeyboardInput? hleKeyboardInput = null;
@ -178,7 +178,7 @@ namespace Ryujinx.Input.HLE
(SixAxisInput, SixAxisInput) motionState = default; (SixAxisInput, SixAxisInput) motionState = default;
NpadController controller = _controllers[(int)inputConfig.PlayerIndex]; NpadController controller = _controllers[(int)inputConfig.PlayerIndex];
Ryujinx.HLE.HOS.Services.Hid.PlayerIndex playerIndex = (Ryujinx.HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex; PlayerIndex playerIndex = (PlayerIndex)inputConfig.PlayerIndex;
bool isJoyconPair = false; bool isJoyconPair = false;
@ -195,7 +195,7 @@ namespace Ryujinx.Input.HLE
inputState.Buttons |= _device.Hid.UpdateStickButtons(inputState.LStick, inputState.RStick); inputState.Buttons |= _device.Hid.UpdateStickButtons(inputState.LStick, inputState.RStick);
isJoyconPair = inputConfig.ControllerType == Common.Configuration.Hid.ControllerType.JoyconPair; isJoyconPair = inputConfig.ControllerType == ControllerType.JoyconPair;
var altMotionState = isJoyconPair ? controller.GetHLEMotionState(true) : default; var altMotionState = isJoyconPair ? controller.GetHLEMotionState(true) : default;
@ -284,7 +284,7 @@ namespace Ryujinx.Input.HLE
{ {
lock (_lock) lock (_lock)
{ {
return _inputConfig.Find(x => x.PlayerIndex == (Ryujinx.Common.Configuration.Hid.PlayerIndex)index); return _inputConfig.Find(x => x.PlayerIndex == (Common.Configuration.Hid.PlayerIndex)index);
} }
} }
@ -314,6 +314,7 @@ namespace Ryujinx.Input.HLE
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
Dispose(true); Dispose(true);
} }
} }

View File

@ -31,7 +31,7 @@ namespace Ryujinx.Input.HLE
MouseStateSnapshot snapshot = IMouse.GetMouseStateSnapshot(_mouse); MouseStateSnapshot snapshot = IMouse.GetMouseStateSnapshot(_mouse);
var touchPosition = IMouse.GetScreenPosition(snapshot.Position, _mouse.ClientSize, aspectRatio); var touchPosition = IMouse.GetScreenPosition(snapshot.Position, _mouse.ClientSize, aspectRatio);
TouchPoint currentPoint = new TouchPoint TouchPoint currentPoint = new()
{ {
Attribute = TouchAttribute.End, Attribute = TouchAttribute.End,
@ -41,7 +41,7 @@ namespace Ryujinx.Input.HLE
// Placeholder values till more data is acquired // Placeholder values till more data is acquired
DiameterX = 10, DiameterX = 10,
DiameterY = 10, DiameterY = 10,
Angle = 90 Angle = 90,
}; };
_device.Hid.Touchscreen.Update(currentPoint); _device.Hid.Touchscreen.Update(currentPoint);
@ -71,7 +71,7 @@ namespace Ryujinx.Input.HLE
attribute = TouchAttribute.End; attribute = TouchAttribute.End;
} }
TouchPoint currentPoint = new TouchPoint TouchPoint currentPoint = new()
{ {
Attribute = attribute, Attribute = attribute,
@ -81,7 +81,7 @@ namespace Ryujinx.Input.HLE
// Placeholder values till more data is acquired // Placeholder values till more data is acquired
DiameterX = 10, DiameterX = 10,
DiameterY = 10, DiameterY = 10,
Angle = 90 Angle = 90,
}; };
_device.Hid.Touchscreen.Update(currentPoint); _device.Hid.Touchscreen.Update(currentPoint);
@ -94,6 +94,9 @@ namespace Ryujinx.Input.HLE
return false; return false;
} }
public void Dispose() { } public void Dispose()
{
GC.SuppressFinalize(this);
}
} }
} }

View File

@ -8,7 +8,9 @@ namespace Ryujinx.Input
/// </summary> /// </summary>
public interface IMouse : IGamepad public interface IMouse : IGamepad
{ {
#pragma warning disable IDE0051 // Remove unused private member
private const int SwitchPanelWidth = 1280; private const int SwitchPanelWidth = 1280;
#pragma warning restore IDE0051
private const int SwitchPanelHeight = 720; private const int SwitchPanelHeight = 720;
/// <summary> /// <summary>
@ -101,4 +103,4 @@ namespace Ryujinx.Input
return new Vector2(); return new Vector2();
} }
} }
} }

View File

@ -137,6 +137,6 @@
BackSlash, BackSlash,
Unbound, Unbound,
Count Count,
} }
} }

View File

@ -7,7 +7,7 @@ namespace Ryujinx.Input
/// </summary> /// </summary>
public class KeyboardStateSnapshot public class KeyboardStateSnapshot
{ {
private bool[] _keysState; private readonly bool[] _keysState;
/// <summary> /// <summary>
/// Create a new <see cref="KeyboardStateSnapshot"/>. /// Create a new <see cref="KeyboardStateSnapshot"/>.

View File

@ -19,7 +19,7 @@ namespace Ryujinx.Input.Motion.CemuHook
{ {
public class Client : IDisposable public class Client : IDisposable
{ {
public const uint Magic = 0x43555344; // DSUC public const uint Magic = 0x43555344; // DSUC
public const ushort Version = 1001; public const ushort Version = 1001;
private bool _active; private bool _active;
@ -29,15 +29,15 @@ namespace Ryujinx.Input.Motion.CemuHook
private readonly Dictionary<int, UdpClient> _clients; private readonly Dictionary<int, UdpClient> _clients;
private readonly bool[] _clientErrorStatus = new bool[Enum.GetValues<PlayerIndex>().Length]; private readonly bool[] _clientErrorStatus = new bool[Enum.GetValues<PlayerIndex>().Length];
private readonly long[] _clientRetryTimer = new long[Enum.GetValues<PlayerIndex>().Length]; private readonly long[] _clientRetryTimer = new long[Enum.GetValues<PlayerIndex>().Length];
private NpadManager _npadManager; private readonly NpadManager _npadManager;
public Client(NpadManager npadManager) public Client(NpadManager npadManager)
{ {
_npadManager = npadManager; _npadManager = npadManager;
_hosts = new Dictionary<int, IPEndPoint>(); _hosts = new Dictionary<int, IPEndPoint>();
_motionData = new Dictionary<int, Dictionary<int, MotionInput>>(); _motionData = new Dictionary<int, Dictionary<int, MotionInput>>();
_clients = new Dictionary<int, UdpClient>(); _clients = new Dictionary<int, UdpClient>();
CloseClients(); CloseClients();
} }
@ -84,7 +84,7 @@ namespace Ryujinx.Input.Motion.CemuHook
try try
{ {
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(host), port); IPEndPoint endPoint = new(IPAddress.Parse(host), port);
client = new UdpClient(host, port); client = new UdpClient(host, port);
@ -141,9 +141,9 @@ namespace Ryujinx.Input.Motion.CemuHook
{ {
lock (_motionData) lock (_motionData)
{ {
if (_motionData.ContainsKey(player)) if (_motionData.TryGetValue(player, out Dictionary<int, MotionInput> value))
{ {
if (_motionData[player].TryGetValue(slot, out input)) if (value.TryGetValue(slot, out input))
{ {
return true; return true;
} }
@ -164,26 +164,26 @@ namespace Ryujinx.Input.Motion.CemuHook
private void Send(byte[] data, int clientId) private void Send(byte[] data, int clientId)
{ {
if (_clients.TryGetValue(clientId, out UdpClient _client)) if (_clients.TryGetValue(clientId, out UdpClient client))
{ {
if (_client != null && _client.Client != null && _client.Client.Connected) if (client != null && client.Client != null && client.Client.Connected)
{ {
try try
{ {
_client?.Send(data, data.Length); client?.Send(data, data.Length);
} }
catch (SocketException socketException) catch (SocketException socketException)
{ {
if (!_clientErrorStatus[clientId]) if (!_clientErrorStatus[clientId])
{ {
Logger.Warning?.PrintMsg(LogClass.Hid, $"Unable to send data request to motion source at {_client.Client.RemoteEndPoint}. Error: {socketException.ErrorCode}"); Logger.Warning?.PrintMsg(LogClass.Hid, $"Unable to send data request to motion source at {client.Client.RemoteEndPoint}. Error: {socketException.ErrorCode}");
} }
_clientErrorStatus[clientId] = true; _clientErrorStatus[clientId] = true;
RemoveClient(clientId); RemoveClient(clientId);
_client?.Dispose(); client?.Dispose();
SetRetryTimer(clientId); SetRetryTimer(clientId);
} }
@ -193,7 +193,7 @@ namespace Ryujinx.Input.Motion.CemuHook
RemoveClient(clientId); RemoveClient(clientId);
_client?.Dispose(); client?.Dispose();
SetRetryTimer(clientId); SetRetryTimer(clientId);
} }
@ -203,13 +203,13 @@ namespace Ryujinx.Input.Motion.CemuHook
private byte[] Receive(int clientId, int timeout = 0) private byte[] Receive(int clientId, int timeout = 0)
{ {
if (_hosts.TryGetValue(clientId, out IPEndPoint endPoint) && _clients.TryGetValue(clientId, out UdpClient _client)) if (_hosts.TryGetValue(clientId, out IPEndPoint endPoint) && _clients.TryGetValue(clientId, out UdpClient client))
{ {
if (_client != null && _client.Client != null && _client.Client.Connected) if (client != null && client.Client != null && client.Client.Connected)
{ {
_client.Client.ReceiveTimeout = timeout; client.Client.ReceiveTimeout = timeout;
var result = _client?.Receive(ref endPoint); var result = client?.Receive(ref endPoint);
if (result.Length > 0) if (result.Length > 0)
{ {
@ -242,9 +242,9 @@ namespace Ryujinx.Input.Motion.CemuHook
public void ReceiveLoop(int clientId) public void ReceiveLoop(int clientId)
{ {
if (_hosts.TryGetValue(clientId, out IPEndPoint endPoint) && _clients.TryGetValue(clientId, out UdpClient _client)) if (_hosts.TryGetValue(clientId, out IPEndPoint endPoint) && _clients.TryGetValue(clientId, out UdpClient client))
{ {
if (_client != null && _client.Client != null && _client.Client.Connected) if (client != null && client.Client != null && client.Client.Connected)
{ {
try try
{ {
@ -271,7 +271,7 @@ namespace Ryujinx.Input.Motion.CemuHook
RemoveClient(clientId); RemoveClient(clientId);
_client?.Dispose(); client?.Dispose();
SetRetryTimer(clientId); SetRetryTimer(clientId);
} }
@ -281,7 +281,7 @@ namespace Ryujinx.Input.Motion.CemuHook
RemoveClient(clientId); RemoveClient(clientId);
_client?.Dispose(); client?.Dispose();
SetRetryTimer(clientId); SetRetryTimer(clientId);
} }
@ -297,8 +297,8 @@ namespace Ryujinx.Input.Motion.CemuHook
data = data.AsSpan()[16..].ToArray(); data = data.AsSpan()[16..].ToArray();
using MemoryStream stream = new MemoryStream(data); using MemoryStream stream = new(data);
using BinaryReader reader = new BinaryReader(stream); using BinaryReader reader = new(stream);
switch (type) switch (type)
{ {
@ -310,18 +310,18 @@ namespace Ryujinx.Input.Motion.CemuHook
case MessageType.Data: case MessageType.Data:
ControllerDataResponse inputData = reader.ReadStruct<ControllerDataResponse>(); ControllerDataResponse inputData = reader.ReadStruct<ControllerDataResponse>();
Vector3 accelerometer = new Vector3() Vector3 accelerometer = new()
{ {
X = -inputData.AccelerometerX, X = -inputData.AccelerometerX,
Y = inputData.AccelerometerZ, Y = inputData.AccelerometerZ,
Z = -inputData.AccelerometerY Z = -inputData.AccelerometerY,
}; };
Vector3 gyroscrope = new Vector3() Vector3 gyroscrope = new()
{ {
X = inputData.GyroscopePitch, X = inputData.GyroscopePitch,
Y = inputData.GyroscopeRoll, Y = inputData.GyroscopeRoll,
Z = -inputData.GyroscopeYaw Z = -inputData.GyroscopeYaw,
}; };
ulong timestamp = inputData.MotionTimestamp; ulong timestamp = inputData.MotionTimestamp;
@ -346,7 +346,7 @@ namespace Ryujinx.Input.Motion.CemuHook
} }
else else
{ {
MotionInput input = new MotionInput(); MotionInput input = new();
input.Update(accelerometer, gyroscrope, timestamp, cemuHookConfig.Sensitivity, (float)cemuHookConfig.GyroDeadzone); input.Update(accelerometer, gyroscrope, timestamp, cemuHookConfig.Sensitivity, (float)cemuHookConfig.GyroDeadzone);
@ -355,11 +355,11 @@ namespace Ryujinx.Input.Motion.CemuHook
} }
else else
{ {
MotionInput input = new MotionInput(); MotionInput input = new();
input.Update(accelerometer, gyroscrope, timestamp, cemuHookConfig.Sensitivity, (float)cemuHookConfig.GyroDeadzone); input.Update(accelerometer, gyroscrope, timestamp, cemuHookConfig.Sensitivity, (float)cemuHookConfig.GyroDeadzone);
_motionData.Add(clientId, new Dictionary<int, MotionInput>() { { slot, input } }); _motionData.Add(clientId, new Dictionary<int, MotionInput> { { slot, input } });
} }
} }
else else
@ -380,38 +380,37 @@ namespace Ryujinx.Input.Motion.CemuHook
Header header = GenerateHeader(clientId); Header header = GenerateHeader(clientId);
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream()) using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
writer.WriteStruct(header);
ControllerInfoRequest request = new()
{ {
writer.WriteStruct(header); Type = MessageType.Info,
PortsCount = 4,
};
ControllerInfoRequest request = new ControllerInfoRequest() request.PortIndices[0] = (byte)slot;
{
Type = MessageType.Info,
PortsCount = 4
};
request.PortIndices[0] = (byte)slot; writer.WriteStruct(request);
writer.WriteStruct(request); header.Length = (ushort)(stream.Length - 16);
header.Length = (ushort)(stream.Length - 16); writer.Seek(6, SeekOrigin.Begin);
writer.Write(header.Length);
writer.Seek(6, SeekOrigin.Begin); Crc32.Hash(stream.ToArray(), header.Crc32.AsSpan());
writer.Write(header.Length);
Crc32.Hash(stream.ToArray(), header.Crc32.AsSpan()); writer.Seek(8, SeekOrigin.Begin);
writer.Write(header.Crc32.AsSpan());
writer.Seek(8, SeekOrigin.Begin); byte[] data = stream.ToArray();
writer.Write(header.Crc32.AsSpan());
byte[] data = stream.ToArray(); Send(data, clientId);
Send(data, clientId);
}
} }
public unsafe void RequestData(int clientId, int slot) public void RequestData(int clientId, int slot)
{ {
if (!_active) if (!_active)
{ {
@ -420,44 +419,43 @@ namespace Ryujinx.Input.Motion.CemuHook
Header header = GenerateHeader(clientId); Header header = GenerateHeader(clientId);
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream()) using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
writer.WriteStruct(header);
ControllerDataRequest request = new()
{ {
writer.WriteStruct(header); Type = MessageType.Data,
Slot = (byte)slot,
SubscriberType = SubscriberType.Slot,
};
ControllerDataRequest request = new ControllerDataRequest() writer.WriteStruct(request);
{
Type = MessageType.Data,
Slot = (byte)slot,
SubscriberType = SubscriberType.Slot
};
writer.WriteStruct(request); header.Length = (ushort)(stream.Length - 16);
header.Length = (ushort)(stream.Length - 16); writer.Seek(6, SeekOrigin.Begin);
writer.Write(header.Length);
writer.Seek(6, SeekOrigin.Begin); Crc32.Hash(stream.ToArray(), header.Crc32.AsSpan());
writer.Write(header.Length);
Crc32.Hash(stream.ToArray(), header.Crc32.AsSpan()); writer.Seek(8, SeekOrigin.Begin);
writer.Write(header.Crc32.AsSpan());
writer.Seek(8, SeekOrigin.Begin); byte[] data = stream.ToArray();
writer.Write(header.Crc32.AsSpan());
byte[] data = stream.ToArray(); Send(data, clientId);
Send(data, clientId);
}
} }
private Header GenerateHeader(int clientId) private static Header GenerateHeader(int clientId)
{ {
Header header = new Header() Header header = new()
{ {
Id = (uint)clientId, Id = (uint)clientId,
MagicString = Magic, MagicString = Magic,
Version = Version, Version = Version,
Length = 0 Length = 0,
}; };
return header; return header;
@ -465,9 +463,10 @@ namespace Ryujinx.Input.Motion.CemuHook
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
_active = false; _active = false;
CloseClients(); CloseClients();
} }
} }
} }

View File

@ -16,15 +16,15 @@ namespace Ryujinx.Input.Motion.CemuHook.Protocol
public struct ControllerDataResponse public struct ControllerDataResponse
{ {
public SharedResponse Shared; public SharedResponse Shared;
public byte Connected; public byte Connected;
public uint PacketId; public uint PacketId;
public byte ExtraButtons; public byte ExtraButtons;
public byte MainButtons; public byte MainButtons;
public ushort PSExtraInput; public ushort PSExtraInput;
public ushort LeftStickXY; public ushort LeftStickXY;
public ushort RightStickXY; public ushort RightStickXY;
public uint DPadAnalog; public uint DPadAnalog;
public ulong MainButtonsAnalog; public ulong MainButtonsAnalog;
public Array6<byte> Touch1; public Array6<byte> Touch1;
public Array6<byte> Touch2; public Array6<byte> Touch2;
@ -42,6 +42,6 @@ namespace Ryujinx.Input.Motion.CemuHook.Protocol
{ {
All, All,
Slot, Slot,
Mac Mac,
} }
} }

View File

@ -7,7 +7,7 @@ namespace Ryujinx.Input.Motion.CemuHook.Protocol
public struct ControllerInfoResponse public struct ControllerInfoResponse
{ {
public SharedResponse Shared; public SharedResponse Shared;
private byte _zero; private readonly byte _zero;
} }
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
@ -17,4 +17,4 @@ namespace Ryujinx.Input.Motion.CemuHook.Protocol
public int PortsCount; public int PortsCount;
public Array4<byte> PortIndices; public Array4<byte> PortIndices;
} }
} }

View File

@ -12,4 +12,4 @@ namespace Ryujinx.Input.Motion.CemuHook.Protocol
public Array4<byte> Crc32; public Array4<byte> Crc32;
public uint Id; public uint Id;
} }
} }

View File

@ -4,6 +4,6 @@
{ {
Protocol = 0x100000, Protocol = 0x100000,
Info, Info,
Data Data,
} }
} }

View File

@ -6,11 +6,11 @@ namespace Ryujinx.Input.Motion.CemuHook.Protocol
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SharedResponse public struct SharedResponse
{ {
public MessageType Type; public MessageType Type;
public byte Slot; public byte Slot;
public SlotState State; public SlotState State;
public DeviceModelType ModelType; public DeviceModelType ModelType;
public ConnectionType ConnectionType; public ConnectionType ConnectionType;
public Array6<byte> MacAddress; public Array6<byte> MacAddress;
public BatteryStatus BatteryStatus; public BatteryStatus BatteryStatus;
@ -20,21 +20,21 @@ namespace Ryujinx.Input.Motion.CemuHook.Protocol
{ {
Disconnected, Disconnected,
Reserved, Reserved,
Connected Connected,
} }
public enum DeviceModelType : byte public enum DeviceModelType : byte
{ {
None, None,
PartialGyro, PartialGyro,
FullGyro FullGyro,
} }
public enum ConnectionType : byte public enum ConnectionType : byte
{ {
None, None,
USB, USB,
Bluetooth Bluetooth,
} }
public enum BatteryStatus : byte public enum BatteryStatus : byte
@ -46,6 +46,6 @@ namespace Ryujinx.Input.Motion.CemuHook.Protocol
High, High,
Full, Full,
Charging, Charging,
Charged Charged,
} }
} }

View File

@ -6,19 +6,19 @@ namespace Ryujinx.Input
{ {
public class MotionInput public class MotionInput
{ {
public ulong TimeStamp { get; set; } public ulong TimeStamp { get; set; }
public Vector3 Accelerometer { get; set; } public Vector3 Accelerometer { get; set; }
public Vector3 Gyroscrope { get; set; } public Vector3 Gyroscrope { get; set; }
public Vector3 Rotation { get; set; } public Vector3 Rotation { get; set; }
private readonly MotionSensorFilter _filter; private readonly MotionSensorFilter _filter;
public MotionInput() public MotionInput()
{ {
TimeStamp = 0; TimeStamp = 0;
Accelerometer = new Vector3(); Accelerometer = new Vector3();
Gyroscrope = new Vector3(); Gyroscrope = new Vector3();
Rotation = new Vector3(); Rotation = new Vector3();
// TODO: RE the correct filter. // TODO: RE the correct filter.
_filter = new MotionSensorFilter(0f); _filter = new MotionSensorFilter(0f);
@ -62,4 +62,4 @@ namespace Ryujinx.Input
return degree * (MathF.PI / 180); return degree * (MathF.PI / 180);
} }
} }
} }

View File

@ -106,19 +106,19 @@ namespace Ryujinx.Input.Motion
float q1 = Quaternion.W; float q1 = Quaternion.W;
// Estimated direction of gravity. // Estimated direction of gravity.
Vector3 gravity = new Vector3() Vector3 gravity = new()
{ {
X = 2f * (q2 * q4 - q1 * q3), X = 2f * (q2 * q4 - q1 * q3),
Y = 2f * (q1 * q2 + q3 * q4), Y = 2f * (q1 * q2 + q3 * q4),
Z = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4 Z = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4,
}; };
// Error is cross product between estimated direction and measured direction of gravity. // Error is cross product between estimated direction and measured direction of gravity.
Vector3 error = new Vector3() Vector3 error = new()
{ {
X = accel.Y * gravity.Z - accel.Z * gravity.Y, X = accel.Y * gravity.Z - accel.Z * gravity.Y,
Y = accel.Z * gravity.X - accel.X * gravity.Z, Y = accel.Z * gravity.X - accel.X * gravity.Z,
Z = accel.X * gravity.Y - accel.Y * gravity.X Z = accel.X * gravity.Y - accel.Y * gravity.X,
}; };
if (Ki > 0f) if (Ki > 0f)
@ -134,7 +134,7 @@ namespace Ryujinx.Input.Motion
gyro += (Kp * error) + (Ki * _intergralError); gyro += (Kp * error) + (Ki * _intergralError);
// Integrate rate of change of quaternion. // Integrate rate of change of quaternion.
Vector3 delta = new Vector3(q2, q3, q4); Vector3 delta = new(q2, q3, q4);
q1 += (-q2 * gyro.X - q3 * gyro.Y - q4 * gyro.Z) * (SampleRateCoefficient * SamplePeriod); q1 += (-q2 * gyro.X - q3 * gyro.Y - q4 * gyro.Z) * (SampleRateCoefficient * SamplePeriod);
q2 += (q1 * gyro.X + delta.Y * gyro.Z - delta.Z * gyro.Y) * (SampleRateCoefficient * SamplePeriod); q2 += (q1 * gyro.X + delta.Y * gyro.Z - delta.Z * gyro.Y) * (SampleRateCoefficient * SamplePeriod);
@ -142,7 +142,7 @@ namespace Ryujinx.Input.Motion
q4 += (q1 * gyro.Z + delta.X * gyro.Y - delta.Y * gyro.X) * (SampleRateCoefficient * SamplePeriod); q4 += (q1 * gyro.Z + delta.X * gyro.Y - delta.Y * gyro.X) * (SampleRateCoefficient * SamplePeriod);
// Normalise quaternion. // Normalise quaternion.
Quaternion quaternion = new Quaternion(q2, q3, q4, q1); Quaternion quaternion = new(q2, q3, q4, q1);
norm = 1f / quaternion.Length(); norm = 1f / quaternion.Length();
@ -159,4 +159,4 @@ namespace Ryujinx.Input.Motion
Quaternion = Quaternion.Identity; Quaternion = Quaternion.Identity;
} }
} }
} }

View File

@ -20,6 +20,6 @@
/// Gyroscope. /// Gyroscope.
/// </summary> /// </summary>
/// <remarks>Values are in degrees</remarks> /// <remarks>Values are in degrees</remarks>
Gyroscope Gyroscope,
} }
} }

View File

@ -11,6 +11,6 @@ namespace Ryujinx.Input
Button7, Button7,
Button8, Button8,
Button9, Button9,
Count Count,
} }
} }

View File

@ -8,7 +8,7 @@ namespace Ryujinx.Input
/// </summary> /// </summary>
public class MouseStateSnapshot public class MouseStateSnapshot
{ {
private bool[] _buttonState; private readonly bool[] _buttonState;
/// <summary> /// <summary>
/// The position of the mouse cursor /// The position of the mouse cursor
@ -31,7 +31,7 @@ namespace Ryujinx.Input
_buttonState = buttonState; _buttonState = buttonState;
Position = position; Position = position;
Scroll = scroll; Scroll = scroll;
} }
/// <summary> /// <summary>
@ -42,4 +42,4 @@ namespace Ryujinx.Input
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsPressed(MouseButton button) => _buttonState[(int)button]; public bool IsPressed(MouseButton button) => _buttonState[(int)button];
} }
} }

View File

@ -9,6 +9,6 @@
Left, Left,
Right, Right,
Count Count,
} }
} }

View File

@ -136,7 +136,7 @@ namespace Ryujinx.Memory
{ {
size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
data.Slice(0, size).CopyTo(GetHostSpanContiguous(va, size)); data[..size].CopyTo(GetHostSpanContiguous(va, size));
offset += size; offset += size;
} }
@ -215,7 +215,7 @@ namespace Ryujinx.Memory
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPagesCount(ulong va, uint size, out ulong startVa) private static int GetPagesCount(ulong va, uint size, out ulong startVa)
{ {
// WARNING: Always check if ulong does not overflow during the operations. // WARNING: Always check if ulong does not overflow during the operations.
startVa = va & ~(ulong)PageMask; startVa = va & ~(ulong)PageMask;
@ -224,7 +224,7 @@ namespace Ryujinx.Memory
return (int)(vaSpan / PageSize); return (int)(vaSpan / PageSize);
} }
private void ThrowMemoryNotContiguous() => throw new MemoryNotContiguousException(); private static void ThrowMemoryNotContiguous() => throw new MemoryNotContiguousException();
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool IsContiguousAndMapped(ulong va, int size) => IsContiguous(va, size) && IsMapped(va); private bool IsContiguousAndMapped(ulong va, int size) => IsContiguous(va, size) && IsMapped(va);
@ -361,7 +361,7 @@ namespace Ryujinx.Memory
{ {
size = Math.Min(data.Length, PageSize - (int)(va & PageMask)); size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
GetHostSpanContiguous(va, size).CopyTo(data.Slice(0, size)); GetHostSpanContiguous(va, size).CopyTo(data[..size]);
offset += size; offset += size;
} }

View File

@ -47,6 +47,6 @@ namespace Ryujinx.Memory
/// Indicates that the memory will be used to store JIT generated code. /// Indicates that the memory will be used to store JIT generated code.
/// On some platforms, this requires special flags to be passed that will allow the memory to be executable. /// On some platforms, this requires special flags to be passed that will allow the memory to be executable.
/// </summary> /// </summary>
Jit = 1 << 5 Jit = 1 << 5,
} }
} }

View File

@ -364,9 +364,9 @@ namespace Ryujinx.Memory
/// <param name="pointer">Native pointer</param> /// <param name="pointer">Native pointer</param>
/// <param name="offset">Offset to add</param> /// <param name="offset">Offset to add</param>
/// <returns>Native pointer with the added offset</returns> /// <returns>Native pointer with the added offset</returns>
private IntPtr PtrAddr(IntPtr pointer, ulong offset) private static IntPtr PtrAddr(IntPtr pointer, ulong offset)
{ {
return (IntPtr)(pointer.ToInt64() + (long)offset); return new IntPtr(pointer.ToInt64() + (long)offset);
} }
/// <summary> /// <summary>
@ -439,4 +439,4 @@ namespace Ryujinx.Memory
private static void ThrowInvalidMemoryRegionException() => throw new InvalidMemoryRegionException(); private static void ThrowInvalidMemoryRegionException() => throw new InvalidMemoryRegionException();
} }
} }

View File

@ -203,4 +203,4 @@ namespace Ryujinx.Memory
} }
} }
} }
} }

View File

@ -50,7 +50,7 @@ namespace Ryujinx.Memory
} }
} }
IntPtr ptr = mmap(IntPtr.Zero, size, prot, flags, -1, 0); IntPtr ptr = Mmap(IntPtr.Zero, size, prot, flags, -1, 0);
if (ptr == MAP_FAILED) if (ptr == MAP_FAILED)
{ {
@ -115,7 +115,7 @@ namespace Ryujinx.Memory
MemoryPermission.ReadAndExecute => MmapProts.PROT_READ | MmapProts.PROT_EXEC, MemoryPermission.ReadAndExecute => MmapProts.PROT_READ | MmapProts.PROT_EXEC,
MemoryPermission.ReadWriteExecute => MmapProts.PROT_READ | MmapProts.PROT_WRITE | MmapProts.PROT_EXEC, MemoryPermission.ReadWriteExecute => MmapProts.PROT_READ | MmapProts.PROT_WRITE | MmapProts.PROT_EXEC,
MemoryPermission.Execute => MmapProts.PROT_EXEC, MemoryPermission.Execute => MmapProts.PROT_EXEC,
_ => throw new MemoryProtectionException(permission) _ => throw new MemoryProtectionException(permission),
}; };
} }
@ -185,12 +185,12 @@ namespace Ryujinx.Memory
public static void DestroySharedMemory(IntPtr handle) public static void DestroySharedMemory(IntPtr handle)
{ {
close((int)handle); close(handle.ToInt32());
} }
public static IntPtr MapSharedMemory(IntPtr handle, ulong size) public static IntPtr MapSharedMemory(IntPtr handle, ulong size)
{ {
return mmap(IntPtr.Zero, size, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_SHARED, (int)handle, 0); return Mmap(IntPtr.Zero, size, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_SHARED, handle.ToInt32(), 0);
} }
public static void UnmapSharedMemory(IntPtr address, ulong size) public static void UnmapSharedMemory(IntPtr address, ulong size)
@ -200,12 +200,12 @@ namespace Ryujinx.Memory
public static void MapView(IntPtr sharedMemory, ulong srcOffset, IntPtr location, ulong size) public static void MapView(IntPtr sharedMemory, ulong srcOffset, IntPtr location, ulong size)
{ {
mmap(location, size, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_FIXED | MmapFlags.MAP_SHARED, (int)sharedMemory, (long)srcOffset); Mmap(location, size, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_FIXED | MmapFlags.MAP_SHARED, sharedMemory.ToInt32(), (long)srcOffset);
} }
public static void UnmapView(IntPtr location, ulong size) public static void UnmapView(IntPtr location, ulong size)
{ {
mmap(location, size, MmapProts.PROT_NONE, MmapFlags.MAP_FIXED | MmapFlags.MAP_PRIVATE | MmapFlags.MAP_ANONYMOUS | MmapFlags.MAP_NORESERVE, -1, 0); Mmap(location, size, MmapProts.PROT_NONE, MmapFlags.MAP_FIXED | MmapFlags.MAP_PRIVATE | MmapFlags.MAP_ANONYMOUS | MmapFlags.MAP_NORESERVE, -1, 0);
} }
} }
} }

View File

@ -148,4 +148,4 @@ namespace Ryujinx.Memory
} }
} }
} }
} }

View File

@ -14,7 +14,7 @@ namespace Ryujinx.Memory
PROT_NONE = 0, PROT_NONE = 0,
PROT_READ = 1, PROT_READ = 1,
PROT_WRITE = 2, PROT_WRITE = 2,
PROT_EXEC = 4 PROT_EXEC = 4,
} }
[Flags] [Flags]
@ -26,7 +26,7 @@ namespace Ryujinx.Memory
MAP_NORESERVE = 8, MAP_NORESERVE = 8,
MAP_FIXED = 16, MAP_FIXED = 16,
MAP_UNLOCKED = 32, MAP_UNLOCKED = 32,
MAP_JIT_DARWIN = 0x800 MAP_JIT_DARWIN = 0x800,
} }
[Flags] [Flags]
@ -164,9 +164,9 @@ namespace Ryujinx.Memory
return result; return result;
} }
public static IntPtr mmap(IntPtr address, ulong length, MmapProts prot, MmapFlags flags, int fd, long offset) public static IntPtr Mmap(IntPtr address, ulong length, MmapProts prot, MmapFlags flags, int fd, long offset)
{ {
return Internal_mmap(address, length, prot, MmapFlagsToSystemFlags(flags), fd, offset); return Internal_mmap(address, length, prot, MmapFlagsToSystemFlags(flags), fd, offset);
} }
} }
} }

View File

@ -18,6 +18,6 @@ namespace Ryujinx.Memory
/// and allocate its own private storage for the mapping. /// and allocate its own private storage for the mapping.
/// This allows some mappings that would otherwise fail due to host platform restrictions to succeed. /// This allows some mappings that would otherwise fail due to host platform restrictions to succeed.
/// </summary> /// </summary>
Private = 1 << 0 Private = 1 << 0,
} }
} }

View File

@ -16,4 +16,4 @@ namespace Ryujinx.Memory
{ {
} }
} }
} }

View File

@ -46,6 +46,6 @@ namespace Ryujinx.Memory
/// <summary> /// <summary>
/// Indicates an invalid protection. /// Indicates an invalid protection.
/// </summary> /// </summary>
Invalid = 255 Invalid = 255,
} }
} }

View File

@ -5,12 +5,12 @@ namespace Ryujinx.Memory.Range
/// <summary> /// <summary>
/// Range of memory composed of an address and size. /// Range of memory composed of an address and size.
/// </summary> /// </summary>
public struct HostMemoryRange : IEquatable<HostMemoryRange> public readonly struct HostMemoryRange : IEquatable<HostMemoryRange>
{ {
/// <summary> /// <summary>
/// An empty memory range, with a null address and zero size. /// An empty memory range, with a null address and zero size.
/// </summary> /// </summary>
public static HostMemoryRange Empty => new HostMemoryRange(0, 0); public static HostMemoryRange Empty => new(0, 0);
/// <summary> /// <summary>
/// Start address of the range. /// Start address of the range.
@ -67,5 +67,15 @@ namespace Ryujinx.Memory.Range
{ {
return HashCode.Combine(Address, Size); return HashCode.Combine(Address, Size);
} }
public static bool operator ==(HostMemoryRange left, HostMemoryRange right)
{
return left.Equals(right);
}
public static bool operator !=(HostMemoryRange left, HostMemoryRange right)
{
return !(left == right);
}
} }
} }

View File

@ -28,4 +28,4 @@ namespace Ryujinx.Memory.Range
/// <returns>True if overlapping, false otherwise</returns> /// <returns>True if overlapping, false otherwise</returns>
bool OverlapsWith(ulong address, ulong size); bool OverlapsWith(ulong address, ulong size);
} }
} }

View File

@ -8,7 +8,7 @@
/// <summary> /// <summary>
/// An empty memory range, with a null address and zero size. /// An empty memory range, with a null address and zero size.
/// </summary> /// </summary>
public static MemoryRange Empty => new MemoryRange(0UL, 0); public static MemoryRange Empty => new(0UL, 0);
/// <summary> /// <summary>
/// Start address of the range. /// Start address of the range.

View File

@ -310,7 +310,7 @@ namespace Ryujinx.Memory.Range
return _singleRange.GetHashCode(); return _singleRange.GetHashCode();
} }
HashCode hash = new HashCode(); HashCode hash = new();
foreach (MemoryRange range in _ranges) foreach (MemoryRange range in _ranges)
{ {
@ -328,5 +328,15 @@ namespace Ryujinx.Memory.Range
{ {
return HasSingleRange ? _singleRange.ToString() : string.Join(", ", _ranges); return HasSingleRange ? _singleRange.ToString() : string.Join(", ", _ranges);
} }
public static bool operator ==(MultiRange left, MultiRange right)
{
return left.Equals(right);
}
public static bool operator !=(MultiRange left, MultiRange right)
{
return !(left == right);
}
} }
} }

View File

@ -238,7 +238,7 @@ namespace Ryujinx.Memory.Range
if (index < 0) if (index < 0)
{ {
return default(T); return default;
} }
return _items[index].Value; return _items[index].Value;
@ -398,7 +398,7 @@ namespace Ryujinx.Memory.Range
/// <returns>List index of the item, or complement index of nearest item with lower value on the list</returns> /// <returns>List index of the item, or complement index of nearest item with lower value on the list</returns>
private int BinarySearch(ulong address) private int BinarySearch(ulong address)
{ {
int left = 0; int left = 0;
int right = Count - 1; int right = Count - 1;
while (left <= right) while (left <= right)
@ -435,7 +435,7 @@ namespace Ryujinx.Memory.Range
/// <returns>List index of the item, or complement index of nearest item with lower value on the list</returns> /// <returns>List index of the item, or complement index of nearest item with lower value on the list</returns>
private int BinarySearch(ulong address, ulong endAddress) private int BinarySearch(ulong address, ulong endAddress)
{ {
int left = 0; int left = 0;
int right = Count - 1; int right = Count - 1;
while (left <= right) while (left <= right)
@ -480,4 +480,4 @@ namespace Ryujinx.Memory.Range
} }
} }
} }
} }

View File

@ -21,7 +21,7 @@ namespace Ryujinx.Memory.Tracking
/// This lock must be obtained when traversing or updating the region-handle hierarchy. /// This lock must be obtained when traversing or updating the region-handle hierarchy.
/// It is not required when reading dirty flags. /// It is not required when reading dirty flags.
/// </summary> /// </summary>
internal object TrackingLock = new object(); internal object TrackingLock = new();
/// <summary> /// <summary>
/// Create a new tracking structure for the given "physical" memory block, /// Create a new tracking structure for the given "physical" memory block,
@ -114,7 +114,7 @@ namespace Ryujinx.Memory.Tracking
/// <returns>A list of virtual regions within the given range</returns> /// <returns>A list of virtual regions within the given range</returns>
internal List<VirtualRegion> GetVirtualRegionsForHandle(ulong va, ulong size) internal List<VirtualRegion> GetVirtualRegionsForHandle(ulong va, ulong size)
{ {
List<VirtualRegion> result = new List<VirtualRegion>(); List<VirtualRegion> result = new();
_virtualRegions.GetOrAddRegions(result, va, size, (va, size) => new VirtualRegion(this, va, size)); _virtualRegions.GetOrAddRegions(result, va, size, (va, size) => new VirtualRegion(this, va, size));
return result; return result;
@ -172,7 +172,7 @@ namespace Ryujinx.Memory.Tracking
lock (TrackingLock) lock (TrackingLock)
{ {
bool mapped = _memoryManager.IsRangeMapped(address, size); bool mapped = _memoryManager.IsRangeMapped(address, size);
RegionHandle handle = new RegionHandle(this, paAddress, paSize, address, size, id, mapped); RegionHandle handle = new(this, paAddress, paSize, address, size, id, mapped);
return handle; return handle;
} }
@ -194,7 +194,7 @@ namespace Ryujinx.Memory.Tracking
lock (TrackingLock) lock (TrackingLock)
{ {
bool mapped = _memoryManager.IsRangeMapped(address, size); bool mapped = _memoryManager.IsRangeMapped(address, size);
RegionHandle handle = new RegionHandle(this, paAddress, paSize, address, size, bitmap, bit, id, mapped); RegionHandle handle = new(this, paAddress, paSize, address, size, bitmap, bit, id, mapped);
return handle; return handle;
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
@ -21,11 +22,11 @@ namespace Ryujinx.Memory.Tracking
private readonly ulong Granularity; private readonly ulong Granularity;
private readonly ulong Size; private readonly ulong Size;
private ConcurrentBitmap _dirtyBitmap; private readonly ConcurrentBitmap _dirtyBitmap;
private int _sequenceNumber; private int _sequenceNumber;
private BitMap _sequenceNumberBitmap; private readonly BitMap _sequenceNumberBitmap;
private BitMap _dirtyCheckedBitmap; private readonly BitMap _dirtyCheckedBitmap;
private int _uncheckedHandles; private int _uncheckedHandles;
public bool Dirty { get; private set; } = true; public bool Dirty { get; private set; } = true;
@ -54,7 +55,7 @@ namespace Ryujinx.Memory.Tracking
// It is assumed that the provided handles do not overlap, in order, are on page boundaries, // It is assumed that the provided handles do not overlap, in order, are on page boundaries,
// and don't extend past the requested range. // and don't extend past the requested range.
foreach (RegionHandle handle in handles) foreach (RegionHandle handle in handles.Cast<RegionHandle>())
{ {
int startIndex = (int)((handle.RealAddress - address) / granularity); int startIndex = (int)((handle.RealAddress - address) / granularity);
@ -406,6 +407,8 @@ namespace Ryujinx.Memory.Tracking
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
foreach (var handle in _handles) foreach (var handle in _handles)
{ {
handle.Dispose(); handle.Dispose();

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection.Metadata;
using System.Threading; using System.Threading;
namespace Ryujinx.Memory.Tracking namespace Ryujinx.Memory.Tracking
@ -50,7 +49,7 @@ namespace Ryujinx.Memory.Tracking
internal IMultiRegionHandle Parent { get; set; } internal IMultiRegionHandle Parent { get; set; }
private event Action _onDirty; private event Action OnDirty;
private readonly object _preActionLock = new(); private readonly object _preActionLock = new();
private RegionSignal _preAction; // Action to perform before a read or write. This will block the memory access. private RegionSignal _preAction; // Action to perform before a read or write. This will block the memory access.
@ -269,7 +268,7 @@ namespace Ryujinx.Memory.Tracking
Dirty = true; Dirty = true;
if (!oldDirty) if (!oldDirty)
{ {
_onDirty?.Invoke(); OnDirty?.Invoke();
} }
Parent?.SignalWrite(); Parent?.SignalWrite();
} }
@ -311,7 +310,10 @@ namespace Ryujinx.Memory.Tracking
/// <param name="consecutiveCheck">True if this reprotect is the result of consecutive dirty checks</param> /// <param name="consecutiveCheck">True if this reprotect is the result of consecutive dirty checks</param>
public void Reprotect(bool asDirty, bool consecutiveCheck = false) public void Reprotect(bool asDirty, bool consecutiveCheck = false)
{ {
if (_volatile) return; if (_volatile)
{
return;
}
Dirty = asDirty; Dirty = asDirty;
@ -403,7 +405,7 @@ namespace Ryujinx.Memory.Tracking
/// <param name="action">Action to call on dirty</param> /// <param name="action">Action to call on dirty</param>
public void RegisterDirtyEvent(Action action) public void RegisterDirtyEvent(Action action)
{ {
_onDirty += action; OnDirty += action;
} }
/// <summary> /// <summary>
@ -461,6 +463,8 @@ namespace Ryujinx.Memory.Tracking
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
GC.SuppressFinalize(this);
_disposed = true; _disposed = true;
lock (_tracking.TrackingLock) lock (_tracking.TrackingLock)

View File

@ -17,7 +17,7 @@ namespace Ryujinx.Memory.Tracking
private readonly ulong _address; private readonly ulong _address;
private readonly ulong _granularity; private readonly ulong _granularity;
private readonly ulong _size; private readonly ulong _size;
private MemoryTracking _tracking; private readonly MemoryTracking _tracking;
private readonly int _id; private readonly int _id;
public bool Dirty { get; private set; } = true; public bool Dirty { get; private set; } = true;
@ -271,6 +271,8 @@ namespace Ryujinx.Memory.Tracking
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
foreach (var handle in _handles) foreach (var handle in _handles)
{ {
handle?.Dispose(); handle?.Dispose();

View File

@ -8,7 +8,7 @@ namespace Ryujinx.Memory.Tracking
/// </summary> /// </summary>
class VirtualRegion : AbstractRegion class VirtualRegion : AbstractRegion
{ {
public List<RegionHandle> Handles = new List<RegionHandle>(); public List<RegionHandle> Handles = new();
private readonly MemoryTracking _tracking; private readonly MemoryTracking _tracking;
private MemoryPermission _lastPermission; private MemoryPermission _lastPermission;
@ -86,7 +86,10 @@ namespace Ryujinx.Memory.Tracking
foreach (var handle in Handles) foreach (var handle in Handles)
{ {
result &= handle.RequiredPermission; result &= handle.RequiredPermission;
if (result == 0) return result; if (result == 0)
{
return result;
}
} }
return result; return result;
} }
@ -128,7 +131,7 @@ namespace Ryujinx.Memory.Tracking
public override INonOverlappingRange Split(ulong splitAddress) public override INonOverlappingRange Split(ulong splitAddress)
{ {
VirtualRegion newRegion = new VirtualRegion(_tracking, splitAddress, EndAddress - splitAddress, _lastPermission); VirtualRegion newRegion = new(_tracking, splitAddress, EndAddress - splitAddress, _lastPermission);
Size = splitAddress - Address; Size = splitAddress - Address;
// The new region inherits all of our parents. // The new region inherits all of our parents.

View File

@ -84,4 +84,4 @@ namespace Ryujinx.Memory.WindowsShared
} }
} }
} }
} }

View File

@ -31,9 +31,11 @@ namespace Ryujinx.Memory.WindowsShared
_partialUnmapStatePtr = PartialUnmapState.GlobalState; _partialUnmapStatePtr = PartialUnmapState.GlobalState;
_partialUnmapTrimThread = new Thread(TrimThreadLocalMapLoop); _partialUnmapTrimThread = new Thread(TrimThreadLocalMapLoop)
_partialUnmapTrimThread.Name = "CPU.PartialUnmapTrimThread"; {
_partialUnmapTrimThread.IsBackground = true; Name = "CPU.PartialUnmapTrimThread",
IsBackground = true,
};
_partialUnmapTrimThread.Start(); _partialUnmapTrimThread.Start();
} }
@ -704,8 +706,6 @@ namespace Ryujinx.Memory.WindowsShared
count = _protections.GetNodes(address, endAddress, ref overlaps); count = _protections.GetNodes(address, endAddress, ref overlaps);
} }
ulong startAddress = address;
for (int index = 0; index < count; index++) for (int index = 0; index < count; index++)
{ {
var protection = overlaps[index]; var protection = overlaps[index];
@ -733,4 +733,4 @@ namespace Ryujinx.Memory.WindowsShared
} }
} }
} }
} }

View File

@ -7,8 +7,8 @@ namespace Ryujinx.Memory.WindowsShared
[SupportedOSPlatform("windows")] [SupportedOSPlatform("windows")]
static partial class WindowsApi static partial class WindowsApi
{ {
public static readonly IntPtr InvalidHandleValue = new IntPtr(-1); public static readonly IntPtr InvalidHandleValue = new(-1);
public static readonly IntPtr CurrentProcessHandle = new IntPtr(-1); public static readonly IntPtr CurrentProcessHandle = new(-1);
[LibraryImport("kernel32.dll", SetLastError = true)] [LibraryImport("kernel32.dll", SetLastError = true)]
public static partial IntPtr VirtualAlloc( public static partial IntPtr VirtualAlloc(
@ -96,8 +96,8 @@ namespace Ryujinx.Memory.WindowsShared
MemoryPermission.ReadAndExecute => MemoryProtection.ExecuteRead, MemoryPermission.ReadAndExecute => MemoryProtection.ExecuteRead,
MemoryPermission.ReadWriteExecute => MemoryProtection.ExecuteReadWrite, MemoryPermission.ReadWriteExecute => MemoryProtection.ExecuteReadWrite,
MemoryPermission.Execute => MemoryProtection.Execute, MemoryPermission.Execute => MemoryProtection.Execute,
_ => throw new MemoryProtectionException(permission) _ => throw new MemoryProtectionException(permission),
}; };
} }
} }
} }

View File

@ -23,4 +23,4 @@ namespace Ryujinx.Memory.WindowsShared
return $"{functionName} returned error code 0x{WindowsApi.GetLastError():X}."; return $"{functionName} returned error code 0x{WindowsApi.GetLastError():X}.";
} }
} }
} }

View File

@ -10,14 +10,14 @@ namespace Ryujinx.Memory.WindowsShared
Commit = 0x1000, Commit = 0x1000,
Reserve = 0x2000, Reserve = 0x2000,
Decommit = 0x4000, Decommit = 0x4000,
ReplacePlaceholder = 0x4000, ReplacePlaceholder = Decommit,
Release = 0x8000, Release = 0x8000,
ReservePlaceholder = 0x40000, ReservePlaceholder = 0x40000,
Reset = 0x80000, Reset = 0x80000,
Physical = 0x400000, Physical = 0x400000,
TopDown = 0x100000, TopDown = 0x100000,
WriteWatch = 0x200000, WriteWatch = 0x200000,
LargePages = 0x20000000 LargePages = 0x20000000,
} }
[Flags] [Flags]
@ -33,7 +33,7 @@ namespace Ryujinx.Memory.WindowsShared
ExecuteWriteCopy = 0x80, ExecuteWriteCopy = 0x80,
GuardModifierflag = 0x100, GuardModifierflag = 0x100,
NoCacheModifierflag = 0x200, NoCacheModifierflag = 0x200,
WriteCombineModifierflag = 0x400 WriteCombineModifierflag = 0x400,
} }
[Flags] [Flags]
@ -47,6 +47,6 @@ namespace Ryujinx.Memory.WindowsShared
SectionCommit = 0x8000000, SectionCommit = 0x8000000,
SectionImage = 0x1000000, SectionImage = 0x1000000,
SectionNoCache = 0x10000000, SectionNoCache = 0x10000000,
SectionReserve = 0x4000000 SectionReserve = 0x4000000,
} }
} }