Compare commits

..

10 Commits

Author SHA1 Message Date
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
gdkchan
c5d9e67cb2 Fix some Vulkan validation errors (#5452)
* Fix some validation errors and silence the annoying pipeline barrier error

* Remove bogus decref/incref on index buffer state

* Make unsafe blit opt-in rather than opt-out

* Remove Vulkan debugger messages blacklist

* Adjust GetImageUsage to not set the storage bit for multisample textures if not supported
2023-07-14 09:08:52 +02:00
Mary
e5261228d7 infra: Fix team name in reviewer.yml 2023-07-12 19:22:09 +02:00
Mary
e61c09bc85 infra: Fix PR triage once and for all (#5442)
Switch to a custom made python script that query GitHub API to grab latest state of the PR after label assign.
2023-07-12 18:31:08 +02:00
ealekseychik
ac2444f908 Move ShaderBinaries into individual .spv files (#5280)
* Move ShaderBinaries into individual spv files

* Rename binaries directory, remove variables and add helper method instead

* Update .csproj file

* Move ShaderBinaries into individual spv files

* Rename binaries directory, remove variables and add helper method instead

* Split shader binaries into folders, use string.Join to create filepath

* Move files back to general binaries folder

* Remove ShaderSource suffix from file names

---------

Co-authored-by: Egor Alekseychik <e.alekseychik@syberry.com>
Co-authored-by: Gabriel A <gab.dark.100@gmail.com>
2023-07-11 14:41:18 -03:00
1064 changed files with 8559 additions and 10405 deletions

View File

@@ -1,8 +0,0 @@
addReviewers: true
reviewers:
- marysaka
filterLabels:
include:
- audio

View File

@@ -1,11 +0,0 @@
addReviewers: true
reviewers:
- gdkchan
- riperiperi
- marysaka
- LDj3SNuD
filterLabels:
include:
- cpu

View File

@@ -1,4 +0,0 @@
addReviewers: true
reviewers:
- Ryujinx/developers

View File

@@ -1,10 +0,0 @@
addReviewers: true
reviewers:
- gdkchan
- riperiperi
- marysaka
filterLabels:
include:
- gpu

View File

@@ -1,11 +0,0 @@
addReviewers: true
reviewers:
- Ack77
- emmauss
- TSRBerry
- marysaka
filterLabels:
include:
- gui

View File

@@ -1,11 +0,0 @@
addReviewers: true
reviewers:
- gdkchan
- Ack77
- marysaka
- TSRBerry
filterLabels:
include:
- horizon

View File

@@ -1,9 +0,0 @@
addReviewers: true
reviewers:
- marysaka
- TSRBerry
filterLabels:
include:
- infra

32
.github/reviewers.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
audio:
- marysaka
cpu:
- gdkchan
- riperiperi
- marysaka
- LDj3SNuD
gpu:
- gdkchan
- riperiperi
- marysaka
gui:
- Ack77
- emmauss
- TSRBerry
- marysaka
horizon:
- gdkchan
- Ack77
- marysaka
- TSRBerry
infra:
- marysaka
- TSRBerry
default:
- marysaka

79
.github/update_reviewers.py vendored Normal file
View File

@@ -0,0 +1,79 @@
from pathlib import Path
from typing import List, Set
from github import Github
from github.Repository import Repository
from github.GithubException import GithubException
import sys
import yaml
def add_reviewers(
reviewers: Set[str], team_reviewers: Set[str], new_entries: List[str]
):
for reviewer in new_entries:
if reviewer.startswith("@"):
team_reviewers.add(reviewer[1:])
else:
reviewers.add(reviewer)
def update_reviewers(config, repo: Repository, pr_id: int) -> int:
pull_request = repo.get_pull(pr_id)
if not pull_request:
sys.stderr.writable(f"Unknown PR #{pr_id}\n")
return 1
pull_request_author = pull_request.user.login
reviewers = set()
team_reviewers = set()
for label in pull_request.labels:
if label.name in config:
add_reviewers(reviewers, team_reviewers, config[label.name])
if "default" in config:
add_reviewers(reviewers, team_reviewers, config["default"])
if pull_request_author in reviewers:
reviewers.remove(pull_request_author)
try:
reviewers = list(reviewers)
team_reviewers = list(team_reviewers)
print(
f"Attempting to assign reviewers ({reviewers}) and team_reviewers ({team_reviewers})"
)
pull_request.create_review_request(reviewers, team_reviewers)
return 0
except GithubException as e:
sys.stderr.write(f"Cannot assign review request for PR #{pr_id}: {e}\n")
return 1
if __name__ == "__main__":
if len(sys.argv) != 5:
sys.stderr.write("usage: <token> <repo_path> <pr_id> <config_path>\n")
sys.exit(1)
token = sys.argv[1]
repo_path = sys.argv[2]
pr_id = int(sys.argv[3])
config_path = Path(sys.argv[4])
g = Github(token)
repo = g.get_repo(repo_path)
if not repo:
sys.stderr.write("Repository not found!\n")
sys.exit(1)
if not config_path.exists():
sys.stderr.write(f'Config "{config_path}" not found!\n')
sys.exit(1)
with open(config_path, "r") as f:
config = yaml.safe_load(f)
sys.exit(update_reviewers(config, repo, pr_id))

View File

@@ -12,43 +12,23 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# Grab sources to get update_reviewers.py and reviewers.yml
- name: Fetch sources
uses: actions/checkout@v3
with:
# Ensure we pin the source origin as pull_request_target run under forks.
fetch-depth: 0
repository: Ryujinx/Ryujinx
ref: master
- name: Update labels based on changes - name: Update labels based on changes
uses: actions/labeler@v4 uses: actions/labeler@v4
with: with:
sync-labels: true sync-labels: true
dot: true dot: true
- name: Auto Assign [Audio] - name: Assign reviewers
uses: kentaro-m/auto-assign-action@v1.2.5 run: |
with: pip3 install PyGithub
configuration-path: '.github/assign/audio.yml' python3 .github/update_reviewers.py ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${{ github.event.pull_request.number }} .github/reviewers.yml
shell: bash
- name: Auto Assign [CPU]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/cpu.yml'
- name: Auto Assign [GPU]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/gpu.yml'
- name: Auto Assign [GUI]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/gui.yml'
- name: Auto Assign [Horizon]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/horizon.yml'
- name: Auto Assign [Infra]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/infra.yml'
- name: Auto Assign [Global]
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: '.github/assign/global.yml'

View File

@@ -34,7 +34,7 @@
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" /> <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.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" /> <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="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" /> <PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" /> <PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />

View File

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

View File

@@ -114,7 +114,7 @@ namespace Ryujinx.Ava.Common
public static void OpenSaveDir(ulong saveDataId) 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)) if (!Directory.Exists(saveRootPath))
{ {

View File

@@ -2,6 +2,7 @@ using LibHac.Fs;
using LibHac.Ncm; using LibHac.Ncm;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.HLE.FileSystem;
using Ryujinx.Ui.App.Common; using Ryujinx.Ui.App.Common;
using System; using System;
using System.IO; using System.IO;
@@ -81,7 +82,7 @@ namespace Ryujinx.Ava.UI.Models
Task.Run(() => 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); 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 contentPath = contentManager.GetInstalledContentPath(0x010000000000080A, StorageId.BuiltInSystem, NcaContentType.Data);
string avatarPath = virtualFileSystem.SwitchPathToSystemPath(contentPath); string avatarPath = VirtualFileSystem.SwitchPathToSystemPath(contentPath);
if (!string.IsNullOrWhiteSpace(avatarPath)) if (!string.IsNullOrWhiteSpace(avatarPath))
{ {

View File

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

View File

@@ -168,6 +168,16 @@ namespace Ryujinx.Graphics.Vulkan
return ComponentType.Float; return ComponentType.Float;
} }
public ImageAspectFlags GetDepthStencilAspectFlags()
{
if (_depthStencil == null)
{
return ImageAspectFlags.None;
}
return _depthStencil.Info.Format.ConvertAspectFlags();
}
public bool IsValidColorAttachment(int bindIndex) public bool IsValidColorAttachment(int bindIndex)
{ {
return (uint)bindIndex < Constants.MaxRenderTargets && (_validColorAttachments & (1u << bindIndex)) != 0; return (uint)bindIndex < Constants.MaxRenderTargets && (_validColorAttachments & (1u << bindIndex)) != 0;
@@ -226,7 +236,7 @@ namespace Ryujinx.Graphics.Vulkan
_depthStencil?.Storage.SetModification( _depthStencil?.Storage.SetModification(
AccessFlags.DepthStencilAttachmentWriteBit, AccessFlags.DepthStencilAttachmentWriteBit,
PipelineStageFlags.ColorAttachmentOutputBit); PipelineStageFlags.LateFragmentTestsBit);
} }
public void InsertClearBarrier(CommandBufferScoped cbs, int index) public void InsertClearBarrier(CommandBufferScoped cbs, int index)

View File

@@ -1,10 +1,11 @@
using Ryujinx.Graphics.GAL; using Ryujinx.Common;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Shader; using Ryujinx.Graphics.Shader;
using Ryujinx.Graphics.Shader.Translation; using Ryujinx.Graphics.Shader.Translation;
using Ryujinx.Graphics.Vulkan.Shaders;
using Silk.NET.Vulkan; using Silk.NET.Vulkan;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Numerics; using System.Numerics;
using CompareOp = Ryujinx.Graphics.GAL.CompareOp; using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
using Format = Ryujinx.Graphics.GAL.Format; using Format = Ryujinx.Graphics.GAL.Format;
@@ -26,6 +27,7 @@ namespace Ryujinx.Graphics.Vulkan
class HelperShader : IDisposable class HelperShader : IDisposable
{ {
private const int UniformBufferAlignment = 256; private const int UniformBufferAlignment = 256;
private const string ShaderBinariesPath = "Ryujinx.Graphics.Vulkan/Shaders/SpirvBinaries";
private readonly PipelineHelperShader _pipeline; private readonly PipelineHelperShader _pipeline;
private readonly ISampler _samplerLinear; private readonly ISampler _samplerLinear;
@@ -67,40 +69,40 @@ namespace Ryujinx.Graphics.Vulkan
_programColorBlit = gd.CreateProgramWithMinimalLayout(new[] _programColorBlit = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorBlitFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorBlitFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, blitResourceLayout); }, blitResourceLayout);
_programColorBlitMs = gd.CreateProgramWithMinimalLayout(new[] _programColorBlitMs = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorBlitMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorBlitMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, blitResourceLayout); }, blitResourceLayout);
_programColorBlitClearAlpha = gd.CreateProgramWithMinimalLayout(new[] _programColorBlitClearAlpha = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorBlitClearAlphaFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorBlitClearAlphaFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, blitResourceLayout); }, blitResourceLayout);
var colorClearResourceLayout = new ResourceLayoutBuilder().Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1).Build(); var colorClearResourceLayout = new ResourceLayoutBuilder().Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1).Build();
_programColorClearF = gd.CreateProgramWithMinimalLayout(new[] _programColorClearF = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorClearVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorClearFFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorClearFFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, colorClearResourceLayout); }, colorClearResourceLayout);
_programColorClearSI = gd.CreateProgramWithMinimalLayout(new[] _programColorClearSI = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorClearVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorClearSIFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorClearSIFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, colorClearResourceLayout); }, colorClearResourceLayout);
_programColorClearUI = gd.CreateProgramWithMinimalLayout(new[] _programColorClearUI = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorClearVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorClearVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorClearUIFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorClearUIFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, colorClearResourceLayout); }, colorClearResourceLayout);
var strideChangeResourceLayout = new ResourceLayoutBuilder() var strideChangeResourceLayout = new ResourceLayoutBuilder()
@@ -110,7 +112,7 @@ namespace Ryujinx.Graphics.Vulkan
_programStrideChange = gd.CreateProgramWithMinimalLayout(new[] _programStrideChange = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ChangeBufferStrideShaderSource, ShaderStage.Compute, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ChangeBufferStride.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
}, strideChangeResourceLayout); }, strideChangeResourceLayout);
var colorCopyResourceLayout = new ResourceLayoutBuilder() var colorCopyResourceLayout = new ResourceLayoutBuilder()
@@ -120,17 +122,17 @@ namespace Ryujinx.Graphics.Vulkan
_programColorCopyShortening = gd.CreateProgramWithMinimalLayout(new[] _programColorCopyShortening = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorCopyShorteningComputeShaderSource, ShaderStage.Compute, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorCopyShorteningCompute.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
}, colorCopyResourceLayout); }, colorCopyResourceLayout);
_programColorCopyToNonMs = gd.CreateProgramWithMinimalLayout(new[] _programColorCopyToNonMs = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorCopyToNonMsComputeShaderSource, ShaderStage.Compute, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorCopyToNonMsCompute.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
}, colorCopyResourceLayout); }, colorCopyResourceLayout);
_programColorCopyWidening = gd.CreateProgramWithMinimalLayout(new[] _programColorCopyWidening = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorCopyWideningComputeShaderSource, ShaderStage.Compute, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorCopyWideningCompute.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
}, colorCopyResourceLayout); }, colorCopyResourceLayout);
var colorDrawToMsResourceLayout = new ResourceLayoutBuilder() var colorDrawToMsResourceLayout = new ResourceLayoutBuilder()
@@ -139,8 +141,8 @@ namespace Ryujinx.Graphics.Vulkan
_programColorDrawToMs = gd.CreateProgramWithMinimalLayout(new[] _programColorDrawToMs = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorDrawToMsVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorDrawToMsVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.ColorDrawToMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorDrawToMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, colorDrawToMsResourceLayout); }, colorDrawToMsResourceLayout);
var convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder() var convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder()
@@ -150,7 +152,7 @@ namespace Ryujinx.Graphics.Vulkan
_programConvertD32S8ToD24S8 = gd.CreateProgramWithMinimalLayout(new[] _programConvertD32S8ToD24S8 = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ConvertD32S8ToD24S8ShaderSource, ShaderStage.Compute, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ConvertD32S8ToD24S8.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
}, convertD32S8ToD24S8ResourceLayout); }, convertD32S8ToD24S8ResourceLayout);
var convertIndexBufferResourceLayout = new ResourceLayoutBuilder() var convertIndexBufferResourceLayout = new ResourceLayoutBuilder()
@@ -160,7 +162,7 @@ namespace Ryujinx.Graphics.Vulkan
_programConvertIndexBuffer = gd.CreateProgramWithMinimalLayout(new[] _programConvertIndexBuffer = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ConvertIndexBufferShaderSource, ShaderStage.Compute, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ConvertIndexBuffer.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
}, convertIndexBufferResourceLayout); }, convertIndexBufferResourceLayout);
var convertIndirectDataResourceLayout = new ResourceLayoutBuilder() var convertIndirectDataResourceLayout = new ResourceLayoutBuilder()
@@ -171,61 +173,66 @@ namespace Ryujinx.Graphics.Vulkan
_programConvertIndirectData = gd.CreateProgramWithMinimalLayout(new[] _programConvertIndirectData = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ConvertIndirectDataShaderSource, ShaderStage.Compute, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ConvertIndirectData.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
}, convertIndirectDataResourceLayout); }, convertIndirectDataResourceLayout);
_programDepthBlit = gd.CreateProgramWithMinimalLayout(new[] _programDepthBlit = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.DepthBlitFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("DepthBlitFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, blitResourceLayout); }, blitResourceLayout);
_programDepthBlitMs = gd.CreateProgramWithMinimalLayout(new[] _programDepthBlitMs = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.DepthBlitMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("DepthBlitMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, blitResourceLayout); }, blitResourceLayout);
_programDepthDrawToMs = gd.CreateProgramWithMinimalLayout(new[] _programDepthDrawToMs = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorDrawToMsVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorDrawToMsVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.DepthDrawToMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("DepthDrawToMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, colorDrawToMsResourceLayout); }, colorDrawToMsResourceLayout);
_programDepthDrawToNonMs = gd.CreateProgramWithMinimalLayout(new[] _programDepthDrawToNonMs = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorDrawToMsVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorDrawToMsVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.DepthDrawToNonMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("DepthDrawToNonMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, colorDrawToMsResourceLayout); }, colorDrawToMsResourceLayout);
if (gd.Capabilities.SupportsShaderStencilExport) if (gd.Capabilities.SupportsShaderStencilExport)
{ {
_programStencilBlit = gd.CreateProgramWithMinimalLayout(new[] _programStencilBlit = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.StencilBlitFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("StencilBlitFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, blitResourceLayout); }, blitResourceLayout);
_programStencilBlitMs = gd.CreateProgramWithMinimalLayout(new[] _programStencilBlitMs = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorBlitVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorBlitVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.StencilBlitMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("StencilBlitMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, blitResourceLayout); }, blitResourceLayout);
_programStencilDrawToMs = gd.CreateProgramWithMinimalLayout(new[] _programStencilDrawToMs = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorDrawToMsVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorDrawToMsVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.StencilDrawToMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("StencilDrawToMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, colorDrawToMsResourceLayout); }, colorDrawToMsResourceLayout);
_programStencilDrawToNonMs = gd.CreateProgramWithMinimalLayout(new[] _programStencilDrawToNonMs = gd.CreateProgramWithMinimalLayout(new[]
{ {
new ShaderSource(ShaderBinaries.ColorDrawToMsVertexShaderSource, ShaderStage.Vertex, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("ColorDrawToMsVertex.spv"), ShaderStage.Vertex, TargetLanguage.Spirv),
new ShaderSource(ShaderBinaries.StencilDrawToNonMsFragmentShaderSource, ShaderStage.Fragment, TargetLanguage.Spirv), new ShaderSource(ReadSpirv("StencilDrawToNonMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
}, colorDrawToMsResourceLayout); }, colorDrawToMsResourceLayout);
} }
} }
private static byte[] ReadSpirv(string fileName)
{
return EmbeddedResources.Read(string.Join('/', ShaderBinariesPath, fileName));
}
public void Blit( public void Blit(
VulkanRenderer gd, VulkanRenderer gd,
TextureView src, TextureView src,

View File

@@ -152,9 +152,6 @@ namespace Ryujinx.Graphics.Vulkan
{ {
if (_buffer == from) if (_buffer == from)
{ {
_buffer.DecrementReferenceCount();
to.IncrementReferenceCount();
_buffer = to; _buffer = to;
} }
} }

View File

@@ -245,13 +245,28 @@ namespace Ryujinx.Graphics.Vulkan
public unsafe void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask) public unsafe void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
{ {
// TODO: Use stencilMask (fully) // TODO: Use stencilMask (fully).
if (FramebufferParams == null || !FramebufferParams.HasDepthStencil) if (FramebufferParams == null || !FramebufferParams.HasDepthStencil)
{ {
return; return;
} }
var clearValue = new ClearValue(null, new ClearDepthStencilValue(depthValue, (uint)stencilValue));
var flags = depthMask ? ImageAspectFlags.DepthBit : 0;
if (stencilMask != 0)
{
flags |= ImageAspectFlags.StencilBit;
}
flags &= FramebufferParams.GetDepthStencilAspectFlags();
if (flags == ImageAspectFlags.None)
{
return;
}
if (_renderPass == null) if (_renderPass == null)
{ {
CreateRenderPass(); CreateRenderPass();
@@ -259,14 +274,6 @@ namespace Ryujinx.Graphics.Vulkan
BeginRenderPass(); BeginRenderPass();
var clearValue = new ClearValue(null, new ClearDepthStencilValue(depthValue, (uint)stencilValue));
var flags = depthMask ? ImageAspectFlags.DepthBit : 0;
if (stencilMask != 0)
{
flags |= ImageAspectFlags.StencilBit;
}
var attachment = new ClearAttachment(flags, 0, clearValue); var attachment = new ClearAttachment(flags, 0, clearValue);
var clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount); var clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount);
@@ -935,7 +942,7 @@ namespace Ryujinx.Graphics.Vulkan
SignalStateChange(); SignalStateChange();
if (_program.IsCompute) if (internalProgram.IsCompute)
{ {
EndRenderPass(); EndRenderPass();
} }

View File

@@ -21,6 +21,31 @@
<EmbeddedResource Include="Effects\Shaders\SmaaBlend.spv" /> <EmbeddedResource Include="Effects\Shaders\SmaaBlend.spv" />
<EmbeddedResource Include="Effects\Shaders\SmaaEdge.spv" /> <EmbeddedResource Include="Effects\Shaders\SmaaEdge.spv" />
<EmbeddedResource Include="Effects\Shaders\SmaaNeighbour.spv" /> <EmbeddedResource Include="Effects\Shaders\SmaaNeighbour.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ChangeBufferStride.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorBlitClearAlphaFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorBlitFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorBlitMsFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorBlitVertex.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorClearFFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorClearSIFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorClearUIFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorClearVertex.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorCopyShorteningCompute.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorCopyToNonMsCompute.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorCopyWideningCompute.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorDrawToMsFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ColorDrawToMsVertex.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ConvertD32S8ToD24S8.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ConvertIndexBuffer.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\ConvertIndirectData.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\DepthBlitFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\DepthBlitMsFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\DepthDrawToMsFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\DepthDrawToNonMsFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\StencilBlitFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\StencilBlitMsFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\StencilDrawToMsFragment.spv" />
<EmbeddedResource Include="Shaders\SpirvBinaries\StencilDrawToNonMsFragment.spv" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

File diff suppressed because it is too large Load Diff

View File

@@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Vulkan
var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples); var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities.SupportsShaderStorageImageMultisample); var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities.SupportsShaderStorageImageMultisample, forceStorage: true);
var flags = ImageCreateFlags.CreateMutableFormatBit; var flags = ImageCreateFlags.CreateMutableFormatBit;
@@ -291,7 +291,7 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
public static ImageUsageFlags GetImageUsage(Format format, Target target, bool supportsMsStorage) public static ImageUsageFlags GetImageUsage(Format format, Target target, bool supportsMsStorage, bool forceStorage = false)
{ {
var usage = DefaultUsageFlags; var usage = DefaultUsageFlags;
@@ -304,7 +304,7 @@ namespace Ryujinx.Graphics.Vulkan
usage |= ImageUsageFlags.ColorAttachmentBit; usage |= ImageUsageFlags.ColorAttachmentBit;
} }
if (format.IsImageCompatible() && (supportsMsStorage || !target.IsMultisample())) if (((forceStorage && !format.IsDepthOrStencil()) || format.IsImageCompatible()) && (supportsMsStorage || !target.IsMultisample()))
{ {
usage |= ImageUsageFlags.StorageBit; usage |= ImageUsageFlags.StorageBit;
} }

View File

@@ -116,7 +116,14 @@ namespace Ryujinx.Graphics.Vulkan
return new Auto<DisposableImageView>(new DisposableImageView(gd.Api, device, imageView), null, storage.GetImage()); return new Auto<DisposableImageView>(new DisposableImageView(gd.Api, device, imageView), null, storage.GetImage());
} }
_imageView = CreateImageView(componentMapping, subresourceRange, type, ImageUsageFlags.SampledBit); ImageUsageFlags shaderUsage = ImageUsageFlags.SampledBit;
if (info.Format.IsImageCompatible())
{
shaderUsage |= ImageUsageFlags.StorageBit;
}
_imageView = CreateImageView(componentMapping, subresourceRange, type, shaderUsage);
// Framebuffer attachments and storage images requires a identity component mapping. // Framebuffer attachments and storage images requires a identity component mapping.
var identityComponentMapping = new ComponentMapping( var identityComponentMapping = new ComponentMapping(
@@ -378,7 +385,7 @@ namespace Ryujinx.Graphics.Vulkan
bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil(); bool isDepthOrStencil = dst.Info.Format.IsDepthOrStencil();
if (VulkanConfiguration.UseSlowSafeBlitOnAmd && (_gd.Vendor == Vendor.Amd || _gd.IsMoltenVk)) if (!VulkanConfiguration.UseUnsafeBlit || (_gd.Vendor != Vendor.Nvidia && _gd.Vendor != Vendor.Intel))
{ {
_gd.HelperShader.Blit( _gd.HelperShader.Blit(
_gd, _gd,

View File

@@ -3,7 +3,7 @@
static class VulkanConfiguration static class VulkanConfiguration
{ {
public const bool UseFastBufferUpdates = true; public const bool UseFastBufferUpdates = true;
public const bool UseSlowSafeBlitOnAmd = true; public const bool UseUnsafeBlit = true;
public const bool UsePushDescriptors = false; public const bool UsePushDescriptors = false;
public const bool ForceD24S8Unsupported = false; public const bool ForceD24S8Unsupported = false;

View File

@@ -10,17 +10,6 @@ namespace Ryujinx.Graphics.Vulkan
{ {
class VulkanDebugMessenger : IDisposable class VulkanDebugMessenger : IDisposable
{ {
private static readonly string[] _excludedMessages = {
// NOTE: Done on purpose right now.
"UNASSIGNED-CoreValidation-Shader-OutputNotConsumed",
// TODO: Figure out if fixable
"VUID-vkCmdDrawIndexed-None-04584",
// TODO: Might be worth looking into making this happy to possibly optimize copies.
"UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout",
// TODO: Fix this, it's causing too much noise right now.
"VUID-VkSubpassDependency-srcSubpass-00867",
};
private readonly Vk _api; private readonly Vk _api;
private readonly Instance _instance; private readonly Instance _instance;
private readonly GraphicsDebugLevel _logLevel; private readonly GraphicsDebugLevel _logLevel;
@@ -108,14 +97,6 @@ namespace Ryujinx.Graphics.Vulkan
{ {
var msg = Marshal.PtrToStringAnsi((IntPtr)pCallbackData->PMessage); var msg = Marshal.PtrToStringAnsi((IntPtr)pCallbackData->PMessage);
foreach (string excludedMessagePart in _excludedMessages)
{
if (msg.Contains(excludedMessagePart))
{
return 0;
}
}
if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt)) if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt))
{ {
Logger.Error?.Print(LogClass.Gpu, msg); Logger.Error?.Print(LogClass.Gpu, msg);

View File

@@ -377,8 +377,8 @@ namespace Ryujinx.Graphics.Vulkan
ShaderFloat64 = supportedFeatures.ShaderFloat64, ShaderFloat64 = supportedFeatures.ShaderFloat64,
ShaderImageGatherExtended = supportedFeatures.ShaderImageGatherExtended, ShaderImageGatherExtended = supportedFeatures.ShaderImageGatherExtended,
ShaderStorageImageMultisample = supportedFeatures.ShaderStorageImageMultisample, ShaderStorageImageMultisample = supportedFeatures.ShaderStorageImageMultisample,
// ShaderStorageImageReadWithoutFormat = true, ShaderStorageImageReadWithoutFormat = supportedFeatures.ShaderStorageImageReadWithoutFormat,
// ShaderStorageImageWriteWithoutFormat = true, ShaderStorageImageWriteWithoutFormat = supportedFeatures.ShaderStorageImageWriteWithoutFormat,
TessellationShader = supportedFeatures.TessellationShader, TessellationShader = supportedFeatures.TessellationShader,
VertexPipelineStoresAndAtomics = supportedFeatures.VertexPipelineStoresAndAtomics, VertexPipelineStoresAndAtomics = supportedFeatures.VertexPipelineStoresAndAtomics,
RobustBufferAccess = useRobustBufferAccess, RobustBufferAccess = useRobustBufferAccess,

View File

@@ -47,7 +47,7 @@ namespace Ryujinx.HLE.Exceptions
private string BuildMessage() private string BuildMessage()
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new();
// Print the IPC command details (service name, command ID, and handler) // Print the IPC command details (service name, command ID, and handler)
(Type callingType, MethodBase callingMethod) = WalkStackTrace(new StackTrace(this)); (Type callingType, MethodBase callingMethod) = WalkStackTrace(new StackTrace(this));

View File

@@ -30,13 +30,13 @@ namespace Ryujinx.HLE.FileSystem
private Dictionary<StorageId, LinkedList<LocationEntry>> _locationEntries; private Dictionary<StorageId, LinkedList<LocationEntry>> _locationEntries;
private Dictionary<string, ulong> _sharedFontTitleDictionary; private readonly Dictionary<string, ulong> _sharedFontTitleDictionary;
private Dictionary<ulong, string> _systemTitlesNameDictionary; private readonly Dictionary<ulong, string> _systemTitlesNameDictionary;
private Dictionary<string, string> _sharedFontFilenameDictionary; private readonly Dictionary<string, string> _sharedFontFilenameDictionary;
private SortedDictionary<(ulong titleId, NcaContentType type), string> _contentDictionary; private SortedDictionary<(ulong titleId, NcaContentType type), string> _contentDictionary;
private struct AocItem private readonly struct AocItem
{ {
public readonly string ContainerPath; public readonly string ContainerPath;
public readonly string NcaPath; public readonly string NcaPath;
@@ -48,9 +48,9 @@ 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(); private readonly object _lock = new();
@@ -66,7 +66,7 @@ namespace Ryujinx.HLE.FileSystem
{ "FontExtendedChineseSimplified", 0x0100000000000814 }, { "FontExtendedChineseSimplified", 0x0100000000000814 },
{ "FontKorean", 0x0100000000000812 }, { "FontKorean", 0x0100000000000812 },
{ "FontChineseTraditional", 0x0100000000000813 }, { "FontChineseTraditional", 0x0100000000000813 },
{ "FontNintendoExtended", 0x0100000000000810 } { "FontNintendoExtended", 0x0100000000000810 },
}; };
_systemTitlesNameDictionary = new Dictionary<ulong, string>() _systemTitlesNameDictionary = new Dictionary<ulong, string>()
@@ -86,12 +86,12 @@ namespace Ryujinx.HLE.FileSystem
{ "FontExtendedChineseSimplified", "nintendo_udsg-r_ext_zh-cn_003.bfttf" }, { "FontExtendedChineseSimplified", "nintendo_udsg-r_ext_zh-cn_003.bfttf" },
{ "FontKorean", "nintendo_udsg-r_ko_003.bfttf" }, { "FontKorean", "nintendo_udsg-r_ko_003.bfttf" },
{ "FontChineseTraditional", "nintendo_udjxh-db_zh-tw_003.bfttf" }, { "FontChineseTraditional", "nintendo_udjxh-db_zh-tw_003.bfttf" },
{ "FontNintendoExtended", "nintendo_ext_003.bfttf" } { "FontNintendoExtended", "nintendo_ext_003.bfttf" },
}; };
_virtualFileSystem = virtualFileSystem; _virtualFileSystem = virtualFileSystem;
_aocData = new SortedList<ulong, AocItem>(); AocData = new SortedList<ulong, AocItem>();
} }
public void LoadEntries(Switch device = null) public void LoadEntries(Switch device = null)
@@ -110,7 +110,7 @@ namespace Ryujinx.HLE.FileSystem
try try
{ {
contentPathString = ContentPath.GetContentPath(storageId); contentPathString = ContentPath.GetContentPath(storageId);
contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString); contentDirectory = ContentPath.GetRealPath(contentPathString);
registeredDirectory = Path.Combine(contentDirectory, "registered"); registeredDirectory = Path.Combine(contentDirectory, "registered");
} }
catch (NotSupportedException) catch (NotSupportedException)
@@ -120,7 +120,7 @@ namespace Ryujinx.HLE.FileSystem
Directory.CreateDirectory(registeredDirectory); Directory.CreateDirectory(registeredDirectory);
LinkedList<LocationEntry> locationList = new LinkedList<LocationEntry>(); LinkedList<LocationEntry> locationList = new();
void AddEntry(LocationEntry entry) void AddEntry(LocationEntry entry)
{ {
@@ -133,26 +133,21 @@ namespace Ryujinx.HLE.FileSystem
{ {
string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty); string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty);
using (FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0])) using FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0]);
{ Nca nca = new(_virtualFileSystem.KeySet, ncaFile.AsStorage());
Nca nca = new Nca(_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 // Change path format to switch's
switchPath = switchPath.Replace('\\', '/'); switchPath = switchPath.Replace('\\', '/');
LocationEntry entry = new LocationEntry(switchPath, LocationEntry entry = new(switchPath, 0, nca.Header.TitleId, nca.Header.ContentType);
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);
} }
} }
}
foreach (string filePath in Directory.EnumerateFiles(contentDirectory)) foreach (string filePath in Directory.EnumerateFiles(contentDirectory))
{ {
@@ -160,36 +155,28 @@ namespace Ryujinx.HLE.FileSystem
{ {
string ncaName = Path.GetFileNameWithoutExtension(filePath); string ncaName = Path.GetFileNameWithoutExtension(filePath);
using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read)) using FileStream ncaFile = new(filePath, FileMode.Open, FileAccess.Read);
{ Nca nca = new(_virtualFileSystem.KeySet, ncaFile.AsStorage());
Nca nca = new Nca(_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 // Change path format to switch's
switchPath = switchPath.Replace('\\', '/'); switchPath = switchPath.Replace('\\', '/');
LocationEntry entry = new LocationEntry(switchPath, LocationEntry entry = new(switchPath, 0, nca.Header.TitleId, nca.Header.ContentType);
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);
} }
} }
}
if (_locationEntries.TryGetValue(storageId, out var locationEntriesItem) && locationEntriesItem?.Count == 0) if (_locationEntries.TryGetValue(storageId, out var locationEntriesItem) && locationEntriesItem?.Count == 0)
{ {
_locationEntries.Remove(storageId); _locationEntries.Remove(storageId);
} }
if (!_locationEntries.ContainsKey(storageId)) _locationEntries.TryAdd(storageId, locationList);
{
_locationEntries.Add(storageId, locationList);
}
} }
if (device != null) if (device != null)
@@ -239,7 +226,7 @@ namespace Ryujinx.HLE.FileSystem
public void AddAocItem(ulong titleId, string containerPath, string ncaPath, bool mergedToContainer = false) public void AddAocItem(ulong titleId, string containerPath, string ncaPath, bool mergedToContainer = false)
{ {
// TODO: Check Aoc version. // 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}"); Logger.Warning?.Print(LogClass.Application, $"Duplicate AddOnContent detected. TitleId {titleId:X16}");
} }
@@ -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) public bool GetAocDataStorage(ulong aocTitleId, out IStorage aocStorage, IntegrityCheckLevel integrityCheckLevel)
{ {
aocStorage = null; 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); var file = new FileStream(aoc.ContainerPath, FileMode.Open, FileAccess.Read);
using var ncaFile = new UniqueRef<IFile>(); using var ncaFile = new UniqueRef<IFile>();
@@ -331,7 +318,7 @@ namespace Ryujinx.HLE.FileSystem
if (_contentDictionary.ContainsValue(ncaId)) if (_contentDictionary.ContainsValue(ncaId))
{ {
var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId); var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId);
ulong titleId = content.Key.Item1; ulong titleId = content.Key.titleId;
NcaContentType contentType = content.Key.type; NcaContentType contentType = content.Key.type;
StorageId storage = GetInstalledStorage(titleId, contentType, storageId); StorageId storage = GetInstalledStorage(titleId, contentType, storageId);
@@ -403,21 +390,19 @@ namespace Ryujinx.HLE.FileSystem
return false; return false;
} }
string installedPath = _virtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath); string installedPath = VirtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
if (!string.IsNullOrWhiteSpace(installedPath)) if (!string.IsNullOrWhiteSpace(installedPath))
{ {
if (File.Exists(installedPath)) if (File.Exists(installedPath))
{ {
using (FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read)) using FileStream file = new(installedPath, FileMode.Open, FileAccess.Read);
{ Nca nca = new(_virtualFileSystem.KeySet, file.AsStorage());
Nca nca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
bool contentCheck = nca.Header.ContentType == contentType; bool contentCheck = nca.Header.ContentType == contentType;
return contentCheck; return contentCheck;
} }
} }
}
return false; return false;
} }
@@ -426,9 +411,9 @@ namespace Ryujinx.HLE.FileSystem
{ {
LinkedList<LocationEntry> locationList = null; LinkedList<LocationEntry> locationList = null;
if (_locationEntries.ContainsKey(storageId)) if (_locationEntries.TryGetValue(storageId, out LinkedList<LocationEntry> locationEntry))
{ {
locationList = _locationEntries[storageId]; locationList = locationEntry;
} }
if (locationList != null) if (locationList != null)
@@ -446,9 +431,9 @@ namespace Ryujinx.HLE.FileSystem
{ {
LinkedList<LocationEntry> locationList = null; LinkedList<LocationEntry> locationList = null;
if (_locationEntries.ContainsKey(storageId)) if (_locationEntries.TryGetValue(storageId, out LinkedList<LocationEntry> locationEntry))
{ {
locationList = _locationEntries[storageId]; locationList = locationEntry;
} }
if (locationList != null) if (locationList != null)
@@ -488,7 +473,7 @@ namespace Ryujinx.HLE.FileSystem
public void InstallFirmware(string firmwareSource) public void InstallFirmware(string firmwareSource)
{ {
string contentPathString = ContentPath.GetContentPath(StorageId.BuiltInSystem); string contentPathString = ContentPath.GetContentPath(StorageId.BuiltInSystem);
string contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString); string contentDirectory = ContentPath.GetRealPath(contentPathString);
string registeredDirectory = Path.Combine(contentDirectory, "registered"); string registeredDirectory = Path.Combine(contentDirectory, "registered");
string temporaryDirectory = Path.Combine(contentDirectory, "temp"); string temporaryDirectory = Path.Combine(contentDirectory, "temp");
@@ -510,10 +495,10 @@ namespace Ryujinx.HLE.FileSystem
throw new FileNotFoundException("Firmware file does not exist."); 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": case ".zip":
@@ -523,7 +508,7 @@ namespace Ryujinx.HLE.FileSystem
} }
break; break;
case ".xci": case ".xci":
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage()); Xci xci = new(_virtualFileSystem.KeySet, file.AsStorage());
InstallFromCart(xci, temporaryDirectory); InstallFromCart(xci, temporaryDirectory);
break; break;
default: default:
@@ -532,7 +517,6 @@ namespace Ryujinx.HLE.FileSystem
FinishInstallation(temporaryDirectory, registeredDirectory); FinishInstallation(temporaryDirectory, registeredDirectory);
} }
}
private void FinishInstallation(string temporaryDirectory, string registeredDirectory) private void FinishInstallation(string temporaryDirectory, string registeredDirectory)
{ {
@@ -555,7 +539,7 @@ namespace Ryujinx.HLE.FileSystem
{ {
foreach (var entry in filesystem.EnumerateEntries("/", "*.nca")) 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); SaveNca(nca, entry.Name.Remove(entry.Name.IndexOf('.')), temporaryDirectory);
} }
@@ -575,9 +559,7 @@ 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)
{ {
@@ -587,12 +569,12 @@ namespace Ryujinx.HLE.FileSystem
string[] pathComponents = entry.FullName.Replace(".cnmt", "").Split('/'); string[] pathComponents = entry.FullName.Replace(".cnmt", "").Split('/');
string ncaId = pathComponents[pathComponents.Length - 1]; string ncaId = pathComponents[^1];
// If this is a fragmented nca, we need to get the previous element.GetZip // If this is a fragmented nca, we need to get the previous element.GetZip
if (ncaId.Equals("00")) if (ncaId.Equals("00"))
{ {
ncaId = pathComponents[pathComponents.Length - 2]; ncaId = pathComponents[^2];
} }
if (ncaId.Contains(".nca")) if (ncaId.Contains(".nca"))
@@ -606,21 +588,18 @@ namespace Ryujinx.HLE.FileSystem
} }
} }
} }
}
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"); string newPath = Path.Combine(temporaryDirectory, ncaId + ".nca");
Directory.CreateDirectory(newPath); Directory.CreateDirectory(newPath);
using (FileStream file = File.Create(Path.Combine(newPath, "00"))) using FileStream file = File.Create(Path.Combine(newPath, "00"));
{
nca.BaseStorage.AsStream().CopyTo(file); 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>(); using var file = new UniqueRef<IFile>();
@@ -636,14 +615,12 @@ namespace Ryujinx.HLE.FileSystem
return file.Release(); return file.Release();
} }
private Stream GetZipStream(ZipArchiveEntry entry) private static Stream GetZipStream(ZipArchiveEntry entry)
{ {
MemoryStream dest = MemoryStreamManager.Shared.GetStream(); MemoryStream dest = MemoryStreamManager.Shared.GetStream();
using (Stream src = entry.Open()) using Stream src = entry.Open();
{
src.CopyTo(dest); src.CopyTo(dest);
}
return dest; return dest;
} }
@@ -659,7 +636,7 @@ namespace Ryujinx.HLE.FileSystem
throw new MissingKeyException("HeaderKey is empty. Cannot decrypt NCA headers."); 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)) if (Directory.Exists(firmwarePackage))
{ {
@@ -671,10 +648,10 @@ namespace Ryujinx.HLE.FileSystem
throw new FileNotFoundException("Firmware file does not exist."); 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": case ".zip":
@@ -683,7 +660,7 @@ namespace Ryujinx.HLE.FileSystem
return VerifyAndGetVersionZip(archive); return VerifyAndGetVersionZip(archive);
} }
case ".xci": case ".xci":
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage()); Xci xci = new(_virtualFileSystem.KeySet, file.AsStorage());
if (xci.HasPartition(XciPartitionType.Update)) if (xci.HasPartition(XciPartitionType.Update))
{ {
@@ -698,7 +675,6 @@ namespace Ryujinx.HLE.FileSystem
default: default:
break; break;
} }
}
SystemVersion VerifyAndGetVersionDirectory(string firmwareDirectory) SystemVersion VerifyAndGetVersionDirectory(string firmwareDirectory)
{ {
@@ -713,11 +689,10 @@ namespace Ryujinx.HLE.FileSystem
{ {
if (entry.FullName.EndsWith(".nca") || entry.FullName.EndsWith(".nca/00")) if (entry.FullName.EndsWith(".nca") || entry.FullName.EndsWith(".nca/00"))
{ {
using (Stream ncaStream = GetZipStream(entry)) using Stream ncaStream = GetZipStream(entry);
{
IStorage storage = ncaStream.AsStorage(); IStorage storage = ncaStream.AsStorage();
Nca nca = new Nca(_virtualFileSystem.KeySet, storage); Nca nca = new(_virtualFileSystem.KeySet, storage);
if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem)) if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem))
{ {
@@ -730,7 +705,6 @@ namespace Ryujinx.HLE.FileSystem
} }
} }
} }
}
if (updateNcas.TryGetValue(SystemUpdateTitleId, out var ncaEntry)) if (updateNcas.TryGetValue(SystemUpdateTitleId, out var ncaEntry))
{ {
@@ -742,7 +716,7 @@ namespace Ryujinx.HLE.FileSystem
using (Stream ncaStream = GetZipStream(fileEntry)) 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); IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
@@ -772,9 +746,8 @@ namespace Ryujinx.HLE.FileSystem
{ {
string versionEntry = updateNcasItem.Find(x => x.type != NcaContentType.Meta).path; 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());
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage());
var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
@@ -785,7 +758,6 @@ namespace Ryujinx.HLE.FileSystem
systemVersion = new SystemVersion(systemVersionFile.Get.AsStream()); systemVersion = new SystemVersion(systemVersionFile.Get.AsStream());
} }
} }
}
foreach (CnmtContentMetaEntry metaEntry in metaEntries) foreach (CnmtContentMetaEntry metaEntry in metaEntries)
{ {
@@ -807,11 +779,9 @@ namespace Ryujinx.HLE.FileSystem
ZipArchiveEntry metaZipEntry = archive.GetEntry(metaPath); ZipArchiveEntry metaZipEntry = archive.GetEntry(metaPath);
ZipArchiveEntry contentZipEntry = archive.GetEntry(contentPath); ZipArchiveEntry contentZipEntry = archive.GetEntry(contentPath);
using (Stream metaNcaStream = GetZipStream(metaZipEntry)) using Stream metaNcaStream = GetZipStream(metaZipEntry);
{ using Stream contentNcaStream = GetZipStream(contentZipEntry);
using (Stream contentNcaStream = GetZipStream(contentZipEntry)) Nca metaNca = new(_virtualFileSystem.KeySet, metaNcaStream.AsStorage());
{
Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaNcaStream.AsStorage());
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
@@ -828,11 +798,11 @@ namespace Ryujinx.HLE.FileSystem
{ {
byte[] contentData = new byte[size]; byte[] contentData = new byte[size];
Span<byte> content = new Span<byte>(contentData); Span<byte> content = new(contentData);
contentStorage.Read(0, content); 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); LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash);
@@ -844,8 +814,6 @@ namespace Ryujinx.HLE.FileSystem
} }
} }
} }
}
}
if (updateNcas.Count > 0) if (updateNcas.Count > 0)
{ {
@@ -853,9 +821,9 @@ namespace Ryujinx.HLE.FileSystem
foreach (var entry in updateNcas) 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(); 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) if (nca.Header.TitleId == SystemUpdateTitleId && nca.Header.ContentType == NcaContentType.Meta)
{ {
@@ -936,7 +904,7 @@ namespace Ryujinx.HLE.FileSystem
{ {
if (updateNcas.TryGetValue(metaEntry.TitleId, out var ncaEntry)) if (updateNcas.TryGetValue(metaEntry.TitleId, out var ncaEntry))
{ {
var metaNcaEntry = ncaEntry.Find(x => x.type == NcaContentType.Meta); string metaNcaPath = ncaEntry.Find(x => x.type == NcaContentType.Meta).path;
string contentPath = 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. // Nintendo in 9.0.0, removed PPC and only kept the meta nca of it.
@@ -948,10 +916,10 @@ namespace Ryujinx.HLE.FileSystem
continue; 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(); 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); IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
@@ -967,11 +935,11 @@ namespace Ryujinx.HLE.FileSystem
{ {
byte[] contentData = new byte[size]; byte[] contentData = new byte[size];
Span<byte> content = new Span<byte>(contentData); Span<byte> content = new(contentData);
contentStorage.Read(0, content); 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); LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash);
@@ -1017,11 +985,10 @@ namespace Ryujinx.HLE.FileSystem
{ {
if (entry.ContentType == NcaContentType.Data) 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());
Nca nca = new Nca(_virtualFileSystem.KeySet, fileStream.AsStorage());
if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data) if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data)
{ {
@@ -1034,8 +1001,6 @@ namespace Ryujinx.HLE.FileSystem
return new SystemVersion(systemVersionFile.Get.AsStream()); return new SystemVersion(systemVersionFile.Get.AsStream());
} }
} }
}
} }
} }
} }

