mirror of
https://github.com/Ryubing/Ryujinx.git
synced 2025-03-15 09:54:47 +00:00
Compare commits
57 commits
Canary-1.2
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
7664f8cde9 | ||
|
ddc00cf2d8 | ||
|
05b4bd8c61 | ||
|
20111a651c | ||
|
659e580f4d | ||
|
e6339ac950 | ||
|
6b402847d2 | ||
|
3b06f4cb78 | ||
|
cdf60eecc0 | ||
|
1219f329c1 | ||
|
d5527f87cb | ||
|
fc75dbc8b8 | ||
|
04361b864a | ||
|
7271e7050d | ||
|
1ca4484148 | ||
|
056f56bc70 | ||
|
bda699f68e | ||
|
0db85d0aa9 | ||
|
44632e5d8b | ||
|
551d2c1134 | ||
|
25cc9b24b4 | ||
|
638c616ab7 | ||
|
109f0fc659 | ||
|
dfcb8a7fc0 | ||
|
d87d3235e9 | ||
|
f3a9cecf72 | ||
|
97a1bbdd74 | ||
|
e379fad5da | ||
|
c76f32a4ee | ||
|
7bdf013ba6 | ||
|
e07130ecc3 | ||
|
dd02c8e25d | ||
|
bed3835718 | ||
|
2b06826922 | ||
|
a23c6bf547 | ||
|
27cdf876a2 | ||
|
b0c0e8f7ad | ||
|
2317c06364 | ||
|
c12a59ecd6 | ||
|
57c22a1f32 | ||
|
f7976753fd | ||
|
b45a65fbdc | ||
|
c410474d83 | ||
|
ffdc419417 | ||
|
da3f4e1d3a | ||
|
69d79322bb | ||
|
c3af1dbf1a | ||
|
10ac381525 | ||
|
e104ee6be3 | ||
|
e65d1ec6c9 | ||
|
534f92506b | ||
|
10d20c1ae3 | ||
|
e294a79975 | ||
|
ec06a86899 | ||
|
2e4de17472 | ||
|
9227cbe5a7 | ||
|
332bcdfaf1 |
189 changed files with 3345 additions and 1956 deletions
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
@ -19,6 +19,7 @@ jobs:
|
||||||
configuration: [Debug, Release]
|
configuration: [Debug, Release]
|
||||||
platform:
|
platform:
|
||||||
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
||||||
|
- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
|
||||||
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
- { name: osx-x64, os: macos-13, zip_os_name: osx_x64 }
|
- { name: osx-x64, os: macos-13, zip_os_name: osx_x64 }
|
||||||
|
|
2
.github/workflows/canary.yml
vendored
2
.github/workflows/canary.yml
vendored
|
@ -62,6 +62,7 @@ jobs:
|
||||||
| Platform | Artifact |
|
| Platform | Artifact |
|
||||||
|--|--|
|
|--|--|
|
||||||
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||||
|
| Windows ARM 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
|
||||||
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||||
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||||
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||||
|
@ -79,6 +80,7 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
platform:
|
platform:
|
||||||
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
||||||
|
- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
|
||||||
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
steps:
|
steps:
|
||||||
|
|
15
.github/workflows/release.yml
vendored
15
.github/workflows/release.yml
vendored
|
@ -12,7 +12,8 @@ env:
|
||||||
RYUJINX_BASE_VERSION: "1.2"
|
RYUJINX_BASE_VERSION: "1.2"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
|
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx"
|
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
|
||||||
|
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Stable-Releases"
|
||||||
RELEASE: 1
|
RELEASE: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -33,7 +34,7 @@ jobs:
|
||||||
script: |
|
script: |
|
||||||
github.rest.git.createRef({
|
github.rest.git.createRef({
|
||||||
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}",
|
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}",
|
||||||
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}",
|
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}",
|
||||||
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
||||||
sha: context.sha
|
sha: context.sha
|
||||||
})
|
})
|
||||||
|
@ -52,7 +53,7 @@ jobs:
|
||||||
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||||
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||||
|
|
||||||
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
|
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
||||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||||
|
@ -65,6 +66,7 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
platform:
|
platform:
|
||||||
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
|
||||||
|
- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
|
||||||
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
|
||||||
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
|
||||||
steps:
|
steps:
|
||||||
|
@ -92,7 +94,7 @@ jobs:
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
@ -116,6 +118,7 @@ jobs:
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
if: matrix.platform.os == 'ubuntu-latest'
|
||||||
run: |
|
run: |
|
||||||
pushd publish
|
pushd publish
|
||||||
|
rm libarmeilleure-jitsupport.dylib
|
||||||
chmod +x Ryujinx.sh Ryujinx
|
chmod +x Ryujinx.sh Ryujinx
|
||||||
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||||
popd
|
popd
|
||||||
|
@ -173,7 +176,7 @@ jobs:
|
||||||
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||||
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||||
|
|
||||||
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
|
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
replacesArtifacts: true
|
replacesArtifacts: true
|
||||||
|
@ -222,7 +225,7 @@ jobs:
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.2" />
|
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.2" />
|
||||||
<PackageVersion Include="Open.NAT.Core" Version="2.1.0.5" />
|
<PackageVersion Include="Open.NAT.Core" Version="2.1.0.5" />
|
||||||
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
|
||||||
<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.SDL2-CS" Version="2.30.0-build32" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||||
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
||||||
|
@ -53,8 +53,8 @@
|
||||||
<PackageVersion Include="SkiaSharp" Version="2.88.9" />
|
<PackageVersion Include="SkiaSharp" Version="2.88.9" />
|
||||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
||||||
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
||||||
<PackageVersion Include="System.IO.Hashing" Version="9.0.0" />
|
<PackageVersion Include="System.IO.Hashing" Version="9.0.2" />
|
||||||
<PackageVersion Include="System.Management" Version="9.0.0" />
|
<PackageVersion Include="System.Management" Version="9.0.2" />
|
||||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<table align="center">
|
<table align="center">
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" width="25%">
|
<td align="center" width="25%">
|
||||||
<img src="https://raw.githubusercontent.com/GreemDev/ryuassets/refs/heads/main/RyujinxApp_1024.png" alt="Ryujinx" >
|
<img src="https://raw.githubusercontent.com/Ryubing/Assets/refs/heads/main/RyujinxApp_1024.png" alt="Ryujinx" >
|
||||||
</td>
|
</td>
|
||||||
<td align="center" width="75%">
|
<td align="center" width="75%">
|
||||||
|
|
||||||
# Ryujinx
|
# Ryujinx
|
||||||
|
|
||||||
[](https://github.com/Ryubing/Ryujinx/actions/workflows/release.yml)
|
[](https://github.com/Ryubing/Ryujinx/actions/workflows/release.yml)
|
||||||
[](https://github.com/Ryubing/Ryujinx/releases/latest)
|
[](https://github.com/Ryubing/Ryujinx/releases/latest)
|
||||||
<br>
|
<br>
|
||||||
[](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml)
|
[](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml)
|
||||||
[](https://github.com/Ryubing/Canary-Releases/releases/latest)
|
[](https://github.com/Ryubing/Canary-Releases/releases/latest)
|
||||||
|
@ -97,7 +97,7 @@ If you are planning to contribute or just want to learn more about this project
|
||||||
|
|
||||||
- **Input**
|
- **Input**
|
||||||
|
|
||||||
We currently have support for keyboard, mouse, touch input, JoyCon input support, and nearly all controllers.
|
We currently have support for keyboard, mouse, touch input, Joy-Con input support, and nearly all controllers.
|
||||||
Motion controls are natively supported in most cases; for dual-JoyCon motion support, DS4Windows or BetterJoy are currently required.
|
Motion controls are natively supported in most cases; for dual-JoyCon motion support, DS4Windows or BetterJoy are currently required.
|
||||||
In all scenarios, you can set up everything inside the input configuration menu.
|
In all scenarios, you can set up everything inside the input configuration menu.
|
||||||
|
|
||||||
|
|
|
@ -631,6 +631,7 @@
|
||||||
010030D012FF6000,"Bus Driver Simulator",,playable,2022-10-17 13:55:27
|
010030D012FF6000,"Bus Driver Simulator",,playable,2022-10-17 13:55:27
|
||||||
0100A9101418C000,"BUSTAFELLOWS",nvdec,playable,2020-10-17 20:04:41
|
0100A9101418C000,"BUSTAFELLOWS",nvdec,playable,2020-10-17 20:04:41
|
||||||
0100177005C8A000,"BUTCHER",,playable,2021-01-11 18:50:17
|
0100177005C8A000,"BUTCHER",,playable,2021-01-11 18:50:17
|
||||||
|
01008c2019598000,"Bluey: The Videogame",,playable,2025-02-11 04:38:00
|
||||||
01000B900D8B0000,"Cadence of Hyrule: Crypt of the NecroDancer Featuring The Legend of Zelda",slow;nvdec,playable,2024-04-01 22:43:40
|
01000B900D8B0000,"Cadence of Hyrule: Crypt of the NecroDancer Featuring The Legend of Zelda",slow;nvdec,playable,2024-04-01 22:43:40
|
||||||
010065700EE06000,"Cadence of Hyrule: Crypt of the NecroDancer Featuring The Legend of Zelda Demo",demo;gpu;nvdec,ingame,2021-02-14 21:48:15
|
010065700EE06000,"Cadence of Hyrule: Crypt of the NecroDancer Featuring The Legend of Zelda Demo",demo;gpu;nvdec,ingame,2021-02-14 21:48:15
|
||||||
01005C00117A8000,"Café Enchanté",,playable,2020-11-13 14:54:25
|
01005C00117A8000,"Café Enchanté",,playable,2020-11-13 14:54:25
|
||||||
|
@ -1382,6 +1383,9 @@
|
||||||
0100763015C2E000,"Gunvolt Chronicles: Luminous Avenger iX 2",crash;Needs Update,nothing,2022-04-29 15:34:34
|
0100763015C2E000,"Gunvolt Chronicles: Luminous Avenger iX 2",crash;Needs Update,nothing,2022-04-29 15:34:34
|
||||||
01002C8018554000,"Gurimugurimoa OnceMore Demo",,playable,2022-07-29 22:07:31
|
01002C8018554000,"Gurimugurimoa OnceMore Demo",,playable,2022-07-29 22:07:31
|
||||||
0100AC601DCA8000,"GYLT",crash,ingame,2024-03-18 20:16:51
|
0100AC601DCA8000,"GYLT",crash,ingame,2024-03-18 20:16:51
|
||||||
|
0100c3c012718000,"Grand Theft Auto: III – The Definitive Edition",gpu;UE4,ingame,2022-10-31 20:13:52
|
||||||
|
0100182014022000,"Grand Theft Auto: Vice City – The Definitive Edition",gpu;UE4,ingame,2022-10-31 20:13:52
|
||||||
|
010065a014024000,"Grand Theft Auto: San Andreas – The Definitive Edition",gpu;UE4,ingame,2022-10-31 20:13:52
|
||||||
0100822012D76000,"HAAK",gpu,ingame,2023-02-19 14:31:05
|
0100822012D76000,"HAAK",gpu,ingame,2023-02-19 14:31:05
|
||||||
01007E100EFA8000,"Habroxia",,playable,2020-06-16 23:04:42
|
01007E100EFA8000,"Habroxia",,playable,2020-06-16 23:04:42
|
||||||
0100535012974000,"Hades",vulkan,playable,2022-10-05 10:45:21
|
0100535012974000,"Hades",vulkan,playable,2022-10-05 10:45:21
|
||||||
|
@ -2729,7 +2733,7 @@
|
||||||
0100C2500FC20000,"Splatoon™ 3",ldn-works;opengl-backend-bug;LAN;amd-vendor-bug,playable,2024-08-04 23:49:11
|
0100C2500FC20000,"Splatoon™ 3",ldn-works;opengl-backend-bug;LAN;amd-vendor-bug,playable,2024-08-04 23:49:11
|
||||||
0100BA0018500000,"Splatoon™ 3: Splatfest World Premiere",gpu;online-broken;demo,ingame,2022-09-19 03:17:12
|
0100BA0018500000,"Splatoon™ 3: Splatfest World Premiere",gpu;online-broken;demo,ingame,2022-09-19 03:17:12
|
||||||
010062800D39C000,"SpongeBob SquarePants: Battle for Bikini Bottom - Rehydrated",online-broken;UE4;ldn-broken;vulkan-backend-bug,playable,2023-08-01 19:29:34
|
010062800D39C000,"SpongeBob SquarePants: Battle for Bikini Bottom - Rehydrated",online-broken;UE4;ldn-broken;vulkan-backend-bug,playable,2023-08-01 19:29:34
|
||||||
01009FB0172F4000,"SpongeBob SquarePants: The Cosmic Shake",gpu;UE4,ingame,2023-08-01 19:29:53
|
01009FB0172F4000,"SpongeBob SquarePants: The Cosmic Shake",gpu;UE4,ingame,2024-03-04 16:35:00
|
||||||
010097C01336A000,"Spooky Chase",,playable,2022-11-04 12:17:44
|
010097C01336A000,"Spooky Chase",,playable,2022-11-04 12:17:44
|
||||||
0100C6100D75E000,"Spooky Ghosts Dot Com",,playable,2021-06-15 15:16:11
|
0100C6100D75E000,"Spooky Ghosts Dot Com",,playable,2021-06-15 15:16:11
|
||||||
0100DE9005170000,"Sports Party",nvdec,playable,2021-03-05 13:40:42
|
0100DE9005170000,"Sports Party",nvdec,playable,2021-03-05 13:40:42
|
||||||
|
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64;win-arm64;osx-arm64;linux-arm64</RuntimeIdentifiers>
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -11,15 +11,15 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.dll" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
|
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.dll" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<TargetPath>libsoundio.dll</TargetPath>
|
<TargetPath>libsoundio.dll</TargetPath>
|
||||||
</ContentWithTargetPath>
|
</ContentWithTargetPath>
|
||||||
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.dylib" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'">
|
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.dylib" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'win-arm64'">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<TargetPath>libsoundio.dylib</TargetPath>
|
<TargetPath>libsoundio.dylib</TargetPath>
|
||||||
</ContentWithTargetPath>
|
</ContentWithTargetPath>
|
||||||
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.so" Condition="'$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64'">
|
<ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.so" Condition="'$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'win-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64' AND '$(RuntimeIdentifier)' != 'linux-arm64'">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<TargetPath>libsoundio.so</TargetPath>
|
<TargetPath>libsoundio.so</TargetPath>
|
||||||
</ContentWithTargetPath>
|
</ContentWithTargetPath>
|
||||||
|
|
|
@ -9,7 +9,8 @@ namespace Ryujinx.Common.Configuration
|
||||||
public enum DirtyHack : byte
|
public enum DirtyHack : byte
|
||||||
{
|
{
|
||||||
Xc2MenuSoftlockFix = 1,
|
Xc2MenuSoftlockFix = 1,
|
||||||
ShaderTranslationDelay = 2
|
// ShaderTranslationDelay = 2
|
||||||
|
NifmServiceDisableIsAnyInternetRequestAccepted = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly struct EnabledDirtyHack(DirtyHack hack, int value)
|
public readonly struct EnabledDirtyHack(DirtyHack hack, int value)
|
||||||
|
|
|
@ -5,15 +5,34 @@ using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
|
public enum OperatingSystemType
|
||||||
|
{
|
||||||
|
MacOS,
|
||||||
|
Linux,
|
||||||
|
Windows
|
||||||
|
}
|
||||||
|
|
||||||
public static class RunningPlatform
|
public static class RunningPlatform
|
||||||
{
|
{
|
||||||
|
public static readonly OperatingSystemType CurrentOS
|
||||||
|
= IsMacOS
|
||||||
|
? OperatingSystemType.MacOS
|
||||||
|
: IsWindows
|
||||||
|
? OperatingSystemType.Windows
|
||||||
|
: IsLinux
|
||||||
|
? OperatingSystemType.Linux
|
||||||
|
: throw new PlatformNotSupportedException();
|
||||||
|
|
||||||
|
public static Architecture Architecture => RuntimeInformation.OSArchitecture;
|
||||||
|
public static Architecture CurrentProcessArchitecture => RuntimeInformation.ProcessArchitecture;
|
||||||
|
|
||||||
public static bool IsMacOS => OperatingSystem.IsMacOS();
|
public static bool IsMacOS => OperatingSystem.IsMacOS();
|
||||||
public static bool IsWindows => OperatingSystem.IsWindows();
|
public static bool IsWindows => OperatingSystem.IsWindows();
|
||||||
public static bool IsLinux => OperatingSystem.IsLinux();
|
public static bool IsLinux => OperatingSystem.IsLinux();
|
||||||
|
|
||||||
public static bool IsArm => RuntimeInformation.OSArchitecture is Architecture.Arm64;
|
public static bool IsArm => Architecture is Architecture.Arm64;
|
||||||
|
|
||||||
public static bool IsX64 => RuntimeInformation.OSArchitecture is Architecture.X64;
|
public static bool IsX64 => Architecture is Architecture.X64;
|
||||||
|
|
||||||
public static bool IsIntelMac => IsMacOS && IsX64;
|
public static bool IsIntelMac => IsMacOS && IsX64;
|
||||||
public static bool IsArmMac => IsMacOS && IsArm;
|
public static bool IsArmMac => IsMacOS && IsArm;
|
||||||
|
|
|
@ -37,9 +37,9 @@ namespace Ryujinx.Common
|
||||||
public static string GetChangelogUrl(Version currentVersion, Version newVersion) =>
|
public static string GetChangelogUrl(Version currentVersion, Version newVersion) =>
|
||||||
IsCanaryBuild
|
IsCanaryBuild
|
||||||
? $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelSourceRepo}/compare/Canary-{currentVersion}...Canary-{newVersion}"
|
? $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelSourceRepo}/compare/Canary-{currentVersion}...Canary-{newVersion}"
|
||||||
: $"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelSourceRepo}/releases/tag/{newVersion}";
|
: GetChangelogForVersion(newVersion);
|
||||||
|
|
||||||
public static string GetChangelogForVersion(Version version) =>
|
public static string GetChangelogForVersion(Version version) =>
|
||||||
$"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelRepo}/releases/tag/{version}";
|
$"https://github.com/{ReleaseChannelOwner}/{ReleaseChannelRepo}/releases/{version}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using Ryujinx.Common.Helper;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Common
|
namespace Ryujinx.Common
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Graphics.GAL.Multithreading;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
|
@ -10,6 +12,20 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
bool PreferThreading { get; }
|
bool PreferThreading { get; }
|
||||||
|
|
||||||
|
public IRenderer TryMakeThreaded(BackendThreading backendThreading = BackendThreading.Auto)
|
||||||
|
{
|
||||||
|
if (backendThreading is BackendThreading.On ||
|
||||||
|
(backendThreading is BackendThreading.Auto && PreferThreading))
|
||||||
|
{
|
||||||
|
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({backendThreading}): True");
|
||||||
|
return new ThreadedRenderer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({backendThreading}): False");
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
IPipeline Pipeline { get; }
|
IPipeline Pipeline { get; }
|
||||||
|
|
||||||
IWindow Window { get; }
|
IWindow Window { get; }
|
||||||
|
|
|
@ -12,8 +12,8 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native
|
||||||
|
|
||||||
private static readonly Dictionary<string, (int, int)> _librariesWhitelist = new()
|
private static readonly Dictionary<string, (int, int)> _librariesWhitelist = new()
|
||||||
{
|
{
|
||||||
{ AvCodecLibraryName, (58, 59) },
|
{ AvCodecLibraryName, (58, 61) },
|
||||||
{ AvUtilLibraryName, (56, 57) },
|
{ AvUtilLibraryName, (56, 59) },
|
||||||
};
|
};
|
||||||
|
|
||||||
private static string FormatLibraryNameForCurrentOs(string libraryName, int version)
|
private static string FormatLibraryNameForCurrentOs(string libraryName, int version)
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm
|
||||||
|
|
||||||
private readonly LanDiscovery _lanDiscovery;
|
private readonly LanDiscovery _lanDiscovery;
|
||||||
|
|
||||||
public LdnMitmClient(HLEConfiguration config)
|
public LdnMitmClient(HleConfiguration config)
|
||||||
{
|
{
|
||||||
UnicastIPAddressInformation localIpInterface = NetworkHelpers.GetLocalInterface(config.MultiplayerLanInterfaceId).Item2;
|
UnicastIPAddressInformation localIpInterface = NetworkHelpers.GetLocalInterface(config.MultiplayerLanInterfaceId).Item2;
|
||||||
|
|
||||||
|
|
|
@ -51,13 +51,13 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu
|
||||||
private string _passphrase;
|
private string _passphrase;
|
||||||
private byte[] _gameVersion = new byte[0x10];
|
private byte[] _gameVersion = new byte[0x10];
|
||||||
|
|
||||||
private readonly HLEConfiguration _config;
|
private readonly HleConfiguration _config;
|
||||||
|
|
||||||
public event EventHandler<NetworkChangeEventArgs> NetworkChange;
|
public event EventHandler<NetworkChangeEventArgs> NetworkChange;
|
||||||
|
|
||||||
public ProxyConfig Config { get; private set; }
|
public ProxyConfig Config { get; private set; }
|
||||||
|
|
||||||
public LdnMasterProxyClient(string address, int port, HLEConfiguration config) : base(address, port)
|
public LdnMasterProxyClient(string address, int port, HleConfiguration config) : base(address, port)
|
||||||
{
|
{
|
||||||
if (ProxyHelpers.SupportsNoDelay())
|
if (ProxyHelpers.SupportsNoDelay())
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
|
||||||
// CreateGeneralServiceOld() -> object<nn::nifm::detail::IGeneralService>
|
// CreateGeneralServiceOld() -> object<nn::nifm::detail::IGeneralService>
|
||||||
public ResultCode CreateGeneralServiceOld(ServiceCtx context)
|
public ResultCode CreateGeneralServiceOld(ServiceCtx context)
|
||||||
{
|
{
|
||||||
MakeObject(context, new IGeneralService());
|
MakeObject(context, new IGeneralService(context));
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
|
||||||
// CreateGeneralService(u64, pid) -> object<nn::nifm::detail::IGeneralService>
|
// CreateGeneralService(u64, pid) -> object<nn::nifm::detail::IGeneralService>
|
||||||
public ResultCode CreateGeneralService(ServiceCtx context)
|
public ResultCode CreateGeneralService(ServiceCtx context)
|
||||||
{
|
{
|
||||||
MakeObject(context, new IGeneralService());
|
MakeObject(context, new IGeneralService(context));
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService;
|
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService;
|
||||||
|
@ -17,12 +18,12 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||||
private UnicastIPAddressInformation _targetAddressInfoCache = null;
|
private UnicastIPAddressInformation _targetAddressInfoCache = null;
|
||||||
private string _cacheChosenInterface = null;
|
private string _cacheChosenInterface = null;
|
||||||
|
|
||||||
public IGeneralService()
|
public IGeneralService(ServiceCtx context)
|
||||||
{
|
{
|
||||||
_generalServiceDetail = new GeneralServiceDetail
|
_generalServiceDetail = new GeneralServiceDetail
|
||||||
{
|
{
|
||||||
ClientId = GeneralServiceManager.Count,
|
ClientId = GeneralServiceManager.Count,
|
||||||
IsAnyInternetRequestAccepted = true, // NOTE: Why not accept any internet request?
|
IsAnyInternetRequestAccepted = !context.Device.DirtyHacks.IsEnabled(DirtyHack.NifmServiceDisableIsAnyInternetRequestAccepted), // NOTE: Why not accept any internet request?
|
||||||
};
|
};
|
||||||
|
|
||||||
NetworkChange.NetworkAddressChanged += LocalInterfaceCacheHandler;
|
NetworkChange.NetworkAddressChanged += LocalInterfaceCacheHandler;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu.Proxy;
|
using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu.Proxy;
|
||||||
using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
|
@ -15,55 +15,55 @@ namespace Ryujinx.HLE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// HLE configuration.
|
/// HLE configuration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class HLEConfiguration
|
public class HleConfiguration
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The virtual file system used by the FS service.
|
/// The virtual file system used by the FS service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
internal readonly VirtualFileSystem VirtualFileSystem;
|
internal VirtualFileSystem VirtualFileSystem { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The manager for handling a LibHac Horizon instance.
|
/// The manager for handling a LibHac Horizon instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
internal readonly LibHacHorizonManager LibHacHorizonManager;
|
internal LibHacHorizonManager LibHacHorizonManager { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The account manager used by the account service.
|
/// The account manager used by the account service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
internal readonly AccountManager AccountManager;
|
internal AccountManager AccountManager { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The content manager used by the NCM service.
|
/// The content manager used by the NCM service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
internal readonly ContentManager ContentManager;
|
internal ContentManager ContentManager { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The persistent information between run for multi-application capabilities.
|
/// The persistent information between run for multi-application capabilities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
public readonly UserChannelPersistence UserChannelPersistence;
|
public UserChannelPersistence UserChannelPersistence { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The GPU renderer to use for all GPU operations.
|
/// The GPU renderer to use for all GPU operations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
internal readonly IRenderer GpuRenderer;
|
internal IRenderer GpuRenderer { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The audio device driver to use for all audio operations.
|
/// The audio device driver to use for all audio operations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
internal readonly IHardwareDeviceDriver AudioDeviceDriver;
|
internal IHardwareDeviceDriver AudioDeviceDriver { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The handler for various UI related operations needed outside of HLE.
|
/// The handler for various UI related operations needed outside of HLE.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
internal readonly IHostUIHandler HostUIHandler;
|
internal IHostUIHandler HostUIHandler { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Control the memory configuration used by the emulation context.
|
/// Control the memory configuration used by the emulation context.
|
||||||
|
@ -195,15 +195,7 @@ namespace Ryujinx.HLE
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
public EnabledDirtyHack[] Hacks { internal get; set; }
|
public EnabledDirtyHack[] Hacks { internal get; set; }
|
||||||
|
|
||||||
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
|
public HleConfiguration(MemoryConfiguration memoryConfiguration,
|
||||||
LibHacHorizonManager libHacHorizonManager,
|
|
||||||
ContentManager contentManager,
|
|
||||||
AccountManager accountManager,
|
|
||||||
UserChannelPersistence userChannelPersistence,
|
|
||||||
IRenderer gpuRenderer,
|
|
||||||
IHardwareDeviceDriver audioDeviceDriver,
|
|
||||||
MemoryConfiguration memoryConfiguration,
|
|
||||||
IHostUIHandler hostUIHandler,
|
|
||||||
SystemLanguage systemLanguage,
|
SystemLanguage systemLanguage,
|
||||||
RegionCode region,
|
RegionCode region,
|
||||||
VSyncMode vSyncMode,
|
VSyncMode vSyncMode,
|
||||||
|
@ -227,15 +219,7 @@ namespace Ryujinx.HLE
|
||||||
int customVSyncInterval,
|
int customVSyncInterval,
|
||||||
EnabledDirtyHack[] dirtyHacks = null)
|
EnabledDirtyHack[] dirtyHacks = null)
|
||||||
{
|
{
|
||||||
VirtualFileSystem = virtualFileSystem;
|
|
||||||
LibHacHorizonManager = libHacHorizonManager;
|
|
||||||
AccountManager = accountManager;
|
|
||||||
ContentManager = contentManager;
|
|
||||||
UserChannelPersistence = userChannelPersistence;
|
|
||||||
GpuRenderer = gpuRenderer;
|
|
||||||
AudioDeviceDriver = audioDeviceDriver;
|
|
||||||
MemoryConfiguration = memoryConfiguration;
|
MemoryConfiguration = memoryConfiguration;
|
||||||
HostUIHandler = hostUIHandler;
|
|
||||||
SystemLanguage = systemLanguage;
|
SystemLanguage = systemLanguage;
|
||||||
Region = region;
|
Region = region;
|
||||||
VSyncMode = vSyncMode;
|
VSyncMode = vSyncMode;
|
||||||
|
@ -259,5 +243,30 @@ namespace Ryujinx.HLE
|
||||||
MultiplayerLdnServer = multiplayerLdnServer;
|
MultiplayerLdnServer = multiplayerLdnServer;
|
||||||
Hacks = dirtyHacks ?? [];
|
Hacks = dirtyHacks ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the pre-configured services to use for this <see cref="HleConfiguration"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
public HleConfiguration Configure(
|
||||||
|
VirtualFileSystem virtualFileSystem,
|
||||||
|
LibHacHorizonManager libHacHorizonManager,
|
||||||
|
ContentManager contentManager,
|
||||||
|
AccountManager accountManager,
|
||||||
|
UserChannelPersistence userChannelPersistence,
|
||||||
|
IRenderer gpuRenderer,
|
||||||
|
IHardwareDeviceDriver audioDeviceDriver,
|
||||||
|
IHostUIHandler hostUIHandler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
VirtualFileSystem = virtualFileSystem;
|
||||||
|
LibHacHorizonManager = libHacHorizonManager;
|
||||||
|
AccountManager = accountManager;
|
||||||
|
ContentManager = contentManager;
|
||||||
|
UserChannelPersistence = userChannelPersistence;
|
||||||
|
GpuRenderer = gpuRenderer;
|
||||||
|
AudioDeviceDriver = audioDeviceDriver;
|
||||||
|
HostUIHandler = hostUIHandler;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -71,16 +71,24 @@ namespace Ryujinx.HLE.Loaders.Mods
|
||||||
int patchOffset = (int)offset;
|
int patchOffset = (int)offset;
|
||||||
int patchSize = patch.Length;
|
int patchSize = patch.Length;
|
||||||
|
|
||||||
if (patchOffset < protectedOffset || patchOffset > memory.Length)
|
if (patchOffset < protectedOffset)
|
||||||
{
|
{
|
||||||
continue; // Add warning?
|
Logger.Warning?.Print(LogClass.ModLoader, $"Attempted to patch protected memory ({patchOffset:x} is within protected boundary of {protectedOffset:x}).");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (patchOffset > memory.Length)
|
||||||
|
{
|
||||||
|
Logger.Warning?.Print(LogClass.ModLoader, $"Attempted to patch out of bounds memory (offset {patchOffset} ({patchOffset:x}) exceeds memory buffer length {memory.Length}).");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
patchOffset -= protectedOffset;
|
patchOffset -= protectedOffset;
|
||||||
|
|
||||||
if (patchOffset + patchSize > memory.Length)
|
if (patchOffset + patchSize > memory.Length)
|
||||||
{
|
{
|
||||||
patchSize = memory.Length - patchOffset; // Add warning?
|
Logger.Warning?.Print(LogClass.ModLoader, $"Patch offset ({patchOffset:x}) + size ({patchSize}) is greater than the size of the memory buffer ({memory.Length}). Attempting to fix this...");
|
||||||
|
patchSize = memory.Length - patchOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}");
|
Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}");
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace Ryujinx.HLE
|
||||||
{
|
{
|
||||||
public static Switch Shared { get; private set; }
|
public static Switch Shared { get; private set; }
|
||||||
|
|
||||||
public HLEConfiguration Configuration { get; }
|
public HleConfiguration Configuration { get; }
|
||||||
public IHardwareDeviceDriver AudioDeviceDriver { get; }
|
public IHardwareDeviceDriver AudioDeviceDriver { get; }
|
||||||
public MemoryBlock Memory { get; }
|
public MemoryBlock Memory { get; }
|
||||||
public GpuContext Gpu { get; }
|
public GpuContext Gpu { get; }
|
||||||
|
@ -44,7 +44,7 @@ namespace Ryujinx.HLE
|
||||||
|
|
||||||
public DirtyHacks DirtyHacks { get; }
|
public DirtyHacks DirtyHacks { get; }
|
||||||
|
|
||||||
public Switch(HLEConfiguration configuration)
|
public Switch(HleConfiguration configuration)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(configuration.GpuRenderer);
|
ArgumentNullException.ThrowIfNull(configuration.GpuRenderer);
|
||||||
ArgumentNullException.ThrowIfNull(configuration.AudioDeviceDriver);
|
ArgumentNullException.ThrowIfNull(configuration.AudioDeviceDriver);
|
||||||
|
@ -94,16 +94,20 @@ namespace Ryujinx.HLE
|
||||||
Gpu.GPFifo.DispatchCalls();
|
Gpu.GPFifo.DispatchCalls();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void IncrementCustomVSyncInterval()
|
public int IncrementCustomVSyncInterval()
|
||||||
{
|
{
|
||||||
CustomVSyncInterval += 1;
|
CustomVSyncInterval += 1;
|
||||||
UpdateVSyncInterval();
|
UpdateVSyncInterval();
|
||||||
|
|
||||||
|
return CustomVSyncInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DecrementCustomVSyncInterval()
|
public int DecrementCustomVSyncInterval()
|
||||||
{
|
{
|
||||||
CustomVSyncInterval -= 1;
|
CustomVSyncInterval -= 1;
|
||||||
UpdateVSyncInterval();
|
UpdateVSyncInterval();
|
||||||
|
|
||||||
|
return CustomVSyncInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateVSyncInterval()
|
public void UpdateVSyncInterval()
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<Styles
|
<Styles
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
|
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||||
xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia">
|
xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia">
|
||||||
<Design.PreviewWith>
|
<Design.PreviewWith>
|
||||||
<Border Height="2000"
|
<Border Height="2000"
|
||||||
|
@ -30,7 +31,8 @@
|
||||||
<Button
|
<Button
|
||||||
Name="btnRem"
|
Name="btnRem"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Content="Add" />
|
Content="Add"
|
||||||
|
Classes="red"/>
|
||||||
<TextBox
|
<TextBox
|
||||||
Width="100"
|
Width="100"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
@ -41,7 +43,13 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<ui:NumberBox Value="1" />
|
<ui:NumberBox Value="1" />
|
||||||
|
<MenuItem
|
||||||
|
Header="123 0000"
|
||||||
|
ToolTip.Tip="What this"/>
|
||||||
|
<TextBlock
|
||||||
|
Classes="globalConfigMarker"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
</Border>
|
</Border>
|
||||||
</Design.PreviewWith>
|
</Design.PreviewWith>
|
||||||
<Style Selector="DropDownButton">
|
<Style Selector="DropDownButton">
|
||||||
|
@ -331,6 +339,14 @@
|
||||||
<Setter Property="Margin"
|
<Setter Property="Margin"
|
||||||
Value="0,5,0,0" />
|
Value="0,5,0,0" />
|
||||||
</Style>
|
</Style>
|
||||||
|
<Style Selector="TextBlock.globalConfigMarker" >
|
||||||
|
<Setter Property="Foreground" Value="SeaGreen"/>
|
||||||
|
<Setter Property="Margin" Value="5,0,0,0"/>
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||||
|
<Setter Property="Text" Value="{ext:Locale GameSpecificConfigurationGlobal}"/>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="StackPanel.globalConfigMarker">
|
||||||
|
</Style>
|
||||||
<Style Selector="ContextMenu">
|
<Style Selector="ContextMenu">
|
||||||
<Setter Property="BorderBrush"
|
<Setter Property="BorderBrush"
|
||||||
Value="{DynamicResource MenuFlyoutPresenterBorderBrush}" />
|
Value="{DynamicResource MenuFlyoutPresenterBorderBrush}" />
|
||||||
|
@ -373,6 +389,19 @@
|
||||||
<Setter Property="Background"
|
<Setter Property="Background"
|
||||||
Value="{DynamicResource AppListHoverBackgroundColor}" />
|
Value="{DynamicResource AppListHoverBackgroundColor}" />
|
||||||
</Style>
|
</Style>
|
||||||
|
<Style Selector="Button.red /template/ ContentPresenter">
|
||||||
|
<Setter Property="CornerRadius" Value="4"/>
|
||||||
|
<Setter Property="Background" Value="red"/>
|
||||||
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Button.red:pointerover /template/ ContentPresenter">
|
||||||
|
<Setter Property="CornerRadius" Value="4"/>
|
||||||
|
<Setter Property="Background" Value="{DynamicResource WarningBackgroundColor}" />
|
||||||
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Styles.Resources>
|
<Styles.Resources>
|
||||||
<SolidColorBrush x:Key="ThemeAccentColorBrush"
|
<SolidColorBrush x:Key="ThemeAccentColorBrush"
|
||||||
Color="{DynamicResource SystemAccentColor}" />
|
Color="{DynamicResource SystemAccentColor}" />
|
||||||
|
@ -411,7 +440,7 @@
|
||||||
<x:Double x:Key="ControlContentThemeFontSize">13</x:Double>
|
<x:Double x:Key="ControlContentThemeFontSize">13</x:Double>
|
||||||
<x:Double x:Key="MenuItemHeight">26</x:Double>
|
<x:Double x:Key="MenuItemHeight">26</x:Double>
|
||||||
<x:Double x:Key="TabItemMinHeight">28</x:Double>
|
<x:Double x:Key="TabItemMinHeight">28</x:Double>
|
||||||
<x:Double x:Key="ContentDialogMaxWidth">900</x:Double>
|
<x:Double x:Key="ContentDialogMaxWidth">700</x:Double>
|
||||||
<x:Double x:Key="ContentDialogMaxHeight">756</x:Double>
|
<x:Double x:Key="ContentDialogMaxHeight">756</x:Double>
|
||||||
</Styles.Resources>
|
</Styles.Resources>
|
||||||
</Styles>
|
</Styles>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
<ResourceDictionary.ThemeDictionaries>
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
<ResourceDictionary x:Key="Default">
|
<ResourceDictionary x:Key="Default">
|
||||||
|
@ -12,11 +12,13 @@
|
||||||
<Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
|
<Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
|
||||||
<Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
|
<Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
|
||||||
<Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
|
<Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
|
||||||
|
<Color x:Key="WarningBackgroundColor">#FF6347</Color>
|
||||||
<Color x:Key="SecondaryTextColor">#A0000000</Color>
|
<Color x:Key="SecondaryTextColor">#A0000000</Color>
|
||||||
<Color x:Key="FavoriteApplicationIconColor">#fffcd12a</Color>
|
<Color x:Key="FavoriteApplicationIconColor">#fffcd12a</Color>
|
||||||
<Color x:Key="Switch">#FF2EEAC9</Color>
|
<Color x:Key="Switch">#FF2EEAC9</Color>
|
||||||
<Color x:Key="Unbounded">#FFFF4554</Color>
|
<Color x:Key="Unbounded">#FFFF4554</Color>
|
||||||
<Color x:Key="Custom">#6483F5</Color>
|
<Color x:Key="Custom">#6483F5</Color>
|
||||||
|
<Color x:Key="Warning">#800080</Color>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
<ResourceDictionary x:Key="Light">
|
<ResourceDictionary x:Key="Light">
|
||||||
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
|
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
|
||||||
|
@ -29,11 +31,13 @@
|
||||||
<Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
|
<Color x:Key="MenuFlyoutPresenterBorderColor">#C1C1C1</Color>
|
||||||
<Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
|
<Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
|
||||||
<Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
|
<Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
|
||||||
|
<Color x:Key="WarningBackgroundColor">#FF6347</Color>
|
||||||
<Color x:Key="SecondaryTextColor">#A0000000</Color>
|
<Color x:Key="SecondaryTextColor">#A0000000</Color>
|
||||||
<Color x:Key="FavoriteApplicationIconColor">#fffcd12a</Color>
|
<Color x:Key="FavoriteApplicationIconColor">#fffcd12a</Color>
|
||||||
<Color x:Key="Switch">#13c3a4</Color>
|
<Color x:Key="Switch">#13c3a4</Color>
|
||||||
<Color x:Key="Unbounded">#FFFF4554</Color>
|
<Color x:Key="Unbounded">#FFFF4554</Color>
|
||||||
<Color x:Key="Custom">#6483F5</Color>
|
<Color x:Key="Custom">#6483F5</Color>
|
||||||
|
<Color x:Key="Warning">#800080</Color>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
<ResourceDictionary x:Key="Dark">
|
<ResourceDictionary x:Key="Dark">
|
||||||
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
|
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
|
||||||
|
@ -46,11 +50,13 @@
|
||||||
<Color x:Key="MenuFlyoutPresenterBorderColor">#3D3D3D</Color>
|
<Color x:Key="MenuFlyoutPresenterBorderColor">#3D3D3D</Color>
|
||||||
<Color x:Key="AppListBackgroundColor">#0FFFFFFF</Color>
|
<Color x:Key="AppListBackgroundColor">#0FFFFFFF</Color>
|
||||||
<Color x:Key="AppListHoverBackgroundColor">#1EFFFFFF</Color>
|
<Color x:Key="AppListHoverBackgroundColor">#1EFFFFFF</Color>
|
||||||
|
<Color x:Key="WarningBackgroundColor">#FF6347</Color>
|
||||||
<Color x:Key="SecondaryTextColor">#A0FFFFFF</Color>
|
<Color x:Key="SecondaryTextColor">#A0FFFFFF</Color>
|
||||||
<Color x:Key="FavoriteApplicationIconColor">#fffcd12a</Color>
|
<Color x:Key="FavoriteApplicationIconColor">#fffcd12a</Color>
|
||||||
<Color x:Key="Switch">#FF2EEAC9</Color>
|
<Color x:Key="Switch">#FF2EEAC9</Color>
|
||||||
<Color x:Key="Unbounded">#FFFF4554</Color>
|
<Color x:Key="Unbounded">#FFFF4554</Color>
|
||||||
<Color x:Key="Custom">#6483F5</Color>
|
<Color x:Key="Custom">#6483F5</Color>
|
||||||
|
<Color x:Key="Warning">#FFA500</Color>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</ResourceDictionary.ThemeDictionaries>
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -13,10 +13,10 @@ using LibHac.Tools.Fs;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Controls;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
|
@ -216,11 +216,7 @@ namespace Ryujinx.Ava.Common
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
|
(Nca updatePatchNca, _) = mainNca.GetUpdateData(_virtualFileSystem, ConfigurationState.Instance.System.IntegrityCheckLevel, programIndex, out _);
|
||||||
? IntegrityCheckLevel.ErrorOnInvalid
|
|
||||||
: IntegrityCheckLevel.None;
|
|
||||||
|
|
||||||
(Nca updatePatchNca, _) = mainNca.GetUpdateData(_virtualFileSystem, checkLevel, programIndex, out _);
|
|
||||||
if (updatePatchNca is not null)
|
if (updatePatchNca is not null)
|
||||||
{
|
{
|
||||||
patchNca = updatePatchNca;
|
patchNca = updatePatchNca;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Gommon;
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.Systems;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System;
|
using System;
|
||||||
|
@ -25,7 +26,21 @@ namespace Ryujinx.Ava.Common.Locale
|
||||||
public LocaleManager()
|
public LocaleManager()
|
||||||
{
|
{
|
||||||
_localeStrings = new Dictionary<LocaleKeys, string>();
|
_localeStrings = new Dictionary<LocaleKeys, string>();
|
||||||
_dynamicValues = new ConcurrentDictionary<LocaleKeys, object[]>();
|
_dynamicValues = new ConcurrentDictionary<LocaleKeys, object[]>(new Dictionary<LocaleKeys, object[]>
|
||||||
|
{
|
||||||
|
{ LocaleKeys.DialogConfirmationTitle, [RyujinxApp.FullAppName] },
|
||||||
|
{ LocaleKeys.DialogUpdaterTitle, [RyujinxApp.FullAppName] },
|
||||||
|
{ LocaleKeys.DialogErrorTitle, [RyujinxApp.FullAppName] },
|
||||||
|
{ LocaleKeys.DialogWarningTitle, [RyujinxApp.FullAppName] },
|
||||||
|
{ LocaleKeys.DialogExitTitle, [RyujinxApp.FullAppName] },
|
||||||
|
{ LocaleKeys.DialogStopEmulationTitle, [RyujinxApp.FullAppName] },
|
||||||
|
{ LocaleKeys.RyujinxInfo, [RyujinxApp.FullAppName] },
|
||||||
|
{ LocaleKeys.RyujinxConfirm, [RyujinxApp.FullAppName] },
|
||||||
|
{ LocaleKeys.RyujinxUpdater, [RyujinxApp.FullAppName] },
|
||||||
|
{ LocaleKeys.RyujinxRebooter, [RyujinxApp.FullAppName] },
|
||||||
|
{ LocaleKeys.CompatibilityListSearchBoxWatermarkWithCount, [CompatibilityDatabase.Entries.Length] },
|
||||||
|
{ LocaleKeys.CompatibilityListTitle, [CompatibilityDatabase.Entries.Length] }
|
||||||
|
});
|
||||||
|
|
||||||
Load();
|
Load();
|
||||||
}
|
}
|
||||||
|
@ -44,16 +59,6 @@ namespace Ryujinx.Ava.Common.Locale
|
||||||
|
|
||||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDynamicValues(LocaleKeys.DialogConfirmationTitle, RyujinxApp.FullAppName);
|
|
||||||
SetDynamicValues(LocaleKeys.DialogUpdaterTitle, RyujinxApp.FullAppName);
|
|
||||||
SetDynamicValues(LocaleKeys.DialogErrorTitle, RyujinxApp.FullAppName);
|
|
||||||
SetDynamicValues(LocaleKeys.DialogWarningTitle, RyujinxApp.FullAppName);
|
|
||||||
SetDynamicValues(LocaleKeys.DialogExitTitle, RyujinxApp.FullAppName);
|
|
||||||
SetDynamicValues(LocaleKeys.DialogStopEmulationTitle, RyujinxApp.FullAppName);
|
|
||||||
SetDynamicValues(LocaleKeys.RyujinxInfo, RyujinxApp.FullAppName);
|
|
||||||
SetDynamicValues(LocaleKeys.RyujinxConfirm, RyujinxApp.FullAppName);
|
|
||||||
SetDynamicValues(LocaleKeys.RyujinxUpdater, RyujinxApp.FullAppName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string this[LocaleKeys key]
|
public string this[LocaleKeys key]
|
||||||
|
|
|
@ -24,4 +24,17 @@ namespace Ryujinx.Ava.Common.Markup
|
||||||
protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension)
|
protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension)
|
||||||
=> bindingExtension.Source = LocaleManager.Instance;
|
=> bindingExtension.Source = LocaleManager.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class WindowTitleExtension(LocaleKeys key, bool includeVersion) : BasicMarkupExtension<string>
|
||||||
|
{
|
||||||
|
public WindowTitleExtension(LocaleKeys key) : this(key, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Name => "WindowTitleTranslation";
|
||||||
|
protected override string Value => RyujinxApp.FormatTitle(key, includeVersion);
|
||||||
|
|
||||||
|
protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension)
|
||||||
|
=> bindingExtension.Source = LocaleManager.Instance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,9 @@ namespace Ryujinx.Ava.Common
|
||||||
|
|
||||||
internal class TrimmerWindow : Ryujinx.Common.Logging.XCIFileTrimmerLog
|
internal class TrimmerWindow : Ryujinx.Common.Logging.XCIFileTrimmerLog
|
||||||
{
|
{
|
||||||
private readonly XCITrimmerViewModel _viewModel;
|
private readonly XciTrimmerViewModel _viewModel;
|
||||||
|
|
||||||
public TrimmerWindow(XCITrimmerViewModel viewModel)
|
public TrimmerWindow(XciTrimmerViewModel viewModel)
|
||||||
{
|
{
|
||||||
_viewModel = viewModel;
|
_viewModel = viewModel;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,8 @@ using DiscordRPC;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using Ryujinx.Audio.Backends.SDL2;
|
using Ryujinx.Audio.Backends.SDL2;
|
||||||
using Ryujinx.Ava;
|
using Ryujinx.Ava;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems;
|
||||||
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
|
@ -11,7 +12,6 @@ using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading;
|
|
||||||
using Ryujinx.Graphics.OpenGL;
|
using Ryujinx.Graphics.OpenGL;
|
||||||
using Ryujinx.Graphics.Vulkan;
|
using Ryujinx.Graphics.Vulkan;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
|
@ -312,26 +312,10 @@ namespace Ryujinx.Headless
|
||||||
return new OpenGLRenderer();
|
return new OpenGLRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options)
|
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) =>
|
||||||
{
|
new(
|
||||||
BackendThreading threadingMode = options.BackendThreading;
|
new HleConfiguration(
|
||||||
|
|
||||||
bool threadedGAL = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading);
|
|
||||||
|
|
||||||
if (threadedGAL)
|
|
||||||
{
|
|
||||||
renderer = new ThreadedRenderer(renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
HLEConfiguration configuration = new(_virtualFileSystem,
|
|
||||||
_libHacHorizonManager,
|
|
||||||
_contentManager,
|
|
||||||
_accountManager,
|
|
||||||
_userChannelPersistence,
|
|
||||||
renderer,
|
|
||||||
new SDL2HardwareDeviceDriver(),
|
|
||||||
options.DramSize,
|
options.DramSize,
|
||||||
window,
|
|
||||||
options.SystemLanguage,
|
options.SystemLanguage,
|
||||||
options.SystemRegion,
|
options.SystemRegion,
|
||||||
options.VSyncMode,
|
options.VSyncMode,
|
||||||
|
@ -352,9 +336,18 @@ namespace Ryujinx.Headless
|
||||||
false,
|
false,
|
||||||
string.Empty,
|
string.Empty,
|
||||||
string.Empty,
|
string.Empty,
|
||||||
options.CustomVSyncInterval);
|
options.CustomVSyncInterval
|
||||||
|
)
|
||||||
return new Switch(configuration);
|
.Configure(
|
||||||
}
|
_virtualFileSystem,
|
||||||
|
_libHacHorizonManager,
|
||||||
|
_contentManager,
|
||||||
|
_accountManager,
|
||||||
|
_userChannelPersistence,
|
||||||
|
renderer.TryMakeThreaded(options.BackendThreading),
|
||||||
|
new SDL2HardwareDeviceDriver(),
|
||||||
|
window
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using CommandLine;
|
using CommandLine;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava;
|
using Ryujinx.Ava;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using CommandLine;
|
using CommandLine;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
|
using Ryujinx.Ava.Systems.Configuration.System;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
|
@ -37,7 +38,7 @@ namespace Ryujinx.Headless
|
||||||
EnableInternetAccess = configurationState.System.EnableInternetAccess;
|
EnableInternetAccess = configurationState.System.EnableInternetAccess;
|
||||||
|
|
||||||
if (NeedsOverride(nameof(DisableFsIntegrityChecks)))
|
if (NeedsOverride(nameof(DisableFsIntegrityChecks)))
|
||||||
DisableFsIntegrityChecks = configurationState.System.EnableFsIntegrityChecks;
|
DisableFsIntegrityChecks = !configurationState.System.EnableFsIntegrityChecks;
|
||||||
|
|
||||||
if (NeedsOverride(nameof(FsGlobalAccessLogMode)))
|
if (NeedsOverride(nameof(FsGlobalAccessLogMode)))
|
||||||
FsGlobalAccessLogMode = configurationState.System.FsGlobalAccessLogMode;
|
FsGlobalAccessLogMode = configurationState.System.FsGlobalAccessLogMode;
|
||||||
|
@ -58,10 +59,10 @@ namespace Ryujinx.Headless
|
||||||
DisableDockedMode = !configurationState.System.EnableDockedMode;
|
DisableDockedMode = !configurationState.System.EnableDockedMode;
|
||||||
|
|
||||||
if (NeedsOverride(nameof(SystemLanguage)))
|
if (NeedsOverride(nameof(SystemLanguage)))
|
||||||
SystemLanguage = (SystemLanguage)(int)configurationState.System.Language.Value;
|
SystemLanguage = configurationState.System.Language.Value.ToHLE();
|
||||||
|
|
||||||
if (NeedsOverride(nameof(SystemRegion)))
|
if (NeedsOverride(nameof(SystemRegion)))
|
||||||
SystemRegion = (RegionCode)(int)configurationState.System.Region.Value;
|
SystemRegion = configurationState.System.Region.Value.ToHLE();
|
||||||
|
|
||||||
if (NeedsOverride(nameof(SystemTimeZone)))
|
if (NeedsOverride(nameof(SystemTimeZone)))
|
||||||
SystemTimeZone = configurationState.System.TimeZone;
|
SystemTimeZone = configurationState.System.TimeZone;
|
||||||
|
|
|
@ -5,10 +5,12 @@ using Gommon;
|
||||||
using Projektanker.Icons.Avalonia;
|
using Projektanker.Icons.Avalonia;
|
||||||
using Projektanker.Icons.Avalonia.FontAwesome;
|
using Projektanker.Icons.Avalonia.FontAwesome;
|
||||||
using Projektanker.Icons.Avalonia.MaterialDesign;
|
using Projektanker.Icons.Avalonia.MaterialDesign;
|
||||||
|
using Ryujinx.Ava.Systems;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
|
using Ryujinx.Ava.Systems.Configuration.System;
|
||||||
using Ryujinx.Ava.Utilities.SystemInfo;
|
using Ryujinx.Ava.Utilities.SystemInfo;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
|
@ -32,8 +34,10 @@ namespace Ryujinx.Ava
|
||||||
public static double DesktopScaleFactor { get; set; } = 1.0;
|
public static double DesktopScaleFactor { get; set; } = 1.0;
|
||||||
public static string Version { get; private set; }
|
public static string Version { get; private set; }
|
||||||
public static string ConfigurationPath { get; private set; }
|
public static string ConfigurationPath { get; private set; }
|
||||||
|
public static string GlobalConfigurationPath { get; private set; }
|
||||||
public static bool PreviewerDetached { get; private set; }
|
public static bool PreviewerDetached { get; private set; }
|
||||||
public static bool UseHardwareAcceleration { get; private set; }
|
public static bool UseHardwareAcceleration { get; private set; }
|
||||||
|
public static string BackendThreadingArg { get; private set; }
|
||||||
|
|
||||||
[LibraryImport("user32.dll", SetLastError = true)]
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
public static partial int MessageBoxA(nint hWnd, [MarshalAs(UnmanagedType.LPStr)] string text, [MarshalAs(UnmanagedType.LPStr)] string caption, uint type);
|
public static partial int MessageBoxA(nint hWnd, [MarshalAs(UnmanagedType.LPStr)] string text, [MarshalAs(UnmanagedType.LPStr)] string caption, uint type);
|
||||||
|
@ -156,11 +160,38 @@ namespace Ryujinx.Ava
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetDirGameUserConfig(string gameId, bool rememberGlobalDir = false, bool changeFolderForGame = false)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(gameId))
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string gameDir = Path.Combine(AppDataManager.GamesDirPath, gameId, ReleaseInformation.ConfigName);
|
||||||
|
|
||||||
|
// Should load with the game if there is a custom setting for the game
|
||||||
|
if (rememberGlobalDir)
|
||||||
|
{
|
||||||
|
GlobalConfigurationPath = ConfigurationPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changeFolderForGame)
|
||||||
|
{
|
||||||
|
ConfigurationPath = gameDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gameDir;
|
||||||
|
}
|
||||||
|
|
||||||
public static void ReloadConfig()
|
public static void ReloadConfig()
|
||||||
{
|
{
|
||||||
|
//It is necessary that when a user setting appears, the global setting remains available
|
||||||
|
GlobalConfigurationPath = null;
|
||||||
|
|
||||||
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
|
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
|
||||||
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
|
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
|
||||||
|
|
||||||
|
|
||||||
// Now load the configuration as the other subsystems are now registered
|
// Now load the configuration as the other subsystems are now registered
|
||||||
if (File.Exists(localConfigurationPath))
|
if (File.Exists(localConfigurationPath))
|
||||||
{
|
{
|
||||||
|
@ -217,6 +248,11 @@ namespace Ryujinx.Ava
|
||||||
_ => ConfigurationState.Instance.Graphics.BackendThreading
|
_ => ConfigurationState.Instance.Graphics.BackendThreading
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (CommandLineState.OverrideBackendThreadingAfterReboot is not null)
|
||||||
|
{
|
||||||
|
BackendThreadingArg = CommandLineState.OverrideBackendThreadingAfterReboot;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if docked mode was overriden.
|
// Check if docked mode was overriden.
|
||||||
if (CommandLineState.OverrideDockedMode.HasValue)
|
if (CommandLineState.OverrideDockedMode.HasValue)
|
||||||
ConfigurationState.Instance.System.EnableDockedMode.Value = CommandLineState.OverrideDockedMode.Value;
|
ConfigurationState.Instance.System.EnableDockedMode.Value = CommandLineState.OverrideDockedMode.Value;
|
||||||
|
@ -232,6 +268,33 @@ namespace Ryujinx.Ava
|
||||||
_ => ConfigurationState.Instance.HideCursor,
|
_ => ConfigurationState.Instance.HideCursor,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check if memoryManagerMode was overridden.
|
||||||
|
if (CommandLineState.OverrideMemoryManagerMode is not null)
|
||||||
|
if (Enum.TryParse(CommandLineState.OverrideMemoryManagerMode, true, out MemoryManagerMode result))
|
||||||
|
{
|
||||||
|
ConfigurationState.Instance.System.MemoryManagerMode.Value = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if PPTC was overridden.
|
||||||
|
if (CommandLineState.OverridePPTC is not null)
|
||||||
|
if (Enum.TryParse(CommandLineState.OverridePPTC, true, out bool result))
|
||||||
|
{
|
||||||
|
ConfigurationState.Instance.System.EnablePtc.Value = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if region was overridden.
|
||||||
|
if (CommandLineState.OverrideSystemRegion is not null)
|
||||||
|
if (Enum.TryParse(CommandLineState.OverrideSystemRegion, true, out HLE.HOS.SystemState.RegionCode result))
|
||||||
|
{
|
||||||
|
ConfigurationState.Instance.System.Region.Value = result.ToUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if language was overridden.
|
||||||
|
if (CommandLineState.OverrideSystemLanguage is not null)
|
||||||
|
if (Enum.TryParse(CommandLineState.OverrideSystemLanguage, true, out HLE.HOS.SystemState.SystemLanguage result))
|
||||||
|
{
|
||||||
|
ConfigurationState.Instance.System.Language.Value = result.ToUI();
|
||||||
|
}
|
||||||
|
|
||||||
// Check if hardware-acceleration was overridden.
|
// Check if hardware-acceleration was overridden.
|
||||||
if (CommandLineState.OverrideHardwareAcceleration != null)
|
if (CommandLineState.OverrideHardwareAcceleration != null)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64;win-arm64;osx-arm64;linux-arm64;</RuntimeIdentifiers>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Version>1.0.0-dirty</Version>
|
<Version>1.0.0-dirty</Version>
|
||||||
|
@ -29,12 +29,18 @@
|
||||||
<TrimMode>partial</TrimMode>
|
<TrimMode>partial</TrimMode>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'win-arm64'">
|
||||||
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
|
<PublishTrimmed>false</PublishTrimmed>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
FluentAvalonia, used in the Avalonia UI, requires a workaround for the json serializer used internally when using .NET 8+ System.Text.Json.
|
FluentAvalonia, used in the Avalonia UI, requires a workaround for the json serializer used internally when using .NET 8+ System.Text.Json.
|
||||||
See:
|
See:
|
||||||
https://github.com/amwx/FluentAvalonia/issues/481
|
https://github.com/amwx/FluentAvalonia/issues/481
|
||||||
https://devblogs.microsoft.com/dotnet/system-text-json-in-dotnet-8/
|
https://devblogs.microsoft.com/dotnet/system-text-json-in-dotnet-8/
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
|
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -57,8 +63,8 @@
|
||||||
<PackageReference Include="Projektanker.Icons.Avalonia.MaterialDesign" />
|
<PackageReference Include="Projektanker.Icons.Avalonia.MaterialDesign" />
|
||||||
<PackageReference Include="OpenTK.Core" />
|
<PackageReference Include="OpenTK.Core" />
|
||||||
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
||||||
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" />
|
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" />
|
||||||
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
|
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'win-arm64'" />
|
||||||
<PackageReference Include="securifybv.ShellLink" />
|
<PackageReference Include="securifybv.ShellLink" />
|
||||||
<PackageReference Include="Sep" />
|
<PackageReference Include="Sep" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan" />
|
<PackageReference Include="Silk.NET.Vulkan" />
|
||||||
|
@ -84,17 +90,19 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="..\..\distribution\windows\alsoft.ini" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
|
<Content Include="..\..\distribution\windows\alsoft.ini" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
<TargetPath>alsoft.ini</TargetPath>
|
<TargetPath>alsoft.ini</TargetPath>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="..\..\distribution\legal\THIRDPARTY.md">
|
<Content Include="..\..\distribution\legal\THIRDPARTY.md">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
<TargetPath>THIRDPARTY.md</TargetPath>
|
<TargetPath>THIRDPARTY.md</TargetPath>
|
||||||
|
<Visible>False</Visible>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="..\..\LICENSE.txt">
|
<Content Include="..\..\LICENSE.txt">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
<TargetPath>LICENSE.txt</TargetPath>
|
<TargetPath>LICENSE.txt</TargetPath>
|
||||||
|
<Visible>False</Visible>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ using Avalonia.Threading;
|
||||||
using DiscordRPC;
|
using DiscordRPC;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Ns;
|
using LibHac.Ns;
|
||||||
using LibHac.Tools.FsSystem;
|
|
||||||
using Ryujinx.Audio.Backends.Dummy;
|
using Ryujinx.Audio.Backends.Dummy;
|
||||||
using Ryujinx.Audio.Backends.OpenAL;
|
using Ryujinx.Audio.Backends.OpenAL;
|
||||||
using Ryujinx.Audio.Backends.SDL2;
|
using Ryujinx.Audio.Backends.SDL2;
|
||||||
|
@ -21,8 +20,8 @@ using Ryujinx.Ava.UI.Renderer;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Multiplayer;
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
|
@ -35,11 +34,9 @@ using Ryujinx.Graphics.GAL.Multithreading;
|
||||||
using Ryujinx.Graphics.Gpu;
|
using Ryujinx.Graphics.Gpu;
|
||||||
using Ryujinx.Graphics.OpenGL;
|
using Ryujinx.Graphics.OpenGL;
|
||||||
using Ryujinx.Graphics.Vulkan;
|
using Ryujinx.Graphics.Vulkan;
|
||||||
using Ryujinx.HLE;
|
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||||
using Ryujinx.HLE.HOS.SystemState;
|
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Input.HLE;
|
using Ryujinx.Input.HLE;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
@ -62,7 +59,7 @@ using Size = Avalonia.Size;
|
||||||
using Switch = Ryujinx.HLE.Switch;
|
using Switch = Ryujinx.HLE.Switch;
|
||||||
using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
|
using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
|
||||||
|
|
||||||
namespace Ryujinx.Ava
|
namespace Ryujinx.Ava.Systems
|
||||||
{
|
{
|
||||||
internal class AppHost
|
internal class AppHost
|
||||||
{
|
{
|
||||||
|
@ -470,7 +467,7 @@ namespace Ryujinx.Ava
|
||||||
|
|
||||||
Dispatcher.UIThread.InvokeAsync(() =>
|
Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar);
|
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI);
|
||||||
});
|
});
|
||||||
|
|
||||||
_viewModel.SetUiProgressHandlers(Device);
|
_viewModel.SetUiProgressHandlers(Device);
|
||||||
|
@ -872,7 +869,7 @@ namespace Ryujinx.Ava
|
||||||
Device?.System.TogglePauseEmulation(false);
|
Device?.System.TogglePauseEmulation(false);
|
||||||
|
|
||||||
_viewModel.IsPaused = false;
|
_viewModel.IsPaused = false;
|
||||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar);
|
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI);
|
||||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed");
|
Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -881,7 +878,7 @@ namespace Ryujinx.Ava
|
||||||
Device?.System.TogglePauseEmulation(true);
|
Device?.System.TogglePauseEmulation(true);
|
||||||
|
|
||||||
_viewModel.IsPaused = true;
|
_viewModel.IsPaused = true;
|
||||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowTitleBar, LocaleManager.Instance[LocaleKeys.Paused]);
|
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI, LocaleManager.Instance[LocaleKeys.Paused]);
|
||||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused");
|
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -902,53 +899,19 @@ namespace Ryujinx.Ava
|
||||||
_ => new OpenGLRenderer()
|
_ => new OpenGLRenderer()
|
||||||
};
|
};
|
||||||
|
|
||||||
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
|
|
||||||
|
|
||||||
bool isGALThreaded = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading);
|
|
||||||
if (isGALThreaded)
|
|
||||||
{
|
|
||||||
renderer = new ThreadedRenderer(renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({threadingMode}): {isGALThreaded}");
|
|
||||||
|
|
||||||
// Initialize Configuration.
|
// Initialize Configuration.
|
||||||
MemoryConfiguration memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value;
|
Device = new Switch(ConfigurationState.Instance.CreateHleConfiguration()
|
||||||
|
.Configure(
|
||||||
Device = new Switch(new HLEConfiguration(
|
|
||||||
VirtualFileSystem,
|
VirtualFileSystem,
|
||||||
_viewModel.LibHacHorizonManager,
|
_viewModel.LibHacHorizonManager,
|
||||||
ContentManager,
|
ContentManager,
|
||||||
_accountManager,
|
_accountManager,
|
||||||
_userChannelPersistence,
|
_userChannelPersistence,
|
||||||
renderer,
|
renderer.TryMakeThreaded(ConfigurationState.Instance.Graphics.BackendThreading),
|
||||||
InitializeAudio(),
|
InitializeAudio(),
|
||||||
memoryConfiguration,
|
_viewModel.UiHandler
|
||||||
_viewModel.UiHandler,
|
)
|
||||||
(SystemLanguage)ConfigurationState.Instance.System.Language.Value,
|
);
|
||||||
(RegionCode)ConfigurationState.Instance.System.Region.Value,
|
|
||||||
ConfigurationState.Instance.Graphics.VSyncMode,
|
|
||||||
ConfigurationState.Instance.System.EnableDockedMode,
|
|
||||||
ConfigurationState.Instance.System.EnablePtc,
|
|
||||||
ConfigurationState.Instance.System.EnableInternetAccess,
|
|
||||||
ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
|
|
||||||
ConfigurationState.Instance.System.FsGlobalAccessLogMode,
|
|
||||||
ConfigurationState.Instance.System.MatchSystemTime
|
|
||||||
? 0
|
|
||||||
: ConfigurationState.Instance.System.SystemTimeOffset,
|
|
||||||
ConfigurationState.Instance.System.TimeZone,
|
|
||||||
ConfigurationState.Instance.System.MemoryManagerMode,
|
|
||||||
ConfigurationState.Instance.System.IgnoreMissingServices,
|
|
||||||
ConfigurationState.Instance.Graphics.AspectRatio,
|
|
||||||
ConfigurationState.Instance.System.AudioVolume,
|
|
||||||
ConfigurationState.Instance.System.UseHypervisor,
|
|
||||||
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value,
|
|
||||||
ConfigurationState.Instance.Multiplayer.Mode,
|
|
||||||
ConfigurationState.Instance.Multiplayer.DisableP2p,
|
|
||||||
ConfigurationState.Instance.Multiplayer.LdnPassphrase,
|
|
||||||
ConfigurationState.Instance.Multiplayer.GetLdnServer(),
|
|
||||||
ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value,
|
|
||||||
ConfigurationState.Instance.Hacks.ShowDirtyHacks ? ConfigurationState.Instance.Hacks.EnabledHacks : null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IHardwareDeviceDriver InitializeAudio()
|
private static IHardwareDeviceDriver InitializeAudio()
|
||||||
|
@ -1113,6 +1076,13 @@ namespace Ryujinx.Ava
|
||||||
});
|
});
|
||||||
|
|
||||||
(RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true);
|
(RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(true);
|
||||||
|
|
||||||
|
// Reload settings when the game is turned off
|
||||||
|
// (resets custom settings if there were any)
|
||||||
|
Program.ReloadConfig();
|
||||||
|
|
||||||
|
// Reload application list (changes the status of the user setting if it was added or removed during the game)
|
||||||
|
Dispatcher.UIThread.Post(() => RyujinxApp.MainWindow.LoadApplications());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitStatus()
|
public void InitStatus()
|
||||||
|
@ -1175,6 +1145,9 @@ namespace Ryujinx.Ava
|
||||||
|
|
||||||
private void UpdateShaderCount()
|
private void UpdateShaderCount()
|
||||||
{
|
{
|
||||||
|
if (_displayCount is 0 && _renderer.ProgramCount is 0)
|
||||||
|
return;
|
||||||
|
|
||||||
// If there is a mismatch between total program compile and previous count
|
// If there is a mismatch between total program compile and previous count
|
||||||
// this means new shaders have been compiled and should be displayed.
|
// this means new shaders have been compiled and should be displayed.
|
||||||
if (_renderer.ProgramCount != _previousCount)
|
if (_renderer.ProgramCount != _previousCount)
|
||||||
|
@ -1248,12 +1221,10 @@ namespace Ryujinx.Ava
|
||||||
VSyncModeToggle();
|
VSyncModeToggle();
|
||||||
break;
|
break;
|
||||||
case KeyboardHotkeyState.CustomVSyncIntervalDecrement:
|
case KeyboardHotkeyState.CustomVSyncIntervalDecrement:
|
||||||
Device.DecrementCustomVSyncInterval();
|
_viewModel.CustomVSyncInterval = Device.DecrementCustomVSyncInterval();
|
||||||
_viewModel.CustomVSyncInterval -= 1;
|
|
||||||
break;
|
break;
|
||||||
case KeyboardHotkeyState.CustomVSyncIntervalIncrement:
|
case KeyboardHotkeyState.CustomVSyncIntervalIncrement:
|
||||||
Device.IncrementCustomVSyncInterval();
|
_viewModel.CustomVSyncInterval = Device.IncrementCustomVSyncInterval();
|
||||||
_viewModel.CustomVSyncInterval += 1;
|
|
||||||
break;
|
break;
|
||||||
case KeyboardHotkeyState.Screenshot:
|
case KeyboardHotkeyState.Screenshot:
|
||||||
ScreenshotRequested = true;
|
ScreenshotRequested = true;
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.Ava.Systems.AppLibrary
|
||||||
{
|
{
|
||||||
public class ApplicationCountUpdatedEventArgs : EventArgs
|
public class ApplicationCountUpdatedEventArgs : EventArgs
|
||||||
{
|
{
|
|
@ -9,8 +9,8 @@ using LibHac.Tools.Fs;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Utilities.Compat;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.PlayReport;
|
using Ryujinx.Ava.Systems.PlayReport;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
||||||
|
@ -18,11 +18,12 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.Ava.Systems.AppLibrary
|
||||||
{
|
{
|
||||||
public class ApplicationData
|
public class ApplicationData
|
||||||
{
|
{
|
||||||
public bool Favorite { get; set; }
|
public bool Favorite { get; set; }
|
||||||
|
public bool HasIndependentConfiguration { get; set; }
|
||||||
public byte[] Icon { get; set; }
|
public byte[] Icon { get; set; }
|
||||||
public string Name { get; set; } = "Unknown";
|
public string Name { get; set; } = "Unknown";
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
||||||
{
|
{
|
||||||
_id = value;
|
_id = value;
|
||||||
|
|
||||||
Compatibility = CompatibilityCsv.Find(value);
|
Compatibility = CompatibilityDatabase.Find(value);
|
||||||
RichPresenceSpec = PlayReports.Analyzer.TryGetSpec(IdString, out GameSpec gameSpec)
|
RichPresenceSpec = PlayReports.Analyzer.TryGetSpec(IdString, out GameSpec gameSpec)
|
||||||
? gameSpec
|
? gameSpec
|
||||||
: default(Optional<GameSpec>);
|
: default(Optional<GameSpec>);
|
|
@ -1,6 +1,6 @@
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.Ava.Systems.AppLibrary
|
||||||
{
|
{
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
[JsonSerializable(typeof(ApplicationMetadata))]
|
[JsonSerializable(typeof(ApplicationMetadata))]
|
|
@ -12,8 +12,9 @@ using LibHac.Tools.Fs;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
using Ryujinx.Ava.Common.Models;
|
using Ryujinx.Ava.Common.Models;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
|
using Ryujinx.Ava.Systems.Configuration.System;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Multiplayer;
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
|
@ -38,7 +39,7 @@ using MissingKeyException = LibHac.Common.Keys.MissingKeyException;
|
||||||
using Path = System.IO.Path;
|
using Path = System.IO.Path;
|
||||||
using TimeSpan = System.TimeSpan;
|
using TimeSpan = System.TimeSpan;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.Ava.Systems.AppLibrary
|
||||||
{
|
{
|
||||||
public class ApplicationLibrary
|
public class ApplicationLibrary
|
||||||
{
|
{
|
||||||
|
@ -532,6 +533,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
||||||
data.Favorite = appMetadata.Favorite;
|
data.Favorite = appMetadata.Favorite;
|
||||||
data.TimePlayed = appMetadata.TimePlayed;
|
data.TimePlayed = appMetadata.TimePlayed;
|
||||||
data.LastPlayed = appMetadata.LastPlayed;
|
data.LastPlayed = appMetadata.LastPlayed;
|
||||||
|
data.HasIndependentConfiguration = File.Exists(Program.GetDirGameUserConfig(data.IdBaseString, false, false)); // Just check user config
|
||||||
}
|
}
|
||||||
|
|
||||||
data.FileExtension = Path.GetExtension(applicationPath).TrimStart('.').ToUpper();
|
data.FileExtension = Path.GetExtension(applicationPath).TrimStart('.').ToUpper();
|
||||||
|
@ -616,15 +618,11 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
||||||
case ".xci":
|
case ".xci":
|
||||||
case ".nsp":
|
case ".nsp":
|
||||||
{
|
{
|
||||||
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
|
|
||||||
? IntegrityCheckLevel.ErrorOnInvalid
|
|
||||||
: IntegrityCheckLevel.None;
|
|
||||||
|
|
||||||
using IFileSystem pfs =
|
using IFileSystem pfs =
|
||||||
PartitionFileSystemUtils.OpenApplicationFileSystem(filePath, _virtualFileSystem);
|
PartitionFileSystemUtils.OpenApplicationFileSystem(filePath, _virtualFileSystem);
|
||||||
|
|
||||||
Dictionary<ulong, ContentMetaData> updates =
|
Dictionary<ulong, ContentMetaData> updates =
|
||||||
pfs.GetContentData(ContentMetaType.Patch, _virtualFileSystem, checkLevel);
|
pfs.GetContentData(ContentMetaType.Patch, _virtualFileSystem, ConfigurationState.Instance.System.IntegrityCheckLevel);
|
||||||
|
|
||||||
if (updates.Count == 0)
|
if (updates.Count == 0)
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.Ava.Systems.AppLibrary
|
||||||
{
|
{
|
||||||
public class ApplicationMetadata
|
public class ApplicationMetadata
|
||||||
{
|
{
|
|
@ -4,7 +4,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.Ava.Systems.AppLibrary
|
||||||
{
|
{
|
||||||
public struct LdnGameData
|
public struct LdnGameData
|
||||||
{
|
{
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.Ava.Systems.AppLibrary
|
||||||
{
|
{
|
||||||
public class LdnGameDataReceivedEventArgs : EventArgs
|
public class LdnGameDataReceivedEventArgs : EventArgs
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.Ava.Systems.AppLibrary
|
||||||
{
|
{
|
||||||
[JsonSerializable(typeof(IEnumerable<LdnGameData>))]
|
[JsonSerializable(typeof(IEnumerable<LdnGameData>))]
|
||||||
internal partial class LdnGameDataSerializerContext : JsonSerializerContext;
|
internal partial class LdnGameDataSerializerContext : JsonSerializerContext;
|
|
@ -9,26 +9,11 @@ using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Compat
|
namespace Ryujinx.Ava.Systems
|
||||||
{
|
{
|
||||||
public struct ColumnIndices(Func<ReadOnlySpan<char>, int> getIndex)
|
public class CompatibilityDatabase
|
||||||
{
|
{
|
||||||
public const string TitleIdCol = "\"title_id\"";
|
static CompatibilityDatabase() => Load();
|
||||||
public const string GameNameCol = "\"game_name\"";
|
|
||||||
public const string LabelsCol = "\"labels\"";
|
|
||||||
public const string StatusCol = "\"status\"";
|
|
||||||
public const string LastUpdatedCol = "\"last_updated\"";
|
|
||||||
|
|
||||||
public readonly int TitleId = getIndex(TitleIdCol);
|
|
||||||
public readonly int GameName = getIndex(GameNameCol);
|
|
||||||
public readonly int Labels = getIndex(LabelsCol);
|
|
||||||
public readonly int Status = getIndex(StatusCol);
|
|
||||||
public readonly int LastUpdated = getIndex(LastUpdatedCol);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CompatibilityCsv
|
|
||||||
{
|
|
||||||
static CompatibilityCsv() => Load();
|
|
||||||
|
|
||||||
public static void Load()
|
public static void Load()
|
||||||
{
|
{
|
||||||
|
@ -65,16 +50,6 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||||
|
|
||||||
public static CompatibilityEntry Find(ulong titleId)
|
public static CompatibilityEntry Find(ulong titleId)
|
||||||
=> Find(titleId.ToString("X16"));
|
=> Find(titleId.ToString("X16"));
|
||||||
|
|
||||||
public static LocaleKeys? GetStatus(string titleId)
|
|
||||||
=> Find(titleId)?.Status;
|
|
||||||
|
|
||||||
public static LocaleKeys? GetStatus(ulong titleId) => GetStatus(titleId.ToString("X16"));
|
|
||||||
|
|
||||||
public static string GetLabels(string titleId)
|
|
||||||
=> Find(titleId)?.FormattedIssueLabels;
|
|
||||||
|
|
||||||
public static string GetLabels(ulong titleId) => GetLabels(titleId.ToString("X16"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CompatibilityEntry
|
public class CompatibilityEntry
|
||||||
|
@ -135,6 +110,7 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||||
|
|
||||||
public string FormattedIssueLabels => Labels
|
public string FormattedIssueLabels => Labels
|
||||||
.Select(FormatLabelName)
|
.Select(FormatLabelName)
|
||||||
|
.Where(x => x != null)
|
||||||
.JoinToString(", ");
|
.JoinToString(", ");
|
||||||
|
|
||||||
public override string ToString() =>
|
public override string ToString() =>
|
||||||
|
@ -158,7 +134,6 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||||
"gui" => "GUI",
|
"gui" => "GUI",
|
||||||
"help wanted" => "Help Wanted",
|
"help wanted" => "Help Wanted",
|
||||||
"horizon" => "Horizon",
|
"horizon" => "Horizon",
|
||||||
"infra" => "Project Infra",
|
|
||||||
"invalid" => "Invalid",
|
"invalid" => "Invalid",
|
||||||
"kernel" => "Kernel",
|
"kernel" => "Kernel",
|
||||||
"ldn" => "LDN",
|
"ldn" => "LDN",
|
||||||
|
@ -172,9 +147,9 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||||
"ldn-untested" => "LDN Untested",
|
"ldn-untested" => "LDN Untested",
|
||||||
"ldn-broken" => "LDN Broken",
|
"ldn-broken" => "LDN Broken",
|
||||||
"ldn-partial" => "Partial LDN",
|
"ldn-partial" => "Partial LDN",
|
||||||
"nvdec" => "NVDEC",
|
"nvdec" => "GPU Video Decoding",
|
||||||
"services" => "NX Services",
|
"services" => "HLE Services",
|
||||||
"services-horizon" => "Horizon OS Services",
|
"services-horizon" => "New HLE Services",
|
||||||
"slow" => "Runs Slow",
|
"slow" => "Runs Slow",
|
||||||
"crash" => "Crashes",
|
"crash" => "Crashes",
|
||||||
"deadlock" => "Deadlock",
|
"deadlock" => "Deadlock",
|
||||||
|
@ -182,7 +157,7 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||||
"opengl" => "OpenGL",
|
"opengl" => "OpenGL",
|
||||||
"opengl-backend-bug" => "OpenGL Backend Bug",
|
"opengl-backend-bug" => "OpenGL Backend Bug",
|
||||||
"vulkan-backend-bug" => "Vulkan Backend Bug",
|
"vulkan-backend-bug" => "Vulkan Backend Bug",
|
||||||
"mac-bug" => "Mac-specific Bug(s)",
|
"mac-bug" => "Mac-specific Problems",
|
||||||
"amd-vendor-bug" => "AMD GPU Bug",
|
"amd-vendor-bug" => "AMD GPU Bug",
|
||||||
"intel-vendor-bug" => "Intel GPU Bug",
|
"intel-vendor-bug" => "Intel GPU Bug",
|
||||||
"loader-allocator" => "Loader Allocator",
|
"loader-allocator" => "Loader Allocator",
|
||||||
|
@ -191,18 +166,22 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||||
"UE4" => "Unreal Engine 4",
|
"UE4" => "Unreal Engine 4",
|
||||||
"homebrew" => "Homebrew Content",
|
"homebrew" => "Homebrew Content",
|
||||||
"online-broken" => "Online Broken",
|
"online-broken" => "Online Broken",
|
||||||
_ => Capitalize(labelName)
|
_ => null
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static string Capitalize(string value)
|
public struct ColumnIndices(Func<ReadOnlySpan<char>, int> getIndex)
|
||||||
{
|
{
|
||||||
if (value == string.Empty)
|
private const string TitleIdCol = "\"title_id\"";
|
||||||
return string.Empty;
|
private const string GameNameCol = "\"game_name\"";
|
||||||
|
private const string LabelsCol = "\"labels\"";
|
||||||
|
private const string StatusCol = "\"status\"";
|
||||||
|
private const string LastUpdatedCol = "\"last_updated\"";
|
||||||
|
|
||||||
char firstChar = value[0];
|
public readonly int TitleId = getIndex(TitleIdCol);
|
||||||
string rest = value[1..];
|
public readonly int GameName = getIndex(GameNameCol);
|
||||||
|
public readonly int Labels = getIndex(LabelsCol);
|
||||||
return $"{char.ToUpper(firstChar)}{rest}";
|
public readonly int Status = getIndex(StatusCol);
|
||||||
}
|
public readonly int LastUpdated = getIndex(LastUpdatedCol);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Systems.Configuration
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(TypedStringEnumConverter<AudioBackend>))]
|
[JsonConverter(typeof(TypedStringEnumConverter<AudioBackend>))]
|
||||||
public enum AudioBackend
|
public enum AudioBackend
|
|
@ -1,5 +1,5 @@
|
||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
using Ryujinx.Ava.Systems.Configuration.System;
|
||||||
using Ryujinx.Ava.Utilities.Configuration.UI;
|
using Ryujinx.Ava.Systems.Configuration.UI;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Multiplayer;
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
|
@ -8,14 +8,14 @@ using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Systems.Configuration
|
||||||
{
|
{
|
||||||
public class ConfigurationFileFormat
|
public class ConfigurationFileFormat
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current version of the file format
|
/// The current version of the file format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CurrentVersion = 67;
|
public const int CurrentVersion = 68;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the configuration file format
|
/// Version of the configuration file format
|
|
@ -1,6 +1,6 @@
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Systems.Configuration
|
||||||
{
|
{
|
||||||
internal static class ConfigurationFileFormatSettings
|
internal static class ConfigurationFileFormatSettings
|
||||||
{
|
{
|
|
@ -1,6 +1,6 @@
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Systems.Configuration
|
||||||
{
|
{
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
[JsonSerializable(typeof(ConfigurationFileFormat))]
|
[JsonSerializable(typeof(ConfigurationFileFormat))]
|
|
@ -1,7 +1,7 @@
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
using Ryujinx.Ava.Systems.Configuration.System;
|
||||||
using Ryujinx.Ava.Utilities.Configuration.UI;
|
using Ryujinx.Ava.Systems.Configuration.UI;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
|
@ -14,13 +14,14 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using RyuLogger = Ryujinx.Common.Logging.Logger;
|
using RyuLogger = Ryujinx.Common.Logging.Logger;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Systems.Configuration
|
||||||
{
|
{
|
||||||
public partial class ConfigurationState
|
public partial class ConfigurationState
|
||||||
{
|
{
|
||||||
public void Load(ConfigurationFileFormat cff, string configurationFilePath)
|
public void Load(ConfigurationFileFormat cff, string configurationFilePath, string titleId = "")
|
||||||
{
|
{
|
||||||
bool configurationFileUpdated = false;
|
bool configurationFileUpdated = false;
|
||||||
|
bool shouldLoadFromFile = string.IsNullOrEmpty(titleId);
|
||||||
|
|
||||||
if (cff.Version is < 0 or > ConfigurationFileFormat.CurrentVersion)
|
if (cff.Version is < 0 or > ConfigurationFileFormat.CurrentVersion)
|
||||||
{
|
{
|
||||||
|
@ -43,14 +44,14 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
configurationFileUpdated = true;
|
configurationFileUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EnableDiscordIntegration.Value = cff.EnableDiscordIntegration;
|
EnableDiscordIntegration.Value = cff.EnableDiscordIntegration;
|
||||||
CheckUpdatesOnStart.Value = cff.CheckUpdatesOnStart;
|
UpdateCheckerType.Value = shouldLoadFromFile ? cff.UpdateCheckerType : UpdateCheckerType.Value; // Get from global config only
|
||||||
UpdateCheckerType.Value = cff.UpdateCheckerType;
|
|
||||||
FocusLostActionType.Value = cff.FocusLostActionType;
|
FocusLostActionType.Value = cff.FocusLostActionType;
|
||||||
ShowConfirmExit.Value = cff.ShowConfirmExit;
|
ShowConfirmExit.Value = shouldLoadFromFile ? cff.ShowConfirmExit : ShowConfirmExit.Value; // Get from global config only
|
||||||
RememberWindowState.Value = cff.RememberWindowState;
|
RememberWindowState.Value = shouldLoadFromFile ? cff.RememberWindowState : RememberWindowState.Value; // Get from global config only
|
||||||
ShowTitleBar.Value = cff.ShowTitleBar;
|
ShowOldUI.Value = shouldLoadFromFile ? cff.ShowTitleBar : ShowOldUI.Value; // Get from global config only
|
||||||
EnableHardwareAcceleration.Value = cff.EnableHardwareAcceleration;
|
EnableHardwareAcceleration.Value = shouldLoadFromFile ? cff.EnableHardwareAcceleration : EnableHardwareAcceleration.Value; // Get from global config only
|
||||||
HideCursor.Value = cff.HideCursor;
|
HideCursor.Value = cff.HideCursor;
|
||||||
|
|
||||||
Logger.EnableFileLog.Value = cff.EnableFileLog;
|
Logger.EnableFileLog.Value = cff.EnableFileLog;
|
||||||
|
@ -87,8 +88,8 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
System.Language.Value = cff.SystemLanguage;
|
System.Language.Value = cff.SystemLanguage;
|
||||||
System.Region.Value = cff.SystemRegion;
|
System.Region.Value = cff.SystemRegion;
|
||||||
System.TimeZone.Value = cff.SystemTimeZone;
|
System.TimeZone.Value = cff.SystemTimeZone;
|
||||||
System.SystemTimeOffset.Value = cff.SystemTimeOffset;
|
System.SystemTimeOffset.Value = shouldLoadFromFile ? cff.SystemTimeOffset : System.SystemTimeOffset.Value; // Get from global config only
|
||||||
System.MatchSystemTime.Value = cff.MatchSystemTime;
|
System.MatchSystemTime.Value = shouldLoadFromFile ? cff.MatchSystemTime : System.MatchSystemTime.Value; // Get from global config only
|
||||||
System.EnableDockedMode.Value = cff.DockedMode;
|
System.EnableDockedMode.Value = cff.DockedMode;
|
||||||
System.EnablePtc.Value = cff.EnablePtc;
|
System.EnablePtc.Value = cff.EnablePtc;
|
||||||
System.EnableLowPowerPtc.Value = cff.EnableLowPowerPtc;
|
System.EnableLowPowerPtc.Value = cff.EnableLowPowerPtc;
|
||||||
|
@ -103,46 +104,47 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
System.IgnoreControllerApplet.Value = cff.IgnoreApplet;
|
System.IgnoreControllerApplet.Value = cff.IgnoreApplet;
|
||||||
System.UseHypervisor.Value = cff.UseHypervisor;
|
System.UseHypervisor.Value = cff.UseHypervisor;
|
||||||
|
|
||||||
UI.GuiColumns.FavColumn.Value = cff.GuiColumns.FavColumn;
|
UI.GuiColumns.FavColumn.Value = shouldLoadFromFile ? cff.GuiColumns.FavColumn : UI.GuiColumns.FavColumn.Value;
|
||||||
UI.GuiColumns.IconColumn.Value = cff.GuiColumns.IconColumn;
|
UI.GuiColumns.IconColumn.Value = shouldLoadFromFile ? cff.GuiColumns.IconColumn : UI.GuiColumns.IconColumn.Value;
|
||||||
UI.GuiColumns.AppColumn.Value = cff.GuiColumns.AppColumn;
|
UI.GuiColumns.AppColumn.Value = shouldLoadFromFile ? cff.GuiColumns.AppColumn : UI.GuiColumns.AppColumn.Value;
|
||||||
UI.GuiColumns.DevColumn.Value = cff.GuiColumns.DevColumn;
|
UI.GuiColumns.DevColumn.Value = shouldLoadFromFile ? cff.GuiColumns.DevColumn : UI.GuiColumns.DevColumn.Value;
|
||||||
UI.GuiColumns.VersionColumn.Value = cff.GuiColumns.VersionColumn;
|
UI.GuiColumns.VersionColumn.Value = shouldLoadFromFile ? cff.GuiColumns.VersionColumn : UI.GuiColumns.VersionColumn.Value;
|
||||||
UI.GuiColumns.TimePlayedColumn.Value = cff.GuiColumns.TimePlayedColumn;
|
UI.GuiColumns.TimePlayedColumn.Value = shouldLoadFromFile ? cff.GuiColumns.TimePlayedColumn : UI.GuiColumns.TimePlayedColumn.Value;
|
||||||
UI.GuiColumns.LastPlayedColumn.Value = cff.GuiColumns.LastPlayedColumn;
|
UI.GuiColumns.LastPlayedColumn.Value = shouldLoadFromFile ? cff.GuiColumns.LastPlayedColumn : UI.GuiColumns.LastPlayedColumn.Value;
|
||||||
UI.GuiColumns.FileExtColumn.Value = cff.GuiColumns.FileExtColumn;
|
UI.GuiColumns.FileExtColumn.Value = shouldLoadFromFile ? cff.GuiColumns.FileExtColumn : UI.GuiColumns.FileExtColumn.Value;
|
||||||
UI.GuiColumns.FileSizeColumn.Value = cff.GuiColumns.FileSizeColumn;
|
UI.GuiColumns.FileSizeColumn.Value = shouldLoadFromFile ? cff.GuiColumns.FileSizeColumn : UI.GuiColumns.FileSizeColumn.Value;
|
||||||
UI.GuiColumns.PathColumn.Value = cff.GuiColumns.PathColumn;
|
UI.GuiColumns.PathColumn.Value = shouldLoadFromFile ? cff.GuiColumns.PathColumn : UI.GuiColumns.PathColumn.Value;
|
||||||
UI.ColumnSort.SortColumnId.Value = cff.ColumnSort.SortColumnId;
|
UI.ColumnSort.SortColumnId.Value = shouldLoadFromFile ? cff.ColumnSort.SortColumnId : UI.ColumnSort.SortColumnId.Value;
|
||||||
UI.ColumnSort.SortAscending.Value = cff.ColumnSort.SortAscending;
|
UI.ColumnSort.SortAscending.Value = shouldLoadFromFile ? cff.ColumnSort.SortAscending : UI.ColumnSort.SortAscending.Value;
|
||||||
UI.GameDirs.Value = cff.GameDirs;
|
UI.GameDirs.Value = shouldLoadFromFile ? cff.GameDirs : UI.GameDirs.Value;
|
||||||
UI.AutoloadDirs.Value = cff.AutoloadDirs ?? [];
|
UI.AutoloadDirs.Value = shouldLoadFromFile ? (cff.AutoloadDirs ?? []) : UI.AutoloadDirs.Value;
|
||||||
UI.ShownFileTypes.NSP.Value = cff.ShownFileTypes.NSP;
|
UI.ShownFileTypes.NSP.Value = shouldLoadFromFile ? cff.ShownFileTypes.NSP : UI.ShownFileTypes.NSP.Value;
|
||||||
UI.ShownFileTypes.PFS0.Value = cff.ShownFileTypes.PFS0;
|
UI.ShownFileTypes.PFS0.Value = shouldLoadFromFile ? cff.ShownFileTypes.PFS0 : UI.ShownFileTypes.PFS0.Value;
|
||||||
UI.ShownFileTypes.XCI.Value = cff.ShownFileTypes.XCI;
|
UI.ShownFileTypes.XCI.Value = shouldLoadFromFile ? cff.ShownFileTypes.XCI : UI.ShownFileTypes.XCI.Value;
|
||||||
UI.ShownFileTypes.NCA.Value = cff.ShownFileTypes.NCA;
|
UI.ShownFileTypes.NCA.Value = shouldLoadFromFile ? cff.ShownFileTypes.NCA : UI.ShownFileTypes.NCA.Value;
|
||||||
UI.ShownFileTypes.NRO.Value = cff.ShownFileTypes.NRO;
|
UI.ShownFileTypes.NRO.Value = shouldLoadFromFile ? cff.ShownFileTypes.NRO : UI.ShownFileTypes.NRO.Value;
|
||||||
UI.ShownFileTypes.NSO.Value = cff.ShownFileTypes.NSO;
|
UI.ShownFileTypes.NSO.Value = shouldLoadFromFile ? cff.ShownFileTypes.NSO : UI.ShownFileTypes.NSO.Value;
|
||||||
UI.LanguageCode.Value = cff.LanguageCode;
|
UI.LanguageCode.Value = shouldLoadFromFile ? cff.LanguageCode : UI.LanguageCode.Value;
|
||||||
UI.BaseStyle.Value = cff.BaseStyle;
|
UI.BaseStyle.Value = shouldLoadFromFile ? cff.BaseStyle : UI.BaseStyle.Value;
|
||||||
UI.GameListViewMode.Value = cff.GameListViewMode;
|
UI.GameListViewMode.Value = shouldLoadFromFile ? cff.GameListViewMode : UI.GameListViewMode.Value;
|
||||||
UI.ShowNames.Value = cff.ShowNames;
|
UI.ShowNames.Value = shouldLoadFromFile ? cff.ShowNames : UI.ShowNames.Value;
|
||||||
UI.IsAscendingOrder.Value = cff.IsAscendingOrder;
|
UI.IsAscendingOrder.Value = shouldLoadFromFile ? cff.IsAscendingOrder : UI.IsAscendingOrder.Value;
|
||||||
UI.GridSize.Value = cff.GridSize;
|
UI.GridSize.Value = shouldLoadFromFile ? cff.GridSize : UI.GridSize.Value;
|
||||||
UI.ApplicationSort.Value = cff.ApplicationSort;
|
UI.ApplicationSort.Value = shouldLoadFromFile ? cff.ApplicationSort : UI.ApplicationSort.Value;
|
||||||
UI.StartFullscreen.Value = cff.StartFullscreen;
|
UI.StartFullscreen.Value = shouldLoadFromFile ? cff.StartFullscreen : UI.StartFullscreen.Value;
|
||||||
UI.StartNoUI.Value = cff.StartNoUI;
|
UI.StartNoUI.Value = shouldLoadFromFile ? cff.StartNoUI : UI.StartNoUI.Value;
|
||||||
UI.ShowConsole.Value = cff.ShowConsole;
|
UI.ShowConsole.Value = shouldLoadFromFile ? cff.ShowConsole : UI.ShowConsole.Value;
|
||||||
UI.WindowStartup.WindowSizeWidth.Value = cff.WindowStartup.WindowSizeWidth;
|
UI.WindowStartup.WindowSizeWidth.Value = shouldLoadFromFile ? cff.WindowStartup.WindowSizeWidth : UI.WindowStartup.WindowSizeWidth.Value;
|
||||||
UI.WindowStartup.WindowSizeHeight.Value = cff.WindowStartup.WindowSizeHeight;
|
UI.WindowStartup.WindowSizeHeight.Value = shouldLoadFromFile ? cff.WindowStartup.WindowSizeHeight : UI.WindowStartup.WindowSizeHeight.Value;
|
||||||
UI.WindowStartup.WindowPositionX.Value = cff.WindowStartup.WindowPositionX;
|
UI.WindowStartup.WindowPositionX.Value = shouldLoadFromFile ? cff.WindowStartup.WindowPositionX : UI.WindowStartup.WindowPositionX.Value;
|
||||||
UI.WindowStartup.WindowPositionY.Value = cff.WindowStartup.WindowPositionY;
|
UI.WindowStartup.WindowPositionY.Value = shouldLoadFromFile ? cff.WindowStartup.WindowPositionY : UI.WindowStartup.WindowPositionY.Value;
|
||||||
UI.WindowStartup.WindowMaximized.Value = cff.WindowStartup.WindowMaximized;
|
UI.WindowStartup.WindowMaximized.Value = shouldLoadFromFile ? cff.WindowStartup.WindowMaximized : UI.WindowStartup.WindowMaximized.Value;
|
||||||
|
|
||||||
|
|
||||||
Hid.EnableKeyboard.Value = cff.EnableKeyboard;
|
Hid.EnableKeyboard.Value = cff.EnableKeyboard;
|
||||||
Hid.EnableMouse.Value = cff.EnableMouse;
|
Hid.EnableMouse.Value = cff.EnableMouse;
|
||||||
Hid.DisableInputWhenOutOfFocus.Value = cff.DisableInputWhenOutOfFocus;
|
Hid.DisableInputWhenOutOfFocus.Value = shouldLoadFromFile ? cff.DisableInputWhenOutOfFocus: Hid.DisableInputWhenOutOfFocus.Value; // Get from global config only
|
||||||
Hid.Hotkeys.Value = cff.Hotkeys;
|
Hid.Hotkeys.Value = shouldLoadFromFile ? cff.Hotkeys : Hid.Hotkeys.Value; // Get from global config only
|
||||||
Hid.InputConfig.Value = cff.InputConfig ?? [];
|
Hid.InputConfig.Value = cff.InputConfig ?? [];
|
||||||
Hid.RainbowSpeed.Value = cff.RainbowSpeed;
|
Hid.RainbowSpeed.Value = cff.RainbowSpeed;
|
||||||
|
|
||||||
|
@ -159,8 +161,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
|
|
||||||
Hacks.Xc2MenuSoftlockFix.Value = hacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix);
|
Hacks.Xc2MenuSoftlockFix.Value = hacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix);
|
||||||
|
|
||||||
Hacks.EnableShaderTranslationDelay.Value = hacks.IsEnabled(DirtyHack.ShaderTranslationDelay);
|
|
||||||
Hacks.ShaderTranslationDelay.Value = hacks[DirtyHack.ShaderTranslationDelay].CoerceAtLeast(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configurationFileUpdated)
|
if (configurationFileUpdated)
|
||||||
|
@ -439,6 +439,8 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
(65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off),
|
(65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off),
|
||||||
(66, static cff => cff.DisableInputWhenOutOfFocus = false),
|
(66, static cff => cff.DisableInputWhenOutOfFocus = false),
|
||||||
(67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing)
|
(67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing)
|
||||||
|
// 68 was the version that added per-game configs; the file structure did not change
|
||||||
|
// the version was increased so external tools could know that your Ryujinx version has per-game config capabilities.
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
using ARMeilleure;
|
using ARMeilleure;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using LibHac.Tools.FsSystem;
|
||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
using Ryujinx.Ava.Systems.Configuration.System;
|
||||||
using Ryujinx.Ava.Utilities.Configuration.UI;
|
using Ryujinx.Ava.Systems.Configuration.UI;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
|
@ -15,7 +15,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using RyuLogger = Ryujinx.Common.Logging.Logger;
|
using RyuLogger = Ryujinx.Common.Logging.Logger;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Systems.Configuration
|
||||||
{
|
{
|
||||||
public partial class ConfigurationState
|
public partial class ConfigurationState
|
||||||
{
|
{
|
||||||
|
@ -351,6 +351,10 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> EnableFsIntegrityChecks { get; private set; }
|
public ReactiveObject<bool> EnableFsIntegrityChecks { get; private set; }
|
||||||
|
|
||||||
|
public IntegrityCheckLevel IntegrityCheckLevel => EnableFsIntegrityChecks
|
||||||
|
? IntegrityCheckLevel.ErrorOnInvalid
|
||||||
|
: IntegrityCheckLevel.None;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables FS access log output to the console. Possible modes are 0-3
|
/// Enables FS access log output to the console. Possible modes are 0-3
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -679,18 +683,15 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
|
|
||||||
public ReactiveObject<bool> Xc2MenuSoftlockFix { get; private set; }
|
public ReactiveObject<bool> Xc2MenuSoftlockFix { get; private set; }
|
||||||
|
|
||||||
public ReactiveObject<bool> EnableShaderTranslationDelay { get; private set; }
|
public ReactiveObject<bool> DisableNifmIsAnyInternetRequestAccepted { get; private set; }
|
||||||
|
|
||||||
public ReactiveObject<int> ShaderTranslationDelay { get; private set; }
|
|
||||||
|
|
||||||
public HacksSection()
|
public HacksSection()
|
||||||
{
|
{
|
||||||
ShowDirtyHacks = new ReactiveObject<bool>();
|
ShowDirtyHacks = new ReactiveObject<bool>();
|
||||||
Xc2MenuSoftlockFix = new ReactiveObject<bool>();
|
Xc2MenuSoftlockFix = new ReactiveObject<bool>();
|
||||||
Xc2MenuSoftlockFix.Event += HackChanged;
|
Xc2MenuSoftlockFix.Event += HackChanged;
|
||||||
EnableShaderTranslationDelay = new ReactiveObject<bool>();
|
DisableNifmIsAnyInternetRequestAccepted = new ReactiveObject<bool>();
|
||||||
EnableShaderTranslationDelay.Event += HackChanged;
|
DisableNifmIsAnyInternetRequestAccepted.Event += HackChanged;
|
||||||
ShaderTranslationDelay = new ReactiveObject<int>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HackChanged(object sender, ReactiveEventArgs<bool> rxe)
|
private void HackChanged(object sender, ReactiveEventArgs<bool> rxe)
|
||||||
|
@ -721,8 +722,8 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
if (Xc2MenuSoftlockFix)
|
if (Xc2MenuSoftlockFix)
|
||||||
Apply(DirtyHack.Xc2MenuSoftlockFix);
|
Apply(DirtyHack.Xc2MenuSoftlockFix);
|
||||||
|
|
||||||
if (EnableShaderTranslationDelay)
|
if (DisableNifmIsAnyInternetRequestAccepted)
|
||||||
Apply(DirtyHack.ShaderTranslationDelay, ShaderTranslationDelay);
|
Apply(DirtyHack.NifmServiceDisableIsAnyInternetRequestAccepted);
|
||||||
|
|
||||||
return enabledHacks.ToArray();
|
return enabledHacks.ToArray();
|
||||||
|
|
||||||
|
@ -779,11 +780,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> EnableDiscordIntegration { get; private set; }
|
public ReactiveObject<bool> EnableDiscordIntegration { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks for updates when Ryujinx starts when enabled
|
|
||||||
/// </summary>
|
|
||||||
public ReactiveObject<bool> CheckUpdatesOnStart { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification.
|
/// Checks for updates when Ryujinx starts when enabled, either prompting when an update is found or just showing a notification.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -805,9 +801,9 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
public ReactiveObject<bool> RememberWindowState { get; private set; }
|
public ReactiveObject<bool> RememberWindowState { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables or disables the redesigned title bar
|
/// Disable the new title bar layout & window layout changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> ShowTitleBar { get; private set; }
|
public ReactiveObject<bool> ShowOldUI { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables hardware-accelerated rendering for Avalonia
|
/// Enables hardware-accelerated rendering for Avalonia
|
||||||
|
@ -828,15 +824,44 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
Hid = new HidSection();
|
Hid = new HidSection();
|
||||||
Multiplayer = new MultiplayerSection();
|
Multiplayer = new MultiplayerSection();
|
||||||
Hacks = new HacksSection();
|
Hacks = new HacksSection();
|
||||||
EnableDiscordIntegration = new ReactiveObject<bool>();
|
|
||||||
CheckUpdatesOnStart = new ReactiveObject<bool>();
|
|
||||||
UpdateCheckerType = new ReactiveObject<UpdaterType>();
|
UpdateCheckerType = new ReactiveObject<UpdaterType>();
|
||||||
FocusLostActionType = new ReactiveObject<FocusLostType>();
|
FocusLostActionType = new ReactiveObject<FocusLostType>();
|
||||||
|
HideCursor = new ReactiveObject<HideCursorMode>();
|
||||||
|
EnableDiscordIntegration = new ReactiveObject<bool>();
|
||||||
ShowConfirmExit = new ReactiveObject<bool>();
|
ShowConfirmExit = new ReactiveObject<bool>();
|
||||||
RememberWindowState = new ReactiveObject<bool>();
|
RememberWindowState = new ReactiveObject<bool>();
|
||||||
ShowTitleBar = new ReactiveObject<bool>();
|
ShowOldUI = new ReactiveObject<bool>();
|
||||||
EnableHardwareAcceleration = new ReactiveObject<bool>();
|
EnableHardwareAcceleration = new ReactiveObject<bool>();
|
||||||
HideCursor = new ReactiveObject<HideCursorMode>();
|
}
|
||||||
}
|
|
||||||
|
public HleConfiguration CreateHleConfiguration() =>
|
||||||
|
new(
|
||||||
|
System.DramSize,
|
||||||
|
System.Language.Value.ToHLE(),
|
||||||
|
System.Region.Value.ToHLE(),
|
||||||
|
Graphics.VSyncMode,
|
||||||
|
System.EnableDockedMode,
|
||||||
|
System.EnablePtc,
|
||||||
|
System.EnableInternetAccess,
|
||||||
|
System.EnableFsIntegrityChecks
|
||||||
|
? IntegrityCheckLevel.ErrorOnInvalid
|
||||||
|
: IntegrityCheckLevel.None,
|
||||||
|
System.FsGlobalAccessLogMode,
|
||||||
|
System.MatchSystemTime
|
||||||
|
? 0
|
||||||
|
: System.SystemTimeOffset,
|
||||||
|
System.TimeZone,
|
||||||
|
System.MemoryManagerMode,
|
||||||
|
System.IgnoreMissingServices,
|
||||||
|
Graphics.AspectRatio,
|
||||||
|
System.AudioVolume,
|
||||||
|
System.UseHypervisor,
|
||||||
|
Multiplayer.LanInterfaceId,
|
||||||
|
Multiplayer.Mode,
|
||||||
|
Multiplayer.DisableP2p,
|
||||||
|
Multiplayer.LdnPassphrase,
|
||||||
|
Instance.Multiplayer.GetLdnServer(),
|
||||||
|
Instance.Graphics.CustomVSyncInterval,
|
||||||
|
Instance.Hacks.ShowDirtyHacks ? Instance.Hacks.EnabledHacks : null);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
using Ryujinx.Ava.Systems.Configuration.System;
|
||||||
using Ryujinx.Ava.Utilities.Configuration.UI;
|
using Ryujinx.Ava.Systems.Configuration.UI;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||||
|
@ -9,7 +9,7 @@ using Ryujinx.HLE;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Systems.Configuration
|
||||||
{
|
{
|
||||||
public partial class ConfigurationState
|
public partial class ConfigurationState
|
||||||
{
|
{
|
||||||
|
@ -56,12 +56,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
MatchSystemTime = System.MatchSystemTime,
|
MatchSystemTime = System.MatchSystemTime,
|
||||||
DockedMode = System.EnableDockedMode,
|
DockedMode = System.EnableDockedMode,
|
||||||
EnableDiscordIntegration = EnableDiscordIntegration,
|
EnableDiscordIntegration = EnableDiscordIntegration,
|
||||||
CheckUpdatesOnStart = CheckUpdatesOnStart,
|
|
||||||
UpdateCheckerType = UpdateCheckerType,
|
UpdateCheckerType = UpdateCheckerType,
|
||||||
FocusLostActionType = FocusLostActionType,
|
FocusLostActionType = FocusLostActionType,
|
||||||
ShowConfirmExit = ShowConfirmExit,
|
ShowConfirmExit = ShowConfirmExit,
|
||||||
RememberWindowState = RememberWindowState,
|
RememberWindowState = RememberWindowState,
|
||||||
ShowTitleBar = ShowTitleBar,
|
ShowTitleBar = ShowOldUI,
|
||||||
EnableHardwareAcceleration = EnableHardwareAcceleration,
|
EnableHardwareAcceleration = EnableHardwareAcceleration,
|
||||||
HideCursor = HideCursor,
|
HideCursor = HideCursor,
|
||||||
VSyncMode = Graphics.VSyncMode,
|
VSyncMode = Graphics.VSyncMode,
|
||||||
|
@ -183,7 +182,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
||||||
FocusLostActionType.Value = FocusLostType.DoNothing;
|
FocusLostActionType.Value = FocusLostType.DoNothing;
|
||||||
ShowConfirmExit.Value = true;
|
ShowConfirmExit.Value = true;
|
||||||
RememberWindowState.Value = true;
|
RememberWindowState.Value = true;
|
||||||
ShowTitleBar.Value = !OperatingSystem.IsWindows();
|
ShowOldUI.Value = !OperatingSystem.IsWindows();
|
||||||
EnableHardwareAcceleration.Value = true;
|
EnableHardwareAcceleration.Value = true;
|
||||||
HideCursor.Value = HideCursorMode.OnIdle;
|
HideCursor.Value = HideCursorMode.OnIdle;
|
||||||
Graphics.VSyncMode.Value = VSyncMode.Switch;
|
Graphics.VSyncMode.Value = VSyncMode.Switch;
|
|
@ -1,8 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using static Ryujinx.Ava.Utilities.Configuration.ConfigurationState.UISection;
|
using static Ryujinx.Ava.Systems.Configuration.ConfigurationState.UISection;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Systems.Configuration
|
||||||
{
|
{
|
||||||
public enum FileTypes
|
public enum FileTypes
|
||||||
{
|
{
|
|
@ -4,7 +4,7 @@ using Ryujinx.Common.Logging.Targets;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.Ava.Systems.Configuration
|
||||||
{
|
{
|
||||||
public static class LoggerModule
|
public static class LoggerModule
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration.System
|
namespace Ryujinx.Ava.Systems.Configuration.System
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(TypedStringEnumConverter<Language>))]
|
[JsonConverter(typeof(TypedStringEnumConverter<Language>))]
|
||||||
public enum Language
|
public enum Language
|
||||||
|
@ -25,4 +25,13 @@ namespace Ryujinx.Ava.Utilities.Configuration.System
|
||||||
TraditionalChinese,
|
TraditionalChinese,
|
||||||
BrazilianPortuguese,
|
BrazilianPortuguese,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class LanguageEnumHelper
|
||||||
|
{
|
||||||
|
public static Language ToUI(this HLE.HOS.SystemState.SystemLanguage hleLanguage)
|
||||||
|
=> (Language)hleLanguage;
|
||||||
|
|
||||||
|
public static HLE.HOS.SystemState.SystemLanguage ToHLE(this Language uiLanguage)
|
||||||
|
=> (HLE.HOS.SystemState.SystemLanguage)uiLanguage;
|
||||||
|
}
|
||||||
}
|
}
|
26
src/Ryujinx/Systems/Configuration/System/Region.cs
Normal file
26
src/Ryujinx/Systems/Configuration/System/Region.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
using Ryujinx.Common.Utilities;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.Systems.Configuration.System
|
||||||
|
{
|
||||||
|
[JsonConverter(typeof(TypedStringEnumConverter<Region>))]
|
||||||
|
public enum Region
|
||||||
|
{
|
||||||
|
Japan,
|
||||||
|
USA,
|
||||||
|
Europe,
|
||||||
|
Australia,
|
||||||
|
China,
|
||||||
|
Korea,
|
||||||
|
Taiwan,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RegionEnumHelper
|
||||||
|
{
|
||||||
|
public static Region ToUI(this HLE.HOS.SystemState.RegionCode hleRegion)
|
||||||
|
=> (Region)hleRegion;
|
||||||
|
|
||||||
|
public static HLE.HOS.SystemState.RegionCode ToHLE(this Region uiRegion)
|
||||||
|
=> (HLE.HOS.SystemState.RegionCode)uiRegion;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration.UI
|
namespace Ryujinx.Ava.Systems.Configuration.UI
|
||||||
{
|
{
|
||||||
public struct ColumnSort
|
public struct ColumnSort
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration.UI
|
namespace Ryujinx.Ava.Systems.Configuration.UI
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(TypedStringEnumConverter<FocusLostType>))]
|
[JsonConverter(typeof(TypedStringEnumConverter<FocusLostType>))]
|
||||||
public enum FocusLostType
|
public enum FocusLostType
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration.UI
|
namespace Ryujinx.Ava.Systems.Configuration.UI
|
||||||
{
|
{
|
||||||
public struct GuiColumns
|
public struct GuiColumns
|
||||||
{
|
{
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration.UI
|
namespace Ryujinx.Ava.Systems.Configuration.UI
|
||||||
{
|
{
|
||||||
public struct ShownFileTypes
|
public struct ShownFileTypes
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration.UI
|
namespace Ryujinx.Ava.Systems.Configuration.UI
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(TypedStringEnumConverter<UpdaterType>))]
|
[JsonConverter(typeof(TypedStringEnumConverter<UpdaterType>))]
|
||||||
public enum UpdaterType
|
public enum UpdaterType
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration.UI
|
namespace Ryujinx.Ava.Systems.Configuration.UI
|
||||||
{
|
{
|
||||||
public struct WindowStartup
|
public struct WindowStartup
|
||||||
{
|
{
|
|
@ -1,18 +1,17 @@
|
||||||
using DiscordRPC;
|
using DiscordRPC;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Ava.Utilities.PlayReport;
|
using Ryujinx.Ava.Systems.PlayReport;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using Ryujinx.HLE.Loaders.Processes;
|
using Ryujinx.HLE.Loaders.Processes;
|
||||||
using Ryujinx.Horizon;
|
using Ryujinx.Horizon;
|
||||||
using Ryujinx.Horizon.Prepo.Types;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.Ava
|
namespace Ryujinx.Ava.Systems
|
||||||
{
|
{
|
||||||
public static class DiscordIntegrationModule
|
public static class DiscordIntegrationModule
|
||||||
{
|
{
|
||||||
|
@ -124,7 +123,7 @@ namespace Ryujinx.Ava
|
||||||
_currentApp = null;
|
_currentApp = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandlePlayReport(PlayReport playReport)
|
private static void HandlePlayReport(Horizon.Prepo.Types.PlayReport playReport)
|
||||||
{
|
{
|
||||||
if (_discordClient is null) return;
|
if (_discordClient is null) return;
|
||||||
if (!TitleIDs.CurrentApplication.Value.HasValue) return;
|
if (!TitleIDs.CurrentApplication.Value.HasValue) return;
|
|
@ -1,5 +1,5 @@
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -7,7 +7,7 @@ using System.Collections.ObjectModel;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.PlayReport
|
namespace Ryujinx.Ava.Systems.PlayReport
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The entrypoint for the Play Report analysis system.
|
/// The entrypoint for the Play Report analysis system.
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Ryujinx.Ava.Utilities.PlayReport
|
namespace Ryujinx.Ava.Systems.PlayReport
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The delegate type that powers single value formatters.<br/>
|
/// The delegate type that powers single value formatters.<br/>
|
|
@ -1,8 +1,8 @@
|
||||||
using MsgPack;
|
using MsgPack;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.PlayReport
|
namespace Ryujinx.Ava.Systems.PlayReport
|
||||||
{
|
{
|
||||||
public abstract class MatchedValue<T>
|
public abstract class MatchedValue<T>
|
||||||
{
|
{
|
|
@ -5,7 +5,7 @@ using System.Buffers.Binary;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.PlayReport
|
namespace Ryujinx.Ava.Systems.PlayReport
|
||||||
{
|
{
|
||||||
public partial class PlayReports
|
public partial class PlayReports
|
||||||
{
|
{
|
||||||
|
@ -60,11 +60,12 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||||
_ => FormattedValue.ForceReset
|
_ => FormattedValue.ForceReset
|
||||||
};
|
};
|
||||||
|
|
||||||
private static FormattedValue PokemonSVUnionCircle(SingleValue value)
|
private static FormattedValue PokemonSV(MultiValue values)
|
||||||
=> value.Matched.BoxedValue is 0 ? "Playing Alone" : "Playing in a group";
|
{
|
||||||
|
|
||||||
private static FormattedValue PokemonSVArea(SingleValue value)
|
string playStatus = values.Matched[0].BoxedValue is 0 ? "Playing Alone" : "Playing in a group";
|
||||||
=> value.Matched.StringValue switch
|
|
||||||
|
FormattedValue locations = values.Matched[1].ToString() switch
|
||||||
{
|
{
|
||||||
// Base Game Locations
|
// Base Game Locations
|
||||||
"a_w01" => "South Area One",
|
"a_w01" => "South Area One",
|
||||||
|
@ -92,11 +93,14 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||||
"a_w24" => "South Paldean Sea",
|
"a_w24" => "South Paldean Sea",
|
||||||
"a_w25" => "West Paldean Sea",
|
"a_w25" => "West Paldean Sea",
|
||||||
"a_w26" => "East Paldean Sea",
|
"a_w26" => "East Paldean Sea",
|
||||||
"a_w27" => "Nouth Paldean Sea",
|
"a_w27" => "North Paldean Sea",
|
||||||
//TODO DLC Locations
|
//TODO DLC Locations
|
||||||
_ => FormattedValue.ForceReset
|
_ => FormattedValue.ForceReset
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return$"{playStatus} in {locations}";
|
||||||
|
}
|
||||||
|
|
||||||
private static FormattedValue SuperSmashBrosUltimate_Mode(SparseMultiValue values)
|
private static FormattedValue SuperSmashBrosUltimate_Mode(SparseMultiValue values)
|
||||||
{
|
{
|
||||||
// Check if the PlayReport is for a challenger approach or an achievement.
|
// Check if the PlayReport is for a challenger approach or an achievement.
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.PlayReport
|
namespace Ryujinx.Ava.Systems.PlayReport
|
||||||
{
|
{
|
||||||
public static partial class PlayReports
|
public static partial class PlayReports
|
||||||
{
|
{
|
||||||
|
@ -59,9 +59,8 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||||
.AddSpec(
|
.AddSpec(
|
||||||
["0100a3d008c5c000", "01008f6008c5e000"],
|
["0100a3d008c5c000", "01008f6008c5e000"],
|
||||||
spec => spec
|
spec => spec
|
||||||
.WithDescription("based on what area of Paldea you're exploring.")
|
.WithDescription("based on if you're playing alone or in a group and what area of Paldea you're exploring.")
|
||||||
.AddValueFormatter("area_no", PokemonSVArea)
|
.AddMultiValueFormatter(["team_circle", "area_no"], PokemonSV)
|
||||||
.AddValueFormatter("team_circle", PokemonSVUnionCircle)
|
|
||||||
)
|
)
|
||||||
.AddSpec(
|
.AddSpec(
|
||||||
"01006a800016e000",
|
"01006a800016e000",
|
|
@ -1,10 +1,10 @@
|
||||||
using MsgPack;
|
using MsgPack;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.PlayReport
|
namespace Ryujinx.Ava.Systems.PlayReport
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A mapping of title IDs to value formatter specs.
|
/// A mapping of title IDs to value formatter specs.
|
||||||
|
@ -103,7 +103,7 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||||
/// matching a specific set of keys that could exist in a Play Report for the previously specified title IDs.
|
/// matching a specific set of keys that could exist in a Play Report for the previously specified title IDs.
|
||||||
/// <br/><br/>
|
/// <br/><br/>
|
||||||
/// The 'Sparse' multi-value formatters do not require every key to be present.
|
/// The 'Sparse' multi-value formatters do not require every key to be present.
|
||||||
/// If you need this requirement, use <see cref="AddMultiValueFormatter(string[], Ryujinx.Ava.Utilities.PlayReport.MultiValueFormatter)"/>.
|
/// If you need this requirement, use <see cref="AddMultiValueFormatter(string[], MultiValueFormatter)"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reportKeys">The key names to match.</param>
|
/// <param name="reportKeys">The key names to match.</param>
|
||||||
/// <param name="valueFormatter">The function which can format the values.</param>
|
/// <param name="valueFormatter">The function which can format the values.</param>
|
||||||
|
@ -118,7 +118,7 @@ namespace Ryujinx.Ava.Utilities.PlayReport
|
||||||
/// matching a specific set of keys that could exist in a Play Report for the previously specified title IDs.
|
/// matching a specific set of keys that could exist in a Play Report for the previously specified title IDs.
|
||||||
/// <br/><br/>
|
/// <br/><br/>
|
||||||
/// The 'Sparse' multi-value formatters do not require every key to be present.
|
/// The 'Sparse' multi-value formatters do not require every key to be present.
|
||||||
/// If you need this requirement, use <see cref="AddMultiValueFormatter(int, string[], Ryujinx.Ava.Utilities.PlayReport.MultiValueFormatter)"/>.
|
/// If you need this requirement, use <see cref="AddMultiValueFormatter(int, string[], MultiValueFormatter)"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="priority">The resolution priority of this value formatter. Higher resolves sooner.</param>
|
/// <param name="priority">The resolution priority of this value formatter. Higher resolves sooner.</param>
|
||||||
/// <param name="reportKeys">The key names to match.</param>
|
/// <param name="reportKeys">The key names to match.</param>
|
|
@ -3,7 +3,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.PlayReport
|
namespace Ryujinx.Ava.Systems.PlayReport
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The base input data to a ValueFormatter delegate,
|
/// The base input data to a ValueFormatter delegate,
|
74
src/Ryujinx/Systems/Rebooter.cs
Normal file
74
src/Ryujinx/Systems/Rebooter.cs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
using FluentAvalonia.UI.Controls;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using Ryujinx.Ava.Utilities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.Systems
|
||||||
|
{
|
||||||
|
internal static class Rebooter
|
||||||
|
{
|
||||||
|
|
||||||
|
private static readonly string _updateDir = Path.Combine(Path.GetTempPath(), "Ryujinx", "update");
|
||||||
|
|
||||||
|
|
||||||
|
public static void RebootAppWithGame(string gamePath, List<string> args)
|
||||||
|
{
|
||||||
|
_ = Reboot(gamePath, args);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task Reboot(string gamePath, List<string> args)
|
||||||
|
{
|
||||||
|
|
||||||
|
bool shouldRestart = true;
|
||||||
|
|
||||||
|
TaskDialog taskDialog = new()
|
||||||
|
{
|
||||||
|
Header = LocaleManager.Instance[LocaleKeys.RyujinxRebooter],
|
||||||
|
SubHeader = LocaleManager.Instance[LocaleKeys.DialogRebooterMessage],
|
||||||
|
IconSource = new SymbolIconSource { Symbol = Symbol.Games },
|
||||||
|
XamlRoot = RyujinxApp.MainWindow,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (shouldRestart)
|
||||||
|
{
|
||||||
|
List<string> arguments = CommandLineState.Arguments.ToList();
|
||||||
|
string executableDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
|
||||||
|
var dialogTask = taskDialog.ShowAsync(true);
|
||||||
|
await Task.Delay(500);
|
||||||
|
|
||||||
|
// Find the process name.
|
||||||
|
string ryuName = Path.GetFileName(Environment.ProcessPath) ?? string.Empty;
|
||||||
|
|
||||||
|
// Fallback if the executable could not be found.
|
||||||
|
if (ryuName.Length == 0 || !Path.Exists(Path.Combine(executableDirectory, ryuName)))
|
||||||
|
{
|
||||||
|
ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessStartInfo processStart = new(ryuName)
|
||||||
|
{
|
||||||
|
UseShellExecute = true,
|
||||||
|
WorkingDirectory = executableDirectory,
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var arg in args)
|
||||||
|
{
|
||||||
|
processStart.ArgumentList.Add(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
processStart.ArgumentList.Add(gamePath);
|
||||||
|
|
||||||
|
Process.Start(processStart);
|
||||||
|
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava
|
namespace Ryujinx.Ava.Systems
|
||||||
{
|
{
|
||||||
internal static class Updater
|
internal static class Updater
|
||||||
{
|
{
|
||||||
|
@ -44,16 +44,8 @@ namespace Ryujinx.Ava
|
||||||
|
|
||||||
private static string _buildVer;
|
private static string _buildVer;
|
||||||
|
|
||||||
private static readonly string _platformExt =
|
|
||||||
RunningPlatform.IsMacOS
|
private static readonly string _platformExt = BuildPlatformExtension();
|
||||||
? "macos_universal.app.tar.gz"
|
|
||||||
: RunningPlatform.IsWindows
|
|
||||||
? "win_x64.zip"
|
|
||||||
: RunningPlatform.IsX64Linux
|
|
||||||
? "linux_x64.tar.gz"
|
|
||||||
: RunningPlatform.IsArmLinux
|
|
||||||
? "linux_arm64.tar.gz"
|
|
||||||
: throw new PlatformNotSupportedException();
|
|
||||||
|
|
||||||
private static string _buildUrl;
|
private static string _buildUrl;
|
||||||
private static long _buildSize;
|
private static long _buildSize;
|
||||||
|
@ -780,5 +772,34 @@ namespace Ryujinx.Ava
|
||||||
public static void CleanupUpdate() =>
|
public static void CleanupUpdate() =>
|
||||||
Directory.GetFiles(_homeDir, "*.ryuold", SearchOption.AllDirectories)
|
Directory.GetFiles(_homeDir, "*.ryuold", SearchOption.AllDirectories)
|
||||||
.ForEach(File.Delete);
|
.ForEach(File.Delete);
|
||||||
|
|
||||||
|
private static string BuildPlatformExtension()
|
||||||
|
{
|
||||||
|
if (RunningPlatform.IsMacOS)
|
||||||
|
return "macos_universal.app.tar.gz";
|
||||||
|
|
||||||
|
#pragma warning disable CS8509 // It is exhaustive for any values this can contain.
|
||||||
|
string osPrefix = RunningPlatform.CurrentOS switch
|
||||||
|
{
|
||||||
|
OperatingSystemType.Linux => "linux",
|
||||||
|
OperatingSystemType.Windows => "win"
|
||||||
|
};
|
||||||
|
|
||||||
|
string archSuffix = RunningPlatform.Architecture switch
|
||||||
|
{
|
||||||
|
Architecture.Arm64 => "arm64",
|
||||||
|
Architecture.X64 => "x64",
|
||||||
|
_ => throw new PlatformNotSupportedException($"Unknown architecture {Enum.GetName(RunningPlatform.Architecture)}."),
|
||||||
|
};
|
||||||
|
|
||||||
|
string fileExtension = RunningPlatform.CurrentOS switch
|
||||||
|
#pragma warning restore CS8509
|
||||||
|
{
|
||||||
|
OperatingSystemType.Linux => "tar.gz",
|
||||||
|
OperatingSystemType.Windows => "zip"
|
||||||
|
};
|
||||||
|
|
||||||
|
return $"{osPrefix}_{archSuffix}.{fileExtension}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,7 +7,7 @@ using Ryujinx.Ava.UI.Controls;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using Ryujinx.HLE.HOS.Applets;
|
using Ryujinx.HLE.HOS.Applets;
|
||||||
|
@ -95,7 +95,7 @@ namespace Ryujinx.Ava.UI.Applet
|
||||||
_parent.SettingsWindow =
|
_parent.SettingsWindow =
|
||||||
new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
|
new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
|
||||||
|
|
||||||
await _parent.SettingsWindow.ShowDialog(window);
|
await StyleableAppWindow.ShowAsync(_parent.SettingsWindow, window);
|
||||||
|
|
||||||
_parent.SettingsWindow = null;
|
_parent.SettingsWindow = null;
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,7 @@
|
||||||
<viewModels:ProfileSelectorDialogViewModel />
|
<viewModels:ProfileSelectorDialogViewModel />
|
||||||
</Design.DataContext>
|
</Design.DataContext>
|
||||||
|
|
||||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowDefinitions="*,Auto">
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<Border
|
<Border
|
||||||
CornerRadius="5"
|
CornerRadius="5"
|
||||||
|
|
|
@ -9,17 +9,14 @@ using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
|
using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
|
||||||
using UserProfileSft = Ryujinx.HLE.HOS.Services.Account.Acc.UserProfile;
|
using UserProfileSft = Ryujinx.HLE.HOS.Services.Account.Acc.UserProfile;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Applet
|
namespace Ryujinx.Ava.UI.Applet
|
||||||
{
|
{
|
||||||
public partial class ProfileSelectorDialog : UserControl
|
public partial class ProfileSelectorDialog : RyujinxControl<ProfileSelectorDialogViewModel>
|
||||||
{
|
{
|
||||||
public ProfileSelectorDialogViewModel ViewModel { get; set; }
|
|
||||||
|
|
||||||
public ProfileSelectorDialog(ProfileSelectorDialogViewModel viewModel)
|
public ProfileSelectorDialog(ProfileSelectorDialogViewModel viewModel)
|
||||||
{
|
{
|
||||||
DataContext = ViewModel = viewModel;
|
DataContext = ViewModel = viewModel;
|
||||||
|
|
|
@ -19,6 +19,18 @@
|
||||||
Header="{ext:Locale GameListContextMenuCreateShortcut}"
|
Header="{ext:Locale GameListContextMenuCreateShortcut}"
|
||||||
Icon="{ext:Icon fa-solid fa-bookmark}"
|
Icon="{ext:Icon fa-solid fa-bookmark}"
|
||||||
ToolTip.Tip="{OnPlatform Default={ext:Locale GameListContextMenuCreateShortcutToolTip}, macOS={ext:Locale GameListContextMenuCreateShortcutToolTipMacOS}}" />
|
ToolTip.Tip="{OnPlatform Default={ext:Locale GameListContextMenuCreateShortcutToolTip}, macOS={ext:Locale GameListContextMenuCreateShortcutToolTipMacOS}}" />
|
||||||
|
<MenuItem
|
||||||
|
Click="EditGameConfiguration_Click"
|
||||||
|
IsVisible="{Binding SelectedApplication.HasIndependentConfiguration}"
|
||||||
|
Header="{ext:Locale GameListContextMenuEditCustomConfiguration}"
|
||||||
|
Icon="{ext:Icon fa-solid fa-gear}"
|
||||||
|
ToolTip.Tip="{ext:Locale EditCustomConfigurationToolTip}" />
|
||||||
|
<MenuItem
|
||||||
|
Click="EditGameConfiguration_Click"
|
||||||
|
IsVisible="{Binding !SelectedApplication.HasIndependentConfiguration}"
|
||||||
|
Header="{ext:Locale GameListContextMenuCreateCustomConfiguration}"
|
||||||
|
Icon="{ext:Icon fa-solid fa-gear}"
|
||||||
|
ToolTip.Tip="{ext:Locale CreateCustomConfigurationToolTip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
IsVisible="{Binding HasCompatibilityEntry}"
|
IsVisible="{Binding HasCompatibilityEntry}"
|
||||||
Click="OpenApplicationCompatibility_Click"
|
Click="OpenApplicationCompatibility_Click"
|
||||||
|
|
|
@ -11,8 +11,8 @@ using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using Ryujinx.Ava.Utilities.Compat;
|
using Ryujinx.Ava.UI.Views.Dialog;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
|
@ -26,6 +26,7 @@ namespace Ryujinx.Ava.UI.Controls
|
||||||
{
|
{
|
||||||
public class ApplicationContextMenu : MenuFlyout
|
public class ApplicationContextMenu : MenuFlyout
|
||||||
{
|
{
|
||||||
|
|
||||||
public ApplicationContextMenu()
|
public ApplicationContextMenu()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -79,23 +80,26 @@ namespace Ryujinx.Ava.UI.Controls
|
||||||
public async void OpenTitleUpdateManager_Click(object sender, RoutedEventArgs args)
|
public async void OpenTitleUpdateManager_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
await TitleUpdateWindow.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication);
|
await TitleUpdateManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void OpenDownloadableContentManager_Click(object sender, RoutedEventArgs args)
|
public async void OpenDownloadableContentManager_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
await DownloadableContentManagerWindow.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication);
|
await DownloadableContentManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void OpenCheatManager_Click(object sender, RoutedEventArgs args)
|
public async void OpenCheatManager_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
await new CheatWindow(
|
await StyleableAppWindow.ShowAsync(
|
||||||
|
new CheatWindow(
|
||||||
viewModel.VirtualFileSystem,
|
viewModel.VirtualFileSystem,
|
||||||
viewModel.SelectedApplication.IdString,
|
viewModel.SelectedApplication.IdString,
|
||||||
viewModel.SelectedApplication.Name,
|
viewModel.SelectedApplication.Name,
|
||||||
viewModel.SelectedApplication.Path).ShowDialog((Window)viewModel.TopLevel);
|
viewModel.SelectedApplication.Path
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenModsDirectory_Click(object sender, RoutedEventArgs args)
|
public void OpenModsDirectory_Click(object sender, RoutedEventArgs args)
|
||||||
|
@ -123,7 +127,7 @@ namespace Ryujinx.Ava.UI.Controls
|
||||||
public async void OpenModManager_Click(object sender, RoutedEventArgs args)
|
public async void OpenModManager_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
await ModManagerWindow.Show(
|
await ModManagerView.Show(
|
||||||
viewModel.SelectedApplication.Id,
|
viewModel.SelectedApplication.Id,
|
||||||
viewModel.SelectedApplication.IdBase,
|
viewModel.SelectedApplication.IdBase,
|
||||||
viewModel.ApplicationLibrary,
|
viewModel.ApplicationLibrary,
|
||||||
|
@ -387,10 +391,23 @@ namespace Ryujinx.Ava.UI.Controls
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async void EditGameConfiguration_Click(object sender, RoutedEventArgs args)
|
||||||
|
{
|
||||||
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
|
{
|
||||||
|
await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(viewModel));
|
||||||
|
|
||||||
|
// just checking for file presence
|
||||||
|
viewModel.SelectedApplication.HasIndependentConfiguration = File.Exists(Program.GetDirGameUserConfig(viewModel.SelectedApplication.IdString,false,false));
|
||||||
|
|
||||||
|
viewModel.RefreshView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async void OpenApplicationCompatibility_Click(object sender, RoutedEventArgs args)
|
public async void OpenApplicationCompatibility_Click(object sender, RoutedEventArgs args)
|
||||||
{
|
{
|
||||||
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
|
||||||
await CompatibilityList.Show(viewModel.SelectedApplication.IdString);
|
await CompatibilityListWindow.Show(viewModel.SelectedApplication.IdString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void OpenApplicationData_Click(object sender, RoutedEventArgs args)
|
public async void OpenApplicationData_Click(object sender, RoutedEventArgs args)
|
||||||
|
|
|
@ -23,13 +23,12 @@ using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Controls
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
{
|
{
|
||||||
public partial class NavigationDialogHost : UserControl
|
public partial class NavigationDialogHost : RyujinxControl<UserProfileViewModel>
|
||||||
{
|
{
|
||||||
public AccountManager AccountManager { get; }
|
public AccountManager AccountManager { get; }
|
||||||
public ContentManager ContentManager { get; }
|
public ContentManager ContentManager { get; }
|
||||||
public VirtualFileSystem VirtualFileSystem { get; }
|
public VirtualFileSystem VirtualFileSystem { get; }
|
||||||
public HorizonClient HorizonClient { get; }
|
public HorizonClient HorizonClient { get; }
|
||||||
public UserProfileViewModel ViewModel { get; set; }
|
|
||||||
|
|
||||||
public NavigationDialogHost()
|
public NavigationDialogHost()
|
||||||
{
|
{
|
||||||
|
|
24
src/Ryujinx/UI/Controls/RyujinxControl.cs
Normal file
24
src/Ryujinx/UI/Controls/RyujinxControl.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
|
{
|
||||||
|
public class RyujinxControl<TViewModel> : UserControl where TViewModel : BaseModel
|
||||||
|
{
|
||||||
|
public TViewModel ViewModel
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (DataContext is not TViewModel viewModel)
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
$"Underlying DataContext is not of type {typeof(TViewModel).AsPrettyString()}; " +
|
||||||
|
$"Actual type is {DataContext?.GetType().AsPrettyString()}");
|
||||||
|
|
||||||
|
return viewModel;
|
||||||
|
}
|
||||||
|
set => DataContext = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
src/Ryujinx/UI/Controls/RyujinxLogo.cs
Normal file
28
src/Ryujinx/UI/Controls/RyujinxLogo.cs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Media.Imaging;
|
||||||
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
|
{
|
||||||
|
public class RyujinxLogo : Image
|
||||||
|
{
|
||||||
|
// The UI specifically uses a thicker bordered variant of the icon to avoid crunching out the border at lower resolutions.
|
||||||
|
// For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left.
|
||||||
|
// The border gets reduced to colored pixels in the 4 corners.
|
||||||
|
public static readonly Bitmap Bitmap =
|
||||||
|
new(Assembly.GetAssembly(typeof(MainWindowViewModel))!
|
||||||
|
.GetManifestResourceStream("Ryujinx.Assets.UIImages.Logo_Ryujinx_AntiAlias.png")!);
|
||||||
|
|
||||||
|
public RyujinxLogo()
|
||||||
|
{
|
||||||
|
Margin = new Thickness(7, 7, 7, 0);
|
||||||
|
Height = 25;
|
||||||
|
Width = 25;
|
||||||
|
Source = Bitmap;
|
||||||
|
IsVisible = !ConfigurationState.Instance.ShowOldUI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
|
using Avalonia.Input;
|
||||||
using Avalonia.Layout;
|
using Avalonia.Layout;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
using Avalonia.Styling;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using FluentAvalonia.Core;
|
using FluentAvalonia.Core;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
|
@ -20,6 +22,23 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
private static bool _isChoiceDialogOpen;
|
private static bool _isChoiceDialogOpen;
|
||||||
private static ContentDialogOverlayWindow _contentDialogOverlayWindow;
|
private static ContentDialogOverlayWindow _contentDialogOverlayWindow;
|
||||||
|
|
||||||
|
public static ContentDialog ApplyStyles(
|
||||||
|
this ContentDialog contentDialog,
|
||||||
|
double closeButtonWidth = 80,
|
||||||
|
HorizontalAlignment buttonSpaceAlignment = HorizontalAlignment.Right)
|
||||||
|
{
|
||||||
|
Style closeButton = new(x => x.Name("CloseButton"));
|
||||||
|
closeButton.Setters.Add(new Setter(Layoutable.WidthProperty, closeButtonWidth));
|
||||||
|
|
||||||
|
Style closeButtonParent = new(x => x.Name("CommandSpace"));
|
||||||
|
closeButtonParent.Setters.Add(new Setter(Layoutable.HorizontalAlignmentProperty, buttonSpaceAlignment));
|
||||||
|
|
||||||
|
contentDialog.Styles.Add(closeButton);
|
||||||
|
contentDialog.Styles.Add(closeButtonParent);
|
||||||
|
|
||||||
|
return contentDialog;
|
||||||
|
}
|
||||||
|
|
||||||
private async static Task<UserResult> ShowContentDialog(
|
private async static Task<UserResult> ShowContentDialog(
|
||||||
string title,
|
string title,
|
||||||
object content,
|
object content,
|
||||||
|
@ -39,19 +58,19 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
SecondaryButtonText = secondaryButton,
|
SecondaryButtonText = secondaryButton,
|
||||||
CloseButtonText = closeButton,
|
CloseButtonText = closeButton,
|
||||||
Content = content,
|
Content = content,
|
||||||
PrimaryButtonCommand = MiniCommand.Create(() =>
|
PrimaryButtonCommand = Commands.Create(() =>
|
||||||
{
|
{
|
||||||
result = primaryButtonResult;
|
result = primaryButtonResult;
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
|
contentDialog.SecondaryButtonCommand = Commands.Create(() =>
|
||||||
{
|
{
|
||||||
result = UserResult.No;
|
result = UserResult.No;
|
||||||
contentDialog.PrimaryButtonClick -= deferCloseAction;
|
contentDialog.PrimaryButtonClick -= deferCloseAction;
|
||||||
});
|
});
|
||||||
|
|
||||||
contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
|
contentDialog.CloseButtonCommand = Commands.Create(() =>
|
||||||
{
|
{
|
||||||
result = UserResult.Cancel;
|
result = UserResult.Cancel;
|
||||||
contentDialog.PrimaryButtonClick -= deferCloseAction;
|
contentDialog.PrimaryButtonClick -= deferCloseAction;
|
||||||
|
@ -385,6 +404,10 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
ShowInTaskbar = false,
|
ShowInTaskbar = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
_contentDialogOverlayWindow.AttachDevTools(new KeyGesture(Key.F12, KeyModifiers.Control));
|
||||||
|
#endif
|
||||||
|
|
||||||
parent.PositionChanged += OverlayOnPositionChanged;
|
parent.PositionChanged += OverlayOnPositionChanged;
|
||||||
|
|
||||||
void OverlayOnPositionChanged(object sender, PixelPointEventArgs e)
|
void OverlayOnPositionChanged(object sender, PixelPointEventArgs e)
|
||||||
|
|
|
@ -2,7 +2,7 @@ using Avalonia.Data.Converters;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
|
@ -2,9 +2,9 @@ using SkiaSharp;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Windows
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
{
|
{
|
||||||
static class IconColorPicker
|
public static class IconColorPicker
|
||||||
{
|
{
|
||||||
private const int ColorsPerLine = 64;
|
private const int ColorsPerLine = 64;
|
||||||
private const int TotalColors = ColorsPerLine * ColorsPerLine;
|
private const int TotalColors = ColorsPerLine * ColorsPerLine;
|
|
@ -1,7 +1,7 @@
|
||||||
using Avalonia.Logging;
|
using Avalonia.Logging;
|
||||||
using Avalonia.Utilities;
|
using Avalonia.Utilities;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Input;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
|
||||||
{
|
|
||||||
public sealed class MiniCommand<T> : MiniCommand, ICommand
|
|
||||||
{
|
|
||||||
private readonly Action<T> _callback;
|
|
||||||
private bool _busy;
|
|
||||||
private readonly Func<T, Task> _asyncCallback;
|
|
||||||
|
|
||||||
public MiniCommand(Action<T> callback)
|
|
||||||
{
|
|
||||||
_callback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MiniCommand(Func<T, Task> callback)
|
|
||||||
{
|
|
||||||
_asyncCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool Busy
|
|
||||||
{
|
|
||||||
get => _busy;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_busy = value;
|
|
||||||
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override event EventHandler CanExecuteChanged;
|
|
||||||
public override bool CanExecute(object parameter) => !_busy;
|
|
||||||
|
|
||||||
public override async void Execute(object parameter)
|
|
||||||
{
|
|
||||||
if (Busy)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Busy = true;
|
|
||||||
if (_callback != null)
|
|
||||||
{
|
|
||||||
_callback((T)parameter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await _asyncCallback((T)parameter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
Busy = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class MiniCommand : ICommand
|
|
||||||
{
|
|
||||||
public static MiniCommand Create(Action callback) => new MiniCommand<object>(_ => callback());
|
|
||||||
public static MiniCommand Create<TArg>(Action<TArg> callback) => new MiniCommand<TArg>(callback);
|
|
||||||
public static MiniCommand CreateFromTask(Func<Task> callback) => new MiniCommand<object>(_ => callback());
|
|
||||||
public static MiniCommand CreateFromTask<TArg>(Func<TArg, Task> callback) => new MiniCommand<TArg>(callback);
|
|
||||||
|
|
||||||
public abstract bool CanExecute(object parameter);
|
|
||||||
public abstract void Execute(object parameter);
|
|
||||||
public abstract event EventHandler CanExecuteChanged;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
260
src/Ryujinx/UI/Models/Input/StickVisualizer.cs
Normal file
260
src/Ryujinx/UI/Models/Input/StickVisualizer.cs
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||||
|
using Ryujinx.Input;
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Models.Input
|
||||||
|
{
|
||||||
|
public class StickVisualizer : BaseModel, IDisposable
|
||||||
|
{
|
||||||
|
public const int DrawStickPollRate = 50; // Milliseconds per poll.
|
||||||
|
public const int DrawStickCircumference = 5;
|
||||||
|
public const float DrawStickScaleFactor = DrawStickCanvasCenter;
|
||||||
|
public const int DrawStickCanvasSize = 100;
|
||||||
|
public const int DrawStickBorderSize = DrawStickCanvasSize + 5;
|
||||||
|
public const float DrawStickCanvasCenter = (DrawStickCanvasSize - DrawStickCircumference) / 2;
|
||||||
|
public const float MaxVectorLength = DrawStickCanvasSize / 2;
|
||||||
|
|
||||||
|
public CancellationTokenSource PollTokenSource;
|
||||||
|
public CancellationToken PollToken;
|
||||||
|
|
||||||
|
private static float _vectorLength;
|
||||||
|
private static float _vectorMultiplier;
|
||||||
|
|
||||||
|
private bool disposedValue;
|
||||||
|
|
||||||
|
private DeviceType _type;
|
||||||
|
public DeviceType Type
|
||||||
|
{
|
||||||
|
get => _type;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_type = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private GamepadInputConfig _gamepadConfig;
|
||||||
|
public GamepadInputConfig GamepadConfig
|
||||||
|
{
|
||||||
|
get => _gamepadConfig;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_gamepadConfig = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyboardInputConfig _keyboardConfig;
|
||||||
|
public KeyboardInputConfig KeyboardConfig
|
||||||
|
{
|
||||||
|
get => _keyboardConfig;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_keyboardConfig = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private (float, float) _uiStickLeft;
|
||||||
|
public (float, float) UiStickLeft
|
||||||
|
{
|
||||||
|
get => (_uiStickLeft.Item1 * DrawStickScaleFactor, _uiStickLeft.Item2 * DrawStickScaleFactor);
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_uiStickLeft = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
OnPropertyChanged(nameof(UiStickRightX));
|
||||||
|
OnPropertyChanged(nameof(UiStickRightY));
|
||||||
|
OnPropertyChanged(nameof(UiDeadzoneRight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private (float, float) _uiStickRight;
|
||||||
|
public (float, float) UiStickRight
|
||||||
|
{
|
||||||
|
get => (_uiStickRight.Item1 * DrawStickScaleFactor, _uiStickRight.Item2 * DrawStickScaleFactor);
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_uiStickRight = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
OnPropertyChanged(nameof(UiStickLeftX));
|
||||||
|
OnPropertyChanged(nameof(UiStickLeftY));
|
||||||
|
OnPropertyChanged(nameof(UiDeadzoneLeft));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float UiStickLeftX => ClampVector(UiStickLeft).Item1;
|
||||||
|
public float UiStickLeftY => ClampVector(UiStickLeft).Item2;
|
||||||
|
public float UiStickRightX => ClampVector(UiStickRight).Item1;
|
||||||
|
public float UiStickRightY => ClampVector(UiStickRight).Item2;
|
||||||
|
|
||||||
|
public int UiStickCircumference => DrawStickCircumference;
|
||||||
|
public int UiCanvasSize => DrawStickCanvasSize;
|
||||||
|
public int UiStickBorderSize => DrawStickBorderSize;
|
||||||
|
|
||||||
|
public float? UiDeadzoneLeft => _gamepadConfig?.DeadzoneLeft * DrawStickCanvasSize - DrawStickCircumference;
|
||||||
|
public float? UiDeadzoneRight => _gamepadConfig?.DeadzoneRight * DrawStickCanvasSize - DrawStickCircumference;
|
||||||
|
|
||||||
|
private InputViewModel Parent;
|
||||||
|
|
||||||
|
public StickVisualizer(InputViewModel parent)
|
||||||
|
{
|
||||||
|
Parent = parent;
|
||||||
|
|
||||||
|
PollTokenSource = new CancellationTokenSource();
|
||||||
|
PollToken = PollTokenSource.Token;
|
||||||
|
|
||||||
|
Task.Run(Initialize, PollToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateConfig(object config)
|
||||||
|
{
|
||||||
|
if (config is ControllerInputViewModel padConfig)
|
||||||
|
{
|
||||||
|
GamepadConfig = padConfig.Config;
|
||||||
|
Type = DeviceType.Controller;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (config is KeyboardInputViewModel keyConfig)
|
||||||
|
{
|
||||||
|
KeyboardConfig = keyConfig.Config;
|
||||||
|
Type = DeviceType.Keyboard;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type = DeviceType.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Initialize()
|
||||||
|
{
|
||||||
|
(float, float) leftBuffer;
|
||||||
|
(float, float) rightBuffer;
|
||||||
|
|
||||||
|
while (!PollToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
leftBuffer = (0f, 0f);
|
||||||
|
rightBuffer = (0f, 0f);
|
||||||
|
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case DeviceType.Keyboard:
|
||||||
|
IKeyboard keyboard = (IKeyboard)Parent.AvaloniaKeyboardDriver.GetGamepad("0");
|
||||||
|
|
||||||
|
if (keyboard != null)
|
||||||
|
{
|
||||||
|
KeyboardStateSnapshot snapshot = keyboard.GetKeyboardStateSnapshot();
|
||||||
|
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickRight))
|
||||||
|
{
|
||||||
|
leftBuffer.Item1 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickLeft))
|
||||||
|
{
|
||||||
|
leftBuffer.Item1 -= 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickUp))
|
||||||
|
{
|
||||||
|
leftBuffer.Item2 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.LeftStickDown))
|
||||||
|
{
|
||||||
|
leftBuffer.Item2 -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickRight))
|
||||||
|
{
|
||||||
|
rightBuffer.Item1 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickLeft))
|
||||||
|
{
|
||||||
|
rightBuffer.Item1 -= 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickUp))
|
||||||
|
{
|
||||||
|
rightBuffer.Item2 += 1;
|
||||||
|
}
|
||||||
|
if (snapshot.IsPressed((Key)KeyboardConfig.RightStickDown))
|
||||||
|
{
|
||||||
|
rightBuffer.Item2 -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UiStickLeft = leftBuffer;
|
||||||
|
UiStickRight = rightBuffer;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceType.Controller:
|
||||||
|
IGamepad controller = Parent.SelectedGamepad;
|
||||||
|
|
||||||
|
if (controller != null)
|
||||||
|
{
|
||||||
|
leftBuffer = controller.GetStick((StickInputId)GamepadConfig.LeftJoystick);
|
||||||
|
rightBuffer = controller.GetStick((StickInputId)GamepadConfig.RightJoystick);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceType.None:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Unable to poll device type \"{Type}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
UiStickLeft = leftBuffer;
|
||||||
|
UiStickRight = rightBuffer;
|
||||||
|
|
||||||
|
await Task.Delay(DrawStickPollRate, PollToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
PollTokenSource.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (float, float) ClampVector((float, float) vect)
|
||||||
|
{
|
||||||
|
_vectorMultiplier = 1;
|
||||||
|
_vectorLength = MathF.Sqrt((vect.Item1 * vect.Item1) + (vect.Item2 * vect.Item2));
|
||||||
|
|
||||||
|
if (_vectorLength > MaxVectorLength)
|
||||||
|
{
|
||||||
|
_vectorMultiplier = MaxVectorLength / _vectorLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
vect.Item1 = vect.Item1 * _vectorMultiplier + DrawStickCanvasCenter;
|
||||||
|
vect.Item2 = vect.Item2 * _vectorMultiplier + DrawStickCanvasCenter;
|
||||||
|
|
||||||
|
return vect;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposedValue)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
PollTokenSource.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardConfig = null;
|
||||||
|
GamepadConfig = null;
|
||||||
|
Parent = null;
|
||||||
|
|
||||||
|
disposedValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(disposing: true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ using LibHac.Fs;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using SPB.Graphics;
|
using SPB.Graphics;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Renderer
|
namespace Ryujinx.Ava.UI.Renderer
|
||||||
|
@ -39,32 +37,6 @@ namespace Ryujinx.Ava.UI.Renderer
|
||||||
_ => throw new NotImplementedException()
|
_ => throw new NotImplementedException()
|
||||||
};
|
};
|
||||||
|
|
||||||
public RendererHost(string titleId)
|
|
||||||
{
|
|
||||||
Focusable = true;
|
|
||||||
FlowDirection = FlowDirection.LeftToRight;
|
|
||||||
|
|
||||||
EmbeddedWindow =
|
|
||||||
#pragma warning disable CS8524
|
|
||||||
ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch
|
|
||||||
#pragma warning restore CS8524
|
|
||||||
{
|
|
||||||
GraphicsBackend.OpenGl => new EmbeddedWindowOpenGL(),
|
|
||||||
GraphicsBackend.Vulkan => new EmbeddedWindowVulkan(),
|
|
||||||
};
|
|
||||||
|
|
||||||
string backendText = EmbeddedWindow switch
|
|
||||||
{
|
|
||||||
EmbeddedWindowVulkan => "Vulkan",
|
|
||||||
EmbeddedWindowOpenGL => "OpenGL",
|
|
||||||
_ => throw new NotImplementedException()
|
|
||||||
};
|
|
||||||
|
|
||||||
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend ({ConfigurationState.Instance.Graphics.GraphicsBackend.Value}): {backendText}");
|
|
||||||
|
|
||||||
Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,4 +17,9 @@
|
||||||
<sty:FluentAvaloniaTheme PreferUserAccentColor="True" PreferSystemTheme="False" />
|
<sty:FluentAvaloniaTheme PreferUserAccentColor="True" PreferSystemTheme="False" />
|
||||||
<StyleInclude Source="/Assets/Styles/Styles.xaml" />
|
<StyleInclude Source="/Assets/Styles/Styles.xaml" />
|
||||||
</Application.Styles>
|
</Application.Styles>
|
||||||
|
<NativeMenu.Menu>
|
||||||
|
<NativeMenu>
|
||||||
|
<NativeMenuItem Header="About Ryujinx" Click="AboutRyujinx_OnClick" />
|
||||||
|
</NativeMenu>
|
||||||
|
</NativeMenu.Menu>
|
||||||
</Application>
|
</Application>
|
|
@ -7,12 +7,12 @@ using Avalonia.Styling;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using FluentAvalonia.UI.Windowing;
|
using FluentAvalonia.UI.Windowing;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common;
|
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
|
using Ryujinx.Ava.UI.Views.Dialog;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
|
@ -147,5 +147,10 @@ namespace Ryujinx.Ava
|
||||||
Current is RyujinxApp { PlatformSettings: not null } app
|
Current is RyujinxApp { PlatformSettings: not null } app
|
||||||
? ConvertThemeVariant(app.PlatformSettings.GetColorValues().ThemeVariant)
|
? ConvertThemeVariant(app.PlatformSettings.GetColorValues().ThemeVariant)
|
||||||
: ThemeVariant.Default;
|
: ThemeVariant.Default;
|
||||||
|
|
||||||
|
private async void AboutRyujinx_OnClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
await AboutView.Show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,9 +3,8 @@ using Avalonia.Styling;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common;
|
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
|
@ -432,7 +432,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://raw.githubusercontent.com/Ryubing/Ryujinx/refs/heads/master/assets/amiibo/Amiibo.json"));
|
HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://raw.githubusercontent.com/Ryubing/Nfc/refs/heads/main/tags.json"));
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
|
@ -451,7 +451,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HttpResponseMessage response = await _httpClient.GetAsync($"https://raw.githubusercontent.com/Ryubing/Ryujinx/refs/heads/master/assets/amiibo/Amiibo.json");
|
HttpResponseMessage response = await _httpClient.GetAsync("https://raw.githubusercontent.com/Ryubing/Nfc/refs/heads/main/tags.json");
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using Ryujinx.Ava.Utilities.PlayReport;
|
using Ryujinx.Ava.Systems.PlayReport;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.Systems;
|
||||||
using Ryujinx.Ava.Utilities.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Compat
|
namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
public class CompatibilityViewModel : BaseModel
|
public class CompatibilityViewModel : BaseModel, IDisposable
|
||||||
{
|
{
|
||||||
private bool _onlyShowOwnedGames = true;
|
private readonly ApplicationLibrary _appLibrary;
|
||||||
|
|
||||||
private IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityCsv.Entries;
|
private IEnumerable<CompatibilityEntry> _currentEntries = CompatibilityDatabase.Entries;
|
||||||
private string[] _ownedGameTitleIds = [];
|
private string[] _ownedGameTitleIds = [];
|
||||||
|
|
||||||
public IEnumerable<CompatibilityEntry> CurrentEntries => OnlyShowOwnedGames
|
public IEnumerable<CompatibilityEntry> CurrentEntries => OnlyShowOwnedGames
|
||||||
|
@ -20,14 +21,26 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||||
|
|
||||||
public CompatibilityViewModel() {}
|
public CompatibilityViewModel() {}
|
||||||
|
|
||||||
|
private void AppCountUpdated(object _, ApplicationCountUpdatedEventArgs __)
|
||||||
|
=> _ownedGameTitleIds = _appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray();
|
||||||
|
|
||||||
public CompatibilityViewModel(ApplicationLibrary appLibrary)
|
public CompatibilityViewModel(ApplicationLibrary appLibrary)
|
||||||
{
|
{
|
||||||
appLibrary.ApplicationCountUpdated += (_, _)
|
_appLibrary = appLibrary;
|
||||||
=> _ownedGameTitleIds = appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray();
|
|
||||||
|
|
||||||
_ownedGameTitleIds = appLibrary.Applications.Keys.Select(x => x.ToString("X16")).ToArray();
|
AppCountUpdated(null, null);
|
||||||
|
|
||||||
|
_appLibrary.ApplicationCountUpdated += AppCountUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IDisposable.Dispose()
|
||||||
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
_appLibrary.ApplicationCountUpdated -= AppCountUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _onlyShowOwnedGames = true;
|
||||||
|
|
||||||
public bool OnlyShowOwnedGames
|
public bool OnlyShowOwnedGames
|
||||||
{
|
{
|
||||||
get => _onlyShowOwnedGames;
|
get => _onlyShowOwnedGames;
|
||||||
|
@ -45,11 +58,11 @@ namespace Ryujinx.Ava.Utilities.Compat
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(searchTerm))
|
if (string.IsNullOrEmpty(searchTerm))
|
||||||
{
|
{
|
||||||
SetEntries(CompatibilityCsv.Entries);
|
SetEntries(CompatibilityDatabase.Entries);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEntries(CompatibilityCsv.Entries.Where(x =>
|
SetEntries(CompatibilityDatabase.Entries.Where(x =>
|
||||||
x.GameName.ContainsIgnoreCase(searchTerm)
|
x.GameName.ContainsIgnoreCase(searchTerm)
|
||||||
|| x.TitleId.Check(tid => tid.ContainsIgnoreCase(searchTerm))));
|
|| x.TitleId.Check(tid => tid.ContainsIgnoreCase(searchTerm))));
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue