Compare commits

...

9 Commits

Author SHA1 Message Date
TSRBerry
eb528ae0f0 Add workflow to automatically check code style issues for PRs (#4670)
* Add workflow to perform automated checks for PRs

* Downgrade Microsoft.CodeAnalysis to 4.4.0

This is a workaround to fix issues with dotnet-format.
See:
- https://github.com/dotnet/format/issues/1805
- https://github.com/dotnet/format/issues/1800

* Adjust editorconfig to be more compatible with Ryujinx code-style

* Adjust .editorconfig line endings to match .gitattributes

* Disable 'prefer switch expression' rule

* Remove naming styles

These are the default rules, so we don't need to override them.

* Silence IDE0060 in .editorconfig

* Slightly adjust .editorconfig

* Add lost workflow changes

* Move .editorconfig comment to the top

* .editorconfig: private static readonly fields should be _lowerCamelCase

* .editorconfig: Remove alignment for declarations as well

* editorconfig: Add rule for local constants

* Disable CA1822 for HLE services

* Disable CA1822 for ViewModels

Bindings won't work with static members, but this issue is silently ignored.

* Run dotnet format for the whole solution

* Check result code of SDL_GetDisplayBounds

* Fix dotnet format style issues

* Add missing trailing commas

* Update Microsoft.CodeAnalysis.CSharp to 4.6.0

Skipping 4.5.0 since it breaks dotnet format

* Restore old default naming rules for dotnet format

* Add naming rule exception for CPU tests

* checks: Include all files before excluding paths

* Fix dotnet format issues

* Check dotnet format version

* checks: Run dotnet format with severity info again

* checks: Disable naming style rules until they won't crash the process anymore

* Remove unread private member

* checks: Attempt to run analyzers 3 times before giving up

* checks: Enable naming style rules again with the new retry logic
2023-07-24 18:35:04 +02:00
Mary
487261592e ava: Fix regression on title updater and dlc manager window caused by precious commit 2023-07-21 22:50:10 +02:00
MutantAura
9e04e6cba1 Ava UI: Remove IsActive checks from dialog methods (#5456)
* Remove `IsActive` checks from dialog methods

* Remove old windows bandaid

* Remove null dialog code path entirely and return nothing.
2023-07-21 12:24:13 +01:00
TSRBerry
4cf2419e6c HLE: Fix corrupted Mii structs (#5468)
* StructArrayHelpers: Add PureAttribute to all AsSpan() methods

* Fix broken Mii structs
2023-07-19 22:02:31 -03:00
Mary
440abac9f8 chore: Update Ryujinx.SDL2-CS to 2.28.1 (#5453) 2023-07-18 16:08:48 +02:00
TSRBerry
732714349e [Hotfix] sockets: Resolve empty port requests to 0 again (#5459) 2023-07-17 20:47:47 +02:00
TSRBerry
016262514d cpu: Hotfix missing ToNearest rounding mode cases 2023-07-16 20:39:08 +01:00
TSRBerry
326749498b [Ryujinx.HLE] Address dotnet-format issues (#5380)
* 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

* Silence dotnet format IDE0052 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2208 warnings

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

* Address dotnet format CA2211 warnings

* Address dotnet format CA1822 warnings

* Address or silence dotnet format CA1069 warnings

* Make dotnet format succeed in style mode

* Address or silence dotnet format CA2211 warnings

* Address review comments

* Address dotnet format CA2208 warnings properly

* Make ProcessResult readonly

* 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 previously silenced warnings back

I have no clue how these disappeared

* Revert formatting changes for while and for-loops

* Format if-blocks correctly

* Run dotnet format style after rebase

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Fix a few disabled warnings

* Fix naming rule violation, Convert shader properties to auto-property and convert values to const

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

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Run dotnet format after rebase

* Use using declaration instead of block syntax

* Address IDE0251 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

* Fix naming rule violations

* Fix typo

* Add trailing commas, use targeted new and use array initializer

* Fix build issues

* Fix remaining build issues

* Remove SuppressMessage for CA1069 where possible

* Address dotnet format issues

* Address formatting issues

Co-authored-by: Ac_K <acoustik666@gmail.com>

* Add GetHashCode implementation for RenderingSurfaceInfo

* Explicitly silence CA1822 for every affected method in Syscall

* Address formatting issues in Demangler.cs

* Address review feedback

Co-authored-by: Ac_K <acoustik666@gmail.com>

* Revert marking service methods as static

* Next dotnet format pass

* Address review feedback

---------

Co-authored-by: Ac_K <acoustik666@gmail.com>
2023-07-16 19:31:14 +02:00
Mary
fec8291c17 infra: do not assign developers team for now
Hopefully fix PR triage for real...
2023-07-14 11:32:14 +02:00
1101 changed files with 8578 additions and 7796 deletions

View File

@@ -1,8 +1,7 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
# C# files
[*.cs]
[*]
#### Core EditorConfig Options ####
@@ -12,8 +11,11 @@ indent_style = space
tab_width = 4
# New line preferences
end_of_line = crlf
insert_final_newline = false
end_of_line = lf
insert_final_newline = true
# C# files
[*.cs]
#### .NET Coding Conventions ####
@@ -59,7 +61,7 @@ dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_readonly_field = true:suggestion
# Parameter preferences
dotnet_code_quality_unused_parameters = all:suggestion
dotnet_code_quality_unused_parameters = all:silent
#### C# Coding Conventions ####
@@ -85,7 +87,7 @@ csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_prefer_switch_expression = true:suggestion
csharp_style_prefer_switch_expression = false:silent
# Null-checking preferences
csharp_style_conditional_delegate_call = true:suggestion
@@ -94,6 +96,7 @@ csharp_style_conditional_delegate_call = true:suggestion
csharp_prefer_static_local_function = true:suggestion
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
csharp_style_prefer_readonly_struct = true
csharp_style_prefer_method_group_conversion = true
# Code-block preferences
csharp_prefer_braces = true:silent
@@ -109,6 +112,7 @@ csharp_style_prefer_range_operator = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
csharp_style_implicit_object_creation_when_type_is_apparent = true
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:silent
@@ -140,7 +144,6 @@ csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
@@ -158,23 +161,31 @@ csharp_space_between_square_brackets = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
csharp_preserve_single_line_statements = false
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.severity = suggestion
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.symbols = interface
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.style = IPascalCase
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.types_should_be_pascal_case.style = PascalCase
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = PascalCase
dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.symbols = private_static_readonly_fields
dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.severity = suggestion
dotnet_naming_rule.private_static_readonly_fields_should_be_camel_case_and_prefixed_with__.style = _camelCase
dotnet_naming_rule.local_constants_should_be_pascal_case.symbols = local_constants
dotnet_naming_rule.local_constants_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.local_constants_should_be_pascal_case.style = PascalCase
# Symbol specifications
@@ -190,14 +201,39 @@ dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, meth
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private
dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = static, readonly
dotnet_naming_symbols.local_constants.applicable_kinds = local
dotnet_naming_symbols.local_constants.applicable_accessibilities = local
dotnet_naming_symbols.local_constants.required_modifiers = const
# Naming styles
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style._camelCase.required_prefix = _
dotnet_naming_style._camelCase.required_suffix =
dotnet_naming_style._camelCase.word_separator =
dotnet_naming_style._camelCase.capitalization = camel_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.PascalCase.required_prefix =
dotnet_naming_style.PascalCase.required_suffix =
dotnet_naming_style.PascalCase.word_separator =
dotnet_naming_style.PascalCase.capitalization = pascal_case
dotnet_naming_style.IPascalCase.required_prefix = I
dotnet_naming_style.IPascalCase.required_suffix =
dotnet_naming_style.IPascalCase.word_separator =
dotnet_naming_style.IPascalCase.capitalization = pascal_case
[src/Ryujinx.HLE/HOS/Services/**.cs]
# Disable "mark members as static" rule for services
dotnet_diagnostic.CA1822.severity = none
[src/Ryujinx.Ava/UI/ViewModels/**.cs]
# Disable "mark members as static" rule for ViewModels
dotnet_diagnostic.CA1822.severity = none
[src/Ryujinx.Tests/Cpu/*.cs]
# Disable naming rules for CPU tests
dotnet_diagnostic.IDE1006.severity = none

View File

@@ -29,4 +29,4 @@ infra:
- TSRBerry
default:
- "@developers"
- marysaka

View File

@@ -1,19 +1,10 @@
name: Build job
on:
workflow_dispatch:
inputs: {}
pull_request:
branches: [ master ]
paths-ignore:
- '.github/**'
- '*.yml'
- '*.json'
- '*.config'
- 'README.md'
workflow_call:
concurrency:
group: pr-checks-${{ github.event.number }}
group: pr-builds-${{ github.event.number }}
cancel-in-progress: true
env:

71
.github/workflows/checks.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
name: Perform checks
on:
pull_request:
branches: [ master ]
paths:
- '**'
- '!.github/**'
- '!*.yml'
- '!*.config'
- '!README.md'
- '.github/workflows/*.yml'
permissions:
pull-requests: write
checks: write
concurrency:
group: pr-checks-${{ github.event.number }}
cancel-in-progress: true
jobs:
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-dotnet@v3
with:
global-json-file: global.json
- run: dotnet restore
- name: Print dotnet format version
run: dotnet format --version
- name: Run dotnet format whitespace
run: |
dotnet format whitespace --verify-no-changes --report ./whitespace-report.json -v d
- name: Run dotnet format style
run: |
dotnet format style --severity info --verify-no-changes --report ./style-report.json -v d
# For some reason this step sometimes fails with exit code 139 (segfault?),
# so should that be the case we'll try again (3 tries max).
- name: Run dotnet format analyzers
run: |
attempt=0
exit_code=139
until [ $attempt -ge 3 ] || [ $exit_code -ne 139 ]; do
((attempt+=1))
exit_code=0
echo "Attempt: ${attempt}/3"
dotnet format analyzers --severity info --verify-no-changes --report ./analyzers-report.json -v d || exit_code=$?
done
exit $exit_code
- name: Upload report
if: failure()
uses: actions/upload-artifact@v3
with:
name: dotnet-format
path: ./*-report.json
pr_build:
uses: ./.github/workflows/build.yml
needs: format
secrets: inherit

View File

@@ -1,8 +1,10 @@
name: Comment PR artifacts links
on:
workflow_run:
workflows: ['Build job']
workflows: ['Perform checks']
types: [completed]
jobs:
pr_comment:
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'

View File

@@ -20,7 +20,7 @@
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" />
<PackageVersion Include="LibHac" Version="0.18.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.6.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
@@ -34,7 +34,7 @@
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.3-build25" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.28.1-build28" />
<PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />

View File

@@ -20,4 +20,4 @@
}
}
}
}
}

View File

@@ -1448,6 +1448,7 @@ namespace ARMeilleure.Instructions
{
var overflowToInf = fpcr.GetRoundingMode() switch
{
FPRoundingMode.ToNearest => true,
FPRoundingMode.TowardsPlusInfinity => !sign,
FPRoundingMode.TowardsMinusInfinity => sign,
FPRoundingMode.TowardsZero => false,
@@ -2879,6 +2880,7 @@ namespace ARMeilleure.Instructions
{
var overflowToInf = fpcr.GetRoundingMode() switch
{
FPRoundingMode.ToNearest => true,
FPRoundingMode.TowardsPlusInfinity => !sign,
FPRoundingMode.TowardsMinusInfinity => sign,
FPRoundingMode.TowardsZero => false,

View File

@@ -31,7 +31,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
_stillRunning = true;
_updaterThread = new Thread(Update)
{
Name = "HardwareDeviceDriver.OpenAL"
Name = "HardwareDeviceDriver.OpenAL",
};
_updaterThread.Start();

View File

@@ -67,7 +67,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
{
DriverIdentifier = buffer.DataPointer,
BufferId = AL.GenBuffer(),
SampleCount = GetSampleCount(buffer)
SampleCount = GetSampleCount(buffer),
};
AL.BufferData(driverBuffer.BufferId, _targetFormat, buffer.Data, (int)RequestedSampleRate);

View File

@@ -7,7 +7,6 @@ using System;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Threading;
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
using static SDL2.SDL;
@@ -111,7 +110,7 @@ namespace Ryujinx.Audio.Backends.SDL2
channels = (byte)requestedChannelCount,
format = GetSDL2Format(requestedSampleFormat),
freq = (int)requestedSampleRate,
samples = (ushort)sampleCount
samples = (ushort)sampleCount,
};
}

View File

@@ -8,6 +8,6 @@
Alsa = 3,
CoreAudio = 4,
Wasapi = 5,
Dummy = 6
Dummy = 6,
}
}

View File

@@ -3,6 +3,6 @@
public enum SoundIoDeviceAim
{
SoundIoDeviceAimInput = 0,
SoundIoDeviceAimOutput = 1
SoundIoDeviceAimOutput = 1,
}
}

View File

@@ -114,7 +114,7 @@ namespace Ryujinx.Ava.Common
public static void OpenSaveDir(ulong saveDataId)
{
string saveRootPath = Path.Combine(_virtualFileSystem.GetNandPath(), $"user/save/{saveDataId:x16}");
string saveRootPath = Path.Combine(VirtualFileSystem.GetNandPath(), $"user/save/{saveDataId:x16}");
if (!Directory.Exists(saveRootPath))
{

View File

@@ -53,8 +53,6 @@ namespace Ryujinx.Ava.UI.Applet
bool opened = false;
_parent.Activate();
UserResult response = await ContentDialogHelper.ShowDeferredContentDialog(_parent,
title,
message,

View File

@@ -315,8 +315,10 @@ namespace Ryujinx.Ava.UI.Helpers
Window parent = GetMainWindow();
if (parent is { IsActive: true } and MainWindow window && window.ViewModel.IsGameRunning)
if (parent is MainWindow window)
{
parent.Activate();
contentDialogOverlayWindow = new()
{
Height = parent.Bounds.Height,
@@ -369,7 +371,9 @@ namespace Ryujinx.Ava.UI.Helpers
}
else
{
result = await contentDialog.ShowAsync();
result = ContentDialogResult.None;
Logger.Warning?.Print(LogClass.Ui, "Content dialog overlay failed to populate. Default value has been returned.");
}
return result;
@@ -390,7 +394,7 @@ namespace Ryujinx.Ava.UI.Helpers
{
foreach (Window item in al.Windows)
{
if (item.IsActive && item is MainWindow window)
if (item is MainWindow window)
{
return window;
}

View File

@@ -4,6 +4,6 @@
{
List,
Grid,
Chip
Chip,
}
}

View File

@@ -2,6 +2,7 @@ using LibHac.Fs;
using LibHac.Ncm;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.HLE.FileSystem;
using Ryujinx.Ui.App.Common;
using System;
using System.IO;
@@ -81,7 +82,7 @@ namespace Ryujinx.Ava.UI.Models
Task.Run(() =>
{
var saveRoot = Path.Combine(MainWindow.MainWindowViewModel.VirtualFileSystem.GetNandPath(), $"user/save/{info.SaveDataId:x16}");
var saveRoot = Path.Combine(VirtualFileSystem.GetNandPath(), $"user/save/{info.SaveDataId:x16}");
long totalSize = GetDirectorySize(saveRoot);

View File

@@ -105,7 +105,7 @@ namespace Ryujinx.Ava.UI.ViewModels
}
string contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.BuiltInSystem, NcaContentType.Data);
string avatarPath = virtualFileSystem.SwitchPathToSystemPath(contentPath);
string avatarPath = VirtualFileSystem.SwitchPathToSystemPath(contentPath);
if (!string.IsNullOrWhiteSpace(avatarPath))
{

View File

@@ -25,7 +25,7 @@ namespace Ryujinx.Common
_workerThread = new Thread(DoWork)
{
Name = name,
IsBackground = true
IsBackground = true,
};
_workerThread.Start();
}

View File

@@ -8,6 +8,6 @@ namespace Ryujinx.Common.Configuration
{
Auto,
Off,
On
On,
}
}

View File

@@ -7,6 +7,6 @@ namespace Ryujinx.Common.Configuration
public enum GraphicsBackend
{
Vulkan,
OpenGl
OpenGl,
}
}

View File

@@ -9,6 +9,6 @@ namespace Ryujinx.Common.Configuration
None,
Error,
Slowdowns,
All
All,
}
}

View File

@@ -8,6 +8,6 @@ namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
{
Invalid,
GamepadDriver,
CemuHook
CemuHook,
}
}

View File

@@ -8,6 +8,6 @@ namespace Ryujinx.Common.Configuration
{
SoftwarePageTable,
HostMapped,
HostMappedUnsafe
HostMappedUnsafe,
}
}

View File

@@ -6,6 +6,6 @@
OglThreadControlDefault = 0,
OglThreadControlEnable = 1,
OglThreadControlDisable = 2
OglThreadControlDisable = 2,
}
}

View File

@@ -14,6 +14,6 @@ namespace Ryujinx.Common.Logging
Guest,
AccessLog,
Notice,
Trace
Trace,
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
#pragma warning disable CS0169, IDE0051 // Remove unused private member
@@ -9,6 +10,8 @@ namespace Ryujinx.Common.Memory
T _e0;
public readonly int Length => 1;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -18,6 +21,8 @@ namespace Ryujinx.Common.Memory
Array1<T> _other;
public readonly int Length => 2;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -27,6 +32,8 @@ namespace Ryujinx.Common.Memory
Array2<T> _other;
public readonly int Length => 3;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -36,6 +43,8 @@ namespace Ryujinx.Common.Memory
Array3<T> _other;
public readonly int Length => 4;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -45,6 +54,8 @@ namespace Ryujinx.Common.Memory
Array4<T> _other;
public readonly int Length => 5;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -54,6 +65,8 @@ namespace Ryujinx.Common.Memory
Array5<T> _other;
public readonly int Length => 6;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -63,6 +76,8 @@ namespace Ryujinx.Common.Memory
Array6<T> _other;
public readonly int Length => 7;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -72,6 +87,8 @@ namespace Ryujinx.Common.Memory
Array7<T> _other;
public readonly int Length => 8;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -81,6 +98,8 @@ namespace Ryujinx.Common.Memory
Array8<T> _other;
public readonly int Length => 9;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -90,6 +109,8 @@ namespace Ryujinx.Common.Memory
Array9<T> _other;
public readonly int Length => 10;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -99,6 +120,8 @@ namespace Ryujinx.Common.Memory
Array10<T> _other;
public readonly int Length => 11;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -108,6 +131,8 @@ namespace Ryujinx.Common.Memory
Array11<T> _other;
public readonly int Length => 12;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -117,6 +142,8 @@ namespace Ryujinx.Common.Memory
Array12<T> _other;
public readonly int Length => 13;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -126,6 +153,8 @@ namespace Ryujinx.Common.Memory
Array13<T> _other;
public readonly int Length => 14;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -135,6 +164,8 @@ namespace Ryujinx.Common.Memory
Array14<T> _other;
public readonly int Length => 15;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -144,6 +175,8 @@ namespace Ryujinx.Common.Memory
Array15<T> _other;
public readonly int Length => 16;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -153,6 +186,8 @@ namespace Ryujinx.Common.Memory
Array16<T> _other;
public readonly int Length => 17;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -162,6 +197,8 @@ namespace Ryujinx.Common.Memory
Array17<T> _other;
public readonly int Length => 18;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -171,6 +208,8 @@ namespace Ryujinx.Common.Memory
Array18<T> _other;
public readonly int Length => 19;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -180,6 +219,8 @@ namespace Ryujinx.Common.Memory
Array19<T> _other;
public readonly int Length => 20;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -189,6 +230,8 @@ namespace Ryujinx.Common.Memory
Array20<T> _other;
public readonly int Length => 21;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -198,6 +241,8 @@ namespace Ryujinx.Common.Memory
Array21<T> _other;
public readonly int Length => 22;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -207,6 +252,8 @@ namespace Ryujinx.Common.Memory
Array22<T> _other;
public readonly int Length => 23;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -217,6 +264,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 24;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -227,6 +276,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 25;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -237,6 +288,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 26;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -247,6 +300,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 27;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -257,6 +312,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 28;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -267,6 +324,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 29;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -277,6 +336,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 30;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -287,6 +348,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 31;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -297,6 +360,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 32;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -307,6 +372,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 33;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -317,6 +384,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 34;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -327,6 +396,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 35;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -337,6 +408,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 36;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -347,6 +420,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 37;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -357,6 +432,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 38;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -367,6 +444,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 39;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -377,6 +456,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 40;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -387,6 +468,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 41;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -397,6 +480,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 42;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -407,6 +492,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 43;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -417,6 +504,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 44;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -427,6 +516,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 45;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -437,6 +528,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 46;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -447,6 +540,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 47;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -457,6 +552,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 48;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -467,6 +564,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 49;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -477,6 +576,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 50;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -487,6 +588,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 51;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -497,6 +600,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 52;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -507,6 +612,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 53;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -517,6 +624,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 54;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -527,6 +636,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 55;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -537,6 +648,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 56;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -547,6 +660,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 57;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -557,6 +672,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 58;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -567,6 +684,8 @@ namespace Ryujinx.Common.Memory
public readonly int Length => 59;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -576,6 +695,8 @@ namespace Ryujinx.Common.Memory
Array59<T> _other;
public readonly int Length => 60;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -585,6 +706,8 @@ namespace Ryujinx.Common.Memory
Array60<T> _other;
public readonly int Length => 61;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -594,6 +717,8 @@ namespace Ryujinx.Common.Memory
Array61<T> _other;
public readonly int Length => 62;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -603,6 +728,8 @@ namespace Ryujinx.Common.Memory
Array62<T> _other;
public readonly int Length => 63;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -612,6 +739,8 @@ namespace Ryujinx.Common.Memory
Array63<T> _other;
public readonly int Length => 64;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -622,6 +751,8 @@ namespace Ryujinx.Common.Memory
Array8<T> _other2;
public readonly int Length => 73;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -632,6 +763,8 @@ namespace Ryujinx.Common.Memory
Array62<T> _other2;
public readonly int Length => 127;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -642,6 +775,8 @@ namespace Ryujinx.Common.Memory
Array63<T> _other2;
public readonly int Length => 128;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
@@ -652,6 +787,8 @@ namespace Ryujinx.Common.Memory
Array127<T> _other2;
public readonly int Length => 256;
public ref T this[int index] => ref AsSpan()[index];
[Pure]
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
}
}

View File

@@ -179,7 +179,7 @@ namespace Ryujinx.Cpu
{
addressSpace = null;
const MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
const MemoryAllocationFlags AsFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36);
@@ -191,8 +191,8 @@ namespace Ryujinx.Cpu
try
{
baseMemory = new MemoryBlock(addressSpaceSize, asFlags);
mirrorMemory = new MemoryBlock(addressSpaceSize, asFlags);
baseMemory = new MemoryBlock(addressSpaceSize, AsFlags);
mirrorMemory = new MemoryBlock(addressSpaceSize, AsFlags);
addressSpace = new AddressSpace(backingMemory, baseMemory, mirrorMemory, addressSpaceSize, supports4KBPages);
break;

View File

@@ -22,6 +22,6 @@ namespace Ryujinx.Cpu.AppleHv.Arm
UserNoneKernelReadWrite = (1UL << (int)PxnShift) | (1UL << (int)UxnShift) | (0UL << (int)ApShift),
UserNoneKernelRead = (1UL << (int)PxnShift) | (1UL << (int)UxnShift) | (2UL << (int)ApShift),
UserReadKernelRead = (1UL << (int)PxnShift) | (1UL << (int)UxnShift) | (3UL << (int)ApShift)
UserReadKernelRead = (1UL << (int)PxnShift) | (1UL << (int)UxnShift) | (3UL << (int)ApShift),
}
}

View File

@@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.Device
TypeCode.Double => sizeof(double),
TypeCode.Decimal => sizeof(decimal),
TypeCode.Boolean => sizeof(bool),
_ => throw new ArgumentException($"Length for type \"{type.Name}\" is unknown.")
_ => throw new ArgumentException($"Length for type \"{type.Name}\" is unknown."),
};
}
}

View File

@@ -412,7 +412,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
{
ThreadedCounterEvent evt = new ThreadedCounterEvent(this, type, _lastSampleCounterClear);
ThreadedCounterEvent evt = new(this, type, _lastSampleCounterClear);
New<ReportCounterCommand>().Set(Ref(evt), type, Ref(resultHandler), divisor, hostReserved);
QueueCommand();

View File

@@ -187,7 +187,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
X = scale * 2f / viewportWidth,
Y = scale * 2f / viewportHeight,
Z = 1,
W = disableTransformF
W = disableTransformF,
});
}
}
@@ -210,7 +210,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
ReadOnlySpan<byte> data = MemoryMarshal.Cast<SupportBuffer, byte>(MemoryMarshal.CreateSpan(ref _data, 1));
_renderer.SetBufferData(_handle, _startOffset, data.Slice(_startOffset, _endOffset - _startOffset));
_renderer.SetBufferData(_handle, _startOffset, data[_startOffset.._endOffset]);
_startOffset = -1;
_endOffset = -1;

View File

@@ -8,8 +8,6 @@ using System.Threading;
namespace Ryujinx.Graphics.Gpu
{
using Texture = Image.Texture;
/// <summary>
/// GPU image presentation window.
/// </summary>
@@ -202,13 +200,13 @@ namespace Ryujinx.Graphics.Gpu
{
pt.AcquireCallback(_context, pt.UserObj);
Texture texture = pt.Cache.FindOrCreateTexture(null, TextureSearchFlags.WithUpscale, pt.Info, 0, pt.Range);
Image.Texture texture = pt.Cache.FindOrCreateTexture(null, TextureSearchFlags.WithUpscale, pt.Info, 0, pt.Range);
pt.Cache.Tick();
texture.SynchronizeMemory();
ImageCrop crop = new ImageCrop(
ImageCrop crop = new(
(int)(pt.Crop.Left * texture.ScaleFactor),
(int)MathF.Ceiling(pt.Crop.Right * texture.ScaleFactor),
(int)(pt.Crop.Top * texture.ScaleFactor),

View File

@@ -15,6 +15,6 @@
Tsec = 0xe0,
Tsecb = 0xe1,
Nvjpg = 0xc0,
Nvdec = 0xf0
Nvdec = 0xf0,
}
}

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Host1x
_syncMgr = syncMgr;
_state = new DeviceState<Host1xClassRegisters>(new Dictionary<string, RwCallback>
{
{ nameof(Host1xClassRegisters.WaitSyncpt32), new RwCallback(WaitSyncpt32, null) }
{ nameof(Host1xClassRegisters.WaitSyncpt32), new RwCallback(WaitSyncpt32, null) },
});
}

View File

@@ -16,6 +16,6 @@
NonIncrW,
GatherW,
RestartW,
Extend
Extend,
}
}

View File

@@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Host1x
_state = new DeviceState<ThiRegisters>(new Dictionary<string, RwCallback>
{
{ nameof(ThiRegisters.IncrSyncpt), new RwCallback(IncrSyncpt, null) },
{ nameof(ThiRegisters.Method1), new RwCallback(Method1, null) }
{ nameof(ThiRegisters.Method1), new RwCallback(Method1, null) },
});
_previousContextId = -1;

View File

@@ -127,7 +127,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
53, 60, 61, 54, 47, 55, 62, 63,
};
private static ReadOnlySpan<byte> ZigZagScan => new byte[]
@@ -135,7 +135,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264
0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4,
1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4,
1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4,
3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4
3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4,
};
private static void WriteScalingList(ref H264BitStreamWriter writer, IArray<byte> list)

View File

@@ -10,6 +10,6 @@
Verbose = 40,
Debug = 48,
Trace = 56,
MaxOffset = 64
MaxOffset = 64,
}
}

View File

@@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
private static readonly Dictionary<string, (int, int)> _librariesWhitelist = new()
{
{ AvCodecLibraryName, (58, 59) },
{ AvUtilLibraryName, (56, 57) }
{ AvUtilLibraryName, (56, 57) },
};
private static string FormatLibraryNameForCurrentOs(string libraryName, int version)

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Nvdec
_rm = new ResourceManager(gmm, new SurfaceCache(gmm));
_state = new DeviceState<NvdecRegisters>(new Dictionary<string, RwCallback>
{
{ nameof(NvdecRegisters.Execute), new RwCallback(Execute, null) }
{ nameof(NvdecRegisters.Execute), new RwCallback(Execute, null) },
});
_contexts = new ConcurrentDictionary<long, NvdecDecoderContext>();
}

View File

@@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Nvdec.Types.H264
FrameType = 0,
PicWidthInMbsMinus1 = PicWidthInMbs - 1,
PicHeightInMapUnitsMinus1 = (PicHeightInMbs >> (FrameMbsOnlyFlag != 0 ? 0 : 1)) - 1,
QpprimeYZeroTransformBypassFlag = QpprimeYZeroTransformBypassFlag
QpprimeYZeroTransformBypassFlag = QpprimeYZeroTransformBypassFlag,
};
}
}

View File

@@ -68,7 +68,7 @@ namespace Ryujinx.Graphics.Nvdec.Types.Vp8
FirstPartSize = FirstPartSize,
Version = Version,
FrameWidth = FrameWidth,
FrameHeight = FrameHeight
FrameHeight = FrameHeight,
};
}
}

View File

@@ -7,6 +7,6 @@
FrameSizeChanged = 1 << 2,
ErrorResilientMode = 1 << 3,
LastShowFrame = 1 << 4,
IntraOnly = 1 << 5
IntraOnly = 1 << 5,
}
}

View File

@@ -80,7 +80,7 @@ namespace Ryujinx.Graphics.Nvdec.Types.Vp9
SegmentFeatureData = Seg.FeatureData,
ModeRefDeltaEnabled = Lf.ModeRefDeltaEnabled != 0,
RefDeltas = Lf.RefDeltas,
ModeDeltas = Lf.ModeDeltas
ModeDeltas = Lf.ModeDeltas,
};
}
}

View File

@@ -668,7 +668,7 @@ namespace Ryujinx.Graphics.OpenGL
ShaderStage.TessellationEvaluation => ShaderType.TessEvaluationShader,
ShaderStage.Geometry => ShaderType.GeometryShader,
ShaderStage.Fragment => ShaderType.FragmentShader,
_ => ShaderType.VertexShader
_ => ShaderType.VertexShader,
};
}
}

View File

@@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.OpenGL
AmdUnix,
IntelWindows,
IntelUnix,
Nvidia
Nvidia,
}
private static readonly Lazy<GpuVendor> _gpuVendor = new(GetGpuVendor);

View File

@@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
info.BorderColor.Red,
info.BorderColor.Green,
info.BorderColor.Blue,
info.BorderColor.Alpha
info.BorderColor.Alpha,
};
GL.SamplerParameter(Handle, SamplerParameterName.TextureBorderColor, borderColor);

View File

@@ -133,7 +133,7 @@ void main()
1 => SizedInternalFormat.R8ui,
2 => SizedInternalFormat.Rg8ui,
4 => SizedInternalFormat.Rgba8ui,
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
};
}
else if (componentSize == 2)
@@ -143,7 +143,7 @@ void main()
1 => SizedInternalFormat.R16ui,
2 => SizedInternalFormat.Rg16ui,
4 => SizedInternalFormat.Rgba16ui,
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
};
}
else if (componentSize == 4)
@@ -153,7 +153,7 @@ void main()
1 => SizedInternalFormat.R32ui,
2 => SizedInternalFormat.Rg32ui,
4 => SizedInternalFormat.Rgba32ui,
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
};
}
else

View File

@@ -173,7 +173,7 @@ void main()
4 => SizedInternalFormat.R32ui,
8 => SizedInternalFormat.Rg32ui,
16 => SizedInternalFormat.Rgba32ui,
_ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}.")
_ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}."),
};
}

View File

@@ -72,7 +72,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
(int)Info.SwizzleR.Convert(),
(int)Info.SwizzleG.Convert(),
(int)Info.SwizzleB.Convert(),
(int)Info.SwizzleA.Convert()
(int)Info.SwizzleA.Convert(),
};
if (Info.Format == Format.A1B5G5R5Unorm)
@@ -210,7 +210,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
Target.Texture2DMultisample => Target.Texture2D,
Target.Texture2DMultisampleArray => Target.Texture2DArray,
_ => Target
_ => Target,
};
TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast(
@@ -354,7 +354,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
TextureTarget.TextureCubeMapArray => (layer / 6) * mipSize,
TextureTarget.Texture1DArray => layer * mipSize,
TextureTarget.Texture2DArray => layer * mipSize,
_ => 0
_ => 0,
};
}

View File

@@ -210,7 +210,7 @@ namespace Ryujinx.Graphics.OpenGL
GL.Arb.MaxShaderCompilerThreads(Math.Min(Environment.ProcessorCount, 8));
}
_counters.Initialize(_pipeline);
_counters.Initialize();
// This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles.
// This call is expected to fail if we're running with a core profile,

View File

@@ -5,7 +5,6 @@ using Ryujinx.Graphics.OpenGL.Image;
using Ryujinx.Graphics.OpenGL.Queries;
using Ryujinx.Graphics.Shader;
using System;
using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.OpenGL
{
@@ -44,7 +43,7 @@ namespace Ryujinx.Graphics.OpenGL
private CounterQueueEvent _activeConditionalRender;
private Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount];
private readonly Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount];
private readonly (TextureBase, Format)[] _images;
private TextureBase _unit0Texture;

View File

@@ -13,8 +13,6 @@ namespace Ryujinx.Graphics.OpenGL.Queries
public CounterType Type { get; }
public bool Disposed { get; private set; }
private readonly Pipeline _pipeline;
private readonly Queue<CounterQueueEvent> _events = new();
private CounterQueueEvent _current;
@@ -30,12 +28,10 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private readonly Thread _consumerThread;
internal CounterQueue(Pipeline pipeline, CounterType type)
internal CounterQueue(CounterType type)
{
Type = type;
_pipeline = pipeline;
QueryTarget glType = GetTarget(Type);
_queryPool = new Queue<BufferedQuery>(QueryPoolInitialSize);

View File

@@ -14,12 +14,12 @@ namespace Ryujinx.Graphics.OpenGL.Queries
_counterQueues = new CounterQueue[count];
}
public void Initialize(Pipeline pipeline)
public void Initialize()
{
for (int index = 0; index < _counterQueues.Length; index++)
{
CounterType type = (CounterType)index;
_counterQueues[index] = new CounterQueue(pipeline, type);
_counterQueues[index] = new CounterQueue(type);
}
}

View File

@@ -41,7 +41,7 @@ namespace Ryujinx.Graphics.OpenGL
{
Info = view.Info,
View = view,
RemainingFrames = DisposedLiveFrames
RemainingFrames = DisposedLiveFrames,
});
}
}

View File

@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.OpenGL
SyncHandle handle = new()
{
ID = id,
Handle = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None)
Handle = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None),
};

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.Shader
{
public struct BufferDescriptor
public readonly struct BufferDescriptor
{
// New fields should be added to the end of the struct to keep disk shader cache compatibility.

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
class OperandManager
{
private Dictionary<AstOperand, string> _locals;
private readonly Dictionary<AstOperand, string> _locals;
public OperandManager()
{

View File

@@ -13,8 +13,6 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
static class Declarations
{
private static readonly string[] _stagePrefixes = { "cp", "vp", "tcp", "tep", "gp", "fp" };
public static void DeclareParameters(CodeGenContext context, StructuredFunction function)
{
DeclareParameters(context, function.InArguments, 0);
@@ -192,7 +190,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
SamplerType.Texture3D => Dim.Dim3D,
SamplerType.TextureCube => Dim.Cube,
SamplerType.TextureBuffer => Dim.Buffer,
_ => throw new InvalidOperationException($"Invalid sampler type \"{sampler.Type & SamplerType.Mask}\".")
_ => throw new InvalidOperationException($"Invalid sampler type \"{sampler.Type & SamplerType.Mask}\"."),
};
var imageType = context.TypeImage(
@@ -519,10 +517,5 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
: (isOutput ? context.Outputs : context.Inputs);
dict.Add(ioDefinition, spvVar);
}
private static string GetStagePrefix(ShaderStage stage)
{
return _stagePrefixes[(int)stage];
}
}
}

View File

@@ -24,4 +24,4 @@ namespace Ryujinx.Graphics.Shader
return new TextureDefinition(Set, Binding, Name, Type, Format, Flags | flag);
}
}
}
}

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.Shader
{
public struct TextureDescriptor
public readonly struct TextureDescriptor
{
// New fields should be added to the end of the struct to keep disk shader cache compatibility.

View File

@@ -266,7 +266,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{
AccurateType = accurateType,
Type = type,
UsageFlags = usageFlags
UsageFlags = usageFlags,
};
int binding;

View File

@@ -889,7 +889,7 @@ namespace Ryujinx.Graphics.Texture.Astc
0 => 0,
1 => 32,
2 => 63,
_ => 0
_ => 0,
};
break;
@@ -942,7 +942,7 @@ namespace Ryujinx.Graphics.Texture.Astc
2 => 32,
3 => 47,
4 => 63,
_ => 0
_ => 0,
};
break;

View File

@@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Texture.Astc
{
JustBits,
Quint,
Trit
Trit,
}
readonly EIntegerEncoding _encoding;
@@ -162,7 +162,7 @@ namespace Ryujinx.Graphics.Texture.Astc
IntegerEncoded intEncoded = new(EIntegerEncoding.Quint, numberBitsPerValue)
{
BitValue = m[i],
QuintValue = encodings[i]
QuintValue = encodings[i],
};
listIntegerEncoded.Add(ref intEncoded);
@@ -309,7 +309,7 @@ namespace Ryujinx.Graphics.Texture.Astc
2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 0, 2, 1, 1, 2,
1, 2, 1, 1, 2, 2, 2, 1, 1, 2, 2, 1, 2, 1, 2,
0, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 1, 2, 2, 2
2, 1, 2, 2, 2,
};
private static ReadOnlySpan<byte> QuintEncodings => new byte[]
@@ -339,7 +339,7 @@ namespace Ryujinx.Graphics.Texture.Astc
0, 1, 4, 1, 1, 4, 0, 2, 3, 1, 2, 3, 2, 2, 3,
3, 2, 3, 4, 2, 3, 2, 4, 3, 0, 2, 4, 1, 2, 4,
0, 3, 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, 4, 3, 3,
3, 4, 3, 0, 3, 4, 1, 3, 4
3, 4, 3, 0, 3, 4, 1, 3, 4,
};
}
}

View File

@@ -21,12 +21,12 @@ namespace Ryujinx.Graphics.Texture
new int[] { 18, 60, -18, -60 },
new int[] { 24, 80, -24, -80 },
new int[] { 33, 106, -33, -106 },
new int[] { 47, 183, -47, -183 }
new int[] { 47, 183, -47, -183 },
};
private static readonly int[] _etc2Lut =
{
3, 6, 11, 16, 23, 32, 41, 64
3, 6, 11, 16, 23, 32, 41, 64,
};
private static readonly int[][] _etc2AlphaLut =
@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Texture
new int[] { -3, -4, -7, -10, 2, 3, 6, 9 },
new int[] { -1, -2, -3, -10, 0, 1, 2, 9 },
new int[] { -4, -6, -8, -9, 3, 5, 7, 8 },
new int[] { -3, -5, -7, -9, 2, 4, 6, 8 }
new int[] { -3, -5, -7, -9, 2, 4, 6, 8 },
};
public static byte[] DecodeRgb(ReadOnlySpan<byte> data, int width, int height, int depth, int levels, int layers)

View File

@@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.Texture.Encoders
private static readonly int[] _mostFrequentPartitions = new int[]
{
0, 13, 2, 1, 15, 14, 10, 23
0, 13, 2, 1, 15, 14, 10, 23,
};
private static Block CompressBlock(ReadOnlySpan<byte> data, int x, int y, int width, int height, bool fastMode)
@@ -233,7 +233,7 @@ namespace Ryujinx.Graphics.Texture.Encoders
1 => new RgbaColor8(255, 0, 0, 0).ToUInt32(),
2 => new RgbaColor8(0, 255, 0, 0).ToUInt32(),
3 => new RgbaColor8(0, 0, 255, 0).ToUInt32(),
_ => new RgbaColor8(0, 0, 0, 255).ToUInt32()
_ => new RgbaColor8(0, 0, 0, 255).ToUInt32(),
};
}
else

View File

@@ -5,6 +5,6 @@
Fast,
Exhaustive,
ModeMask = 0xff,
Multithreaded = 1 << 8
Multithreaded = 1 << 8,
}
}

View File

@@ -89,7 +89,7 @@ namespace Ryujinx.Graphics.Texture
8 => Convert<ulong>(dst, data),
12 => Convert<Bpp12Pixel>(dst, data),
16 => Convert<Vector128<byte>>(dst, data),
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format.")
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format."),
};
}
@@ -240,7 +240,7 @@ namespace Ryujinx.Graphics.Texture
8 => Convert<ulong>(output, data),
12 => Convert<Bpp12Pixel>(output, data),
16 => Convert<Vector128<byte>>(output, data),
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format.")
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format."),
};
}
return output;
@@ -359,7 +359,7 @@ namespace Ryujinx.Graphics.Texture
8 => Convert<ulong>(dst, data),
12 => Convert<Bpp12Pixel>(dst, data),
16 => Convert<Vector128<byte>>(dst, data),
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format.")
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format."),
};
}
@@ -504,7 +504,7 @@ namespace Ryujinx.Graphics.Texture
8 => Convert<ulong>(output, data),
12 => Convert<Bpp12Pixel>(output, data),
16 => Convert<Vector128<byte>>(output, data),
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format.")
_ => throw new NotSupportedException($"Unable to convert ${bytesPerPixel} bpp pixel format."),
};
}

View File

@@ -11,21 +11,21 @@
new BC7ModeInfo(1, 0, 0, 2, 1, 2, 3, 5, 6),
new BC7ModeInfo(1, 0, 0, 2, 0, 2, 2, 7, 8),
new BC7ModeInfo(1, 0, 2, 0, 0, 4, 0, 7, 7),
new BC7ModeInfo(2, 6, 4, 0, 0, 2, 0, 5, 5)
new BC7ModeInfo(2, 6, 4, 0, 0, 2, 0, 5, 5),
};
public static readonly byte[][] Weights =
{
new byte[] { 0, 21, 43, 64 },
new byte[] { 0, 9, 18, 27, 37, 46, 55, 64 },
new byte[] { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }
new byte[] { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 },
};
public static readonly byte[][] InverseWeights =
{
new byte[] { 64, 43, 21, 0 },
new byte[] { 64, 55, 46, 37, 27, 18, 9, 0 },
new byte[] { 64, 60, 55, 51, 47, 43, 38, 34, 30, 26, 21, 17, 13, 9, 4, 0 }
new byte[] { 64, 60, 55, 51, 47, 43, 38, 34, 30, 26, 21, 17, 13, 9, 4, 0 },
};
public static readonly byte[][][] FixUpIndices = new byte[3][][]
@@ -47,7 +47,7 @@
new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 },
new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 },
new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 },
new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }
new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 }, new byte[] { 0, 0, 0 },
},
new byte[64][]
{
@@ -66,7 +66,7 @@
new byte[] { 0, 6, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 6, 0 }, new byte[] { 0, 8, 0 },
new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 2, 0 },
new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 }, new byte[] { 0, 15, 0 },
new byte[] { 0, 15, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 15, 0 }
new byte[] { 0, 15, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 2, 0 }, new byte[] { 0, 15, 0 },
},
new byte[64][]
{
@@ -85,8 +85,8 @@
new byte[] { 0, 3, 15 }, new byte[] { 0, 15, 3 }, new byte[] { 0, 5, 15 }, new byte[] { 0, 5, 15 },
new byte[] { 0, 5, 15 }, new byte[] { 0, 8, 15 }, new byte[] { 0, 5, 15 }, new byte[] { 0, 10, 15 },
new byte[] { 0, 5, 15 }, new byte[] { 0, 10, 15 }, new byte[] { 0, 8, 15 }, new byte[] { 0, 13, 15 },
new byte[] { 0, 15, 3 }, new byte[] { 0, 12, 15 }, new byte[] { 0, 3, 15 }, new byte[] { 0, 3, 8 }
}
new byte[] { 0, 15, 3 }, new byte[] { 0, 12, 15 }, new byte[] { 0, 3, 15 }, new byte[] { 0, 3, 8 },
},
};
public static readonly byte[][][] PartitionTable = new byte[3][][]
@@ -156,7 +156,7 @@
new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 60
new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 61
new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 62
new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // 63
new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 63
},
new byte[64][]
{
@@ -223,7 +223,7 @@
new byte[16] { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, // 60
new byte[16] { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, // 61
new byte[16] { 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0 }, // 62
new byte[16] { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1 } // 63
new byte[16] { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1 }, // 63
},
new byte[64][]
{
@@ -290,8 +290,8 @@
new byte[16] { 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1 }, // 60
new byte[16] { 0, 2, 2, 2, 1, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2 }, // 61
new byte[16] { 0, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, // 62
new byte[16] { 0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 2, 2, 2, 0 } // 63
}
new byte[16] { 0, 1, 1, 1, 2, 0, 1, 1, 2, 2, 0, 1, 2, 2, 2, 0 }, // 63
},
};
}
}

View File

@@ -1199,7 +1199,7 @@ namespace Ryujinx.Graphics.Texture.Utils
RgbaColor32 weightV = new(colorWeight)
{
A = alphaWeight
A = alphaWeight,
};
RgbaColor32 invWeightV = new RgbaColor32(64) - weightV;

View File

@@ -77,7 +77,7 @@ namespace Ryujinx.Graphics.Texture.Utils
1 => G,
2 => B,
3 => A,
_ => throw new ArgumentOutOfRangeException(nameof(index))
_ => throw new ArgumentOutOfRangeException(nameof(index)),
};
}
}

View File

@@ -417,7 +417,7 @@ namespace Ryujinx.Graphics.Vic.Image
0 => offsets.LumaOffset,
1 => offsets.ChromaUOffset,
2 => offsets.ChromaVOffset,
_ => throw new ArgumentOutOfRangeException(nameof(plane))
_ => throw new ArgumentOutOfRangeException(nameof(plane)),
};
}

View File

@@ -7,6 +7,6 @@ namespace Ryujinx.Graphics.Vic.Types
Bob,
NewBob,
Disi1,
WeaveLumaBobFieldChroma
WeaveLumaBobFieldChroma,
}
}

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Vic.Types
TopFieldChromaBottom,
BottomFieldChromaTop,
SubPicTopFieldChromaBottom,
SubPicBottomFieldChromaTop
SubPicBottomFieldChromaTop,
}
static class FrameFormatExtensions

View File

@@ -76,6 +76,6 @@
Y8___U8___V8_N422R,
Y8___U8___V8_N420,
U8,
V8
V8,
}
}

View File

@@ -19,7 +19,7 @@ namespace Ryujinx.Graphics.Vic
_rm = new ResourceManager(gmm, new BufferPool<Pixel>(), new BufferPool<byte>());
_state = new DeviceState<VicRegisters>(new Dictionary<string, RwCallback>
{
{ nameof(VicRegisters.Execute), new RwCallback(Execute, null) }
{ nameof(VicRegisters.Execute), new RwCallback(Execute, null) },
});
}

View File

@@ -3,6 +3,6 @@ namespace Ryujinx.Graphics.Video
public enum FrameField
{
Progressive,
Interlaced
Interlaced,
}
}

View File

@@ -709,12 +709,14 @@ namespace Ryujinx.Graphics.Vulkan
return CommandBuffer.Handle == cb.Handle;
}
#pragma warning disable CA1822 // Mark member as static
public void SetAlphaTest(bool enable, float reference, CompareOp op)
{
// This is currently handled using shader specialization, as Vulkan does not support alpha test.
// In the future, we may want to use this to write the reference value into the support buffer,
// to avoid creating one version of the shader per reference value used.
}
#pragma warning restore CA1822
public void SetBlendState(AdvancedBlendDescriptor blend)
{

View File

@@ -1,3 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Ryujinx.Tests")]
[assembly: InternalsVisibleTo("Ryujinx.Tests")]

View File

@@ -8,4 +8,4 @@ namespace Ryujinx.HLE.Exceptions
public GuestBrokeExecutionException() : base(ExMsg) { }
}
}
}

View File

@@ -2,8 +2,8 @@
namespace Ryujinx.HLE.Exceptions
{
class InternalServiceException: Exception
class InternalServiceException : Exception
{
public InternalServiceException(string message) : base(message) { }
}
}
}

View File

@@ -6,4 +6,4 @@ namespace Ryujinx.HLE.Exceptions
{
public InvalidFirmwarePackageException(string message) : base(message) { }
}
}
}

View File

@@ -6,4 +6,4 @@ namespace Ryujinx.HLE.Exceptions
{
public InvalidNpdmException(string message) : base(message) { }
}
}
}

View File

@@ -3,13 +3,13 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.HLE.Exceptions
{
public class InvalidStructLayoutException<T> : Exception
public class InvalidStructLayoutException<T> : Exception
{
static readonly Type _structType = typeof(T);
public InvalidStructLayoutException(string message) : base(message) { }
public InvalidStructLayoutException(int expectedSize)
: base($"Type {_structType.Name} has the wrong size. Expected: {expectedSize} bytes, got: {Unsafe.SizeOf<T>()} bytes") { }
}
}
}

View File

@@ -6,4 +6,4 @@ namespace Ryujinx.HLE.Exceptions
{
public InvalidSystemResourceException(string message) : base(message) { }
}
}
}

View File

@@ -47,7 +47,7 @@ namespace Ryujinx.HLE.Exceptions
private string BuildMessage()
{
StringBuilder sb = new StringBuilder();
StringBuilder sb = new();
// Print the IPC command details (service name, command ID, and handler)
(Type callingType, MethodBase callingMethod) = WalkStackTrace(new StackTrace(this));
@@ -58,9 +58,9 @@ namespace Ryujinx.HLE.Exceptions
var ipcCommands = Request.Type > IpcMessageType.TipcCloseSession ? Service.TipcCommands : Service.CmifCommands;
// Find the handler for the method called
var ipcHandler = ipcCommands.FirstOrDefault(x => x.Value == callingMethod);
var ipcHandler = ipcCommands.FirstOrDefault(x => x.Value == callingMethod);
var ipcCommandId = ipcHandler.Key;
var ipcMethod = ipcHandler.Value;
var ipcMethod = ipcHandler.Value;
if (ipcMethod != null)
{
@@ -73,9 +73,9 @@ namespace Ryujinx.HLE.Exceptions
sb.AppendLine(Context.Thread.GetGuestStackTrace());
// Print buffer information
if (Request.PtrBuff.Count > 0 ||
Request.SendBuff.Count > 0 ||
Request.ReceiveBuff.Count > 0 ||
if (Request.PtrBuff.Count > 0 ||
Request.SendBuff.Count > 0 ||
Request.ReceiveBuff.Count > 0 ||
Request.ExchangeBuff.Count > 0 ||
Request.RecvListBuff.Count > 0)
{
@@ -149,7 +149,7 @@ namespace Ryujinx.HLE.Exceptions
// Find the IIpcService method that threw this exception
while ((frame = trace.GetFrame(i++)) != null)
{
var method = frame.GetMethod();
var method = frame.GetMethod();
var declType = method.DeclaringType;
if (typeof(IpcService).IsAssignableFrom(declType))
@@ -161,4 +161,4 @@ namespace Ryujinx.HLE.Exceptions
return (null, null);
}
}
}
}

View File

@@ -6,4 +6,4 @@ namespace Ryujinx.HLE.Exceptions
{
public TamperCompilationException(string message) : base(message) { }
}
}
}

View File

@@ -6,4 +6,4 @@ namespace Ryujinx.HLE.Exceptions
{
public TamperExecutionException(string message) : base(message) { }
}
}
}

View File

@@ -10,4 +10,4 @@ namespace Ryujinx.HLE.Exceptions
public UndefinedInstructionException(ulong address, int opCode) : base(string.Format(ExMsg, address, opCode)) { }
}
}
}

View File

@@ -26,17 +26,17 @@ namespace Ryujinx.HLE.FileSystem
public class ContentManager
{
private const ulong SystemVersionTitleId = 0x0100000000000809;
private const ulong SystemUpdateTitleId = 0x0100000000000816;
private const ulong SystemUpdateTitleId = 0x0100000000000816;
private Dictionary<StorageId, LinkedList<LocationEntry>> _locationEntries;
private Dictionary<string, ulong> _sharedFontTitleDictionary;
private Dictionary<ulong, string> _systemTitlesNameDictionary;
private Dictionary<string, string> _sharedFontFilenameDictionary;
private readonly Dictionary<string, ulong> _sharedFontTitleDictionary;
private readonly Dictionary<ulong, string> _systemTitlesNameDictionary;
private readonly Dictionary<string, string> _sharedFontFilenameDictionary;
private SortedDictionary<(ulong titleId, NcaContentType type), string> _contentDictionary;
private struct AocItem
private readonly struct AocItem
{
public readonly string ContainerPath;
public readonly string NcaPath;
@@ -48,16 +48,16 @@ namespace Ryujinx.HLE.FileSystem
}
}
private SortedList<ulong, AocItem> _aocData { get; }
private SortedList<ulong, AocItem> AocData { get; }
private VirtualFileSystem _virtualFileSystem;
private readonly VirtualFileSystem _virtualFileSystem;
private readonly object _lock = new();
public ContentManager(VirtualFileSystem virtualFileSystem)
{
_contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
_sharedFontTitleDictionary = new Dictionary<string, ulong>
{
@@ -66,7 +66,7 @@ namespace Ryujinx.HLE.FileSystem
{ "FontExtendedChineseSimplified", 0x0100000000000814 },
{ "FontKorean", 0x0100000000000812 },
{ "FontChineseTraditional", 0x0100000000000813 },
{ "FontNintendoExtended", 0x0100000000000810 }
{ "FontNintendoExtended", 0x0100000000000810 },
};
_systemTitlesNameDictionary = new Dictionary<ulong, string>()
@@ -86,12 +86,12 @@ namespace Ryujinx.HLE.FileSystem
{ "FontExtendedChineseSimplified", "nintendo_udsg-r_ext_zh-cn_003.bfttf" },
{ "FontKorean", "nintendo_udsg-r_ko_003.bfttf" },
{ "FontChineseTraditional", "nintendo_udjxh-db_zh-tw_003.bfttf" },
{ "FontNintendoExtended", "nintendo_ext_003.bfttf" }
{ "FontNintendoExtended", "nintendo_ext_003.bfttf" },
};
_virtualFileSystem = virtualFileSystem;
_aocData = new SortedList<ulong, AocItem>();
AocData = new SortedList<ulong, AocItem>();
}
public void LoadEntries(Switch device = null)
@@ -99,18 +99,18 @@ namespace Ryujinx.HLE.FileSystem
lock (_lock)
{
_contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
foreach (StorageId storageId in Enum.GetValues<StorageId>())
{
string contentDirectory = null;
string contentPathString = null;
string contentDirectory = null;
string contentPathString = null;
string registeredDirectory = null;
try
{
contentPathString = ContentPath.GetContentPath(storageId);
contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString);
contentPathString = ContentPath.GetContentPath(storageId);
contentDirectory = ContentPath.GetRealPath(contentPathString);
registeredDirectory = Path.Combine(contentDirectory, "registered");
}
catch (NotSupportedException)
@@ -120,7 +120,7 @@ namespace Ryujinx.HLE.FileSystem
Directory.CreateDirectory(registeredDirectory);
LinkedList<LocationEntry> locationList = new LinkedList<LocationEntry>();
LinkedList<LocationEntry> locationList = new();
void AddEntry(LocationEntry entry)
{
@@ -133,24 +133,19 @@ namespace Ryujinx.HLE.FileSystem
{
string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty);
using (FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0]))
{
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
using FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0]);
Nca nca = new(_virtualFileSystem.KeySet, ncaFile.AsStorage());
string switchPath = contentPathString + ":/" + ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar);
string switchPath = contentPathString + ":/" + ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar);
// Change path format to switch's
switchPath = switchPath.Replace('\\', '/');
// Change path format to switch's
switchPath = switchPath.Replace('\\', '/');
LocationEntry entry = new LocationEntry(switchPath,
0,
nca.Header.TitleId,
nca.Header.ContentType);
LocationEntry entry = new(switchPath, 0, nca.Header.TitleId, nca.Header.ContentType);
AddEntry(entry);
AddEntry(entry);
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName);
}
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName);
}
}
@@ -160,24 +155,19 @@ namespace Ryujinx.HLE.FileSystem
{
string ncaName = Path.GetFileNameWithoutExtension(filePath);
using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
using FileStream ncaFile = new(filePath, FileMode.Open, FileAccess.Read);
Nca nca = new(_virtualFileSystem.KeySet, ncaFile.AsStorage());
string switchPath = contentPathString + ":/" + filePath.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar);
string switchPath = contentPathString + ":/" + filePath.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar);
// Change path format to switch's
switchPath = switchPath.Replace('\\', '/');
// Change path format to switch's
switchPath = switchPath.Replace('\\', '/');
LocationEntry entry = new LocationEntry(switchPath,
0,
nca.Header.TitleId,
nca.Header.ContentType);
LocationEntry entry = new(switchPath, 0, nca.Header.TitleId, nca.Header.ContentType);
AddEntry(entry);
AddEntry(entry);
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName);
}
_contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName);
}
}
@@ -186,10 +176,7 @@ namespace Ryujinx.HLE.FileSystem
_locationEntries.Remove(storageId);
}
if (!_locationEntries.ContainsKey(storageId))
{
_locationEntries.Add(storageId, locationList);
}
_locationEntries.TryAdd(storageId, locationList);
}
if (device != null)
@@ -239,7 +226,7 @@ namespace Ryujinx.HLE.FileSystem
public void AddAocItem(ulong titleId, string containerPath, string ncaPath, bool mergedToContainer = false)
{
// TODO: Check Aoc version.
if (!_aocData.TryAdd(titleId, new AocItem(containerPath, ncaPath)))
if (!AocData.TryAdd(titleId, new AocItem(containerPath, ncaPath)))
{
Logger.Warning?.Print(LogClass.Application, $"Duplicate AddOnContent detected. TitleId {titleId:X16}");
}
@@ -249,7 +236,7 @@ namespace Ryujinx.HLE.FileSystem
if (!mergedToContainer)
{
using FileStream fileStream = File.OpenRead(containerPath);
using FileStream fileStream = File.OpenRead(containerPath);
using PartitionFileSystem partitionFileSystem = new(fileStream.AsStorage());
_virtualFileSystem.ImportTickets(partitionFileSystem);
@@ -257,17 +244,17 @@ namespace Ryujinx.HLE.FileSystem
}
}
public void ClearAocData() => _aocData.Clear();
public void ClearAocData() => AocData.Clear();
public int GetAocCount() => _aocData.Count;
public int GetAocCount() => AocData.Count;
public IList<ulong> GetAocTitleIds() => _aocData.Select(e => e.Key).ToList();
public IList<ulong> GetAocTitleIds() => AocData.Select(e => e.Key).ToList();
public bool GetAocDataStorage(ulong aocTitleId, out IStorage aocStorage, IntegrityCheckLevel integrityCheckLevel)
{
aocStorage = null;
if (_aocData.TryGetValue(aocTitleId, out AocItem aoc))
if (AocData.TryGetValue(aocTitleId, out AocItem aoc))
{
var file = new FileStream(aoc.ContainerPath, FileMode.Open, FileAccess.Read);
using var ncaFile = new UniqueRef<IFile>();
@@ -307,7 +294,7 @@ namespace Ryujinx.HLE.FileSystem
{
lock (_lock)
{
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
LinkedListNode<LocationEntry> locationEntry = locationList.First;
while (locationEntry != null)
@@ -331,7 +318,7 @@ namespace Ryujinx.HLE.FileSystem
if (_contentDictionary.ContainsValue(ncaId))
{
var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId);
ulong titleId = content.Key.Item1;
ulong titleId = content.Key.titleId;
NcaContentType contentType = content.Key.type;
StorageId storage = GetInstalledStorage(titleId, contentType, storageId);
@@ -403,19 +390,17 @@ namespace Ryujinx.HLE.FileSystem
return false;
}
string installedPath = _virtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
string installedPath = VirtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
if (!string.IsNullOrWhiteSpace(installedPath))
{
if (File.Exists(installedPath))
{
using (FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read))
{
Nca nca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
bool contentCheck = nca.Header.ContentType == contentType;
using FileStream file = new(installedPath, FileMode.Open, FileAccess.Read);
Nca nca = new(_virtualFileSystem.KeySet, file.AsStorage());
bool contentCheck = nca.Header.ContentType == contentType;
return contentCheck;
}
return contentCheck;
}
}
@@ -426,9 +411,9 @@ namespace Ryujinx.HLE.FileSystem
{
LinkedList<LocationEntry> locationList = null;
if (_locationEntries.ContainsKey(storageId))
if (_locationEntries.TryGetValue(storageId, out LinkedList<LocationEntry> locationEntry))
{
locationList = _locationEntries[storageId];
locationList = locationEntry;
}
if (locationList != null)
@@ -446,9 +431,9 @@ namespace Ryujinx.HLE.FileSystem
{
LinkedList<LocationEntry> locationList = null;
if (_locationEntries.ContainsKey(storageId))
if (_locationEntries.TryGetValue(storageId, out LinkedList<LocationEntry> locationEntry))
{
locationList = _locationEntries[storageId];
locationList = locationEntry;
}
if (locationList != null)
@@ -487,10 +472,10 @@ namespace Ryujinx.HLE.FileSystem
public void InstallFirmware(string firmwareSource)
{
string contentPathString = ContentPath.GetContentPath(StorageId.BuiltInSystem);
string contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString);
string contentPathString = ContentPath.GetContentPath(StorageId.BuiltInSystem);
string contentDirectory = ContentPath.GetRealPath(contentPathString);
string registeredDirectory = Path.Combine(contentDirectory, "registered");
string temporaryDirectory = Path.Combine(contentDirectory, "temp");
string temporaryDirectory = Path.Combine(contentDirectory, "temp");
if (Directory.Exists(temporaryDirectory))
{
@@ -510,28 +495,27 @@ namespace Ryujinx.HLE.FileSystem
throw new FileNotFoundException("Firmware file does not exist.");
}
FileInfo info = new FileInfo(firmwareSource);
FileInfo info = new(firmwareSource);
using (FileStream file = File.OpenRead(firmwareSource))
using FileStream file = File.OpenRead(firmwareSource);
switch (info.Extension)
{
switch (info.Extension)
{
case ".zip":
using (ZipArchive archive = ZipFile.OpenRead(firmwareSource))
{
InstallFromZip(archive, temporaryDirectory);
}
break;
case ".xci":
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage());
InstallFromCart(xci, temporaryDirectory);
break;
default:
throw new InvalidFirmwarePackageException("Input file is not a valid firmware package");
}
FinishInstallation(temporaryDirectory, registeredDirectory);
case ".zip":
using (ZipArchive archive = ZipFile.OpenRead(firmwareSource))
{
InstallFromZip(archive, temporaryDirectory);
}
break;
case ".xci":
Xci xci = new(_virtualFileSystem.KeySet, file.AsStorage());
InstallFromCart(xci, temporaryDirectory);
break;
default:
throw new InvalidFirmwarePackageException("Input file is not a valid firmware package");
}
FinishInstallation(temporaryDirectory, registeredDirectory);
}
private void FinishInstallation(string temporaryDirectory, string registeredDirectory)
@@ -555,7 +539,7 @@ namespace Ryujinx.HLE.FileSystem
{
foreach (var entry in filesystem.EnumerateEntries("/", "*.nca"))
{
Nca nca = new Nca(_virtualFileSystem.KeySet, OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage());
Nca nca = new(_virtualFileSystem.KeySet, OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage());
SaveNca(nca, entry.Name.Remove(entry.Name.IndexOf('.')), temporaryDirectory);
}
@@ -575,52 +559,47 @@ namespace Ryujinx.HLE.FileSystem
}
}
private void InstallFromZip(ZipArchive archive, string temporaryDirectory)
private static void InstallFromZip(ZipArchive archive, string temporaryDirectory)
{
using (archive)
foreach (var entry in archive.Entries)
{
foreach (var entry in archive.Entries)
if (entry.FullName.EndsWith(".nca") || entry.FullName.EndsWith(".nca/00"))
{
if (entry.FullName.EndsWith(".nca") || entry.FullName.EndsWith(".nca/00"))
// Clean up the name and get the NcaId
string[] pathComponents = entry.FullName.Replace(".cnmt", "").Split('/');
string ncaId = pathComponents[^1];
// If this is a fragmented nca, we need to get the previous element.GetZip
if (ncaId.Equals("00"))
{
// Clean up the name and get the NcaId
ncaId = pathComponents[^2];
}
string[] pathComponents = entry.FullName.Replace(".cnmt", "").Split('/');
if (ncaId.Contains(".nca"))
{
string newPath = Path.Combine(temporaryDirectory, ncaId);
string ncaId = pathComponents[pathComponents.Length - 1];
Directory.CreateDirectory(newPath);
// If this is a fragmented nca, we need to get the previous element.GetZip
if (ncaId.Equals("00"))
{
ncaId = pathComponents[pathComponents.Length - 2];
}
if (ncaId.Contains(".nca"))
{
string newPath = Path.Combine(temporaryDirectory, ncaId);
Directory.CreateDirectory(newPath);
entry.ExtractToFile(Path.Combine(newPath, "00"));
}
entry.ExtractToFile(Path.Combine(newPath, "00"));
}
}
}
}
public void SaveNca(Nca nca, string ncaId, string temporaryDirectory)
public static void SaveNca(Nca nca, string ncaId, string temporaryDirectory)
{
string newPath = Path.Combine(temporaryDirectory, ncaId + ".nca");
Directory.CreateDirectory(newPath);
using (FileStream file = File.Create(Path.Combine(newPath, "00")))
{
nca.BaseStorage.AsStream().CopyTo(file);
}
using FileStream file = File.Create(Path.Combine(newPath, "00"));
nca.BaseStorage.AsStream().CopyTo(file);
}
private IFile OpenPossibleFragmentedFile(IFileSystem filesystem, string path, OpenMode mode)
private static IFile OpenPossibleFragmentedFile(IFileSystem filesystem, string path, OpenMode mode)
{
using var file = new UniqueRef<IFile>();
@@ -636,14 +615,12 @@ namespace Ryujinx.HLE.FileSystem
return file.Release();
}
private Stream GetZipStream(ZipArchiveEntry entry)
private static Stream GetZipStream(ZipArchiveEntry entry)
{
MemoryStream dest = MemoryStreamManager.Shared.GetStream();
using (Stream src = entry.Open())
{
src.CopyTo(dest);
}
using Stream src = entry.Open();
src.CopyTo(dest);
return dest;
}
@@ -659,7 +636,7 @@ namespace Ryujinx.HLE.FileSystem
throw new MissingKeyException("HeaderKey is empty. Cannot decrypt NCA headers.");
}
Dictionary<ulong, List<(NcaContentType type, string path)>> updateNcas = new Dictionary<ulong, List<(NcaContentType, string)>>();
Dictionary<ulong, List<(NcaContentType type, string path)>> updateNcas = new();
if (Directory.Exists(firmwarePackage))
{
@@ -671,33 +648,32 @@ namespace Ryujinx.HLE.FileSystem
throw new FileNotFoundException("Firmware file does not exist.");
}
FileInfo info = new FileInfo(firmwarePackage);
FileInfo info = new(firmwarePackage);
using (FileStream file = File.OpenRead(firmwarePackage))
using FileStream file = File.OpenRead(firmwarePackage);
switch (info.Extension)
{
switch (info.Extension)
{
case ".zip":
using (ZipArchive archive = ZipFile.OpenRead(firmwarePackage))
{
return VerifyAndGetVersionZip(archive);
}
case ".xci":
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage());
case ".zip":
using (ZipArchive archive = ZipFile.OpenRead(firmwarePackage))
{
return VerifyAndGetVersionZip(archive);
}
case ".xci":
Xci xci = new(_virtualFileSystem.KeySet, file.AsStorage());
if (xci.HasPartition(XciPartitionType.Update))
{
XciPartition partition = xci.OpenPartition(XciPartitionType.Update);
if (xci.HasPartition(XciPartitionType.Update))
{
XciPartition partition = xci.OpenPartition(XciPartitionType.Update);
return VerifyAndGetVersion(partition);
}
else
{
throw new InvalidFirmwarePackageException("Update not found in xci file.");
}
default:
break;
}
return VerifyAndGetVersion(partition);
}
else
{
throw new InvalidFirmwarePackageException("Update not found in xci file.");
}
default:
break;
}
SystemVersion VerifyAndGetVersionDirectory(string firmwareDirectory)
@@ -713,21 +689,19 @@ namespace Ryujinx.HLE.FileSystem
{
if (entry.FullName.EndsWith(".nca") || entry.FullName.EndsWith(".nca/00"))
{
using (Stream ncaStream = GetZipStream(entry))
using Stream ncaStream = GetZipStream(entry);
IStorage storage = ncaStream.AsStorage();
Nca nca = new(_virtualFileSystem.KeySet, storage);
if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem))
{
IStorage storage = ncaStream.AsStorage();
Nca nca = new Nca(_virtualFileSystem.KeySet, storage);
if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem))
{
updateNcasItem.Add((nca.Header.ContentType, entry.FullName));
}
else
{
updateNcas.Add(nca.Header.TitleId, new List<(NcaContentType, string)>());
updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullName));
}
updateNcasItem.Add((nca.Header.ContentType, entry.FullName));
}
else
{
updateNcas.Add(nca.Header.TitleId, new List<(NcaContentType, string)>());
updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullName));
}
}
}
@@ -742,7 +716,7 @@ namespace Ryujinx.HLE.FileSystem
using (Stream ncaStream = GetZipStream(fileEntry))
{
Nca metaNca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage());
Nca metaNca = new(_virtualFileSystem.KeySet, ncaStream.AsStorage());
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
@@ -772,18 +746,16 @@ namespace Ryujinx.HLE.FileSystem
{
string versionEntry = updateNcasItem.Find(x => x.type != NcaContentType.Meta).path;
using (Stream ncaStream = GetZipStream(archive.GetEntry(versionEntry)))
using Stream ncaStream = GetZipStream(archive.GetEntry(versionEntry));
Nca nca = new(_virtualFileSystem.KeySet, ncaStream.AsStorage());
var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
using var systemVersionFile = new UniqueRef<IFile>();
if (romfs.OpenFile(ref systemVersionFile.Ref, "/file".ToU8Span(), OpenMode.Read).IsSuccess())
{
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage());
var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
using var systemVersionFile = new UniqueRef<IFile>();
if (romfs.OpenFile(ref systemVersionFile.Ref, "/file".ToU8Span(), OpenMode.Read).IsSuccess())
{
systemVersion = new SystemVersion(systemVersionFile.Get.AsStream());
}
systemVersion = new SystemVersion(systemVersionFile.Get.AsStream());
}
}
@@ -804,43 +776,39 @@ namespace Ryujinx.HLE.FileSystem
continue;
}
ZipArchiveEntry metaZipEntry = archive.GetEntry(metaPath);
ZipArchiveEntry metaZipEntry = archive.GetEntry(metaPath);
ZipArchiveEntry contentZipEntry = archive.GetEntry(contentPath);
using (Stream metaNcaStream = GetZipStream(metaZipEntry))
using Stream metaNcaStream = GetZipStream(metaZipEntry);
using Stream contentNcaStream = GetZipStream(contentZipEntry);
Nca metaNca = new(_virtualFileSystem.KeySet, metaNcaStream.AsStorage());
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
using var metaFile = new UniqueRef<IFile>();
if (fs.OpenFile(ref metaFile.Ref, cnmtPath.ToU8Span(), OpenMode.Read).IsSuccess())
{
using (Stream contentNcaStream = GetZipStream(contentZipEntry))
var meta = new Cnmt(metaFile.Get.AsStream());
IStorage contentStorage = contentNcaStream.AsStorage();
if (contentStorage.GetSize(out long size).IsSuccess())
{
Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaNcaStream.AsStorage());
byte[] contentData = new byte[size];
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
Span<byte> content = new(contentData);
string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
contentStorage.Read(0, content);
using var metaFile = new UniqueRef<IFile>();
Span<byte> hash = new(new byte[32]);
if (fs.OpenFile(ref metaFile.Ref, cnmtPath.ToU8Span(), OpenMode.Read).IsSuccess())
LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash);
if (LibHac.Common.Utilities.ArraysEqual(hash.ToArray(), meta.ContentEntries[0].Hash))
{
var meta = new Cnmt(metaFile.Get.AsStream());
IStorage contentStorage = contentNcaStream.AsStorage();
if (contentStorage.GetSize(out long size).IsSuccess())
{
byte[] contentData = new byte[size];
Span<byte> content = new Span<byte>(contentData);
contentStorage.Read(0, content);
Span<byte> hash = new Span<byte>(new byte[32]);
LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash);
if (LibHac.Common.Utilities.ArraysEqual(hash.ToArray(), meta.ContentEntries[0].Hash))
{
updateNcas.Remove(metaEntry.TitleId);
}
}
updateNcas.Remove(metaEntry.TitleId);
}
}
}
@@ -853,9 +821,9 @@ namespace Ryujinx.HLE.FileSystem
foreach (var entry in updateNcas)
{
foreach (var nca in entry.Value)
foreach (var (type, path) in entry.Value)
{
extraNcas += nca.path + Environment.NewLine;
extraNcas += path + Environment.NewLine;
}
}
@@ -880,7 +848,7 @@ namespace Ryujinx.HLE.FileSystem
{
IStorage ncaStorage = OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage();
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStorage);
Nca nca = new(_virtualFileSystem.KeySet, ncaStorage);
if (nca.Header.TitleId == SystemUpdateTitleId && nca.Header.ContentType == NcaContentType.Meta)
{
@@ -936,8 +904,8 @@ namespace Ryujinx.HLE.FileSystem
{
if (updateNcas.TryGetValue(metaEntry.TitleId, out var ncaEntry))
{
var metaNcaEntry = ncaEntry.Find(x => x.type == NcaContentType.Meta);
string contentPath = ncaEntry.Find(x => x.type != NcaContentType.Meta).path;
string metaNcaPath = ncaEntry.Find(x => x.type == NcaContentType.Meta).path;
string contentPath = ncaEntry.Find(x => x.type != NcaContentType.Meta).path;
// Nintendo in 9.0.0, removed PPC and only kept the meta nca of it.
// This is a perfect valid case, so we should just ignore the missing content nca and continue.
@@ -948,10 +916,10 @@ namespace Ryujinx.HLE.FileSystem
continue;
}
IStorage metaStorage = OpenPossibleFragmentedFile(filesystem, metaNcaEntry.path, OpenMode.Read).AsStorage();
IStorage metaStorage = OpenPossibleFragmentedFile(filesystem, metaNcaPath, OpenMode.Read).AsStorage();
IStorage contentStorage = OpenPossibleFragmentedFile(filesystem, contentPath, OpenMode.Read).AsStorage();
Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaStorage);
Nca metaNca = new(_virtualFileSystem.KeySet, metaStorage);
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
@@ -967,11 +935,11 @@ namespace Ryujinx.HLE.FileSystem
{
byte[] contentData = new byte[size];
Span<byte> content = new Span<byte>(contentData);
Span<byte> content = new(contentData);
contentStorage.Read(0, content);
Span<byte> hash = new Span<byte>(new byte[32]);
Span<byte> hash = new(new byte[32]);
LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash);
@@ -1017,24 +985,21 @@ namespace Ryujinx.HLE.FileSystem
{
if (entry.ContentType == NcaContentType.Data)
{
var path = _virtualFileSystem.SwitchPathToSystemPath(entry.ContentPath);
var path = VirtualFileSystem.SwitchPathToSystemPath(entry.ContentPath);
using (FileStream fileStream = File.OpenRead(path))
using FileStream fileStream = File.OpenRead(path);
Nca nca = new(_virtualFileSystem.KeySet, fileStream.AsStorage());
if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data)
{
Nca nca = new Nca(_virtualFileSystem.KeySet, fileStream.AsStorage());
var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data)
using var systemVersionFile = new UniqueRef<IFile>();
if (romfs.OpenFile(ref systemVersionFile.Ref, "/file".ToU8Span(), OpenMode.Read).IsSuccess())
{
var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
using var systemVersionFile = new UniqueRef<IFile>();
if (romfs.OpenFile(ref systemVersionFile.Ref, "/file".ToU8Span(), OpenMode.Read).IsSuccess())
{
return new SystemVersion(systemVersionFile.Get.AsStream());
}
return new SystemVersion(systemVersionFile.Get.AsStream());
}
}
}
}

View File

@@ -2,7 +2,6 @@
using LibHac.Ncm;
using Ryujinx.Common.Configuration;
using System;
using static Ryujinx.HLE.FileSystem.VirtualFileSystem;
using Path = System.IO.Path;
@@ -10,33 +9,33 @@ namespace Ryujinx.HLE.FileSystem
{
internal static class ContentPath
{
public const string SystemContent = "@SystemContent";
public const string UserContent = "@UserContent";
public const string SdCardContent = "@SdCardContent";
public const string SdCard = "@Sdcard";
public const string CalibFile = "@CalibFile";
public const string Safe = "@Safe";
public const string User = "@User";
public const string System = "@System";
public const string Host = "@Host";
public const string GamecardApp = "@GcApp";
public const string SystemContent = "@SystemContent";
public const string UserContent = "@UserContent";
public const string SdCardContent = "@SdCardContent";
public const string SdCard = "@Sdcard";
public const string CalibFile = "@CalibFile";
public const string Safe = "@Safe";
public const string User = "@User";
public const string System = "@System";
public const string Host = "@Host";
public const string GamecardApp = "@GcApp";
public const string GamecardContents = "@GcS00000001";
public const string GamecardUpdate = "@upp";
public const string GamecardUpdate = "@upp";
public const string RegisteredUpdate = "@RegUpdate";
public const string Nintendo = "Nintendo";
public const string Contents = "Contents";
public static string GetRealPath(VirtualFileSystem fileSystem, string switchContentPath)
public static string GetRealPath(string switchContentPath)
{
return switchContentPath switch
{
SystemContent => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath, Contents),
UserContent => Path.Combine(AppDataManager.BaseDirPath, UserNandPath, Contents),
SdCardContent => Path.Combine(fileSystem.GetSdCardPath(), Nintendo, Contents),
System => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath),
User => Path.Combine(AppDataManager.BaseDirPath, UserNandPath),
_ => throw new NotSupportedException($"Content Path \"`{switchContentPath}`\" is not supported.")
UserContent => Path.Combine(AppDataManager.BaseDirPath, UserNandPath, Contents),
SdCardContent => Path.Combine(GetSdCardPath(), Nintendo, Contents),
System => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath),
User => Path.Combine(AppDataManager.BaseDirPath, UserNandPath),
_ => throw new NotSupportedException($"Content Path \"`{switchContentPath}`\" is not supported."),
};
}
@@ -45,9 +44,9 @@ namespace Ryujinx.HLE.FileSystem
return contentStorageId switch
{
ContentStorageId.System => SystemContent,
ContentStorageId.User => UserContent,
ContentStorageId.User => UserContent,
ContentStorageId.SdCard => SdCardContent,
_ => throw new NotSupportedException($"Content Storage Id \"`{contentStorageId}`\" is not supported.")
_ => throw new NotSupportedException($"Content Storage Id \"`{contentStorageId}`\" is not supported."),
};
}
@@ -56,9 +55,9 @@ namespace Ryujinx.HLE.FileSystem
return storageId switch
{
StorageId.BuiltInSystem => SystemContent,
StorageId.BuiltInUser => UserContent,
StorageId.SdCard => SdCardContent,
_ => throw new NotSupportedException($"Storage Id \"`{storageId}`\" is not supported.")
StorageId.BuiltInUser => UserContent,
StorageId.SdCard => SdCardContent,
_ => throw new NotSupportedException($"Storage Id \"`{storageId}`\" is not supported."),
};
}
@@ -67,16 +66,16 @@ namespace Ryujinx.HLE.FileSystem
return contentPathString.Split(':')[0] switch
{
SystemContent or
System => StorageId.BuiltInSystem,
System => StorageId.BuiltInSystem,
UserContent or
User => StorageId.BuiltInUser,
SdCardContent => StorageId.SdCard,
Host => StorageId.Host,
User => StorageId.BuiltInUser,
SdCardContent => StorageId.SdCard,
Host => StorageId.Host,
GamecardApp or
GamecardContents or
GamecardUpdate => StorageId.GameCard,
_ => StorageId.None
_ => StorageId.None,
};
}
}
}
}

View File

@@ -23,4 +23,4 @@ namespace Ryujinx.HLE.FileSystem
return Result.Success;
}
}
}
}

View File

@@ -4,16 +4,16 @@ namespace Ryujinx.HLE.FileSystem
{
public struct LocationEntry
{
public string ContentPath { get; private set; }
public int Flag { get; private set; }
public ulong TitleId { get; private set; }
public string ContentPath { get; private set; }
public int Flag { get; private set; }
public ulong TitleId { get; private set; }
public NcaContentType ContentType { get; private set; }
public LocationEntry(string contentPath, int flag, ulong titleId, NcaContentType contentType)
{
ContentPath = contentPath;
Flag = flag;
TitleId = titleId;
Flag = flag;
TitleId = titleId;
ContentType = contentType;
}

View File

@@ -5,36 +5,34 @@ namespace Ryujinx.HLE.FileSystem
{
public class SystemVersion
{
public byte Major { get; }
public byte Minor { get; }
public byte Micro { get; }
public byte RevisionMajor { get; }
public byte RevisionMinor { get; }
public byte Major { get; }
public byte Minor { get; }
public byte Micro { get; }
public byte RevisionMajor { get; }
public byte RevisionMinor { get; }
public string PlatformString { get; }
public string Hex { get; }
public string VersionString { get; }
public string VersionTitle { get; }
public string Hex { get; }
public string VersionString { get; }
public string VersionTitle { get; }
public SystemVersion(Stream systemVersionFile)
{
using (BinaryReader reader = new BinaryReader(systemVersionFile))
{
Major = reader.ReadByte();
Minor = reader.ReadByte();
Micro = reader.ReadByte();
using BinaryReader reader = new(systemVersionFile);
Major = reader.ReadByte();
Minor = reader.ReadByte();
Micro = reader.ReadByte();
reader.ReadByte(); // Padding
reader.ReadByte(); // Padding
RevisionMajor = reader.ReadByte();
RevisionMinor = reader.ReadByte();
RevisionMajor = reader.ReadByte();
RevisionMinor = reader.ReadByte();
reader.ReadBytes(2); // Padding
reader.ReadBytes(2); // Padding
PlatformString = StringUtils.ReadInlinedAsciiString(reader, 0x20);
Hex = StringUtils.ReadInlinedAsciiString(reader, 0x40);
VersionString = StringUtils.ReadInlinedAsciiString(reader, 0x18);
VersionTitle = StringUtils.ReadInlinedAsciiString(reader, 0x80);
}
PlatformString = StringUtils.ReadInlinedAsciiString(reader, 0x20);
Hex = StringUtils.ReadInlinedAsciiString(reader, 0x40);
VersionString = StringUtils.ReadInlinedAsciiString(reader, 0x18);
VersionTitle = StringUtils.ReadInlinedAsciiString(reader, 0x80);
}
}
}
}

View File

@@ -26,14 +26,14 @@ namespace Ryujinx.HLE.FileSystem
{
public class VirtualFileSystem : IDisposable
{
public static string SafeNandPath = Path.Combine(AppDataManager.DefaultNandDir, "safe");
public static string SystemNandPath = Path.Combine(AppDataManager.DefaultNandDir, "system");
public static string UserNandPath = Path.Combine(AppDataManager.DefaultNandDir, "user");
public static readonly string SafeNandPath = Path.Combine(AppDataManager.DefaultNandDir, "safe");
public static readonly string SystemNandPath = Path.Combine(AppDataManager.DefaultNandDir, "system");
public static readonly string UserNandPath = Path.Combine(AppDataManager.DefaultNandDir, "user");
public KeySet KeySet { get; private set; }
public EmulatedGameCard GameCard { get; private set; }
public EmulatedSdCard SdCard { get; private set; }
public ModLoader ModLoader { get; private set; }
public KeySet KeySet { get; private set; }
public EmulatedGameCard GameCard { get; private set; }
public EmulatedSdCard SdCard { get; private set; }
public ModLoader ModLoader { get; private set; }
private readonly ConcurrentDictionary<ulong, Stream> _romFsByPid;
@@ -85,15 +85,15 @@ namespace Ryujinx.HLE.FileSystem
return _romFsByPid[pid];
}
public string GetFullPath(string basePath, string fileName)
public static string GetFullPath(string basePath, string fileName)
{
if (fileName.StartsWith("//"))
{
fileName = fileName.Substring(2);
fileName = fileName[2..];
}
else if (fileName.StartsWith('/'))
{
fileName = fileName.Substring(1);
fileName = fileName[1..];
}
else
{
@@ -110,10 +110,10 @@ namespace Ryujinx.HLE.FileSystem
return fullPath;
}
internal string GetSdCardPath() => MakeFullPath(AppDataManager.DefaultSdcardDir);
public string GetNandPath() => MakeFullPath(AppDataManager.DefaultNandDir);
internal static string GetSdCardPath() => MakeFullPath(AppDataManager.DefaultSdcardDir);
public static string GetNandPath() => MakeFullPath(AppDataManager.DefaultNandDir);
public string SwitchPathToSystemPath(string switchPath)
public static string SwitchPathToSystemPath(string switchPath)
{
string[] parts = switchPath.Split(":");
@@ -125,7 +125,7 @@ namespace Ryujinx.HLE.FileSystem
return GetFullPath(MakeFullPath(parts[0]), parts[1]);
}
public string SystemPathToSwitchPath(string systemPath)
public static string SystemPathToSwitchPath(string systemPath)
{
string baseSystemPath = AppDataManager.BaseDirPath + Path.DirectorySeparatorChar;
@@ -148,7 +148,7 @@ namespace Ryujinx.HLE.FileSystem
return null;
}
private string MakeFullPath(string path, bool isDirectory = true)
private static string MakeFullPath(string path, bool isDirectory = true)
{
// Handles Common Switch Content Paths
switch (path)
@@ -185,7 +185,7 @@ namespace Ryujinx.HLE.FileSystem
public void InitializeFsServer(LibHac.Horizon horizon, out HorizonClient fsServerClient)
{
LocalFileSystem serverBaseFs = new LocalFileSystem(AppDataManager.BaseDirPath);
LocalFileSystem serverBaseFs = new(AppDataManager.BaseDirPath);
fsServerClient = horizon.CreatePrivilegedHorizonClient();
var fsServer = new FileSystemServer(fsServerClient);
@@ -207,7 +207,7 @@ namespace Ryujinx.HLE.FileSystem
DeviceOperator = fsServerObjects.DeviceOperator,
ExternalKeySet = KeySet.ExternalKeySet,
FsCreators = fsServerObjects.FsCreators,
RandomGenerator = randomGenerator
RandomGenerator = randomGenerator,
};
FileSystemServerInitializer.InitializeWithConfig(fsServerClient, fsServer, fsServerConfig);
@@ -282,16 +282,28 @@ namespace Ryujinx.HLE.FileSystem
public static Result FixExtraData(HorizonClient hos)
{
Result rc = GetSystemSaveList(hos, out List<ulong> systemSaveIds);
if (rc.IsFailure()) return rc;
if (rc.IsFailure())
{
return rc;
}
rc = FixUnindexedSystemSaves(hos, systemSaveIds);
if (rc.IsFailure()) return rc;
if (rc.IsFailure())
{
return rc;
}
rc = FixExtraDataInSpaceId(hos, SaveDataSpaceId.System);
if (rc.IsFailure()) return rc;
if (rc.IsFailure())
{
return rc;
}
rc = FixExtraDataInSpaceId(hos, SaveDataSpaceId.User);
if (rc.IsFailure()) return rc;
if (rc.IsFailure())
{
return rc;
}
return Result.Success;
}
@@ -303,15 +315,23 @@ namespace Ryujinx.HLE.FileSystem
using var iterator = new UniqueRef<SaveDataIterator>();
Result rc = hos.Fs.OpenSaveDataIterator(ref iterator.Ref, spaceId);
if (rc.IsFailure()) return rc;
if (rc.IsFailure())
{
return rc;
}
while (true)
{
rc = iterator.Get.ReadSaveDataInfo(out long count, info);
if (rc.IsFailure()) return rc;
if (rc.IsFailure())
{
return rc;
}
if (count == 0)
{
return Result.Success;
}
for (int i = 0; i < count; i++)
{
@@ -351,7 +371,9 @@ namespace Ryujinx.HLE.FileSystem
private static Result CreateSaveDataDirectory(HorizonClient hos, in SaveDataInfo info)
{
if (info.SpaceId != SaveDataSpaceId.User && info.SpaceId != SaveDataSpaceId.System)
{
return Result.Success;
}
const string MountName = "SaveDir";
var mountNameU8 = MountName.ToU8Span();
@@ -360,11 +382,15 @@ namespace Ryujinx.HLE.FileSystem
{
SaveDataSpaceId.System => BisPartitionId.System,
SaveDataSpaceId.User => BisPartitionId.User,
_ => throw new ArgumentOutOfRangeException()
_ => throw new ArgumentOutOfRangeException(nameof(info), info.SpaceId, null),
};
Result rc = hos.Fs.MountBis(mountNameU8, partitionId);
if (rc.IsFailure()) return rc;
if (rc.IsFailure())
{
return rc;
}
try
{
var path = $"{MountName}:/save/{info.SaveDataId:x16}".ToU8Span();
@@ -391,28 +417,38 @@ namespace Ryujinx.HLE.FileSystem
var mountName = "system".ToU8Span();
DirectoryHandle handle = default;
List<ulong> localList = new List<ulong>();
List<ulong> localList = new();
try
{
Result rc = hos.Fs.MountBis(mountName, BisPartitionId.System);
if (rc.IsFailure()) return rc;
if (rc.IsFailure())
{
return rc;
}
rc = hos.Fs.OpenDirectory(out handle, "system:/save".ToU8Span(), OpenDirectoryMode.All);
if (rc.IsFailure()) return rc;
if (rc.IsFailure())
{
return rc;
}
DirectoryEntry entry = new DirectoryEntry();
DirectoryEntry entry = new();
while (true)
{
rc = hos.Fs.ReadDirectory(out long readCount, SpanHelpers.AsSpan(ref entry), handle);
if (rc.IsFailure()) return rc;
if (rc.IsFailure())
{
return rc;
}
if (readCount == 0)
{
break;
}
if (Utf8Parser.TryParse(entry.Name, out ulong saveDataId, out int bytesRead, 'x') &&
bytesRead == 16 && (long)saveDataId < 0)
if (Utf8Parser.TryParse(entry.Name, out ulong saveDataId, out int bytesRead, 'x') && bytesRead == 16 && (long)saveDataId < 0)
{
localList.Add(saveDataId);
}
@@ -440,7 +476,7 @@ namespace Ryujinx.HLE.FileSystem
// Only save data IDs added to SystemExtraDataFixInfo will be fixed.
private static Result FixUnindexedSystemSaves(HorizonClient hos, List<ulong> existingSaveIds)
{
foreach (var fixInfo in SystemExtraDataFixInfo)
foreach (var fixInfo in _systemExtraDataFixInfo)
{
if (!existingSaveIds.Contains(fixInfo.StaticSaveDataId))
{
@@ -472,7 +508,9 @@ namespace Ryujinx.HLE.FileSystem
if (!rc.IsSuccess())
{
if (!ResultFs.TargetNotFound.Includes(rc))
{
return rc;
}
// We'll reach this point only if the save data directory exists but it's not in the save data indexer.
// Creating the save will add it to the indexer while leaving its existing contents intact.
@@ -492,7 +530,7 @@ namespace Ryujinx.HLE.FileSystem
OwnerId = info.OwnerId,
Flags = info.Flags,
DataSize = info.DataSize,
JournalSize = info.JournalSize
JournalSize = info.JournalSize,
};
// Make a mask for writing the entire extra data
@@ -507,9 +545,11 @@ namespace Ryujinx.HLE.FileSystem
{
wasFixNeeded = true;
Result rc = hos.Fs.Impl.ReadSaveDataFileSystemExtraData(out SaveDataExtraData extraData, info.SpaceId,
info.SaveDataId);
if (rc.IsFailure()) return rc;
Result rc = hos.Fs.Impl.ReadSaveDataFileSystemExtraData(out SaveDataExtraData extraData, info.SpaceId, info.SaveDataId);
if (rc.IsFailure())
{
return rc;
}
// The extra data should have program ID or static save data ID set if it's valid.
// We only try to fix the extra data if the info from the save data indexer has a program ID or static save data ID.
@@ -543,7 +583,7 @@ namespace Ryujinx.HLE.FileSystem
else
{
// Try to match the system save with one of the known saves
foreach (ExtraDataFixInfo fixInfo in SystemExtraDataFixInfo)
foreach (ExtraDataFixInfo fixInfo in _systemExtraDataFixInfo)
{
if (extraData.Attribute.StaticSaveDataId == fixInfo.StaticSaveDataId)
{
@@ -573,7 +613,7 @@ namespace Ryujinx.HLE.FileSystem
public long JournalSize;
}
private static readonly ExtraDataFixInfo[] SystemExtraDataFixInfo =
private static readonly ExtraDataFixInfo[] _systemExtraDataFixInfo =
{
new ExtraDataFixInfo()
{
@@ -581,7 +621,7 @@ namespace Ryujinx.HLE.FileSystem
OwnerId = 0x010000000000001F,
Flags = SaveDataFlags.KeepAfterResettingSystemSaveDataWithoutUserSaveData,
DataSize = 0x10000,
JournalSize = 0x10000
JournalSize = 0x10000,
},
new ExtraDataFixInfo()
{
@@ -589,12 +629,13 @@ namespace Ryujinx.HLE.FileSystem
OwnerId = 0x0100000000001009,
Flags = SaveDataFlags.None,
DataSize = 0xC000,
JournalSize = 0xC000
}
JournalSize = 0xC000,
},
};
public void Dispose()
{
GC.SuppressFinalize(this);
Dispose(true);
}

View File

@@ -163,57 +163,57 @@ namespace Ryujinx.HLE
/// </summary>
public Action RefreshInputConfig { internal get; set; }
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
LibHacHorizonManager libHacHorizonManager,
ContentManager contentManager,
AccountManager accountManager,
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
LibHacHorizonManager libHacHorizonManager,
ContentManager contentManager,
AccountManager accountManager,
UserChannelPersistence userChannelPersistence,
IRenderer gpuRenderer,
IHardwareDeviceDriver audioDeviceDriver,
MemoryConfiguration memoryConfiguration,
IHostUiHandler hostUiHandler,
SystemLanguage systemLanguage,
RegionCode region,
bool enableVsync,
bool enableDockedMode,
bool enablePtc,
bool enableInternetAccess,
IntegrityCheckLevel fsIntegrityCheckLevel,
int fsGlobalAccessLogMode,
long systemTimeOffset,
string timeZone,
MemoryManagerMode memoryManagerMode,
bool ignoreMissingServices,
AspectRatio aspectRatio,
float audioVolume,
bool useHypervisor,
string multiplayerLanInterfaceId)
IRenderer gpuRenderer,
IHardwareDeviceDriver audioDeviceDriver,
MemoryConfiguration memoryConfiguration,
IHostUiHandler hostUiHandler,
SystemLanguage systemLanguage,
RegionCode region,
bool enableVsync,
bool enableDockedMode,
bool enablePtc,
bool enableInternetAccess,
IntegrityCheckLevel fsIntegrityCheckLevel,
int fsGlobalAccessLogMode,
long systemTimeOffset,
string timeZone,
MemoryManagerMode memoryManagerMode,
bool ignoreMissingServices,
AspectRatio aspectRatio,
float audioVolume,
bool useHypervisor,
string multiplayerLanInterfaceId)
{
VirtualFileSystem = virtualFileSystem;
LibHacHorizonManager = libHacHorizonManager;
AccountManager = accountManager;
ContentManager = contentManager;
UserChannelPersistence = userChannelPersistence;
GpuRenderer = gpuRenderer;
AudioDeviceDriver = audioDeviceDriver;
MemoryConfiguration = memoryConfiguration;
HostUiHandler = hostUiHandler;
SystemLanguage = systemLanguage;
Region = region;
EnableVsync = enableVsync;
EnableDockedMode = enableDockedMode;
EnablePtc = enablePtc;
EnableInternetAccess = enableInternetAccess;
FsIntegrityCheckLevel = fsIntegrityCheckLevel;
FsGlobalAccessLogMode = fsGlobalAccessLogMode;
SystemTimeOffset = systemTimeOffset;
TimeZone = timeZone;
MemoryManagerMode = memoryManagerMode;
IgnoreMissingServices = ignoreMissingServices;
AspectRatio = aspectRatio;
AudioVolume = audioVolume;
UseHypervisor = useHypervisor;
VirtualFileSystem = virtualFileSystem;
LibHacHorizonManager = libHacHorizonManager;
AccountManager = accountManager;
ContentManager = contentManager;
UserChannelPersistence = userChannelPersistence;
GpuRenderer = gpuRenderer;
AudioDeviceDriver = audioDeviceDriver;
MemoryConfiguration = memoryConfiguration;
HostUiHandler = hostUiHandler;
SystemLanguage = systemLanguage;
Region = region;
EnableVsync = enableVsync;
EnableDockedMode = enableDockedMode;
EnablePtc = enablePtc;
EnableInternetAccess = enableInternetAccess;
FsIntegrityCheckLevel = fsIntegrityCheckLevel;
FsGlobalAccessLogMode = fsGlobalAccessLogMode;
SystemTimeOffset = systemTimeOffset;
TimeZone = timeZone;
MemoryManagerMode = memoryManagerMode;
IgnoreMissingServices = ignoreMissingServices;
AspectRatio = aspectRatio;
AudioVolume = audioVolume;
UseHypervisor = useHypervisor;
MultiplayerLanInterfaceId = multiplayerLanInterfaceId;
}
}
}
}

View File

@@ -8,7 +8,7 @@ namespace Ryujinx.HLE.HOS.Applets
{
static class AppletManager
{
private static Dictionary<AppletId, Type> _appletMapping;
private static readonly Dictionary<AppletId, Type> _appletMapping;
static AppletManager()
{
@@ -20,7 +20,7 @@ namespace Ryujinx.HLE.HOS.Applets
{ AppletId.SoftwareKeyboard, typeof(SoftwareKeyboardApplet) },
{ AppletId.LibAppletWeb, typeof(BrowserApplet) },
{ AppletId.LibAppletShop, typeof(BrowserApplet) },
{ AppletId.LibAppletOff, typeof(BrowserApplet) }
{ AppletId.LibAppletOff, typeof(BrowserApplet) },
};
}

View File

@@ -6,6 +6,6 @@
Offline,
Black,
Share,
Lobby
Lobby,
}
}

Some files were not shown because too many files have changed in this diff Show More