View File

@@ -2,7 +2,6 @@
using LibHac.Ncm; using LibHac.Ncm;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using System; using System;
using static Ryujinx.HLE.FileSystem.VirtualFileSystem; using static Ryujinx.HLE.FileSystem.VirtualFileSystem;
using Path = System.IO.Path; using Path = System.IO.Path;
@@ -27,16 +26,16 @@ namespace Ryujinx.HLE.FileSystem
public const string Nintendo = "Nintendo"; public const string Nintendo = "Nintendo";
public const string Contents = "Contents"; public const string Contents = "Contents";
public static string GetRealPath(VirtualFileSystem fileSystem, string switchContentPath) public static string GetRealPath(string switchContentPath)
{ {
return switchContentPath switch return switchContentPath switch
{ {
SystemContent => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath, Contents), SystemContent => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath, Contents),
UserContent => Path.Combine(AppDataManager.BaseDirPath, UserNandPath, Contents), UserContent => Path.Combine(AppDataManager.BaseDirPath, UserNandPath, Contents),
SdCardContent => Path.Combine(fileSystem.GetSdCardPath(), Nintendo, Contents), SdCardContent => Path.Combine(GetSdCardPath(), Nintendo, Contents),
System => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath), System => Path.Combine(AppDataManager.BaseDirPath, SystemNandPath),
User => Path.Combine(AppDataManager.BaseDirPath, UserNandPath), User => Path.Combine(AppDataManager.BaseDirPath, UserNandPath),
_ => throw new NotSupportedException($"Content Path \"`{switchContentPath}`\" is not supported.") _ => throw new NotSupportedException($"Content Path \"`{switchContentPath}`\" is not supported."),
}; };
} }
@@ -47,7 +46,7 @@ namespace Ryujinx.HLE.FileSystem
ContentStorageId.System => SystemContent, ContentStorageId.System => SystemContent,
ContentStorageId.User => UserContent, ContentStorageId.User => UserContent,
ContentStorageId.SdCard => SdCardContent, ContentStorageId.SdCard => SdCardContent,
_ => throw new NotSupportedException($"Content Storage Id \"`{contentStorageId}`\" is not supported.") _ => throw new NotSupportedException($"Content Storage Id \"`{contentStorageId}`\" is not supported."),
}; };
} }
@@ -58,7 +57,7 @@ namespace Ryujinx.HLE.FileSystem
StorageId.BuiltInSystem => SystemContent, StorageId.BuiltInSystem => SystemContent,
StorageId.BuiltInUser => UserContent, StorageId.BuiltInUser => UserContent,
StorageId.SdCard => SdCardContent, StorageId.SdCard => SdCardContent,
_ => throw new NotSupportedException($"Storage Id \"`{storageId}`\" is not supported.") _ => throw new NotSupportedException($"Storage Id \"`{storageId}`\" is not supported."),
}; };
} }
@@ -75,7 +74,7 @@ namespace Ryujinx.HLE.FileSystem
GamecardApp or GamecardApp or
GamecardContents or GamecardContents or
GamecardUpdate => StorageId.GameCard, GamecardUpdate => StorageId.GameCard,
_ => StorageId.None _ => StorageId.None,
}; };
} }
} }

View File

@@ -17,8 +17,7 @@ namespace Ryujinx.HLE.FileSystem
public SystemVersion(Stream systemVersionFile) public SystemVersion(Stream systemVersionFile)
{ {
using (BinaryReader reader = new BinaryReader(systemVersionFile)) using BinaryReader reader = new(systemVersionFile);
{
Major = reader.ReadByte(); Major = reader.ReadByte();
Minor = reader.ReadByte(); Minor = reader.ReadByte();
Micro = reader.ReadByte(); Micro = reader.ReadByte();
@@ -37,4 +36,3 @@ namespace Ryujinx.HLE.FileSystem
} }
} }
} }
}

View File

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

View File

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

View File

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

View File

@@ -13,7 +13,6 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
public event EventHandler AppletStateChanged; public event EventHandler AppletStateChanged;
private AppletSession _normalSession; private AppletSession _normalSession;
private AppletSession _interactiveSession;
private CommonArguments _commonArguments; private CommonArguments _commonArguments;
private List<BrowserArgument> _arguments; private List<BrowserArgument> _arguments;
@@ -29,7 +28,6 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession) public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
{ {
_normalSession = normalSession; _normalSession = normalSession;
_interactiveSession = interactiveSession;
_commonArguments = IApplet.ReadStruct<CommonArguments>(_normalSession.Pop()); _commonArguments = IApplet.ReadStruct<CommonArguments>(_normalSession.Pop());
@@ -48,15 +46,16 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
if ((_commonArguments.AppletVersion >= 0x80000 && _shimKind == ShimKind.Web) || (_commonArguments.AppletVersion >= 0x30000 && _shimKind == ShimKind.Share)) if ((_commonArguments.AppletVersion >= 0x80000 && _shimKind == ShimKind.Web) || (_commonArguments.AppletVersion >= 0x30000 && _shimKind == ShimKind.Share))
{ {
List<BrowserOutput> result = new List<BrowserOutput>(); List<BrowserOutput> result = new()
{
result.Add(new BrowserOutput(BrowserOutputType.ExitReason, (uint)WebExitReason.ExitButton)); new BrowserOutput(BrowserOutputType.ExitReason, (uint)WebExitReason.ExitButton),
};
_normalSession.Push(BuildResponseNew(result)); _normalSession.Push(BuildResponseNew(result));
} }
else else
{ {
WebCommonReturnValue result = new WebCommonReturnValue() WebCommonReturnValue result = new()
{ {
ExitReason = WebExitReason.ExitButton, ExitReason = WebExitReason.ExitButton,
}; };
@@ -69,25 +68,22 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
return ResultCode.Success; return ResultCode.Success;
} }
private byte[] BuildResponseOld(WebCommonReturnValue result) private static byte[] BuildResponseOld(WebCommonReturnValue result)
{
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream())
using (BinaryWriter writer = new BinaryWriter(stream))
{ {
using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using BinaryWriter writer = new(stream);
writer.WriteStruct(result); writer.WriteStruct(result);
return stream.ToArray(); return stream.ToArray();
} }
}
private byte[] BuildResponseNew(List<BrowserOutput> outputArguments) private byte[] BuildResponseNew(List<BrowserOutput> outputArguments)
{ {
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream()) using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
writer.WriteStruct(new WebArgHeader writer.WriteStruct(new WebArgHeader
{ {
Count = (ushort)outputArguments.Count, Count = (ushort)outputArguments.Count,
ShimKind = _shimKind ShimKind = _shimKind,
}); });
foreach (BrowserOutput output in outputArguments) foreach (BrowserOutput output in outputArguments)
@@ -101,4 +97,3 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
} }
} }
} }
}

View File

@@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
Value = value; Value = value;
} }
private static readonly Dictionary<WebArgTLVType, Type> _typeRegistry = new Dictionary<WebArgTLVType, Type> private static readonly Dictionary<WebArgTLVType, Type> _typeRegistry = new()
{ {
{ WebArgTLVType.InitialURL, typeof(string) }, { WebArgTLVType.InitialURL, typeof(string) },
{ WebArgTLVType.CallbackUrl, typeof(string) }, { WebArgTLVType.CallbackUrl, typeof(string) },
@@ -64,11 +64,11 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
public static (ShimKind, List<BrowserArgument>) ParseArguments(ReadOnlySpan<byte> data) public static (ShimKind, List<BrowserArgument>) ParseArguments(ReadOnlySpan<byte> data)
{ {
List<BrowserArgument> browserArguments = new List<BrowserArgument>(); List<BrowserArgument> browserArguments = new();
WebArgHeader header = IApplet.ReadStruct<WebArgHeader>(data.Slice(0, 8)); WebArgHeader header = IApplet.ReadStruct<WebArgHeader>(data[..8]);
ReadOnlySpan<byte> rawTLVs = data.Slice(8); ReadOnlySpan<byte> rawTLVs = data[8..];
for (int i = 0; i < header.Count; i++) for (int i = 0; i < header.Count; i++)
{ {
@@ -77,7 +77,7 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
browserArguments.Add(new BrowserArgument((WebArgTLVType)tlv.Type, tlvData.ToArray())); browserArguments.Add(new BrowserArgument((WebArgTLVType)tlv.Type, tlvData.ToArray()));
rawTLVs = rawTLVs.Slice(Unsafe.SizeOf<WebArgTLV>() + tlv.Size); rawTLVs = rawTLVs[(Unsafe.SizeOf<WebArgTLV>() + tlv.Size)..];
} }
return (header.ShimKind, browserArguments); return (header.ShimKind, browserArguments);

View File

@@ -38,7 +38,7 @@ namespace Ryujinx.HLE.HOS.Applets.Browser
writer.WriteStruct(new WebArgTLV writer.WriteStruct(new WebArgTLV
{ {
Type = (ushort)Type, Type = (ushort)Type,
Size = (ushort)Value.Length Size = (ushort)Value.Length,
}); });
writer.Write(Value); writer.Write(Value);

View File

@@ -9,6 +9,6 @@
PostServiceName = 0x5, PostServiceName = 0x5,
PostServiceNameSize = 0x6, PostServiceNameSize = 0x6,
PostId = 0x7, PostId = 0x7,
MediaPlayerAutoClosedByCompletion = 0x8 MediaPlayerAutoClosedByCompletion = 0x8,
} }
} }

View File

@@ -4,6 +4,6 @@
{ {
OfflineHtmlPage = 1, OfflineHtmlPage = 1,
ApplicationLegalInformation, ApplicationLegalInformation,
SystemDataPage SystemDataPage,
} }
} }

View File

@@ -3,6 +3,6 @@
enum LeftStickMode enum LeftStickMode
{ {
Pointer = 0, Pointer = 0,
Cursor Cursor,
} }
} }

View File

@@ -8,6 +8,6 @@
Share, Share,
Web, Web,
Wifi, Wifi,
Lobby Lobby,
} }
} }

View File

@@ -57,6 +57,6 @@
OverrideWebAudioVolume = 0x3F, OverrideWebAudioVolume = 0x3F,
OverrideMediaAudioVolume = 0x40, OverrideMediaAudioVolume = 0x40,
BootMode = 0x41, BootMode = 0x41,
MediaPlayerUiEnabled = 0x43 MediaPlayerUiEnabled = 0x43,
} }
} }

View File

@@ -6,6 +6,6 @@
BackButton, BackButton,
Requested, Requested,
LastUrl, LastUrl,
ErrorDialog = 7 ErrorDialog = 7,
} }
} }

View File

@@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Applets
{ {
internal class ControllerApplet : IApplet internal class ControllerApplet : IApplet
{ {
private Horizon _system; private readonly Horizon _system;
private AppletSession _normalSession; private AppletSession _normalSession;
@@ -65,7 +65,7 @@ namespace Ryujinx.HLE.HOS.Applets
} }
else else
{ {
Logger.Stub?.PrintStub(LogClass.ServiceHid, $"ControllerSupportArg Version Unknown"); Logger.Stub?.PrintStub(LogClass.ServiceHid, "ControllerSupportArg Version Unknown");
argHeader = IApplet.ReadStruct<ControllerSupportArgHeader>(controllerSupportArg); // Read just the header argHeader = IApplet.ReadStruct<ControllerSupportArgHeader>(controllerSupportArg); // Read just the header
} }
@@ -82,17 +82,17 @@ namespace Ryujinx.HLE.HOS.Applets
playerMin = playerMax = 1; playerMin = playerMax = 1;
} }
int configuredCount = 0; int configuredCount;
PlayerIndex primaryIndex = PlayerIndex.Unknown; PlayerIndex primaryIndex;
while (!_system.Device.Hid.Npads.Validate(playerMin, playerMax, (ControllerType)privateArg.NpadStyleSet, out configuredCount, out primaryIndex)) while (!_system.Device.Hid.Npads.Validate(playerMin, playerMax, (ControllerType)privateArg.NpadStyleSet, out configuredCount, out primaryIndex))
{ {
ControllerAppletUiArgs uiArgs = new ControllerAppletUiArgs ControllerAppletUiArgs uiArgs = new()
{ {
PlayerCountMin = playerMin, PlayerCountMin = playerMin,
PlayerCountMax = playerMax, PlayerCountMax = playerMax,
SupportedStyles = (ControllerType)privateArg.NpadStyleSet, SupportedStyles = (ControllerType)privateArg.NpadStyleSet,
SupportedPlayers = _system.Device.Hid.Npads.GetSupportedPlayers(), SupportedPlayers = _system.Device.Hid.Npads.GetSupportedPlayers(),
IsDocked = _system.State.DockedMode IsDocked = _system.State.DockedMode,
}; };
if (!_system.Device.UiHandler.DisplayMessageDialog(uiArgs)) if (!_system.Device.UiHandler.DisplayMessageDialog(uiArgs))
@@ -101,10 +101,10 @@ namespace Ryujinx.HLE.HOS.Applets
} }
} }
ControllerSupportResultInfo result = new ControllerSupportResultInfo ControllerSupportResultInfo result = new()
{ {
PlayerCount = (sbyte)configuredCount, PlayerCount = (sbyte)configuredCount,
SelectedId = (uint)GetNpadIdTypeFromIndex(primaryIndex) SelectedId = (uint)GetNpadIdTypeFromIndex(primaryIndex),
}; };
Logger.Stub?.PrintStub(LogClass.ServiceHid, $"ControllerApplet ReturnResult {result.PlayerCount} {result.SelectedId}"); Logger.Stub?.PrintStub(LogClass.ServiceHid, $"ControllerApplet ReturnResult {result.PlayerCount} {result.SelectedId}");
@@ -122,26 +122,24 @@ namespace Ryujinx.HLE.HOS.Applets
return ResultCode.Success; return ResultCode.Success;
} }
private byte[] BuildResponse(ControllerSupportResultInfo result) private static byte[] BuildResponse(ControllerSupportResultInfo result)
{
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream())
using (BinaryWriter writer = new BinaryWriter(stream))
{ {
using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using BinaryWriter writer = new(stream);
writer.Write(MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(ref result, Unsafe.SizeOf<ControllerSupportResultInfo>()))); writer.Write(MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(ref result, Unsafe.SizeOf<ControllerSupportResultInfo>())));
return stream.ToArray(); return stream.ToArray();
} }
}
private byte[] BuildResponse() private static byte[] BuildResponse()
{
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream())
using (BinaryWriter writer = new BinaryWriter(stream))
{ {
using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using BinaryWriter writer = new(stream);
writer.Write((ulong)ResultCode.Success); writer.Write((ulong)ResultCode.Success);
return stream.ToArray(); return stream.ToArray();
} }
} }
} }
}

View File

@@ -2,7 +2,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Applets namespace Ryujinx.HLE.HOS.Applets
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ControllerSupportArgHeader struct ControllerSupportArgHeader
{ {

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Applets namespace Ryujinx.HLE.HOS.Applets
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
struct ControllerSupportArgPrivate struct ControllerSupportArgPrivate
{ {
public uint PrivateSize; public uint PrivateSize;

View File

@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Applets namespace Ryujinx.HLE.HOS.Applets
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
// (8.0.0+ version) // (8.0.0+ version)
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ControllerSupportArgV7 struct ControllerSupportArgV7

View File

@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Applets namespace Ryujinx.HLE.HOS.Applets
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
// (1.0.0+ version) // (1.0.0+ version)
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ControllerSupportArgVPre7 struct ControllerSupportArgVPre7

View File

@@ -4,6 +4,6 @@ namespace Ryujinx.HLE.HOS.Applets
{ {
ShowControllerSupport = 0, ShowControllerSupport = 0,
ShowControllerStrapGuide = 1, ShowControllerStrapGuide = 1,
ShowControllerFirmwareUpdate = 2 ShowControllerFirmwareUpdate = 2,
} }
} }

View File

@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Applets namespace Ryujinx.HLE.HOS.Applets
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ControllerSupportResultInfo struct ControllerSupportResultInfo
{ {

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
{ {
private const long ErrorMessageBinaryTitleId = 0x0100000000000801; private const long ErrorMessageBinaryTitleId = 0x0100000000000801;
private Horizon _horizon; private readonly Horizon _horizon;
private AppletSession _normalSession; private AppletSession _normalSession;
private CommonArguments _commonArguments; private CommonArguments _commonArguments;
private ErrorCommonHeader _errorCommonHeader; private ErrorCommonHeader _errorCommonHeader;
@@ -63,7 +63,8 @@ namespace Ryujinx.HLE.HOS.Applets.Error
break; break;
} }
default: throw new NotImplementedException($"ErrorApplet type {_errorCommonHeader.Type} is not implemented."); default:
throw new NotImplementedException($"ErrorApplet type {_errorCommonHeader.Type} is not implemented.");
} }
AppletStateChanged?.Invoke(this, null); AppletStateChanged?.Invoke(this, null);
@@ -71,15 +72,16 @@ namespace Ryujinx.HLE.HOS.Applets.Error
return ResultCode.Success; return ResultCode.Success;
} }
private (uint module, uint description) HexToResultCode(uint resultCode) private static (uint module, uint description) HexToResultCode(uint resultCode)
{ {
return ((resultCode & 0x1FF) + 2000, (resultCode >> 9) & 0x3FFF); return ((resultCode & 0x1FF) + 2000, (resultCode >> 9) & 0x3FFF);
} }
private string SystemLanguageToLanguageKey(SystemLanguage systemLanguage) private static string SystemLanguageToLanguageKey(SystemLanguage systemLanguage)
{ {
return systemLanguage switch return systemLanguage switch
{ {
#pragma warning disable IDE0055 // Disable formatting
SystemLanguage.Japanese => "ja", SystemLanguage.Japanese => "ja",
SystemLanguage.AmericanEnglish => "en-US", SystemLanguage.AmericanEnglish => "en-US",
SystemLanguage.French => "fr", SystemLanguage.French => "fr",
@@ -98,7 +100,8 @@ namespace Ryujinx.HLE.HOS.Applets.Error
SystemLanguage.SimplifiedChinese => "zh-Hans", SystemLanguage.SimplifiedChinese => "zh-Hans",
SystemLanguage.TraditionalChinese => "zh-Hant", SystemLanguage.TraditionalChinese => "zh-Hant",
SystemLanguage.BrazilianPortuguese => "pt-BR", SystemLanguage.BrazilianPortuguese => "pt-BR",
_ => "en-US" _ => "en-US",
#pragma warning restore IDE0055
}; };
} }
@@ -111,9 +114,8 @@ namespace Ryujinx.HLE.HOS.Applets.Error
{ {
string binaryTitleContentPath = _horizon.ContentManager.GetInstalledContentPath(ErrorMessageBinaryTitleId, StorageId.BuiltInSystem, NcaContentType.Data); string binaryTitleContentPath = _horizon.ContentManager.GetInstalledContentPath(ErrorMessageBinaryTitleId, StorageId.BuiltInSystem, NcaContentType.Data);
using (LibHac.Fs.IStorage ncaFileStream = new LocalStorage(_horizon.Device.FileSystem.SwitchPathToSystemPath(binaryTitleContentPath), FileAccess.Read, FileMode.Open)) using LibHac.Fs.IStorage ncaFileStream = new LocalStorage(FileSystem.VirtualFileSystem.SwitchPathToSystemPath(binaryTitleContentPath), FileAccess.Read, FileMode.Open);
{ Nca nca = new(_horizon.Device.FileSystem.KeySet, ncaFileStream);
Nca nca = new Nca(_horizon.Device.FileSystem.KeySet, ncaFileStream);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _horizon.FsIntegrityCheckLevel); IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, _horizon.FsIntegrityCheckLevel);
string languageCode = SystemLanguageToLanguageKey(_horizon.State.DesiredSystemLanguage); string languageCode = SystemLanguageToLanguageKey(_horizon.State.DesiredSystemLanguage);
string filePath = $"/{module}/{description:0000}/{languageCode}_{key}"; string filePath = $"/{module}/{description:0000}/{languageCode}_{key}";
@@ -123,7 +125,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
using var binaryFile = new UniqueRef<IFile>(); using var binaryFile = new UniqueRef<IFile>();
romfs.OpenFile(ref binaryFile.Ref, filePath.ToU8Span(), OpenMode.Read).ThrowIfFailure(); romfs.OpenFile(ref binaryFile.Ref, filePath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
StreamReader reader = new StreamReader(binaryFile.Get.AsStream(), Encoding.Unicode); StreamReader reader = new(binaryFile.Get.AsStream(), Encoding.Unicode);
return CleanText(reader.ReadToEnd()); return CleanText(reader.ReadToEnd());
} }
@@ -132,7 +134,6 @@ namespace Ryujinx.HLE.HOS.Applets.Error
return ""; return "";
} }
} }
}
private string[] GetButtonsText(uint module, uint description, string key) private string[] GetButtonsText(uint module, uint description, string key)
{ {
@@ -188,7 +189,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
string messageText = Encoding.ASCII.GetString(messageTextBuffer.TakeWhile(b => !b.Equals(0)).ToArray()); string messageText = Encoding.ASCII.GetString(messageTextBuffer.TakeWhile(b => !b.Equals(0)).ToArray());
string detailsText = Encoding.ASCII.GetString(detailsTextBuffer.TakeWhile(b => !b.Equals(0)).ToArray()); string detailsText = Encoding.ASCII.GetString(detailsTextBuffer.TakeWhile(b => !b.Equals(0)).ToArray());
List<string> buttons = new List<string>(); List<string> buttons = new();
// TODO: Handle the LanguageCode to return the translated "OK" and "Details". // TODO: Handle the LanguageCode to return the translated "OK" and "Details".

View File

@@ -8,6 +8,6 @@
ErrorEulaArg, ErrorEulaArg,
ErrorPctlArg, ErrorPctlArg,
ErrorRecordArg, ErrorRecordArg,
SystemUpdateEulaArg = 8 SystemUpdateEulaArg = 8,
} }
} }

View File

@@ -8,10 +8,12 @@ namespace Ryujinx.HLE.HOS.Applets
{ {
internal class PlayerSelectApplet : IApplet internal class PlayerSelectApplet : IApplet
{ {
private Horizon _system; private readonly Horizon _system;
private AppletSession _normalSession; private AppletSession _normalSession;
#pragma warning disable IDE0052 // Remove unread private member
private AppletSession _interactiveSession; private AppletSession _interactiveSession;
#pragma warning restore IDE0052
public event EventHandler AppletStateChanged; public event EventHandler AppletStateChanged;
@@ -44,9 +46,9 @@ namespace Ryujinx.HLE.HOS.Applets
{ {
UserProfile currentUser = _system.AccountManager.LastOpenedUser; UserProfile currentUser = _system.AccountManager.LastOpenedUser;
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream()) using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
writer.Write((ulong)PlayerSelectResult.Success); writer.Write((ulong)PlayerSelectResult.Success);
currentUser.UserId.Write(writer); currentUser.UserId.Write(writer);
@@ -55,4 +57,3 @@ namespace Ryujinx.HLE.HOS.Applets
} }
} }
} }
}

View File

@@ -3,6 +3,6 @@
enum PlayerSelectResult : ulong enum PlayerSelectResult : ulong
{ {
Success = 0, Success = 0,
Failure = 2 Failure = 2,
} }
} }

View File

@@ -13,6 +13,6 @@
/// <summary> /// <summary>
/// Position the cursor at the end of the text /// Position the cursor at the end of the text
/// </summary> /// </summary>
End End,
} }
} }

View File

@@ -43,6 +43,6 @@
/// <summary> /// <summary>
/// [8.0.0+] Request the keyboard applet to use the MovedCursorV2 response when notifying changes in cursor position. /// [8.0.0+] Request the keyboard applet to use the MovedCursorV2 response when notifying changes in cursor position.
/// </summary> /// </summary>
UseMovedCursorV2 = 0xE UseMovedCursorV2 = 0xE,
} }
} }

View File

@@ -88,6 +88,6 @@
/// <summary> /// <summary>
/// Same as MovedCursorUtf8, but with additional fields. /// Same as MovedCursorUtf8, but with additional fields.
/// </summary> /// </summary>
MovedCursorUtf8V2 = 0x10 MovedCursorUtf8V2 = 0x10,
} }
} }

View File

@@ -28,6 +28,6 @@
/// <summary> /// <summary>
/// software keyboard is transitioning to a hidden state because the user pressed either OK or Cancel. /// software keyboard is transitioning to a hidden state because the user pressed either OK or Cancel.
/// </summary> /// </summary>
Disappearing = 0x4 Disappearing = 0x4,
} }
} }

View File

@@ -60,56 +60,52 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
{ {
uint resSize = 2 * sizeof(uint) + 0x1; uint resSize = 2 * sizeof(uint) + 0x1;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.FinishedInitialize, writer); BeginResponse(state, InlineKeyboardResponse.FinishedInitialize, writer);
writer.Write((byte)1); // Data (ignored by the program) writer.Write((byte)1); // Data (ignored by the program)
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] Default(InlineKeyboardState state) public static byte[] Default(InlineKeyboardState state)
{ {
uint resSize = 2 * sizeof(uint); uint resSize = 2 * sizeof(uint);
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.Default, writer); BeginResponse(state, InlineKeyboardResponse.Default, writer);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] ChangedString(string text, uint cursor, InlineKeyboardState state) public static byte[] ChangedString(string text, uint cursor, InlineKeyboardState state)
{ {
uint resSize = 6 * sizeof(uint) + MaxStrLenUTF16; uint resSize = 6 * sizeof(uint) + MaxStrLenUTF16;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.ChangedString, writer); BeginResponse(state, InlineKeyboardResponse.ChangedString, writer);
WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, true); WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, true);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] MovedCursor(string text, uint cursor, InlineKeyboardState state) public static byte[] MovedCursor(string text, uint cursor, InlineKeyboardState state)
{ {
uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16; uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.MovedCursor, writer); BeginResponse(state, InlineKeyboardResponse.MovedCursor, writer);
WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false); WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] MovedTab(string text, uint cursor, InlineKeyboardState state) public static byte[] MovedTab(string text, uint cursor, InlineKeyboardState state)
{ {
@@ -117,176 +113,164 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16; uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.MovedTab, writer); BeginResponse(state, InlineKeyboardResponse.MovedTab, writer);
WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false); WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] DecidedEnter(string text, InlineKeyboardState state) public static byte[] DecidedEnter(string text, InlineKeyboardState state)
{ {
uint resSize = 3 * sizeof(uint) + MaxStrLenUTF16; uint resSize = 3 * sizeof(uint) + MaxStrLenUTF16;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.DecidedEnter, writer); BeginResponse(state, InlineKeyboardResponse.DecidedEnter, writer);
WriteString(text, writer, MaxStrLenUTF16, Encoding.Unicode); WriteString(text, writer, MaxStrLenUTF16, Encoding.Unicode);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] DecidedCancel(InlineKeyboardState state) public static byte[] DecidedCancel(InlineKeyboardState state)
{ {
uint resSize = 2 * sizeof(uint); uint resSize = 2 * sizeof(uint);
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.DecidedCancel, writer); BeginResponse(state, InlineKeyboardResponse.DecidedCancel, writer);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] ChangedStringUtf8(string text, uint cursor, InlineKeyboardState state) public static byte[] ChangedStringUtf8(string text, uint cursor, InlineKeyboardState state)
{ {
uint resSize = 6 * sizeof(uint) + MaxStrLenUTF8; uint resSize = 6 * sizeof(uint) + MaxStrLenUTF8;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.ChangedStringUtf8, writer); BeginResponse(state, InlineKeyboardResponse.ChangedStringUtf8, writer);
WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, true); WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, true);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] MovedCursorUtf8(string text, uint cursor, InlineKeyboardState state) public static byte[] MovedCursorUtf8(string text, uint cursor, InlineKeyboardState state)
{ {
uint resSize = 4 * sizeof(uint) + MaxStrLenUTF8; uint resSize = 4 * sizeof(uint) + MaxStrLenUTF8;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.MovedCursorUtf8, writer); BeginResponse(state, InlineKeyboardResponse.MovedCursorUtf8, writer);
WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, false); WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, false);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] DecidedEnterUtf8(string text, InlineKeyboardState state) public static byte[] DecidedEnterUtf8(string text, InlineKeyboardState state)
{ {
uint resSize = 3 * sizeof(uint) + MaxStrLenUTF8; uint resSize = 3 * sizeof(uint) + MaxStrLenUTF8;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.DecidedEnterUtf8, writer); BeginResponse(state, InlineKeyboardResponse.DecidedEnterUtf8, writer);
WriteString(text, writer, MaxStrLenUTF8, Encoding.UTF8); WriteString(text, writer, MaxStrLenUTF8, Encoding.UTF8);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] UnsetCustomizeDic(InlineKeyboardState state) public static byte[] UnsetCustomizeDic(InlineKeyboardState state)
{ {
uint resSize = 2 * sizeof(uint); uint resSize = 2 * sizeof(uint);
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.UnsetCustomizeDic, writer); BeginResponse(state, InlineKeyboardResponse.UnsetCustomizeDic, writer);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] ReleasedUserWordInfo(InlineKeyboardState state) public static byte[] ReleasedUserWordInfo(InlineKeyboardState state)
{ {
uint resSize = 2 * sizeof(uint); uint resSize = 2 * sizeof(uint);
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.ReleasedUserWordInfo, writer); BeginResponse(state, InlineKeyboardResponse.ReleasedUserWordInfo, writer);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] UnsetCustomizedDictionaries(InlineKeyboardState state) public static byte[] UnsetCustomizedDictionaries(InlineKeyboardState state)
{ {
uint resSize = 2 * sizeof(uint); uint resSize = 2 * sizeof(uint);
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.UnsetCustomizedDictionaries, writer); BeginResponse(state, InlineKeyboardResponse.UnsetCustomizedDictionaries, writer);
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] ChangedStringV2(string text, uint cursor, InlineKeyboardState state) public static byte[] ChangedStringV2(string text, uint cursor, InlineKeyboardState state)
{ {
uint resSize = 6 * sizeof(uint) + MaxStrLenUTF16 + 0x1; uint resSize = 6 * sizeof(uint) + MaxStrLenUTF16 + 0x1;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.ChangedStringV2, writer); BeginResponse(state, InlineKeyboardResponse.ChangedStringV2, writer);
WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, true); WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, true);
writer.Write((byte)0); // Flag == 0 writer.Write((byte)0); // Flag == 0
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] MovedCursorV2(string text, uint cursor, InlineKeyboardState state) public static byte[] MovedCursorV2(string text, uint cursor, InlineKeyboardState state)
{ {
uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16 + 0x1; uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16 + 0x1;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.MovedCursorV2, writer); BeginResponse(state, InlineKeyboardResponse.MovedCursorV2, writer);
WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false); WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false);
writer.Write((byte)0); // Flag == 0 writer.Write((byte)0); // Flag == 0
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] ChangedStringUtf8V2(string text, uint cursor, InlineKeyboardState state) public static byte[] ChangedStringUtf8V2(string text, uint cursor, InlineKeyboardState state)
{ {
uint resSize = 6 * sizeof(uint) + MaxStrLenUTF8 + 0x1; uint resSize = 6 * sizeof(uint) + MaxStrLenUTF8 + 0x1;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.ChangedStringUtf8V2, writer); BeginResponse(state, InlineKeyboardResponse.ChangedStringUtf8V2, writer);
WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, true); WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, true);
writer.Write((byte)0); // Flag == 0 writer.Write((byte)0); // Flag == 0
return stream.ToArray(); return stream.ToArray();
} }
}
public static byte[] MovedCursorUtf8V2(string text, uint cursor, InlineKeyboardState state) public static byte[] MovedCursorUtf8V2(string text, uint cursor, InlineKeyboardState state)
{ {
uint resSize = 4 * sizeof(uint) + MaxStrLenUTF8 + 0x1; uint resSize = 4 * sizeof(uint) + MaxStrLenUTF8 + 0x1;
using (MemoryStream stream = new MemoryStream(new byte[resSize])) using MemoryStream stream = new(new byte[resSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
BeginResponse(state, InlineKeyboardResponse.MovedCursorUtf8V2, writer); BeginResponse(state, InlineKeyboardResponse.MovedCursorUtf8V2, writer);
WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, false); WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, false);
writer.Write((byte)0); // Flag == 0 writer.Write((byte)0); // Flag == 0
@@ -295,4 +279,3 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
} }
} }
} }
}

View File

@@ -13,6 +13,6 @@
/// <summary> /// <summary>
/// Displays the text entry area as a multi-line field. /// Displays the text entry area as a multi-line field.
/// </summary> /// </summary>
MultiLine MultiLine,
} }
} }

View File

@@ -51,6 +51,6 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
/// <summary> /// <summary>
/// Prohibits characters outside of those allowed in Mii Nicknames. /// Prohibits characters outside of those allowed in Mii Nicknames.
/// </summary> /// </summary>
Username = 1 << 8 Username = 1 << 8,
} }
} }

View File

@@ -21,6 +21,6 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
DisableSeGroup = 0x4000, DisableSeGroup = 0x4000,
SetBackspaceEnabled = 0x8000, SetBackspaceEnabled = 0x8000,
AppearTrigger = 0x10000, AppearTrigger = 0x10000,
MustShow = Appear | SetInputText | AppearTrigger MustShow = Appear | SetInputText | AppearTrigger,
} }
} }

View File

@@ -7,6 +7,6 @@
{ {
None = 0, None = 0,
Auto = 1, Auto = 1,
Forced = 2 Forced = 2,
} }
} }

View File

@@ -13,6 +13,6 @@
/// <summary> /// <summary>
/// Hide input characters. /// Hide input characters.
/// </summary> /// </summary>
Enabled Enabled,
} }
} }

View File

@@ -85,33 +85,34 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
public SoftwareKeyboardAppearEx ToExtended() public SoftwareKeyboardAppearEx ToExtended()
{ {
SoftwareKeyboardAppearEx appear = new SoftwareKeyboardAppearEx(); SoftwareKeyboardAppearEx appear = new()
{
appear.KeyboardMode = KeyboardMode; KeyboardMode = KeyboardMode,
appear.OkText = OkText; OkText = OkText,
appear.LeftOptionalSymbolKey = LeftOptionalSymbolKey; LeftOptionalSymbolKey = LeftOptionalSymbolKey,
appear.RightOptionalSymbolKey = RightOptionalSymbolKey; RightOptionalSymbolKey = RightOptionalSymbolKey,
appear.PredictionEnabled = PredictionEnabled; PredictionEnabled = PredictionEnabled,
appear.CancelButtonDisabled = CancelButtonDisabled; CancelButtonDisabled = CancelButtonDisabled,
appear.InvalidChars = InvalidChars; InvalidChars = InvalidChars,
appear.TextMaxLength = TextMaxLength; TextMaxLength = TextMaxLength,
appear.TextMinLength = TextMinLength; TextMinLength = TextMinLength,
appear.UseNewLine = UseNewLine; UseNewLine = UseNewLine,
appear.MiniaturizationMode = MiniaturizationMode; MiniaturizationMode = MiniaturizationMode,
appear.Reserved1 = Reserved1; Reserved1 = Reserved1,
appear.Reserved2 = Reserved2; Reserved2 = Reserved2,
appear.InvalidButtons = InvalidButtons; InvalidButtons = InvalidButtons,
appear.UseSaveData = UseSaveData; UseSaveData = UseSaveData,
appear.Reserved3 = Reserved3; Reserved3 = Reserved3,
appear.Reserved4 = Reserved4; Reserved4 = Reserved4,
appear.Reserved5 = Reserved5; Reserved5 = Reserved5,
appear.Uid0 = Reserved6; Uid0 = Reserved6,
appear.Uid1 = Reserved7; Uid1 = Reserved7,
appear.SamplingNumber = 0; SamplingNumber = 0,
appear.Reserved6 = 0; Reserved6 = 0,
appear.Reserved7 = 0; Reserved7 = 0,
appear.Reserved8 = 0; Reserved8 = 0,
appear.Reserved9 = 0; Reserved9 = 0,
};
return appear; return appear;
} }

View File

@@ -42,9 +42,11 @@ namespace Ryujinx.HLE.HOS.Applets
private SoftwareKeyboardConfig _keyboardForegroundConfig; private SoftwareKeyboardConfig _keyboardForegroundConfig;
// Configuration for background (inline) mode. // Configuration for background (inline) mode.
#pragma warning disable IDE0052 // Remove unread private member
private SoftwareKeyboardInitialize _keyboardBackgroundInitialize; private SoftwareKeyboardInitialize _keyboardBackgroundInitialize;
private SoftwareKeyboardCustomizeDic _keyboardBackgroundDic; private SoftwareKeyboardCustomizeDic _keyboardBackgroundDic;
private SoftwareKeyboardDictSet _keyboardBackgroundDictSet; private SoftwareKeyboardDictSet _keyboardBackgroundDictSet;
#pragma warning restore IDE0052
private SoftwareKeyboardUserWord[] _keyboardBackgroundUserWords; private SoftwareKeyboardUserWord[] _keyboardBackgroundUserWords;
private byte[] _transferMemory; private byte[] _transferMemory;
@@ -217,7 +219,7 @@ namespace Ryujinx.HLE.HOS.Applets
_keyboardForegroundConfig.SubmitText : "OK"), _keyboardForegroundConfig.SubmitText : "OK"),
StringLengthMin = _keyboardForegroundConfig.StringLengthMin, StringLengthMin = _keyboardForegroundConfig.StringLengthMin,
StringLengthMax = _keyboardForegroundConfig.StringLengthMax, StringLengthMax = _keyboardForegroundConfig.StringLengthMax,
InitialText = initialText InitialText = initialText,
}; };
_lastResult = _device.UiHandler.DisplayInputDialog(args, out _textValue) ? KeyboardResult.Accept : KeyboardResult.Cancel; _lastResult = _device.UiHandler.DisplayInputDialog(args, out _textValue) ? KeyboardResult.Accept : KeyboardResult.Cancel;
@@ -237,7 +239,7 @@ namespace Ryujinx.HLE.HOS.Applets
// we truncate it. // we truncate it.
if (_textValue.Length > _keyboardForegroundConfig.StringLengthMax) if (_textValue.Length > _keyboardForegroundConfig.StringLengthMax)
{ {
_textValue = _textValue.Substring(0, _keyboardForegroundConfig.StringLengthMax); _textValue = _textValue[.._keyboardForegroundConfig.StringLengthMax];
} }
// Does the application want to validate the text itself? // Does the application want to validate the text itself?
@@ -319,9 +321,9 @@ namespace Ryujinx.HLE.HOS.Applets
// request from the game, this is because the inline keyboard is expected to // request from the game, this is because the inline keyboard is expected to
// keep running in the background sending data by itself. // keep running in the background sending data by itself.
using (MemoryStream stream = new MemoryStream(data)) using MemoryStream stream = new(data);
using (BinaryReader reader = new BinaryReader(stream)) using BinaryReader reader = new(stream);
{
var request = (InlineKeyboardRequest)reader.ReadUInt32(); var request = (InlineKeyboardRequest)reader.ReadUInt32();
long remaining; long remaining;
@@ -486,11 +488,10 @@ namespace Ryujinx.HLE.HOS.Applets
break; break;
} }
} }
}
private void ActivateFrontend() private void ActivateFrontend()
{ {
Logger.Debug?.Print(LogClass.ServiceAm, $"Activating software keyboard frontend"); Logger.Debug?.Print(LogClass.ServiceAm, "Activating software keyboard frontend");
_inputMode = KeyboardInputMode.ControllerAndKeyboard; _inputMode = KeyboardInputMode.ControllerAndKeyboard;
@@ -509,7 +510,7 @@ namespace Ryujinx.HLE.HOS.Applets
private void DeactivateFrontend() private void DeactivateFrontend()
{ {
Logger.Debug?.Print(LogClass.ServiceAm, $"Deactivating software keyboard frontend"); Logger.Debug?.Print(LogClass.ServiceAm, "Deactivating software keyboard frontend");
_inputMode = KeyboardInputMode.ControllerAndKeyboard; _inputMode = KeyboardInputMode.ControllerAndKeyboard;
_canAcceptController = false; _canAcceptController = false;
@@ -520,7 +521,7 @@ namespace Ryujinx.HLE.HOS.Applets
private void DestroyFrontend() private void DestroyFrontend()
{ {
Logger.Debug?.Print(LogClass.ServiceAm, $"Destroying software keyboard frontend"); Logger.Debug?.Print(LogClass.ServiceAm, "Destroying software keyboard frontend");
_keyboardRenderer?.Dispose(); _keyboardRenderer?.Dispose();
_keyboardRenderer = null; _keyboardRenderer = null;
@@ -575,7 +576,7 @@ namespace Ryujinx.HLE.HOS.Applets
if (text.Length > MaxUiTextSize) if (text.Length > MaxUiTextSize)
{ {
// Limit the text size and change it back. // Limit the text size and change it back.
text = text.Substring(0, MaxUiTextSize); text = text[..MaxUiTextSize];
cursorBegin = Math.Min(cursorBegin, MaxUiTextSize); cursorBegin = Math.Min(cursorBegin, MaxUiTextSize);
cursorEnd = Math.Min(cursorEnd, MaxUiTextSize); cursorEnd = Math.Min(cursorEnd, MaxUiTextSize);
@@ -734,9 +735,8 @@ namespace Ryujinx.HLE.HOS.Applets
{ {
int bufferSize = interactive ? InteractiveBufferSize : StandardBufferSize; int bufferSize = interactive ? InteractiveBufferSize : StandardBufferSize;
using (MemoryStream stream = new MemoryStream(new byte[bufferSize])) using MemoryStream stream = new(new byte[bufferSize]);
using (BinaryWriter writer = new BinaryWriter(stream)) using BinaryWriter writer = new(stream);
{
byte[] output = _encoding.GetBytes(_textValue); byte[] output = _encoding.GetBytes(_textValue);
if (!interactive) if (!interactive)
@@ -762,7 +762,6 @@ namespace Ryujinx.HLE.HOS.Applets
_interactiveSession.Push(stream.ToArray()); _interactiveSession.Push(stream.ToArray());
} }
} }
}
/// <summary> /// <summary>
/// Removes all Unicode control code characters from the input string. /// Removes all Unicode control code characters from the input string.
@@ -787,7 +786,7 @@ namespace Ryujinx.HLE.HOS.Applets
return string.Empty; return string.Empty;
} }
StringBuilder sb = new StringBuilder(capacity: input.Length); StringBuilder sb = new(capacity: input.Length);
foreach (char c in input) foreach (char c in input)
{ {
if (!char.IsControl(c)) if (!char.IsControl(c))

View File

@@ -174,45 +174,46 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
public SoftwareKeyboardCalcEx ToExtended() public SoftwareKeyboardCalcEx ToExtended()
{ {
SoftwareKeyboardCalcEx calc = new SoftwareKeyboardCalcEx(); SoftwareKeyboardCalcEx calc = new()
{
calc.Unknown = Unknown; Unknown = Unknown,
calc.Size = Size; Size = Size,
calc.Unknown1 = Unknown1; Unknown1 = Unknown1,
calc.Unknown2 = Unknown2; Unknown2 = Unknown2,
calc.Flags = Flags; Flags = Flags,
calc.Initialize = Initialize; Initialize = Initialize,
calc.Volume = Volume; Volume = Volume,
calc.CursorPos = CursorPos; CursorPos = CursorPos,
calc.Appear = Appear.ToExtended(); Appear = Appear.ToExtended(),
calc.InputText = InputText; InputText = InputText,
calc.UseUtf8 = UseUtf8; UseUtf8 = UseUtf8,
calc.Unknown3 = Unknown3; Unknown3 = Unknown3,
calc.BackspaceEnabled = BackspaceEnabled; BackspaceEnabled = BackspaceEnabled,
calc.Unknown4 = Unknown4; Unknown4 = Unknown4,
calc.Unknown5 = Unknown5; Unknown5 = Unknown5,
calc.KeytopAsFloating = KeytopAsFloating; KeytopAsFloating = KeytopAsFloating,
calc.FooterScalable = FooterScalable; FooterScalable = FooterScalable,
calc.AlphaEnabledInInputMode = AlphaEnabledInInputMode; AlphaEnabledInInputMode = AlphaEnabledInInputMode,
calc.InputModeFadeType = InputModeFadeType; InputModeFadeType = InputModeFadeType,
calc.TouchDisabled = TouchDisabled; TouchDisabled = TouchDisabled,
calc.HardwareKeyboardDisabled = HardwareKeyboardDisabled; HardwareKeyboardDisabled = HardwareKeyboardDisabled,
calc.Unknown6 = Unknown6; Unknown6 = Unknown6,
calc.Unknown7 = Unknown7; Unknown7 = Unknown7,
calc.KeytopScale0 = KeytopScale0; KeytopScale0 = KeytopScale0,
calc.KeytopScale1 = KeytopScale1; KeytopScale1 = KeytopScale1,
calc.KeytopTranslate0 = KeytopTranslate0; KeytopTranslate0 = KeytopTranslate0,
calc.KeytopTranslate1 = KeytopTranslate1; KeytopTranslate1 = KeytopTranslate1,
calc.KeytopBgAlpha = KeytopBgAlpha; KeytopBgAlpha = KeytopBgAlpha,
calc.FooterBgAlpha = FooterBgAlpha; FooterBgAlpha = FooterBgAlpha,
calc.BalloonScale = BalloonScale; BalloonScale = BalloonScale,
calc.Unknown8 = Unknown8; Unknown8 = Unknown8,
calc.Unknown9 = Unknown9; Unknown9 = Unknown9,
calc.Unknown10 = Unknown10; Unknown10 = Unknown10,
calc.Unknown11 = Unknown11; Unknown11 = Unknown11,
calc.SeGroup = SeGroup; SeGroup = SeGroup,
calc.TriggerFlag = TriggerFlag; TriggerFlag = TriggerFlag,
calc.Trigger = Trigger; Trigger = Trigger,
};
return calc; return calc;
} }

View File

@@ -15,11 +15,11 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
private readonly object _stateLock = new(); private readonly object _stateLock = new();
private SoftwareKeyboardUiState _state = new SoftwareKeyboardUiState(); private readonly SoftwareKeyboardUiState _state = new();
private SoftwareKeyboardRendererBase _renderer; private readonly SoftwareKeyboardRendererBase _renderer;
private TimedAction _textBoxBlinkTimedAction = new TimedAction(); private readonly TimedAction _textBoxBlinkTimedAction = new();
private TimedAction _renderAction = new TimedAction(); private readonly TimedAction _renderAction = new();
public SoftwareKeyboardRenderer(IHostUiTheme uiTheme) public SoftwareKeyboardRenderer(IHostUiTheme uiTheme)
{ {
@@ -47,7 +47,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
private static void StartRenderer(TimedAction timedAction, SoftwareKeyboardRendererBase renderer, SoftwareKeyboardUiState state, object stateLock) private static void StartRenderer(TimedAction timedAction, SoftwareKeyboardRendererBase renderer, SoftwareKeyboardUiState state, object stateLock)
{ {
SoftwareKeyboardUiState internalState = new SoftwareKeyboardUiState(); SoftwareKeyboardUiState internalState = new();
bool canCreateSurface = false; bool canCreateSurface = false;
bool needsUpdate = true; bool needsUpdate = true;
@@ -61,6 +61,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
return; return;
} }
#pragma warning disable IDE0055 // Disable formatting
needsUpdate = UpdateStateField(ref state.InputText, ref internalState.InputText); needsUpdate = UpdateStateField(ref state.InputText, ref internalState.InputText);
needsUpdate |= UpdateStateField(ref state.CursorBegin, ref internalState.CursorBegin); needsUpdate |= UpdateStateField(ref state.CursorBegin, ref internalState.CursorBegin);
needsUpdate |= UpdateStateField(ref state.CursorEnd, ref internalState.CursorEnd); needsUpdate |= UpdateStateField(ref state.CursorEnd, ref internalState.CursorEnd);
@@ -70,6 +71,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
needsUpdate |= UpdateStateField(ref state.TypingEnabled, ref internalState.TypingEnabled); needsUpdate |= UpdateStateField(ref state.TypingEnabled, ref internalState.TypingEnabled);
needsUpdate |= UpdateStateField(ref state.ControllerEnabled, ref internalState.ControllerEnabled); needsUpdate |= UpdateStateField(ref state.ControllerEnabled, ref internalState.ControllerEnabled);
needsUpdate |= UpdateStateField(ref state.TextBoxBlinkCounter, ref internalState.TextBoxBlinkCounter); needsUpdate |= UpdateStateField(ref state.TextBoxBlinkCounter, ref internalState.TextBoxBlinkCounter);
#pragma warning restore IDE0055
canCreateSurface = state.SurfaceInfo != null && internalState.SurfaceInfo == null; canCreateSurface = state.SurfaceInfo != null && internalState.SurfaceInfo == null;
@@ -104,14 +106,12 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
return false; return false;
} }
#pragma warning disable CS8632 public void UpdateTextState(string inputText, int? cursorBegin, int? cursorEnd, bool? overwriteMode, bool? typingEnabled)
public void UpdateTextState(string? inputText, int? cursorBegin, int? cursorEnd, bool? overwriteMode, bool? typingEnabled)
#pragma warning restore CS8632
{ {
lock (_stateLock) lock (_stateLock)
{ {
// Update the parameters that were provided. // Update the parameters that were provided.
_state.InputText = inputText != null ? inputText : _state.InputText; _state.InputText = inputText ?? _state.InputText;
_state.CursorBegin = cursorBegin.GetValueOrDefault(_state.CursorBegin); _state.CursorBegin = cursorBegin.GetValueOrDefault(_state.CursorBegin);
_state.CursorEnd = cursorEnd.GetValueOrDefault(_state.CursorEnd); _state.CursorEnd = cursorEnd.GetValueOrDefault(_state.CursorEnd);
_state.OverwriteMode = overwriteMode.GetValueOrDefault(_state.OverwriteMode); _state.OverwriteMode = overwriteMode.GetValueOrDefault(_state.OverwriteMode);

View File

@@ -32,29 +32,29 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
private Image<Argb32> _surface = null; private Image<Argb32> _surface = null;
private byte[] _bufferData = null; private byte[] _bufferData = null;
private Image _ryujinxLogo = null; private readonly Image _ryujinxLogo = null;
private Image _padAcceptIcon = null; private readonly Image _padAcceptIcon = null;
private Image _padCancelIcon = null; private readonly Image _padCancelIcon = null;
private Image _keyModeIcon = null; private readonly Image _keyModeIcon = null;
private float _textBoxOutlineWidth; private readonly float _textBoxOutlineWidth;
private float _padPressedPenWidth; private readonly float _padPressedPenWidth;
private Color _textNormalColor; private readonly Color _textNormalColor;
private Color _textSelectedColor; private readonly Color _textSelectedColor;
private Color _textOverCursorColor; private readonly Color _textOverCursorColor;
private IBrush _panelBrush; private readonly IBrush _panelBrush;
private IBrush _disabledBrush; private readonly IBrush _disabledBrush;
private IBrush _cursorBrush; private readonly IBrush _cursorBrush;
private IBrush _selectionBoxBrush; private readonly IBrush _selectionBoxBrush;
private Pen _textBoxOutlinePen; private readonly Pen _textBoxOutlinePen;
private Pen _cursorPen; private readonly Pen _cursorPen;
private Pen _selectionBoxPen; private readonly Pen _selectionBoxPen;
private Pen _padPressedPen; private readonly Pen _padPressedPen;
private int _inputTextFontSize; private readonly int _inputTextFontSize;
private Font _messageFont; private Font _messageFont;
private Font _inputTextFont; private Font _inputTextFont;
private Font _labelsTextFont; private Font _labelsTextFont;
@@ -111,13 +111,12 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
{ {
// Try a list of fonts in case any of them is not available in the system. // Try a list of fonts in case any of them is not available in the system.
string[] availableFonts = new string[] string[] availableFonts = {
{
uiThemeFontFamily, uiThemeFontFamily,
"Liberation Sans", "Liberation Sans",
"FreeSans", "FreeSans",
"DejaVu Sans", "DejaVu Sans",
"Lucida Grande" "Lucida Grande",
}; };
foreach (string fontFamily in availableFonts) foreach (string fontFamily in availableFonts)
@@ -138,7 +137,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
throw new Exception($"None of these fonts were found in the system: {String.Join(", ", availableFonts)}!"); throw new Exception($"None of these fonts were found in the system: {String.Join(", ", availableFonts)}!");
} }
private Color ToColor(ThemeColor color, byte? overrideAlpha = null, bool flipRgb = false) private static Color ToColor(ThemeColor color, byte? overrideAlpha = null, bool flipRgb = false)
{ {
var a = (byte)(color.A * 255); var a = (byte)(color.A * 255);
var r = (byte)(color.R * 255); var r = (byte)(color.R * 255);
@@ -155,14 +154,14 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
return Color.FromRgba(r, g, b, overrideAlpha.GetValueOrDefault(a)); return Color.FromRgba(r, g, b, overrideAlpha.GetValueOrDefault(a));
} }
private Image LoadResource(Assembly assembly, string resourcePath, int newWidth, int newHeight) private static Image LoadResource(Assembly assembly, string resourcePath, int newWidth, int newHeight)
{ {
Stream resourceStream = assembly.GetManifestResourceStream(resourcePath); Stream resourceStream = assembly.GetManifestResourceStream(resourcePath);
return LoadResource(resourceStream, newWidth, newHeight); return LoadResource(resourceStream, newWidth, newHeight);
} }
private Image LoadResource(Stream resourceStream, int newWidth, int newHeight) private static Image LoadResource(Stream resourceStream, int newWidth, int newHeight)
{ {
Debug.Assert(resourceStream != null); Debug.Assert(resourceStream != null);
@@ -176,7 +175,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
return image; return image;
} }
private void SetGraphicsOptions(IImageProcessingContext context) private static void SetGraphicsOptions(IImageProcessingContext context)
{ {
context.GetGraphicsOptions().Antialias = true; context.GetGraphicsOptions().Antialias = true;
context.GetShapeGraphicsOptions().GraphicsOptions.Antialias = true; context.GetShapeGraphicsOptions().GraphicsOptions.Antialias = true;
@@ -200,7 +199,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
float halfWidth = _panelRectangle.Width / 2; float halfWidth = _panelRectangle.Width / 2;
float buttonsY = _panelRectangle.Y + 185; float buttonsY = _panelRectangle.Y + 185;
PointF disableButtonPosition = new PointF(halfWidth + 180, buttonsY); PointF disableButtonPosition = new(halfWidth + 180, buttonsY);
DrawControllerToggle(context, disableButtonPosition); DrawControllerToggle(context, disableButtonPosition);
}); });
@@ -240,9 +239,9 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
float halfWidth = _panelRectangle.Width / 2; float halfWidth = _panelRectangle.Width / 2;
float buttonsY = _panelRectangle.Y + 185; float buttonsY = _panelRectangle.Y + 185;
PointF acceptButtonPosition = new PointF(halfWidth - 180, buttonsY); PointF acceptButtonPosition = new(halfWidth - 180, buttonsY);
PointF cancelButtonPosition = new PointF(halfWidth , buttonsY); PointF cancelButtonPosition = new(halfWidth, buttonsY);
PointF disableButtonPosition = new PointF(halfWidth + 180, buttonsY); PointF disableButtonPosition = new(halfWidth + 180, buttonsY);
DrawPadButton(context, acceptButtonPosition, _padAcceptIcon, AcceptText, state.AcceptPressed, state.ControllerEnabled); DrawPadButton(context, acceptButtonPosition, _padAcceptIcon, AcceptText, state.AcceptPressed, state.ControllerEnabled);
DrawPadButton(context, cancelButtonPosition, _padCancelIcon, CancelText, state.CancelPressed, state.ControllerEnabled); DrawPadButton(context, cancelButtonPosition, _padCancelIcon, CancelText, state.CancelPressed, state.ControllerEnabled);
@@ -294,7 +293,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
} }
private static RectangleF MeasureString(string text, Font font) private static RectangleF MeasureString(string text, Font font)
{ {
RendererOptions options = new RendererOptions(font); RendererOptions options = new(font);
if (text == "") if (text == "")
{ {
@@ -310,7 +309,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
private static RectangleF MeasureString(ReadOnlySpan<char> text, Font font) private static RectangleF MeasureString(ReadOnlySpan<char> text, Font font)
{ {
RendererOptions options = new RendererOptions(font); RendererOptions options = new(font);
if (text == "") if (text == "")
{ {
@@ -332,9 +331,9 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
float boxY = _panelRectangle.Y + 110; float boxY = _panelRectangle.Y + 110;
float boxX = (int)((_panelRectangle.Width - boxWidth) / 2); float boxX = (int)((_panelRectangle.Width - boxWidth) / 2);
RectangleF boxRectangle = new RectangleF(boxX, boxY, boxWidth, boxHeight); RectangleF boxRectangle = new(boxX, boxY, boxWidth, boxHeight);
RectangleF boundRectangle = new RectangleF(_panelRectangle.X, boxY - _textBoxOutlineWidth, RectangleF boundRectangle = new(_panelRectangle.X, boxY - _textBoxOutlineWidth,
_panelRectangle.Width, boxHeight + 2 * _textBoxOutlineWidth); _panelRectangle.Width, boxHeight + 2 * _textBoxOutlineWidth);
context.Fill(_panelBrush, boundRectangle); context.Fill(_panelBrush, boundRectangle);
@@ -431,8 +430,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
if (cursorWidth == 0) if (cursorWidth == 0)
{ {
PointF[] points = new PointF[] PointF[] points = {
{
new PointF(cursorPositionXLeft, cursorPositionYTop), new PointF(cursorPositionXLeft, cursorPositionYTop),
new PointF(cursorPositionXLeft, cursorPositionYBottom), new PointF(cursorPositionXLeft, cursorPositionYBottom),
}; };
@@ -446,7 +444,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
context.Draw(cursorPen, cursorRectangle); context.Draw(cursorPen, cursorRectangle);
context.Fill(cursorBrush, cursorRectangle); context.Fill(cursorBrush, cursorRectangle);
Image<Argb32> textOverCursor = new Image<Argb32>((int)cursorRectangle.Width, (int)cursorRectangle.Height); Image<Argb32> textOverCursor = new((int)cursorRectangle.Width, (int)cursorRectangle.Height);
textOverCursor.Mutate(context => textOverCursor.Mutate(context =>
{ {
var textRelativePosition = new PointF(inputTextPosition.X - cursorRectangle.X, inputTextPosition.Y - cursorRectangle.Y); var textRelativePosition = new PointF(inputTextPosition.X - cursorRectangle.X, inputTextPosition.Y - cursorRectangle.Y);

View File

@@ -23,6 +23,6 @@
/// <summary> /// <summary>
/// swkbd has completed. /// swkbd has completed.
/// </summary> /// </summary>
Complete Complete,
} }
} }

View File

@@ -96,7 +96,7 @@ namespace Ryujinx.HLE.HOS
break; break;
default: default:
throw new ArgumentOutOfRangeException(); throw new InvalidOperationException($"{nameof(mode)} contains an invalid value: {mode}");
} }
} }

View File

@@ -4,8 +4,8 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class ArraySubscriptingExpression : BaseNode public class ArraySubscriptingExpression : BaseNode
{ {
private BaseNode _leftNode; private readonly BaseNode _leftNode;
private BaseNode _subscript; private readonly BaseNode _subscript;
public ArraySubscriptingExpression(BaseNode leftNode, BaseNode subscript) : base(NodeType.ArraySubscriptingExpression) public ArraySubscriptingExpression(BaseNode leftNode, BaseNode subscript) : base(NodeType.ArraySubscriptingExpression)
{ {

View File

@@ -4,9 +4,9 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class ArrayType : BaseNode public class ArrayType : BaseNode
{ {
private BaseNode _base; private readonly BaseNode _base;
private BaseNode _dimensionExpression; private readonly BaseNode _dimensionExpression;
private string _dimensionString; private readonly string _dimensionString;
public ArrayType(BaseNode Base, BaseNode dimensionExpression = null) : base(NodeType.ArrayType) public ArrayType(BaseNode Base, BaseNode dimensionExpression = null) : base(NodeType.ArrayType)
{ {
@@ -46,9 +46,9 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
writer.Write(_dimensionString); writer.Write(_dimensionString);
} }
else if (_dimensionExpression != null) else
{ {
_dimensionExpression.Print(writer); _dimensionExpression?.Print(writer);
} }
writer.Write("]"); writer.Write("]");

View File

@@ -55,7 +55,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
ConversionOperatorType, ConversionOperatorType,
LocalName, LocalName,
CtorVtableSpecialName, CtorVtableSpecialName,
ArrayType ArrayType,
} }
public abstract class BaseNode public abstract class BaseNode
@@ -103,7 +103,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
public override string ToString() public override string ToString()
{ {
StringWriter writer = new StringWriter(); StringWriter writer = new();
Print(writer); Print(writer);

View File

@@ -4,9 +4,9 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler.Ast
{ {
public class BinaryExpression : BaseNode public class BinaryExpression : BaseNode
{ {
private BaseNode _leftPart; private readonly BaseNode _leftPart;
private string _name; private readonly string _name;
private BaseNode _rightPart; private readonly BaseNode _rightPart;
public BinaryExpression(BaseNode leftPart, string name, BaseNode rightPart) : base(NodeType.BinaryExpression) public BinaryExpression(BaseNode leftPart, string name, BaseNode rightPart) : base(NodeType.BinaryExpression)
{ {

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