Compare commits
34 Commits
Canary-1.2
...
Canary-1.2
Author | SHA1 | Date | |
---|---|---|---|
d10a478cce | |||
ec1020b165 | |||
4082ebad1a | |||
da8ea06074 | |||
7f9dccb293 | |||
8e4a77aba0 | |||
8fd8a776c9 | |||
eec92c242c | |||
42a739d34c | |||
f362bef43d | |||
f5ce539de9 | |||
4f699afe7a | |||
6caab1aa37 | |||
9baaa2b8f8 | |||
7f376b4f45 | |||
32cdccde12 | |||
cbd851d00e | |||
f463ea1c5d | |||
1dd69912b1 | |||
1fbb0d8e7d | |||
9ee3f1ff36 | |||
d052d74ac4 | |||
df91c4c57a | |||
2aaaa7872f | |||
b5999583d6 | |||
8b3a945b5f | |||
09107b67ff | |||
12b264af44 | |||
0c21b07f19 | |||
18625cf775 | |||
77a9246825 | |||
709eeda94a | |||
7d54424048 | |||
664c63c6a8 |
23
.github/workflows/build.yml
vendored
@ -64,14 +64,9 @@ jobs:
|
|||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
||||||
|
|
||||||
- name: Publish Ryujinx.Headless.SDL2
|
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained
|
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
|
||||||
|
|
||||||
- name: Set executable bit
|
- name: Set executable bit
|
||||||
run: |
|
run: |
|
||||||
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
||||||
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
|
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
|
||||||
|
|
||||||
- name: Build AppImage
|
- name: Build AppImage
|
||||||
@ -119,13 +114,6 @@ jobs:
|
|||||||
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}-AppImage
|
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}-AppImage
|
||||||
path: publish_appimage
|
path: publish_appimage
|
||||||
|
|
||||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: nogui-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
|
|
||||||
path: publish_sdl2_headless
|
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
|
||||||
|
|
||||||
build_macos:
|
build_macos:
|
||||||
name: macOS Universal (${{ matrix.configuration }})
|
name: macOS Universal (${{ matrix.configuration }})
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -171,20 +159,9 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp publish ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp publish ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
||||||
|
|
||||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
|
||||||
run: |
|
|
||||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
|
||||||
|
|
||||||
- name: Upload Ryujinx artifact
|
- name: Upload Ryujinx artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
||||||
path: "publish/*.tar.gz"
|
path: "publish/*.tar.gz"
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
|
|
||||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: nogui-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
|
||||||
path: "publish_headless/*.tar.gz"
|
|
||||||
if: github.event_name == 'pull_request'
|
|
||||||
|
20
.github/workflows/canary.yml
vendored
@ -116,7 +116,6 @@ jobs:
|
|||||||
- name: Publish
|
- name: Publish
|
||||||
run: |
|
run: |
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained
|
|
||||||
|
|
||||||
- name: Packing Windows builds
|
- name: Packing Windows builds
|
||||||
if: matrix.platform.os == 'windows-latest'
|
if: matrix.platform.os == 'windows-latest'
|
||||||
@ -125,11 +124,6 @@ jobs:
|
|||||||
rm publish/libarmeilleure-jitsupport.dylib
|
rm publish/libarmeilleure-jitsupport.dylib
|
||||||
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
|
||||||
rm publish/libarmeilleure-jitsupport.dylib
|
|
||||||
7z a ../release_output/nogui-ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
|
||||||
popd
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Packing Linux builds
|
- name: Packing Linux builds
|
||||||
@ -140,12 +134,6 @@ jobs:
|
|||||||
chmod +x publish/Ryujinx.sh publish/Ryujinx
|
chmod +x publish/Ryujinx.sh publish/Ryujinx
|
||||||
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
|
||||||
rm publish/libarmeilleure-jitsupport.dylib
|
|
||||||
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
|
|
||||||
tar -czvf ../release_output/nogui-ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
|
||||||
popd
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
#- name: Build AppImage (Linux)
|
#- name: Build AppImage (Linux)
|
||||||
@ -191,7 +179,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
artifacts: "release_output/*.tar.gz,release_output/*.zip"
|
artifacts: "release_output/*.tar.gz,release_output/*.zip"
|
||||||
#artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*"
|
#artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: |
|
body: |
|
||||||
# Canary builds:
|
# Canary builds:
|
||||||
@ -262,15 +250,11 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
||||||
|
|
||||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
|
||||||
run: |
|
|
||||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Pushing new release
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
name: "Canary ${{ steps.version_info.outputs.build_version }}"
|
name: "Canary ${{ steps.version_info.outputs.build_version }}"
|
||||||
artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
|
artifacts: "publish_ava/*.tar.gz"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: ""
|
body: ""
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
|
10
.github/workflows/nightly_pr_comment.yml
vendored
@ -38,20 +38,16 @@ jobs:
|
|||||||
return core.error(`No artifacts found`);
|
return core.error(`No artifacts found`);
|
||||||
}
|
}
|
||||||
let body = `Download the artifacts for this pull request:\n`;
|
let body = `Download the artifacts for this pull request:\n`;
|
||||||
let hidden_headless_artifacts = `\n\n <details><summary>GUI-less</summary>\n`;
|
|
||||||
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
||||||
for (const art of artifacts) {
|
for (const art of artifacts) {
|
||||||
|
const url = `https://github.com/Ryubing/Ryujinx/actions/runs/${run_id}/artifacts/${art.id}`;
|
||||||
if(art.name.includes('Debug')) {
|
if(art.name.includes('Debug')) {
|
||||||
hidden_debug_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
hidden_debug_artifacts += `\n* [${art.name}](${url})`;
|
||||||
} else if(art.name.includes('nogui-ryujinx')) {
|
|
||||||
hidden_headless_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
|
||||||
} else {
|
} else {
|
||||||
body += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
body += `\n* [${art.name}](${url})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hidden_headless_artifacts += `\n</details>`;
|
|
||||||
hidden_debug_artifacts += `\n</details>`;
|
hidden_debug_artifacts += `\n</details>`;
|
||||||
body += hidden_headless_artifacts;
|
|
||||||
body += hidden_debug_artifacts;
|
body += hidden_debug_artifacts;
|
||||||
|
|
||||||
const {data: comments} = await github.rest.issues.listComments({repo, owner, issue_number});
|
const {data: comments} = await github.rest.issues.listComments({repo, owner, issue_number});
|
||||||
|
17
.github/workflows/release.yml
vendored
@ -112,7 +112,6 @@ jobs:
|
|||||||
- name: Publish
|
- name: Publish
|
||||||
run: |
|
run: |
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained
|
|
||||||
|
|
||||||
- name: Packing Windows builds
|
- name: Packing Windows builds
|
||||||
if: matrix.platform.os == 'windows-latest'
|
if: matrix.platform.os == 'windows-latest'
|
||||||
@ -121,11 +120,6 @@ jobs:
|
|||||||
rm libarmeilleure-jitsupport.dylib
|
rm libarmeilleure-jitsupport.dylib
|
||||||
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
|
||||||
rm libarmeilleure-jitsupport.dylib
|
|
||||||
7z a ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
|
||||||
popd
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Build AppImage (Linux)
|
- name: Build AppImage (Linux)
|
||||||
@ -172,11 +166,6 @@ jobs:
|
|||||||
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
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
|
||||||
chmod +x Ryujinx.sh Ryujinx.Headless.SDL2
|
|
||||||
tar -czvf ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
|
||||||
popd
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Pushing new release
|
||||||
@ -251,15 +240,11 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
||||||
|
|
||||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
|
||||||
run: |
|
|
||||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Pushing new release
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
artifacts: "publish/*.tar.gz, publish_headless/*.tar.gz"
|
artifacts: "publish/*.tar.gz"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: ""
|
body: ""
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
<PackageVersion Include="Gommon" Version="2.6.8" />
|
<PackageVersion Include="Gommon" Version="2.6.8" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
<PackageVersion Include="SharpMetal" Version="1.0.0-preview20" />
|
<PackageVersion Include="SharpMetal" Version="1.0.0-preview21" />
|
||||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.21.0" />
|
<PackageVersion Include="Silk.NET.Vulkan" Version="2.21.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.21.0" />
|
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.21.0" />
|
||||||
|
12
Ryujinx.sln
@ -57,14 +57,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "src\
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Headless.SDL2", "src\Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}"
|
||||||
@ -213,10 +209,6 @@ Global
|
|||||||
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@ -225,10 +217,6 @@ Global
|
|||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
@ -13,7 +13,7 @@ mkdir -p AppDir/usr/bin
|
|||||||
|
|
||||||
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
|
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
|
||||||
cp distribution/linux/appimage/AppRun AppDir/AppRun
|
cp distribution/linux/appimage/AppRun AppDir/AppRun
|
||||||
cp src/Ryujinx.UI.Common/Resources/Logo_Ryujinx.png AppDir/Ryujinx.svg
|
cp distribution/misc/Logo.svg AppDir/Ryujinx.svg
|
||||||
|
|
||||||
|
|
||||||
cp -r "$BUILDDIR"/* AppDir/usr/bin/
|
cp -r "$BUILDDIR"/* AppDir/usr/bin/
|
||||||
|
@ -9,20 +9,12 @@ namespace Ryujinx.Audio.Backends.Dummy
|
|||||||
{
|
{
|
||||||
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
|
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
|
||||||
{
|
{
|
||||||
private readonly ManualResetEvent _updateRequiredEvent;
|
private readonly ManualResetEvent _updateRequiredEvent = new(false);
|
||||||
private readonly ManualResetEvent _pauseEvent;
|
private readonly ManualResetEvent _pauseEvent = new(true);
|
||||||
|
|
||||||
public static bool IsSupported => true;
|
public static bool IsSupported => true;
|
||||||
|
|
||||||
public float Volume { get; set; }
|
public float Volume { get; set; } = 1f;
|
||||||
|
|
||||||
public DummyHardwareDeviceDriver()
|
|
||||||
{
|
|
||||||
_updateRequiredEvent = new ManualResetEvent(false);
|
|
||||||
_pauseEvent = new ManualResetEvent(true);
|
|
||||||
|
|
||||||
Volume = 1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
|
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
|
||||||
{
|
{
|
||||||
@ -60,7 +52,7 @@ namespace Ryujinx.Audio.Backends.Dummy
|
|||||||
Dispose(true);
|
Dispose(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
private void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
|
35
src/Ryujinx.Common/BitTricks.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
namespace Ryujinx.Common
|
||||||
|
{
|
||||||
|
public class BitTricks
|
||||||
|
{
|
||||||
|
// Never actually written bit packing logic before, so I looked it up.
|
||||||
|
// This code is from https://gist.github.com/Alan-FGR/04938e93e2bffdf5802ceb218a37c195
|
||||||
|
|
||||||
|
public static ulong PackBitFields(uint[] values, byte[] bitFields)
|
||||||
|
{
|
||||||
|
ulong retVal = values[0]; //we set the first value right away
|
||||||
|
for (int f = 1; f < values.Length; f++)
|
||||||
|
{
|
||||||
|
retVal <<= bitFields[f]; // we shift the previous value
|
||||||
|
retVal += values[f];// and add our current value
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint[] UnpackBitFields(ulong packed, byte[] bitFields)
|
||||||
|
{
|
||||||
|
int fields = bitFields.Length - 1; // number of fields to unpack
|
||||||
|
uint[] retArr = new uint[fields + 1]; // init return array
|
||||||
|
int curPos = 0; // current field bit position (start)
|
||||||
|
int lastEnd; // position where last field ended
|
||||||
|
for (int f = fields; f >= 0; f--) // loop from last
|
||||||
|
{
|
||||||
|
lastEnd = curPos; // we store where the last value ended
|
||||||
|
curPos += bitFields[f]; // we get where the current value starts
|
||||||
|
int leftShift = 64 - curPos; // we figure how much left shift we gotta apply for the other numbers to overflow into oblivion
|
||||||
|
retArr[f] = (uint)((packed << leftShift) >> leftShift + lastEnd); // we do magic
|
||||||
|
}
|
||||||
|
return retArr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -36,6 +36,8 @@ namespace Ryujinx.Common.Configuration
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static float ToFloatY(this AspectRatio aspectRatio)
|
public static float ToFloatY(this AspectRatio aspectRatio)
|
||||||
{
|
{
|
||||||
return aspectRatio switch
|
return aspectRatio switch
|
||||||
|
61
src/Ryujinx.Common/Configuration/DirtyHacks.cs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Configuration
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum DirtyHacks : byte
|
||||||
|
{
|
||||||
|
Xc2MenuSoftlockFix = 1,
|
||||||
|
ShaderCompilationThreadSleep = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public record EnabledDirtyHack(DirtyHacks Hack, int Value)
|
||||||
|
{
|
||||||
|
public static readonly byte[] PackedFormat = [8, 32];
|
||||||
|
|
||||||
|
public ulong Pack() => BitTricks.PackBitFields([(uint)Hack, (uint)Value], PackedFormat);
|
||||||
|
|
||||||
|
public static EnabledDirtyHack Unpack(ulong packedHack)
|
||||||
|
{
|
||||||
|
var unpackedFields = BitTricks.UnpackBitFields(packedHack, PackedFormat);
|
||||||
|
if (unpackedFields is not [var hack, var value])
|
||||||
|
throw new ArgumentException(nameof(packedHack));
|
||||||
|
|
||||||
|
return new EnabledDirtyHack((DirtyHacks)hack, (int)value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DirtyHackCollection : Dictionary<DirtyHacks, int>
|
||||||
|
{
|
||||||
|
public DirtyHackCollection(EnabledDirtyHack[] hacks)
|
||||||
|
{
|
||||||
|
foreach ((DirtyHacks dirtyHacks, int value) in hacks)
|
||||||
|
{
|
||||||
|
Add(dirtyHacks, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirtyHackCollection(ulong[] packedHacks)
|
||||||
|
{
|
||||||
|
foreach ((DirtyHacks dirtyHacks, int value) in packedHacks.Select(EnabledDirtyHack.Unpack))
|
||||||
|
{
|
||||||
|
Add(dirtyHacks, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong[] PackEntries() =>
|
||||||
|
this
|
||||||
|
.Select(it =>
|
||||||
|
BitTricks.PackBitFields([(uint)it.Key, (uint)it.Value], EnabledDirtyHack.PackedFormat))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
public static implicit operator DirtyHackCollection(EnabledDirtyHack[] hacks) => new(hacks);
|
||||||
|
public static implicit operator DirtyHackCollection(ulong[] packedHacks) => new(packedHacks);
|
||||||
|
|
||||||
|
public new int this[DirtyHacks hack] => TryGetValue(hack, out var value) ? value : -1;
|
||||||
|
|
||||||
|
public bool IsEnabled(DirtyHacks hack) => ContainsKey(hack);
|
||||||
|
}
|
||||||
|
}
|
@ -9,5 +9,6 @@ namespace Ryujinx.Common.Configuration
|
|||||||
Bilinear,
|
Bilinear,
|
||||||
Nearest,
|
Nearest,
|
||||||
Fsr,
|
Fsr,
|
||||||
|
Area,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,10 @@ namespace Ryujinx.Common
|
|||||||
public static class StreamExtensions
|
public static class StreamExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes a <see cref="ReadOnlySpan{int}" /> to this stream.
|
/// Writes an int span to this stream.
|
||||||
///
|
///
|
||||||
/// This default implementation converts each buffer value to a stack-allocated
|
/// This default implementation converts each buffer value to a stack-allocated
|
||||||
/// byte array, then writes it to the Stream using <cref="System.Stream.Write(byte[])" />.
|
/// byte array, then writes it to the Stream using <see cref="Stream.Write(ReadOnlySpan{byte})" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">The stream to be written to</param>
|
/// <param name="stream">The stream to be written to</param>
|
||||||
/// <param name="buffer">The buffer of values to be written</param>
|
/// <param name="buffer">The buffer of values to be written</param>
|
||||||
|
@ -3,7 +3,7 @@ using System;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
public static partial class ConsoleHelper
|
public static partial class ConsoleHelper
|
||||||
{
|
{
|
@ -8,7 +8,7 @@ using System.Linq;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
public static partial class FileAssociationHelper
|
public static partial class FileAssociationHelper
|
||||||
{
|
{
|
||||||
@ -132,7 +132,7 @@ namespace Ryujinx.UI.Common.Helper
|
|||||||
|
|
||||||
if (uninstall)
|
if (uninstall)
|
||||||
{
|
{
|
||||||
// If the types don't already exist, there's nothing to do and we can call this operation successful.
|
// If the types don't already exist, there's nothing to do, and we can call this operation successful.
|
||||||
if (!AreMimeTypesRegisteredWindows())
|
if (!AreMimeTypesRegisteredWindows())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
@ -3,7 +3,7 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
[SupportedOSPlatform("linux")]
|
[SupportedOSPlatform("linux")]
|
||||||
public static class LinuxHelper
|
public static class LinuxHelper
|
@ -2,7 +2,7 @@ using System;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
public static partial class ObjectiveC
|
public static partial class ObjectiveC
|
@ -5,7 +5,7 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
public static partial class OpenHelper
|
public static partial class OpenHelper
|
||||||
{
|
{
|
@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
@ -158,20 +159,15 @@ namespace Ryujinx.Common.Logging
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static ILogTarget GetTarget(string targetName)
|
private static ILogTarget GetTarget(string targetName)
|
||||||
{
|
=> _logTargets.FirstOrDefault(target => target.Name.Equals(targetName));
|
||||||
foreach (var target in _logTargets)
|
|
||||||
{
|
|
||||||
if (target.Name.Equals(targetName))
|
|
||||||
{
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AddTarget(ILogTarget target)
|
public static void AddTarget(ILogTarget target)
|
||||||
{
|
{
|
||||||
|
if (_logTargets.Any(t => t.Name == target.Name))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_logTargets.Add(target);
|
_logTargets.Add(target);
|
||||||
|
|
||||||
Updated += target.Log;
|
Updated += target.Log;
|
||||||
|
@ -27,11 +27,7 @@ namespace Ryujinx.Common.Logging.Targets
|
|||||||
|
|
||||||
private readonly int _overflowTimeout;
|
private readonly int _overflowTimeout;
|
||||||
|
|
||||||
string ILogTarget.Name { get => _target.Name; }
|
string ILogTarget.Name => _target.Name;
|
||||||
|
|
||||||
public AsyncLogTargetWrapper(ILogTarget target)
|
|
||||||
: this(target, -1)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public AsyncLogTargetWrapper(ILogTarget target, int queueLimit = -1, AsyncLogTargetOverflowAction overflowAction = AsyncLogTargetOverflowAction.Block)
|
public AsyncLogTargetWrapper(ILogTarget target, int queueLimit = -1, AsyncLogTargetOverflowAction overflowAction = AsyncLogTargetOverflowAction.Block)
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,8 @@ namespace Ryujinx.Common
|
|||||||
{
|
{
|
||||||
public static class TitleIDs
|
public static class TitleIDs
|
||||||
{
|
{
|
||||||
|
public static ReactiveObject<Optional<string>> CurrentApplication { get; set; } = new();
|
||||||
|
|
||||||
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
|
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
|
||||||
{
|
{
|
||||||
switch (currentBackend)
|
switch (currentBackend)
|
||||||
@ -33,6 +35,7 @@ namespace Ryujinx.Common
|
|||||||
"010028600EBDA000", // Mario 3D World
|
"010028600EBDA000", // Mario 3D World
|
||||||
"0100152000022000", // Mario Kart 8 Deluxe
|
"0100152000022000", // Mario Kart 8 Deluxe
|
||||||
"01005CA01580E000", // Persona 5
|
"01005CA01580E000", // Persona 5
|
||||||
|
"01001f5010dfa000", // Pokemon Legends Arceus
|
||||||
"01008C0016544000", // Sea of Stars
|
"01008C0016544000", // Sea of Stars
|
||||||
"01006A800016E000", // Smash Ultimate
|
"01006A800016E000", // Smash Ultimate
|
||||||
"0100000000010000", // Super Mario Odyessy
|
"0100000000010000", // Super Mario Odyessy
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Ryujinx.UI.Common
|
namespace Ryujinx.Common.UI
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represent a common error that could be reported to the user by the emulator.
|
/// Represent a common error that could be reported to the user by the emulator.
|
@ -1,12 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public enum AntiAliasing
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Fxaa,
|
|
||||||
SmaaLow,
|
|
||||||
SmaaMedium,
|
|
||||||
SmaaHigh,
|
|
||||||
SmaaUltra,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public enum ScalingFilter
|
|
||||||
{
|
|
||||||
Bilinear,
|
|
||||||
Nearest,
|
|
||||||
Fsr,
|
|
||||||
Area,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Graphics.Device;
|
using Ryujinx.Graphics.Device;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
||||||
@ -91,6 +92,9 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
||||||
|
|
||||||
|
internal DirtyHackCollection DirtyHacks { get; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Host hardware capabilities.
|
/// Host hardware capabilities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -113,7 +117,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// Creates a new instance of the GPU emulation context.
|
/// Creates a new instance of the GPU emulation context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="renderer">Host renderer</param>
|
/// <param name="renderer">Host renderer</param>
|
||||||
public GpuContext(IRenderer renderer)
|
public GpuContext(IRenderer renderer, DirtyHackCollection hackCollection)
|
||||||
{
|
{
|
||||||
Renderer = renderer;
|
Renderer = renderer;
|
||||||
|
|
||||||
@ -136,6 +140,8 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
|
|
||||||
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
||||||
|
|
||||||
|
DirtyHacks = hackCollection;
|
||||||
|
|
||||||
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
@ -366,6 +367,9 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (_context.DirtyHacks.IsEnabled(DirtyHacks.ShaderCompilationThreadSleep))
|
||||||
|
Thread.Sleep(_context.DirtyHacks[DirtyHacks.ShaderCompilationThreadSleep]);
|
||||||
|
|
||||||
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
||||||
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using Ryujinx.Common;
|
||||||
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,4 +1,5 @@
|
|||||||
using SharpMetal;
|
using SharpMetal;
|
||||||
|
using SharpMetal.Foundation;
|
||||||
using SharpMetal.ObjectiveCCore;
|
using SharpMetal.ObjectiveCCore;
|
||||||
using SharpMetal.QuartzCore;
|
using SharpMetal.QuartzCore;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
@ -9,22 +10,13 @@ namespace Ryujinx.Graphics.Metal.SharpMetalExtensions
|
|||||||
[SupportedOSPlatform("macOS")]
|
[SupportedOSPlatform("macOS")]
|
||||||
public static class CAMetalLayerExtensions
|
public static class CAMetalLayerExtensions
|
||||||
{
|
{
|
||||||
private static readonly Selector sel_displaySyncEnabled = "displaySyncEnabled";
|
|
||||||
private static readonly Selector sel_setDisplaySyncEnabled = "setDisplaySyncEnabled:";
|
|
||||||
|
|
||||||
private static readonly Selector sel_developerHUDProperties = "developerHUDProperties";
|
private static readonly Selector sel_developerHUDProperties = "developerHUDProperties";
|
||||||
private static readonly Selector sel_setDeveloperHUDProperties = "setDeveloperHUDProperties:";
|
private static readonly Selector sel_setDeveloperHUDProperties = "setDeveloperHUDProperties:";
|
||||||
|
|
||||||
public static bool IsDisplaySyncEnabled(this CAMetalLayer metalLayer)
|
public static NSDictionary GetDeveloperHudProperties(this CAMetalLayer metalLayer)
|
||||||
=> ObjectiveCRuntime.bool_objc_msgSend(metalLayer.NativePtr, sel_displaySyncEnabled);
|
=> new(ObjectiveCRuntime.IntPtr_objc_msgSend(metalLayer.NativePtr, sel_developerHUDProperties));
|
||||||
|
|
||||||
public static void SetDisplaySyncEnabled(this CAMetalLayer metalLayer, bool enabled)
|
public static void SetDeveloperHudProperties(this CAMetalLayer metalLayer, NSDictionary dictionary)
|
||||||
=> ObjectiveCRuntime.objc_msgSend(metalLayer.NativePtr, sel_setDisplaySyncEnabled, enabled);
|
=> ObjectiveCRuntime.objc_msgSend(metalLayer.NativePtr, sel_setDeveloperHUDProperties, dictionary);
|
||||||
|
|
||||||
public static nint GetDeveloperHudProperties(this CAMetalLayer metalLayer)
|
|
||||||
=> ObjectiveCRuntime.IntPtr_objc_msgSend(metalLayer.NativePtr, sel_developerHUDProperties);
|
|
||||||
|
|
||||||
public static void SetDeveloperHudProperties(this CAMetalLayer metalLayer, nint dictionaryPointer)
|
|
||||||
=> ObjectiveCRuntime.objc_msgSend(metalLayer.NativePtr, sel_setDeveloperHUDProperties, dictionaryPointer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
src/Ryujinx.Graphics.Metal.SharpMetalExtensions/NSHelper.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using SharpMetal.Foundation;
|
||||||
|
using SharpMetal.ObjectiveCCore;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Metal.SharpMetalExtensions
|
||||||
|
{
|
||||||
|
[SupportedOSPlatform("macOS")]
|
||||||
|
public static class NSHelper
|
||||||
|
{
|
||||||
|
private static readonly Selector sel_getCStringMaxLengthEncoding = "getCString:maxLength:encoding:";
|
||||||
|
private static readonly Selector sel_stringWithUTF8String = "stringWithUTF8String:";
|
||||||
|
|
||||||
|
public static unsafe string ToDotNetString(this NSString source)
|
||||||
|
{
|
||||||
|
char[] sourceBuffer = new char[source.Length];
|
||||||
|
fixed (char* pSourceBuffer = sourceBuffer)
|
||||||
|
{
|
||||||
|
ObjectiveC.bool_objc_msgSend(source,
|
||||||
|
sel_getCStringMaxLengthEncoding,
|
||||||
|
pSourceBuffer,
|
||||||
|
source.MaximumLengthOfBytes(NSStringEncoding.UTF16) + 1,
|
||||||
|
(ulong)NSStringEncoding.UTF16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new string(sourceBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NSString ToNSString(this string source)
|
||||||
|
=> new(ObjectiveC.IntPtr_objc_msgSend(new ObjectiveCClass(nameof(NSString)), sel_stringWithUTF8String, source));
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -2,13 +2,10 @@ using Ryujinx.Common.Configuration;
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Metal.Effects;
|
using Ryujinx.Graphics.Metal.Effects;
|
||||||
using Ryujinx.Graphics.Metal.SharpMetalExtensions;
|
|
||||||
using SharpMetal.ObjectiveCCore;
|
using SharpMetal.ObjectiveCCore;
|
||||||
using SharpMetal.QuartzCore;
|
using SharpMetal.QuartzCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
using AntiAliasing = Ryujinx.Graphics.GAL.AntiAliasing;
|
|
||||||
using ScalingFilter = Ryujinx.Graphics.GAL.ScalingFilter;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Metal
|
namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
@ -18,7 +15,7 @@ namespace Ryujinx.Graphics.Metal
|
|||||||
public bool ScreenCaptureRequested { get; set; }
|
public bool ScreenCaptureRequested { get; set; }
|
||||||
|
|
||||||
private readonly MetalRenderer _renderer;
|
private readonly MetalRenderer _renderer;
|
||||||
private readonly CAMetalLayer _metalLayer;
|
private CAMetalLayer _metalLayer;
|
||||||
|
|
||||||
private int _width;
|
private int _width;
|
||||||
private int _height;
|
private int _height;
|
||||||
@ -26,12 +23,14 @@ namespace Ryujinx.Graphics.Metal
|
|||||||
private int _requestedWidth;
|
private int _requestedWidth;
|
||||||
private int _requestedHeight;
|
private int _requestedHeight;
|
||||||
|
|
||||||
// private bool _vsyncEnabled;
|
|
||||||
private AntiAliasing _currentAntiAliasing;
|
private AntiAliasing _currentAntiAliasing;
|
||||||
private bool _updateEffect;
|
private bool _updateEffect;
|
||||||
private IPostProcessingEffect _effect;
|
private IPostProcessingEffect _effect;
|
||||||
private IScalingFilter _scalingFilter;
|
private IScalingFilter _scalingFilter;
|
||||||
private bool _isLinear;
|
private bool _isLinear;
|
||||||
|
|
||||||
|
public bool IsVSyncEnabled => _metalLayer.DisplaySyncEnabled;
|
||||||
|
|
||||||
// private float _scalingFilterLevel;
|
// private float _scalingFilterLevel;
|
||||||
private bool _updateScalingFilter;
|
private bool _updateScalingFilter;
|
||||||
private ScalingFilter _currentScalingFilter;
|
private ScalingFilter _currentScalingFilter;
|
||||||
@ -43,7 +42,7 @@ namespace Ryujinx.Graphics.Metal
|
|||||||
_metalLayer = metalLayer;
|
_metalLayer = metalLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void ResizeIfNeeded()
|
private void ResizeIfNeeded()
|
||||||
{
|
{
|
||||||
if (_requestedWidth != 0 && _requestedHeight != 0)
|
if (_requestedWidth != 0 && _requestedHeight != 0)
|
||||||
{
|
{
|
||||||
@ -57,7 +56,7 @@ namespace Ryujinx.Graphics.Metal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
||||||
{
|
{
|
||||||
if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex)
|
if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex)
|
||||||
{
|
{
|
||||||
@ -144,15 +143,7 @@ namespace Ryujinx.Graphics.Metal
|
|||||||
|
|
||||||
public void ChangeVSyncMode(VSyncMode vSyncMode)
|
public void ChangeVSyncMode(VSyncMode vSyncMode)
|
||||||
{
|
{
|
||||||
switch (vSyncMode)
|
_metalLayer.DisplaySyncEnabled = vSyncMode is VSyncMode.Switch;
|
||||||
{
|
|
||||||
case VSyncMode.Unbounded:
|
|
||||||
_metalLayer.SetDisplaySyncEnabled(false);
|
|
||||||
break;
|
|
||||||
case VSyncMode.Switch:
|
|
||||||
_metalLayer.SetDisplaySyncEnabled(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAntiAliasing(AntiAliasing effect)
|
public void SetAntiAliasing(AntiAliasing effect)
|
||||||
|
@ -2,8 +2,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||||||
{
|
{
|
||||||
internal enum BitDepth
|
internal enum BitDepth
|
||||||
{
|
{
|
||||||
Bits8 = 8, /**< 8 bits */
|
Bits8 = 8, // < 8 bits
|
||||||
Bits10 = 10, /**< 10 bits */
|
Bits10 = 10, // < 10 bits
|
||||||
Bits12 = 12, /**< 12 bits */
|
Bits12 = 12, // < 12 bits
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ using Ryujinx.Graphics.OpenGL.Effects;
|
|||||||
using Ryujinx.Graphics.OpenGL.Effects.Smaa;
|
using Ryujinx.Graphics.OpenGL.Effects.Smaa;
|
||||||
using Ryujinx.Graphics.OpenGL.Image;
|
using Ryujinx.Graphics.OpenGL.Image;
|
||||||
using System;
|
using System;
|
||||||
using AntiAliasing = Ryujinx.Graphics.GAL.AntiAliasing;
|
|
||||||
using ScalingFilter = Ryujinx.Graphics.GAL.ScalingFilter;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.OpenGL
|
namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using Gommon;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
@ -890,7 +891,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private void PrintGpuInformation()
|
private void PrintGpuInformation()
|
||||||
{
|
{
|
||||||
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
|
string gpuInfoMessage = $"{GpuRenderer} ({GpuVersion})";
|
||||||
|
if (!GpuRenderer.StartsWithIgnoreCase(GpuVendor))
|
||||||
|
gpuInfoMessage = gpuInfoMessage.Prepend(GpuVendor);
|
||||||
|
|
||||||
|
Logger.Notice.Print(LogClass.Gpu, gpuInfoMessage);
|
||||||
|
|
||||||
Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB");
|
Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,6 @@ using Silk.NET.Vulkan;
|
|||||||
using Silk.NET.Vulkan.Extensions.KHR;
|
using Silk.NET.Vulkan.Extensions.KHR;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AntiAliasing = Ryujinx.Graphics.GAL.AntiAliasing;
|
|
||||||
using ScalingFilter = Ryujinx.Graphics.GAL.ScalingFilter;
|
|
||||||
using VkFormat = Silk.NET.Vulkan.Format;
|
using VkFormat = Silk.NET.Vulkan.Format;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using System;
|
using System;
|
||||||
using AntiAliasing = Ryujinx.Graphics.GAL.AntiAliasing;
|
|
||||||
using ScalingFilter = Ryujinx.Graphics.GAL.ScalingFilter;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -189,6 +189,11 @@ namespace Ryujinx.HLE
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Action RefreshInputConfig { internal get; set; }
|
public Action RefreshInputConfig { internal get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The desired hacky workarounds.
|
||||||
|
/// </summary>
|
||||||
|
public EnabledDirtyHack[] Hacks { internal get; set; }
|
||||||
|
|
||||||
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
|
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
|
||||||
LibHacHorizonManager libHacHorizonManager,
|
LibHacHorizonManager libHacHorizonManager,
|
||||||
ContentManager contentManager,
|
ContentManager contentManager,
|
||||||
@ -218,7 +223,8 @@ namespace Ryujinx.HLE
|
|||||||
bool multiplayerDisableP2p,
|
bool multiplayerDisableP2p,
|
||||||
string multiplayerLdnPassphrase,
|
string multiplayerLdnPassphrase,
|
||||||
string multiplayerLdnServer,
|
string multiplayerLdnServer,
|
||||||
int customVSyncInterval)
|
int customVSyncInterval,
|
||||||
|
EnabledDirtyHack[] dirtyHacks = null)
|
||||||
{
|
{
|
||||||
VirtualFileSystem = virtualFileSystem;
|
VirtualFileSystem = virtualFileSystem;
|
||||||
LibHacHorizonManager = libHacHorizonManager;
|
LibHacHorizonManager = libHacHorizonManager;
|
||||||
@ -250,6 +256,7 @@ namespace Ryujinx.HLE
|
|||||||
MultiplayerDisableP2p = multiplayerDisableP2p;
|
MultiplayerDisableP2p = multiplayerDisableP2p;
|
||||||
MultiplayerLdnPassphrase = multiplayerLdnPassphrase;
|
MultiplayerLdnPassphrase = multiplayerLdnPassphrase;
|
||||||
MultiplayerLdnServer = multiplayerLdnServer;
|
MultiplayerLdnServer = multiplayerLdnServer;
|
||||||
|
Hacks = dirtyHacks ?? [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using Gommon;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
@ -6,12 +7,13 @@ using System;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
||||||
{
|
{
|
||||||
class AccountSaveDataManager
|
public class AccountSaveDataManager
|
||||||
{
|
{
|
||||||
private readonly string _profilesJsonPath = Path.Join(AppDataManager.BaseDirPath, "system", "Profiles.json");
|
private static readonly string _profilesJsonPath = Path.Join(AppDataManager.BaseDirPath, "system", "Profiles.json");
|
||||||
|
|
||||||
private static readonly ProfilesJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
private static readonly ProfilesJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||||
|
|
||||||
@ -49,6 +51,16 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Optional<UserProfile> GetLastUsedUser()
|
||||||
|
{
|
||||||
|
ProfilesJson profilesJson = JsonHelper.DeserializeFromFile(_profilesJsonPath, _serializerContext.ProfilesJson);
|
||||||
|
|
||||||
|
return profilesJson.Profiles
|
||||||
|
.FindFirst(profile => profile.AccountState == AccountState.Open)
|
||||||
|
.Convert(profileJson => new UserProfile(new UserId(profileJson.UserId), profileJson.Name,
|
||||||
|
profileJson.Image, profileJson.LastModifiedTimestamp));
|
||||||
|
}
|
||||||
|
|
||||||
public void Save(ConcurrentDictionary<string, UserProfile> profiles)
|
public void Save(ConcurrentDictionary<string, UserProfile> profiles)
|
||||||
{
|
{
|
||||||
ProfilesJson profilesJson = new()
|
ProfilesJson profilesJson = new()
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
using LibHac;
|
using LibHac;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Sf;
|
using LibHac.Sf;
|
||||||
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Common.Configuration;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
||||||
{
|
{
|
||||||
@ -13,6 +16,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
|||||||
_baseStorage = SharedRef<LibHac.FsSrv.Sf.IStorage>.CreateMove(ref baseStorage);
|
_baseStorage = SharedRef<LibHac.FsSrv.Sf.IStorage>.CreateMove(ref baseStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const string Xc2TitleId = "0100e95004038000";
|
||||||
|
|
||||||
[CommandCmif(0)]
|
[CommandCmif(0)]
|
||||||
// Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer
|
// Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer
|
||||||
public ResultCode Read(ServiceCtx context)
|
public ResultCode Read(ServiceCtx context)
|
||||||
@ -34,6 +39,13 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
|||||||
using var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true);
|
using var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true);
|
||||||
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
|
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
|
||||||
|
|
||||||
|
if (context.Device.DirtyHacks.IsEnabled(DirtyHacks.Xc2MenuSoftlockFix) && TitleIDs.CurrentApplication.Value == Xc2TitleId)
|
||||||
|
{
|
||||||
|
// Add a load-bearing sleep to avoid XC2 softlock
|
||||||
|
// https://web.archive.org/web/20240728045136/https://github.com/Ryujinx/Ryujinx/issues/2357
|
||||||
|
Thread.Sleep(2);
|
||||||
|
}
|
||||||
|
|
||||||
return (ResultCode)result.Value;
|
return (ResultCode)result.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,10 @@ using LibHac.Fs.Fsa;
|
|||||||
using LibHac.Loader;
|
using LibHac.Loader;
|
||||||
using LibHac.Ns;
|
using LibHac.Ns;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Graphics.Gpu;
|
||||||
using Ryujinx.HLE.Loaders.Executables;
|
using Ryujinx.HLE.Loaders.Executables;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
@ -102,7 +104,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize GPU.
|
// Initialize GPU.
|
||||||
Graphics.Gpu.GraphicsConfig.TitleId = $"{programId:x16}";
|
GraphicsConfig.TitleId = programId.ToString("X16");
|
||||||
device.Gpu.HostInitalized.Set();
|
device.Gpu.HostInitalized.Set();
|
||||||
|
|
||||||
if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible))
|
if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible))
|
||||||
|
@ -6,7 +6,9 @@ using LibHac.Ns;
|
|||||||
using LibHac.Tools.Fs;
|
using LibHac.Tools.Fs;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Graphics.Gpu;
|
||||||
using Ryujinx.HLE.Loaders.Executables;
|
using Ryujinx.HLE.Loaders.Executables;
|
||||||
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
||||||
using System;
|
using System;
|
||||||
@ -59,6 +61,8 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
{
|
{
|
||||||
_latestPid = processResult.ProcessId;
|
_latestPid = processResult.ProcessId;
|
||||||
|
|
||||||
|
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,6 +90,8 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
{
|
{
|
||||||
_latestPid = processResult.ProcessId;
|
_latestPid = processResult.ProcessId;
|
||||||
|
|
||||||
|
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,6 +119,8 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
if (processResult.ProgramId > 0x01000000000007FF)
|
if (processResult.ProgramId > 0x01000000000007FF)
|
||||||
{
|
{
|
||||||
_latestPid = processResult.ProcessId;
|
_latestPid = processResult.ProcessId;
|
||||||
|
|
||||||
|
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -132,6 +140,8 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
{
|
{
|
||||||
_latestPid = processResult.ProcessId;
|
_latestPid = processResult.ProcessId;
|
||||||
|
|
||||||
|
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,14 +193,17 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
if (nacpData.Value.PresenceGroupId != 0)
|
if (nacpData.Value.PresenceGroupId != 0)
|
||||||
{
|
{
|
||||||
programId = nacpData.Value.PresenceGroupId;
|
programId = nacpData.Value.PresenceGroupId;
|
||||||
|
TitleIDs.CurrentApplication.Value = programId.ToString("X16");
|
||||||
}
|
}
|
||||||
else if (nacpData.Value.SaveDataOwnerId != 0)
|
else if (nacpData.Value.SaveDataOwnerId != 0)
|
||||||
{
|
{
|
||||||
programId = nacpData.Value.SaveDataOwnerId;
|
programId = nacpData.Value.SaveDataOwnerId;
|
||||||
|
TitleIDs.CurrentApplication.Value = programId.ToString("X16");
|
||||||
}
|
}
|
||||||
else if (nacpData.Value.AddOnContentBaseId != 0)
|
else if (nacpData.Value.AddOnContentBaseId != 0)
|
||||||
{
|
{
|
||||||
programId = nacpData.Value.AddOnContentBaseId - 0x1000;
|
programId = nacpData.Value.AddOnContentBaseId - 0x1000;
|
||||||
|
TitleIDs.CurrentApplication.Value = programId.ToString("X16");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +217,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Explicitly null TitleId to disable the shader cache.
|
// Explicitly null TitleId to disable the shader cache.
|
||||||
Graphics.Gpu.GraphicsConfig.TitleId = null;
|
GraphicsConfig.TitleId = null;
|
||||||
_device.Gpu.HostInitalized.Set();
|
_device.Gpu.HostInitalized.Set();
|
||||||
|
|
||||||
ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device,
|
ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device,
|
||||||
|
@ -2,6 +2,7 @@ using LibHac.Common;
|
|||||||
using LibHac.Ns;
|
using LibHac.Ns;
|
||||||
using Ryujinx.Audio.Backends.CompatLayer;
|
using Ryujinx.Audio.Backends.CompatLayer;
|
||||||
using Ryujinx.Audio.Integration;
|
using Ryujinx.Audio.Integration;
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Graphics.Gpu;
|
using Ryujinx.Graphics.Gpu;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
@ -17,6 +18,8 @@ namespace Ryujinx.HLE
|
|||||||
{
|
{
|
||||||
public class Switch : IDisposable
|
public class Switch : IDisposable
|
||||||
{
|
{
|
||||||
|
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; }
|
||||||
@ -37,6 +40,8 @@ namespace Ryujinx.HLE
|
|||||||
|
|
||||||
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
|
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
|
||||||
|
|
||||||
|
public DirtyHackCollection DirtyHacks { get; }
|
||||||
|
|
||||||
public Switch(HLEConfiguration configuration)
|
public Switch(HLEConfiguration configuration)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(configuration.GpuRenderer);
|
ArgumentNullException.ThrowIfNull(configuration.GpuRenderer);
|
||||||
@ -52,9 +57,10 @@ namespace Ryujinx.HLE
|
|||||||
: MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Mirrorable;
|
: MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Mirrorable;
|
||||||
|
|
||||||
#pragma warning disable IDE0055 // Disable formatting
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
|
DirtyHacks = new DirtyHackCollection(Configuration.Hacks);
|
||||||
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
|
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
|
||||||
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
|
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
|
||||||
Gpu = new GpuContext(Configuration.GpuRenderer);
|
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks);
|
||||||
System = new HOS.Horizon(this);
|
System = new HOS.Horizon(this);
|
||||||
Statistics = new PerformanceStatistics();
|
Statistics = new PerformanceStatistics();
|
||||||
Hid = new Hid(this, System.HidStorage);
|
Hid = new Hid(this, System.HidStorage);
|
||||||
@ -72,8 +78,11 @@ namespace Ryujinx.HLE
|
|||||||
System.EnablePtc = Configuration.EnablePtc;
|
System.EnablePtc = Configuration.EnablePtc;
|
||||||
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
|
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
|
||||||
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
|
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
|
||||||
|
|
||||||
UpdateVSyncInterval();
|
UpdateVSyncInterval();
|
||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
|
|
||||||
|
Shared = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessFrame()
|
public void ProcessFrame()
|
||||||
@ -142,6 +151,9 @@ namespace Ryujinx.HLE
|
|||||||
AudioDeviceDriver.Dispose();
|
AudioDeviceDriver.Dispose();
|
||||||
FileSystem.Dispose();
|
FileSystem.Dispose();
|
||||||
Memory.Dispose();
|
Memory.Dispose();
|
||||||
|
|
||||||
|
TitleIDs.CurrentApplication.Value = null;
|
||||||
|
Shared = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
||||||
<Version>1.0.0-dirty</Version>
|
|
||||||
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
|
|
||||||
<SigningCertificate Condition=" '$(SigningCertificate)' == '' ">-</SigningCertificate>
|
|
||||||
<TieredPGO>true</TieredPGO>
|
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="OpenTK.Core" />
|
|
||||||
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
|
|
||||||
<Exec Command="codesign --entitlements '$(ProjectDir)..\..\distribution\macos\entitlements.xml' -f -s $(SigningCertificate) '$(TargetDir)$(TargetName)'" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.Input\Ryujinx.Input.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.Input.SDL2\Ryujinx.Input.SDL2.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.HLE\Ryujinx.HLE.csproj" />
|
|
||||||
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Metal\Ryujinx.Graphics.Metal.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="CommandLineParser" />
|
|
||||||
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Include="..\..\distribution\legal\THIRDPARTY.md">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
<TargetPath>THIRDPARTY.md</TargetPath>
|
|
||||||
</Content>
|
|
||||||
<Content Include="..\..\LICENSE.txt">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
<TargetPath>LICENSE.txt</TargetPath>
|
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64' OR ('$(RuntimeIdentifier)' == '' AND $([MSBuild]::IsOSPlatform('Linux')))">
|
|
||||||
<Content Include="..\..\distribution\linux\Ryujinx.sh">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="Ryujinx.bmp" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<!-- Due to .net core 3.1 embedded resource loading -->
|
|
||||||
<PropertyGroup>
|
|
||||||
<EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
|
|
||||||
<ApplicationIcon>..\Ryujinx\Ryujinx.ico</ApplicationIcon>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
|
|
||||||
<PublishSingleFile>true</PublishSingleFile>
|
|
||||||
<PublishTrimmed>true</PublishTrimmed>
|
|
||||||
<TrimMode>partial</TrimMode>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
Before Width: | Height: | Size: 9.1 KiB |
@ -1,12 +0,0 @@
|
|||||||
namespace Ryujinx.UI.Common
|
|
||||||
{
|
|
||||||
public enum FileTypes
|
|
||||||
{
|
|
||||||
NSP,
|
|
||||||
PFS0,
|
|
||||||
XCI,
|
|
||||||
NCA,
|
|
||||||
NRO,
|
|
||||||
NSO
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
using LibHac.Common;
|
|
||||||
using LibHac.Ncm;
|
|
||||||
using LibHac.Ns;
|
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
|
||||||
using Ryujinx.HLE;
|
|
||||||
using Ryujinx.HLE.FileSystem;
|
|
||||||
using Ryujinx.UI.App.Common;
|
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
|
||||||
{
|
|
||||||
public readonly struct AppletMetadata
|
|
||||||
{
|
|
||||||
private readonly ContentManager _contentManager;
|
|
||||||
|
|
||||||
public string Name { get; }
|
|
||||||
public ulong ProgramId { get; }
|
|
||||||
|
|
||||||
public string Version { get; }
|
|
||||||
|
|
||||||
public AppletMetadata(ContentManager contentManager, string name, ulong programId, string version = "1.0.0")
|
|
||||||
: this(name, programId, version)
|
|
||||||
{
|
|
||||||
_contentManager = contentManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AppletMetadata(string name, ulong programId, string version = "1.0.0")
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
ProgramId = programId;
|
|
||||||
Version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetContentPath(ContentManager contentManager)
|
|
||||||
=> (contentManager ?? _contentManager)
|
|
||||||
.GetInstalledContentPath(ProgramId, StorageId.BuiltInSystem, NcaContentType.Program);
|
|
||||||
|
|
||||||
public bool CanStart(ContentManager contentManager, out ApplicationData appData, out BlitStruct<ApplicationControlProperty> appControl)
|
|
||||||
{
|
|
||||||
contentManager ??= _contentManager;
|
|
||||||
if (contentManager == null)
|
|
||||||
{
|
|
||||||
appData = null;
|
|
||||||
appControl = new BlitStruct<ApplicationControlProperty>(0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
appData = new()
|
|
||||||
{
|
|
||||||
Name = Name,
|
|
||||||
Id = ProgramId,
|
|
||||||
Path = GetContentPath(contentManager)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(appData.Path))
|
|
||||||
{
|
|
||||||
appControl = new BlitStruct<ApplicationControlProperty>(0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
appControl = StructHelpers.CreateCustomNacpData(Name, Version);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 81 KiB |
@ -1,132 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1050 1050.5"
|
|
||||||
style="enable-background:new 0 0 1050 1050.5;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:#20221F;}
|
|
||||||
.st1{fill:#3B3B3B;}
|
|
||||||
.st2{fill:#121212;}
|
|
||||||
.st3{fill:#444542;}
|
|
||||||
.st4{fill:#FFFFFF;}
|
|
||||||
.st5{fill:#444542;stroke:#FFFFFF;stroke-width:2;stroke-miterlimit:10;}
|
|
||||||
.st6{fill:#454644;}
|
|
||||||
.st7{fill:#454644;stroke:#FFFFFF;stroke-width:2;stroke-miterlimit:10;}
|
|
||||||
.st8{fill:#3B3C3A;}
|
|
||||||
.st9{font-family:'Helvetica-Bold';}
|
|
||||||
.st10{font-size:40px;}
|
|
||||||
.st11{fill:#0D0D0A;}
|
|
||||||
</style>
|
|
||||||
<g id="Front">
|
|
||||||
<path id="Right_Grip_00000028282943321285403220000008369785803052272051_" class="st0" d="M766,850.5
|
|
||||||
c34,28.2,27.6,35.9,68.5,108.5c36.7,74.7,64.4,104.4,125.1,84.1v0c95.3-57.9,59.3-145.3,43.6-275.2c-10-60.6-35.6-190.3-35.6-190.3
|
|
||||||
L766,850.5z"/>
|
|
||||||
<path id="Left_Grip" class="st0" d="M82.3,577.6c0,0-25.6,129.7-35.6,190.3C31,897.8-5,985.1,90.3,1043v0
|
|
||||||
c60.8,20.3,88.4-9.4,125.1-84.1c40.9-72.7,34.5-80.3,68.5-108.5L82.3,577.6z"/>
|
|
||||||
<path id="Right_Bumper_00000006710349871522532470000011078040965381267594_" class="st1" d="M676.3,378.4
|
|
||||||
c10.1-4.3,39.7-22.5,58.7-19.7c59.5,0.9,166.7,17.7,172.6,81.2"/>
|
|
||||||
<path id="Left_Bumper_00000024680414077879639570000011759596763560342154_" class="st1" d="M142.4,439.9
|
|
||||||
c5.9-63.4,113-80.2,172.6-81.2c19-2.8,48.6,15.4,58.7,19.7"/>
|
|
||||||
<path id="Background_00000141418846164053065470000016150094984198570163_" class="st2" d="M766,850.5
|
|
||||||
c35.5-30.8,68.5-74.7,96-113.5c26.9-36.3,94.7-136.7,105.6-159.3c0-2.4-6.3-30.1-12.8-56.2C919.1,361.9,702.2,378.1,525,378.1
|
|
||||||
c-177.4,0-394.1-16.2-429.9,143.3c-6.5,26-12.8,53.8-12.8,56.2c10.9,22.6,78.8,123,105.6,159.3c27.5,38.8,60.5,82.8,96,113.5"/>
|
|
||||||
<g id="Directional_Pad">
|
|
||||||
<path id="Background_00000032628022449190479560000015279211462520783249_" class="st3" d="M466.2,683.5h-40c-2.8,0-5-2.2-5-5v-40
|
|
||||||
c0-2.8-2.2-5-5-5h-30c-2.8,0-5,2.2-5,5v40c0,2.8-2.2,5-5,5h-40c-2.8,0-5,2.2-5,5v30c0,2.8,2.2,5,5,5h40c2.8,0,5,2.2,5,5v40
|
|
||||||
c0,2.8,2.2,5,5,5h30c2.8,0,5-2.2,5-5v-40c0-2.8,2.2-5,5-5h40c2.8,0,5-2.2,5-5v-30C471.2,685.8,469,683.5,466.2,683.5z"/>
|
|
||||||
<g id="Arrows">
|
|
||||||
<g>
|
|
||||||
<polygon class="st4" points="393.7,746 408.7,746 401.2,761 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st4" points="358.7,696 358.7,711 343.7,703.5 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st4" points="408.7,661 393.7,661 401.2,646 "/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<polygon class="st4" points="443.7,711 443.7,696 458.7,703.5 "/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g id="R_Thumbstick_00000152226188525111835500000011838297421350334865_">
|
|
||||||
<circle id="Background_00000035532849542660068350000006517224202948159422_" class="st0" cx="650.6" cy="703.5" r="55"/>
|
|
||||||
<circle id="Stick" class="st5" cx="650.6" cy="703.5" r="45"/>
|
|
||||||
</g>
|
|
||||||
<g id="L_Thumbstick_00000047032468231999382210000005512347386782594484_">
|
|
||||||
<circle id="Background_00000182502673988292164000000007125719133096369561_" class="st0" cx="240.2" cy="564.8" r="55"/>
|
|
||||||
<circle id="Stick_00000075121990265259598900000000214370239054002365_" class="st5" cx="240.2" cy="564.8" r="45"/>
|
|
||||||
</g>
|
|
||||||
<g id="Minus_Button">
|
|
||||||
<circle id="_Background_00000120554951013892796430000015877571645746699662_" class="st6" cx="401" cy="489.3" r="22.5"/>
|
|
||||||
<polyline id="Plus_00000039131319101621183460000006196023733899658629_" class="st4" points="386.2,491.8 386.2,486.8
|
|
||||||
416.2,486.8 416.2,491.8 "/>
|
|
||||||
</g>
|
|
||||||
<g id="Plus_Button">
|
|
||||||
<circle id="_Background" class="st6" cx="650.4" cy="489.6" r="22.5"/>
|
|
||||||
<polygon id="Plus" class="st4" points="665.6,487.1 653.1,487.1 653.1,474.4 648.1,474.4 648.1,487.1 635.6,487.1 635.6,492.1
|
|
||||||
648.1,492.1 648.1,504.4 653.1,504.4 653.1,492.1 665.6,492.1 "/>
|
|
||||||
</g>
|
|
||||||
<g id="Home_Button_00000029758737660217614780000001403165237001195407_">
|
|
||||||
<circle id="_Background_00000132788487854287834010000009548421243227981499_" class="st6" cx="605.4" cy="564.8" r="22.5"/>
|
|
||||||
<path id="Home" class="st4" d="M605.4,549.8l-15,15h5v15h20v-15h5L605.4,549.8z M610.4,574.8h-10v-10h10V574.8z"/>
|
|
||||||
</g>
|
|
||||||
<g id="Capture_Button_00000105394663133565750060000017455731898661404072_">
|
|
||||||
<path class="st6" d="M468.6,586.5h-30c-2.8,0-5-2.2-5-5v-29.5c0-2.8,2.2-5,5-5h30c2.8,0,5,2.2,5,5v29.5
|
|
||||||
C473.6,584.2,471.4,586.5,468.6,586.5z"/>
|
|
||||||
<circle class="st7" cx="453.6" cy="566.7" r="15"/>
|
|
||||||
</g>
|
|
||||||
<g id="Buttons_00000023239109225132251950000005218343074279628213_">
|
|
||||||
<g id="A_Button">
|
|
||||||
<circle id="Background_00000006699118933065716380000004636085088820886913_" class="st8" cx="863.9" cy="564.8" r="35"/>
|
|
||||||
<text transform="matrix(1 0 0 1 849.4224 578.6607)" class="st4 st9 st10">A</text>
|
|
||||||
</g>
|
|
||||||
<g id="X_Button">
|
|
||||||
<circle id="Background_00000083074713085756701790000016893839312974798515_" class="st8" cx="793.9" cy="494.8" r="35"/>
|
|
||||||
<text transform="matrix(1 0 0 1 780.5266 508.6604)" class="st4 st9 st10">X</text>
|
|
||||||
</g>
|
|
||||||
<g id="Y_Button_00000100344340438574137780000014238704828967683973_">
|
|
||||||
<circle id="Background_00000137100455694543496620000011124722786613194377_" class="st8" cx="723.9" cy="564.8" r="35"/>
|
|
||||||
<text transform="matrix(1 0 0 1 710.5263 578.661)" class="st4 st9 st10">Y</text>
|
|
||||||
</g>
|
|
||||||
<g id="B_Button_00000041994261956088037220000013468634544777304733_">
|
|
||||||
<circle id="Background_00000096038108578846046800000001873940014252420514_" class="st8" cx="793.9" cy="634.8" r="35"/>
|
|
||||||
<text transform="matrix(1 0 0 1 780.9706 648.6605)" class="st4 st9 st10">B</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g id="Top_Down">
|
|
||||||
<path id="Left_Grip_00000026131988385328425370000016677941743356253314_" class="st0" d="M219.2,78.5
|
|
||||||
c-12.5-17.6-25.9-42.3-45.6-58.6C153.5,3.3,112.1-4.7,87.1,5.8c-13.9,5.8-33.4,33.1-42.7,52.8C33.9,80.9,30.4,109.9,32,141.4
|
|
||||||
c1.2,25.1,5.3,51.7,14.2,78.6c0,0,14.3,53.8,42.8,80.8c11.2,10.6,35,26.6,35,26.6l116-217.5C240,109.9,224.6,86.2,219.2,78.5z"/>
|
|
||||||
<path id="Right_Grip_00000016782759094708820330000002450847065936193693_" class="st0" d="M828.6,78.5
|
|
||||||
c12.5-17.6,25.9-42.3,45.6-58.6c20.1-16.6,61.4-24.5,86.5-14.1c13.9,5.8,33.4,33.1,42.7,52.8c10.5,22.3,13.9,51.3,12.4,82.8
|
|
||||||
c-1.2,25.1-5.3,51.7-14.2,78.6c0,0-14.3,53.8-42.8,80.8c-11.2,10.6-35,26.6-35,26.6l-116-217.5C807.8,109.9,823.2,86.2,828.6,78.5z
|
|
||||||
"/>
|
|
||||||
<path id="Background_00000169534857628063347190000007586592143875928969_" class="st11" d="M866,122.2
|
|
||||||
c66.3,18.7,85.1,128.8,69,186c-2.5,54.2-148.9,15.3-265.1,31.2c-41.1,1.7-91.8,2.4-145.9,2.3c-54.1,0-104.8-0.6-145.9-2.3
|
|
||||||
c-116.2-15.9-262.6,23.1-265.1-31.2c-16.1-57.1,2.6-167.3,69-186l60.5-18.8l38.9-1.9c40.2,0.1,142.8,0,242.7,0
|
|
||||||
c99.9,0,202.4,0.1,242.7,0l38.9,1.9L866,122.2z"/>
|
|
||||||
<g id="ZL_Trigger_00000005254517714433203260000014117442438696169895_">
|
|
||||||
<path id="Background_00000111870097528015387240000017384507710402295183_" class="st1" d="M145.9,239.2
|
|
||||||
c15.2-97.4,38.1-147.2,141.7-137c8.2,16.4,43.3,83,50.6,105.7C280.6,227.2,204.7,225.6,145.9,239.2z"/>
|
|
||||||
<text id="ZL_Trigger" transform="matrix(1.0139 0 0 1 218.3906 179.3992)" class="st4 st9 st10">ZL</text>
|
|
||||||
</g>
|
|
||||||
<g id="ZR_Trigger">
|
|
||||||
<path id="Background_00000133526766189752063450000016781240006605114763_" class="st1" d="M716.2,207.9
|
|
||||||
c7.4-22.7,42.5-89.3,50.6-105.7c103.7-10.2,126.5,39.6,141.7,137C849.8,225.6,773.8,227.2,716.2,207.9z"/>
|
|
||||||
|
|
||||||
<text id="ZL_Trigger_00000000206350378518266660000001315160307759857328_" transform="matrix(1.0139 0 0 1 784.2356 179.3992)" class="st4 st9 st10">ZR</text>
|
|
||||||
</g>
|
|
||||||
<g id="R_Trigger_00000085939413106284991650000014018840000393673094_">
|
|
||||||
<path id="Background" class="st1" d="M664,318.5c7-10.1,27.8-78.4,45.4-78.7C1040.8,243.7,897.1,334,664,318.5z"/>
|
|
||||||
<text id="R_Trigger" transform="matrix(1 0 0 1 769.6461 292.8947)" class="st4 st9 st10">R</text>
|
|
||||||
</g>
|
|
||||||
<g id="L_Trigger">
|
|
||||||
<path id="Background_00000043427985111927735300000011910735497762731703_" class="st1" d="M340.6,238.6
|
|
||||||
c17.6,0.3,38.4,68.6,45.4,78.7C152.9,332.8,9.2,242.6,340.6,238.6z"/>
|
|
||||||
|
|
||||||
<text id="R_Trigger_00000092444210070373642420000009814634285137007748_" transform="matrix(1 0 0 1 253.7327 291.7279)" class="st4 st9 st10">L</text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 8.0 KiB |
@ -21,34 +21,6 @@
|
|||||||
<None Remove="Resources\Logo_Ryujinx.png" />
|
<None Remove="Resources\Logo_Ryujinx.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="Resources\Controller_JoyConLeft.svg" />
|
|
||||||
<EmbeddedResource Include="Resources\Controller_JoyConPair.svg" />
|
|
||||||
<EmbeddedResource Include="Resources\Controller_JoyConRight.svg" />
|
|
||||||
<EmbeddedResource Include="Resources\Controller_ProCon.svg" />
|
|
||||||
<EmbeddedResource Include="Resources\Icon_NCA.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Icon_NRO.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Icon_NSO.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Icon_NSP.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Icon_XCI.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Logo_Amiibo.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Logo_Ryujinx.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Logo_Ryujinx_AntiAlias.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Logo_Discord_Dark.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Logo_Discord_Light.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Logo_GitHub_Dark.png" />
|
|
||||||
<EmbeddedResource Include="Resources\Logo_GitHub_Light.png" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64' OR '$(RuntimeIdentifier)' == ''">
|
|
||||||
<EmbeddedResource Include="..\..\distribution\linux\shortcut-template.desktop" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'osx-x64' OR '$(RuntimeIdentifier)' == 'osx-arm64' OR '$(RuntimeIdentifier)' == ''">
|
|
||||||
<EmbeddedResource Include="..\..\distribution\macos\shortcut-template.plist" />
|
|
||||||
<EmbeddedResource Include="..\..\distribution\macos\shortcut-launch-script.sh" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DiscordRichPresence" />
|
<PackageReference Include="DiscordRichPresence" />
|
||||||
<PackageReference Include="DynamicData" />
|
<PackageReference Include="DynamicData" />
|
||||||
|
@ -20,11 +20,15 @@ using Ryujinx.Ava.UI.Models;
|
|||||||
using Ryujinx.Ava.UI.Renderer;
|
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.AppLibrary;
|
||||||
|
using Ryujinx.Ava.Utilities.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;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.SystemInterop;
|
using Ryujinx.Common.SystemInterop;
|
||||||
|
using Ryujinx.Common.UI;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading;
|
using Ryujinx.Graphics.GAL.Multithreading;
|
||||||
@ -39,10 +43,6 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
|
|||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Input.HLE;
|
using Ryujinx.Input.HLE;
|
||||||
using Ryujinx.UI.App.Common;
|
|
||||||
using Ryujinx.UI.Common;
|
|
||||||
using Ryujinx.UI.Common.Configuration;
|
|
||||||
using Ryujinx.UI.Common.Helper;
|
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using SPB.Graphics.Vulkan;
|
using SPB.Graphics.Vulkan;
|
||||||
@ -289,19 +289,19 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
private void UpdateScalingFilterLevel(object sender, ReactiveEventArgs<int> e)
|
private void UpdateScalingFilterLevel(object sender, ReactiveEventArgs<int> e)
|
||||||
{
|
{
|
||||||
_renderer.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value);
|
_renderer.Window?.SetScalingFilter(ConfigurationState.Instance.Graphics.ScalingFilter);
|
||||||
_renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value);
|
_renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateScalingFilter(object sender, ReactiveEventArgs<ScalingFilter> e)
|
private void UpdateScalingFilter(object sender, ReactiveEventArgs<ScalingFilter> e)
|
||||||
{
|
{
|
||||||
_renderer.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value);
|
_renderer.Window?.SetScalingFilter(ConfigurationState.Instance.Graphics.ScalingFilter);
|
||||||
_renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value);
|
_renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateColorSpacePassthrough(object sender, ReactiveEventArgs<bool> e)
|
private void UpdateColorSpacePassthrough(object sender, ReactiveEventArgs<bool> e)
|
||||||
{
|
{
|
||||||
_renderer.Window?.SetColorSpacePassthrough((bool)ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value);
|
_renderer.Window?.SetColorSpacePassthrough(ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateVSyncMode(object sender, ReactiveEventArgs<VSyncMode> e)
|
public void UpdateVSyncMode(object sender, ReactiveEventArgs<VSyncMode> e)
|
||||||
@ -311,6 +311,7 @@ namespace Ryujinx.Ava
|
|||||||
Device.VSyncMode = e.NewValue;
|
Device.VSyncMode = e.NewValue;
|
||||||
Device.UpdateVSyncInterval();
|
Device.UpdateVSyncInterval();
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderer.Window?.ChangeVSyncMode(e.NewValue);
|
_renderer.Window?.ChangeVSyncMode(e.NewValue);
|
||||||
|
|
||||||
_viewModel.ShowCustomVSyncIntervalPicker = (e.NewValue == VSyncMode.Custom);
|
_viewModel.ShowCustomVSyncIntervalPicker = (e.NewValue == VSyncMode.Custom);
|
||||||
@ -526,7 +527,7 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
private void UpdateAntiAliasing(object sender, ReactiveEventArgs<AntiAliasing> e)
|
private void UpdateAntiAliasing(object sender, ReactiveEventArgs<AntiAliasing> e)
|
||||||
{
|
{
|
||||||
_renderer?.Window?.SetAntiAliasing((Graphics.GAL.AntiAliasing)e.NewValue);
|
_renderer?.Window?.SetAntiAliasing(e.NewValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateDockedModeState(object sender, ReactiveEventArgs<bool> e)
|
private void UpdateDockedModeState(object sender, ReactiveEventArgs<bool> e)
|
||||||
@ -577,7 +578,6 @@ namespace Ryujinx.Ava
|
|||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
_isActive = false;
|
_isActive = false;
|
||||||
DiscordIntegrationModule.SwitchToMainState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Exit()
|
private void Exit()
|
||||||
@ -862,12 +862,10 @@ namespace Ryujinx.Ava
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationMetadata appMeta = ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText,
|
ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText,
|
||||||
appMetadata => appMetadata.UpdatePreGame()
|
appMetadata => appMetadata.UpdatePreGame()
|
||||||
);
|
);
|
||||||
|
|
||||||
DiscordIntegrationModule.SwitchToPlayingState(appMeta, Device.Processes.ActiveApplication);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,7 +921,7 @@ namespace Ryujinx.Ava
|
|||||||
// Initialize Configuration.
|
// Initialize Configuration.
|
||||||
var memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value;
|
var memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value;
|
||||||
|
|
||||||
Device = new HLE.Switch(new HLEConfiguration(
|
Device = new Switch(new HLEConfiguration(
|
||||||
VirtualFileSystem,
|
VirtualFileSystem,
|
||||||
_viewModel.LibHacHorizonManager,
|
_viewModel.LibHacHorizonManager,
|
||||||
ContentManager,
|
ContentManager,
|
||||||
@ -953,7 +951,8 @@ namespace Ryujinx.Ava
|
|||||||
ConfigurationState.Instance.Multiplayer.DisableP2p,
|
ConfigurationState.Instance.Multiplayer.DisableP2p,
|
||||||
ConfigurationState.Instance.Multiplayer.LdnPassphrase,
|
ConfigurationState.Instance.Multiplayer.LdnPassphrase,
|
||||||
ConfigurationState.Instance.Multiplayer.LdnServer,
|
ConfigurationState.Instance.Multiplayer.LdnServer,
|
||||||
ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value));
|
ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value,
|
||||||
|
ConfigurationState.Instance.Hacks.ShowDirtyHacks ? ConfigurationState.Instance.Hacks.EnabledHacks : null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IHardwareDeviceDriver InitializeAudio()
|
private static IHardwareDeviceDriver InitializeAudio()
|
||||||
@ -1057,10 +1056,10 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
Device.Gpu.Renderer.Initialize(_glLogLevel);
|
Device.Gpu.Renderer.Initialize(_glLogLevel);
|
||||||
|
|
||||||
_renderer?.Window?.SetAntiAliasing((Graphics.GAL.AntiAliasing)ConfigurationState.Instance.Graphics.AntiAliasing.Value);
|
_renderer?.Window?.SetAntiAliasing(ConfigurationState.Instance.Graphics.AntiAliasing);
|
||||||
_renderer?.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value);
|
_renderer?.Window?.SetScalingFilter(ConfigurationState.Instance.Graphics.ScalingFilter);
|
||||||
_renderer?.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value);
|
_renderer?.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel);
|
||||||
_renderer?.Window?.SetColorSpacePassthrough(ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value);
|
_renderer?.Window?.SetColorSpacePassthrough(ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough);
|
||||||
|
|
||||||
Width = (int)RendererHost.Bounds.Width;
|
Width = (int)RendererHost.Bounds.Width;
|
||||||
Height = (int)RendererHost.Bounds.Height;
|
Height = (int)RendererHost.Bounds.Height;
|
||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 253 KiB After Width: | Height: | Size: 253 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@ -93,7 +93,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Аплет для редагування Mii",
|
"uk_UA": "Аплет для редагування Mii",
|
||||||
"zh_CN": "",
|
"zh_CN": "Mii 小程序",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -743,7 +743,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "从bin文件扫描 Amiibo",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -868,7 +868,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "安装密匙",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -893,7 +893,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "从.KEYS文件或ZIP压缩包安装密匙",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -918,7 +918,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "从一个文件夹安装密匙",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1018,7 +1018,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізати XCI файли",
|
"uk_UA": "Обрізати XCI файли",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件瘦身",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1268,7 +1268,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "常见问题和问题排除页面",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1293,7 +1293,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "打开Ryujinx官方wiki的常见问题和问题排除页面",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1318,7 +1318,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "安装与配置指南",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1343,7 +1343,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "打开Ryujinx官方wiki的安装与配置指南",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1368,7 +1368,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "多人游戏(LDN/LAN)指南",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1393,7 +1393,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "打开Ryujinx官方wiki的多人游戏指南",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2543,7 +2543,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перевірка та Нарізка XCI Файлів",
|
"uk_UA": "Перевірка та Нарізка XCI Файлів",
|
||||||
"zh_CN": "",
|
"zh_CN": "检查并瘦身XCI文件",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2568,7 +2568,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перевірка та Нарізка XCI Файлів для збереження місця на диску",
|
"uk_UA": "Перевірка та Нарізка XCI Файлів для збереження місця на диску",
|
||||||
"zh_CN": "",
|
"zh_CN": "检查并瘦身XCI文件以节约磁盘空间",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2643,7 +2643,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізано XCI Файлів '{0}'",
|
"uk_UA": "Обрізано XCI Файлів '{0}'",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件瘦身中'{0}'",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -10518,7 +10518,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Скасування",
|
"uk_UA": "Скасування",
|
||||||
"zh_CN": "",
|
"zh_CN": "正在取消",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -10543,7 +10543,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Закрити",
|
"uk_UA": "Закрити",
|
||||||
"zh_CN": "",
|
"zh_CN": "关闭",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -11843,7 +11843,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Показати список змін",
|
"uk_UA": "Показати список змін",
|
||||||
"zh_CN": "",
|
"zh_CN": "显示更新日志",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -12318,7 +12318,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件瘦身窗口",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -13043,7 +13043,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "在{0}发现了一个无效的密匙文件",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -13068,7 +13068,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Встановлення Ключів",
|
"uk_UA": "Встановлення Ключів",
|
||||||
"zh_CN": "",
|
"zh_CN": "安装密匙",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -13093,7 +13093,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Новий файл Ключів буде встановлено",
|
"uk_UA": "Новий файл Ключів буде встановлено",
|
||||||
"zh_CN": "",
|
"zh_CN": "将会安装新密匙文件",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -13118,7 +13118,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "\n\nЦе замінить собою поточні файли Ключів.",
|
"uk_UA": "\n\nЦе замінить собою поточні файли Ключів.",
|
||||||
"zh_CN": "",
|
"zh_CN": "\n\n这也许会替换掉一些当前已安装的密匙",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -13143,7 +13143,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "\n\nВи хочете продовжити?",
|
"uk_UA": "\n\nВи хочете продовжити?",
|
||||||
"zh_CN": "",
|
"zh_CN": "\n\n你想要继续吗?",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -13168,7 +13168,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Встановлення Ключів...",
|
"uk_UA": "Встановлення Ключів...",
|
||||||
"zh_CN": "",
|
"zh_CN": "安装密匙中。。。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -13193,7 +13193,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Нові ключі встановлено.",
|
"uk_UA": "Нові ключі встановлено.",
|
||||||
"zh_CN": "",
|
"zh_CN": "已成功安装新密匙文件",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -14243,7 +14243,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Минулі розробники:",
|
"uk_UA": "Минулі розробники:",
|
||||||
"zh_CN": "",
|
"zh_CN": "曾经的维护者:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -15268,7 +15268,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "重新同步系统时间以匹配您电脑的当前日期和时间。\n\n这个操作不会实时同步系统时间与电脑时间,时间仍然可能不同步;在这种情况下,只需再次单击此按钮即可。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -17426,25 +17426,25 @@
|
|||||||
"ID": "TitleUpdateVersionLabel",
|
"ID": "TitleUpdateVersionLabel",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
"ar_SA": "الإصدار: {0}",
|
"ar_SA": "الإصدار: {0}",
|
||||||
"de_DE": "Version {0} - {1}",
|
"de_DE": "",
|
||||||
"el_GR": "Version {0} - {1}",
|
"el_GR": "",
|
||||||
"en_US": "Version {0} - {1}",
|
"en_US": "Version {0}",
|
||||||
"es_ES": "Versión {0} - {1}",
|
"es_ES": "Versión {0}",
|
||||||
"fr_FR": "",
|
"fr_FR": "",
|
||||||
"he_IL": "גרסה {0} - {1}",
|
"he_IL": "גרסה: {0}",
|
||||||
"it_IT": "Versione {0} - {1}",
|
"it_IT": "Versione {0}",
|
||||||
"ja_JP": "バージョン {0} - {1}",
|
"ja_JP": "バージョン {0}",
|
||||||
"ko_KR": "버전 {0} - {1}",
|
"ko_KR": "버전 {0}",
|
||||||
"no_NO": "Versjon {0} - {1}",
|
"no_NO": "Versjon {0}",
|
||||||
"pl_PL": "Wersja {0} - {1}",
|
"pl_PL": "Wersja {0}",
|
||||||
"pt_BR": "Versão {0} - {1}",
|
"pt_BR": "Versão {0}",
|
||||||
"ru_RU": "Версия {0} - {1}",
|
"ru_RU": "Версия {0}",
|
||||||
"sv_SE": "Version {0} - {1}",
|
"sv_SE": "Version {0}",
|
||||||
"th_TH": "เวอร์ชั่น {0} - {1}",
|
"th_TH": "เวอร์ชั่น {0}",
|
||||||
"tr_TR": "Sürüm {0} - {1}",
|
"tr_TR": "Sürüm {0}",
|
||||||
"uk_UA": "Версія {0} - {1}",
|
"uk_UA": "Версія {0}",
|
||||||
"zh_CN": "游戏更新的版本 {0} - {1}",
|
"zh_CN": "游戏更新的版本 {0}",
|
||||||
"zh_TW": "版本 {0} - {1}"
|
"zh_TW": "版本 {0}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -17518,7 +17518,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Часткові",
|
"uk_UA": "Часткові",
|
||||||
"zh_CN": "",
|
"zh_CN": "分区",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -17543,7 +17543,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Необрізані",
|
"uk_UA": "Необрізані",
|
||||||
"zh_CN": "",
|
"zh_CN": "没有瘦身的",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -17568,7 +17568,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізані",
|
"uk_UA": "Обрізані",
|
||||||
"zh_CN": "",
|
"zh_CN": "经过瘦身的",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -17593,7 +17593,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "(Невдача)",
|
"uk_UA": "(Невдача)",
|
||||||
"zh_CN": "",
|
"zh_CN": "(失败)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -17618,7 +17618,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Зберегти {0:n0} Мб",
|
"uk_UA": "Зберегти {0:n0} Мб",
|
||||||
"zh_CN": "",
|
"zh_CN": "能节约 {0:n0} Mb",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -17643,7 +17643,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Збережено {0:n0} Мб",
|
"uk_UA": "Збережено {0:n0} Мб",
|
||||||
"zh_CN": "",
|
"zh_CN": "节约了 {0:n0} Mb",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -17843,7 +17843,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вкажіть Ваше нове ім'я Amiibo",
|
"uk_UA": "Вкажіть Ваше нове ім'я Amiibo",
|
||||||
"zh_CN": "",
|
"zh_CN": "输入你的 Amiibo 的新名字",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -17868,7 +17868,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Будь ласка, проскануйте Ваш Amiibo.",
|
"uk_UA": "Будь ласка, проскануйте Ваш Amiibo.",
|
||||||
"zh_CN": "",
|
"zh_CN": "请现在扫描你的 Amiibo",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -18993,7 +18993,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перевірити та Обрізати XCI файл",
|
"uk_UA": "Перевірити та Обрізати XCI файл",
|
||||||
"zh_CN": "",
|
"zh_CN": "检查并瘦身XCI文件",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19018,7 +19018,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Ця функція спочатку перевірить вільний простір, а потім обрізатиме файл XCI для економії місця на диску.",
|
"uk_UA": "Ця функція спочатку перевірить вільний простір, а потім обрізатиме файл XCI для економії місця на диску.",
|
||||||
"zh_CN": "",
|
"zh_CN": "这个功能将会先检查XCI文件,再对其执行瘦身操作以节约磁盘空间。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19043,7 +19043,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Поточний розмір файла: {0:n} MB\nРозмір файлів гри: {1:n} MB\nЕкономія місця: {2:n} MB",
|
"uk_UA": "Поточний розмір файла: {0:n} MB\nРозмір файлів гри: {1:n} MB\nЕкономія місця: {2:n} MB",
|
||||||
"zh_CN": "",
|
"zh_CN": "当前文件大小: {0:n} MB\n游戏数据大小: {1:n} MB\n节约的磁盘空间: {2:n} MB",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19068,7 +19068,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI файл не потребує обрізання. Перевірте журнали для додаткової інформації",
|
"uk_UA": "XCI файл не потребує обрізання. Перевірте журнали для додаткової інформації",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件不需要被瘦身。查看日志以获得更多细节。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19093,7 +19093,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI файл не може бути обрізаний. Перевірте журнали для додаткової інформації",
|
"uk_UA": "XCI файл не може бути обрізаний. Перевірте журнали для додаткової інформації",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件不能被瘦身。查看日志以获得更多细节。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19118,7 +19118,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали додаткової інформації",
|
"uk_UA": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали додаткової інформації",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件是只读的,且不可以被标记为可读取的。查看日志以获得更多细节。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19143,7 +19143,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Розмір файлу XCI змінився з моменту сканування. Перевірте, чи не записується файл, та спробуйте знову",
|
"uk_UA": "Розмір файлу XCI змінився з моменту сканування. Перевірте, чи не записується файл, та спробуйте знову",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件在扫描后大小发生了变化。请检查文件是否未被写入,然后重试。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19168,7 +19168,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Файл XCI містить дані в зоні вільного простору, тому обрізка небезпечна",
|
"uk_UA": "Файл XCI містить дані в зоні вільного простору, тому обрізка небезпечна",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件的空闲区域内有数据,不能安全瘦身。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19193,7 +19193,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI Файл містить недійсні дані. Перевірте журнали для додаткової інформації",
|
"uk_UA": "XCI Файл містить недійсні дані. Перевірте журнали для додаткової інформації",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件含有无效数据。查看日志以获得更多细节。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19218,7 +19218,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "XCI Файл файл не вдалося відкрити для запису. Перевірте журнали для додаткової інформації",
|
"uk_UA": "XCI Файл файл не вдалося відкрити для запису. Перевірте журнали для додаткової інформації",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件不能被读写。查看日志以获得更多细节。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19243,7 +19243,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Не вдалося обрізати файл XCI",
|
"uk_UA": "Не вдалося обрізати файл XCI",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件瘦身失败",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19268,7 +19268,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Операція перервана",
|
"uk_UA": "Операція перервана",
|
||||||
"zh_CN": "",
|
"zh_CN": "操作已取消",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19293,7 +19293,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Операція не проводилася",
|
"uk_UA": "Операція не проводилася",
|
||||||
"zh_CN": "",
|
"zh_CN": "未执行操作",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19443,7 +19443,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізка XCI Файлів",
|
"uk_UA": "Обрізка XCI Файлів",
|
||||||
"zh_CN": "",
|
"zh_CN": "XCI文件瘦身器",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19468,7 +19468,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "{0} з {1} тайтл(ів) обрано",
|
"uk_UA": "{0} з {1} тайтл(ів) обрано",
|
||||||
"zh_CN": "",
|
"zh_CN": "在 {1} 中选中了 {0} 个游戏 ",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19493,7 +19493,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "{0} з {1} тайтл(ів) обрано ({2} відображається)",
|
"uk_UA": "{0} з {1} тайтл(ів) обрано ({2} відображається)",
|
||||||
"zh_CN": "",
|
"zh_CN": "在 {1} 中选中了 {0} 个游戏 (显示了 {2} 个)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19518,7 +19518,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізка {0} тайтл(ів)...",
|
"uk_UA": "Обрізка {0} тайтл(ів)...",
|
||||||
"zh_CN": "",
|
"zh_CN": "{0} 个游戏瘦身中。。。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19568,7 +19568,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Невдача",
|
"uk_UA": "Невдача",
|
||||||
"zh_CN": "",
|
"zh_CN": "失败",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19593,7 +19593,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Потенційна економія",
|
"uk_UA": "Потенційна економія",
|
||||||
"zh_CN": "",
|
"zh_CN": "潜在的储存空间节省",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19618,7 +19618,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Зекономлено",
|
"uk_UA": "Зекономлено",
|
||||||
"zh_CN": "",
|
"zh_CN": "实际的储存空间节省",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19668,7 +19668,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вибрати показане",
|
"uk_UA": "Вибрати показане",
|
||||||
"zh_CN": "",
|
"zh_CN": "选定显示的",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19693,7 +19693,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Скасувати вибір показаного",
|
"uk_UA": "Скасувати вибір показаного",
|
||||||
"zh_CN": "",
|
"zh_CN": "反选显示的",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -19768,7 +19768,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Обрізка",
|
"uk_UA": "Обрізка",
|
||||||
"zh_CN": "",
|
"zh_CN": "瘦身",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -20143,7 +20143,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Продовжити",
|
"uk_UA": "Продовжити",
|
||||||
"zh_CN": "",
|
"zh_CN": "继续",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -20518,7 +20518,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "自动",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -20543,7 +20543,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "使用Vulkan。\n在ARM Mac上,当玩在其下运行良好的游戏时,使用Metal后端。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -21943,7 +21943,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вимкнути хостинг P2P мережі (може збільшити затримку)",
|
"uk_UA": "Вимкнути хостинг P2P мережі (може збільшити затримку)",
|
||||||
"zh_CN": "",
|
"zh_CN": "禁用P2P网络连接 (也许会增加延迟)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -21968,7 +21968,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вимкнути хостинг P2P мережі, піри будуть підключатися через майстер-сервер замість прямого з'єднання з вами.",
|
"uk_UA": "Вимкнути хостинг P2P мережі, піри будуть підключатися через майстер-сервер замість прямого з'єднання з вами.",
|
||||||
"zh_CN": "",
|
"zh_CN": "禁用P2P网络连接,对方将通过主服务器进行连接,而不是直接连接到您。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -21993,7 +21993,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Мережевий пароль:",
|
"uk_UA": "Мережевий пароль:",
|
||||||
"zh_CN": "",
|
"zh_CN": "网络密码:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22018,7 +22018,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
"uk_UA": "Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
||||||
"zh_CN": "",
|
"zh_CN": "您只能看到与您使用相同密码的游戏房间。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22043,7 +22043,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Введіть пароль у форматі Ryujinx-<8 символів>. Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
"uk_UA": "Введіть пароль у форматі Ryujinx-<8 символів>. Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
||||||
"zh_CN": "",
|
"zh_CN": "以Ryujinx-<8个十六进制字符>的格式输入密码。您只能看到与您使用相同密码的游戏房间。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22068,7 +22068,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "(публічний)",
|
"uk_UA": "(публічний)",
|
||||||
"zh_CN": "",
|
"zh_CN": "(公开的)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22093,7 +22093,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Згенерувати випадкову",
|
"uk_UA": "Згенерувати випадкову",
|
||||||
"zh_CN": "",
|
"zh_CN": "随机生成",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22118,7 +22118,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Генерує новий пароль, яким можна поділитися з іншими гравцями.",
|
"uk_UA": "Генерує новий пароль, яким можна поділитися з іншими гравцями.",
|
||||||
"zh_CN": "",
|
"zh_CN": "生成一个新的密码,可以与其他玩家共享。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22143,7 +22143,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Очистити",
|
"uk_UA": "Очистити",
|
||||||
"zh_CN": "",
|
"zh_CN": "清除",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22168,7 +22168,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Очищає поточну пароль, повертаючись до публічної мережі.",
|
"uk_UA": "Очищає поточну пароль, повертаючись до публічної мережі.",
|
||||||
"zh_CN": "",
|
"zh_CN": "清除当前密码,返回公共网络。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22193,7 +22193,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Невірний пароль! Має бути в форматі \"Ryujinx-<8 символів>\"",
|
"uk_UA": "Невірний пароль! Має бути в форматі \"Ryujinx-<8 символів>\"",
|
||||||
"zh_CN": "",
|
"zh_CN": "无效密码!密码的格式必须是\"Ryujinx-<8个十六进制字符>\"",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22218,7 +22218,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Вертикальна синхронізація (VSync):",
|
"uk_UA": "Вертикальна синхронізація (VSync):",
|
||||||
"zh_CN": "",
|
"zh_CN": "垂直同步(VSync)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22243,7 +22243,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Увімкнути користувацьку частоту оновлення (Експериментально)",
|
"uk_UA": "Увімкнути користувацьку частоту оновлення (Експериментально)",
|
||||||
"zh_CN": "",
|
"zh_CN": "启动自定义刷新率(实验性功能)",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22293,7 +22293,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Безмежна",
|
"uk_UA": "Безмежна",
|
||||||
"zh_CN": "",
|
"zh_CN": "无限制",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22318,7 +22318,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Користувацька",
|
"uk_UA": "Користувацька",
|
||||||
"zh_CN": "",
|
"zh_CN": "自定义刷新率",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22343,7 +22343,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень.",
|
"uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень.",
|
||||||
"zh_CN": "",
|
"zh_CN": "模拟垂直同步。“Switch”模拟了Switch的60Hz刷新率。“无限制”没有刷新率限制。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22368,7 +22368,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.",
|
"uk_UA": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.",
|
||||||
"zh_CN": "",
|
"zh_CN": "模拟垂直同步。“Switch”模拟了Switch的60Hz刷新率。“无限制”没有刷新率限制。“自定义刷新率”模拟指定的自定义刷新率。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22393,7 +22393,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. У інших іграх це може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як це вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.",
|
"uk_UA": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. У інших іграх це може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як це вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.",
|
||||||
"zh_CN": "",
|
"zh_CN": "允许用户指定模拟刷新率。在某些游戏中,这可能会加快或减慢游戏逻辑的速度。在其他游戏中,它可能允许将FPS限制在刷新率的某个倍数,或者导致不可预测的行为。这是一个实验性功能,无法保证游戏会受到怎样的影响。\n\n如果不确定,请关闭。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22418,7 +22418,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Цільове значення користувацької частоти оновлення.",
|
"uk_UA": "Цільове значення користувацької частоти оновлення.",
|
||||||
"zh_CN": "",
|
"zh_CN": "目标自定义刷新率值。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22443,7 +22443,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Користувацька частота оновлення, як відсоток від стандартної частоти оновлення Switch.",
|
"uk_UA": "Користувацька частота оновлення, як відсоток від стандартної частоти оновлення Switch.",
|
||||||
"zh_CN": "",
|
"zh_CN": "自定义刷新率,占正常SWitch刷新率的百分比值。",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22468,7 +22468,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Користувацька частота оновлення %:",
|
"uk_UA": "Користувацька частота оновлення %:",
|
||||||
"zh_CN": "",
|
"zh_CN": "自定义刷新率值 %:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22493,7 +22493,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Значення користувацька частота оновлення:",
|
"uk_UA": "Значення користувацька частота оновлення:",
|
||||||
"zh_CN": "",
|
"zh_CN": "自定义刷新率值:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22518,7 +22518,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "",
|
"uk_UA": "",
|
||||||
"zh_CN": "",
|
"zh_CN": "间隔",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22543,7 +22543,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Перемкнути VSync режим:",
|
"uk_UA": "Перемкнути VSync режим:",
|
||||||
"zh_CN": "",
|
"zh_CN": "设置 VSync 模式:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22568,7 +22568,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Підвищити користувацьку частоту оновлення",
|
"uk_UA": "Підвищити користувацьку частоту оновлення",
|
||||||
"zh_CN": "",
|
"zh_CN": "提高自定义刷新率:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -22593,7 +22593,7 @@
|
|||||||
"th_TH": "",
|
"th_TH": "",
|
||||||
"tr_TR": "",
|
"tr_TR": "",
|
||||||
"uk_UA": "Понизити користувацьку частоту оновлення",
|
"uk_UA": "Понизити користувацьку частоту оновлення",
|
||||||
"zh_CN": "",
|
"zh_CN": "降低自定义刷新率:",
|
||||||
"zh_TW": ""
|
"zh_TW": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,12 @@ using LibHac.Tools.FsSystem.NcaUtils;
|
|||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Controls;
|
using Ryujinx.Ava.UI.Controls;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||||
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
||||||
using Ryujinx.UI.Common.Configuration;
|
|
||||||
using Ryujinx.UI.Common.Helper;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.UI.Common.Configuration;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -2,7 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Models.Amiibo
|
namespace Ryujinx.Ava.Common.Models.Amiibo
|
||||||
{
|
{
|
||||||
public struct AmiiboApi : IEquatable<AmiiboApi>
|
public struct AmiiboApi : IEquatable<AmiiboApi>
|
||||||
{
|
{
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Models.Amiibo
|
namespace Ryujinx.Ava.Common.Models.Amiibo
|
||||||
{
|
{
|
||||||
public class AmiiboApiGamesSwitch
|
public class AmiiboApiGamesSwitch
|
||||||
{
|
{
|
@ -1,6 +1,6 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Models.Amiibo
|
namespace Ryujinx.Ava.Common.Models.Amiibo
|
||||||
{
|
{
|
||||||
public class AmiiboApiUsage
|
public class AmiiboApiUsage
|
||||||
{
|
{
|
@ -2,7 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Models.Amiibo
|
namespace Ryujinx.Ava.Common.Models.Amiibo
|
||||||
{
|
{
|
||||||
public struct AmiiboJson
|
public struct AmiiboJson
|
||||||
{
|
{
|
@ -1,9 +1,7 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Models.Amiibo
|
namespace Ryujinx.Ava.Common.Models.Amiibo
|
||||||
{
|
{
|
||||||
[JsonSerializable(typeof(AmiiboJson))]
|
[JsonSerializable(typeof(AmiiboJson))]
|
||||||
public partial class AmiiboJsonSerializerContext : JsonSerializerContext
|
public partial class AmiiboJsonSerializerContext : JsonSerializerContext;
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
namespace Ryujinx.UI.Common.Models
|
namespace Ryujinx.Ava.Common.Models
|
||||||
{
|
{
|
||||||
// NOTE: most consuming code relies on this model being value-comparable
|
// NOTE: most consuming code relies on this model being value-comparable
|
||||||
public record DownloadableContentModel(ulong TitleId, string ContainerPath, string FullPath)
|
public record DownloadableContentModel(ulong TitleId, string ContainerPath, string FullPath)
|
@ -1,4 +1,4 @@
|
|||||||
namespace Ryujinx.UI.Common.Models.Github
|
namespace Ryujinx.Ava.Common.Models.Github
|
||||||
{
|
{
|
||||||
public class GithubReleaseAssetJsonResponse
|
public class GithubReleaseAssetJsonResponse
|
||||||
{
|
{
|
@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Models.Github
|
namespace Ryujinx.Ava.Common.Models.Github
|
||||||
{
|
{
|
||||||
public class GithubReleasesJsonResponse
|
public class GithubReleasesJsonResponse
|
||||||
{
|
{
|
@ -1,9 +1,7 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Models.Github
|
namespace Ryujinx.Ava.Common.Models.Github
|
||||||
{
|
{
|
||||||
[JsonSerializable(typeof(GithubReleasesJsonResponse), GenerationMode = JsonSourceGenerationMode.Metadata)]
|
[JsonSerializable(typeof(GithubReleasesJsonResponse), GenerationMode = JsonSourceGenerationMode.Metadata)]
|
||||||
public partial class GithubReleasesJsonSerializerContext : JsonSerializerContext
|
public partial class GithubReleasesJsonSerializerContext : JsonSerializerContext;
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
namespace Ryujinx.UI.Common.Models
|
namespace Ryujinx.Ava.Common.Models
|
||||||
{
|
{
|
||||||
// NOTE: most consuming code relies on this model being value-comparable
|
// NOTE: most consuming code relies on this model being value-comparable
|
||||||
public record TitleUpdateModel(ulong TitleId, ulong Version, string DisplayVersion, string Path)
|
public record TitleUpdateModel(ulong TitleId, ulong Version, string DisplayVersion, string Path)
|
@ -1,8 +1,8 @@
|
|||||||
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.UI.App.Common;
|
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Models
|
namespace Ryujinx.Ava.Common.Models
|
||||||
{
|
{
|
||||||
public record XCITrimmerFileModel(
|
public record XCITrimmerFileModel(
|
||||||
string Name,
|
string Name,
|
@ -1,14 +1,14 @@
|
|||||||
using DiscordRPC;
|
using DiscordRPC;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using Humanizer.Localisation;
|
using Humanizer.Localisation;
|
||||||
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.HLE;
|
||||||
using Ryujinx.HLE.Loaders.Processes;
|
using Ryujinx.HLE.Loaders.Processes;
|
||||||
using Ryujinx.UI.App.Common;
|
|
||||||
using Ryujinx.UI.Common.Configuration;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common
|
namespace Ryujinx.Ava
|
||||||
{
|
{
|
||||||
public static class DiscordIntegrationModule
|
public static class DiscordIntegrationModule
|
||||||
{
|
{
|
||||||
@ -45,6 +45,16 @@ namespace Ryujinx.UI.Common
|
|||||||
};
|
};
|
||||||
|
|
||||||
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
|
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
|
||||||
|
TitleIDs.CurrentApplication.Event += (_, e) =>
|
||||||
|
{
|
||||||
|
if (e.NewValue)
|
||||||
|
SwitchToPlayingState(
|
||||||
|
ApplicationLibrary.LoadAndSaveMetaData(e.NewValue),
|
||||||
|
Switch.Shared.Processes.ActiveApplication
|
||||||
|
);
|
||||||
|
else
|
||||||
|
SwitchToMainState();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Update(object sender, ReactiveEventArgs<bool> evnt)
|
private static void Update(object sender, ReactiveEventArgs<bool> evnt)
|
||||||
@ -70,7 +80,7 @@ namespace Ryujinx.UI.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResult procRes)
|
private static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResult procRes)
|
||||||
{
|
{
|
||||||
_discordClient?.SetPresence(new RichPresence
|
_discordClient?.SetPresence(new RichPresence
|
||||||
{
|
{
|
||||||
@ -89,7 +99,7 @@ namespace Ryujinx.UI.Common
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SwitchToMainState() => _discordClient?.SetPresence(_discordPresenceMain);
|
private static void SwitchToMainState() => _discordClient?.SetPresence(_discordPresenceMain);
|
||||||
|
|
||||||
private static string TruncateToByteLength(string input)
|
private static string TruncateToByteLength(string input)
|
||||||
{
|
{
|
@ -2,7 +2,7 @@ using Ryujinx.HLE.UI;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Headless.SDL2
|
namespace Ryujinx.Headless
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Headless text processing class, right now there is no way to forward the input to it.
|
/// Headless text processing class, right now there is no way to forward the input to it.
|
@ -1,6 +1,6 @@
|
|||||||
using Ryujinx.HLE.UI;
|
using Ryujinx.HLE.UI;
|
||||||
|
|
||||||
namespace Ryujinx.Headless.SDL2
|
namespace Ryujinx.Headless
|
||||||
{
|
{
|
||||||
internal class HeadlessHostUiTheme : IHostUITheme
|
internal class HeadlessHostUiTheme : IHostUITheme
|
||||||
{
|
{
|
366
src/Ryujinx/Headless/HeadlessRyujinx.Init.cs
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
using DiscordRPC;
|
||||||
|
using LibHac.Tools.FsSystem;
|
||||||
|
using Ryujinx.Audio.Backends.SDL2;
|
||||||
|
using Ryujinx.Ava;
|
||||||
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
|
using Ryujinx.Common.Configuration.Hid.Controller.Motion;
|
||||||
|
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Common.Utilities;
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using Ryujinx.Graphics.GAL.Multithreading;
|
||||||
|
using Ryujinx.Graphics.Metal;
|
||||||
|
using Ryujinx.Graphics.OpenGL;
|
||||||
|
using Ryujinx.Graphics.Vulkan;
|
||||||
|
using Ryujinx.HLE;
|
||||||
|
using Ryujinx.Input;
|
||||||
|
using Silk.NET.Vulkan;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
|
||||||
|
using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||||
|
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
||||||
|
|
||||||
|
namespace Ryujinx.Headless
|
||||||
|
{
|
||||||
|
public partial class HeadlessRyujinx
|
||||||
|
{
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
// Ensure Discord presence timestamp begins at the absolute start of when Ryujinx is launched
|
||||||
|
DiscordIntegrationModule.StartedAt = Timestamps.Now;
|
||||||
|
|
||||||
|
// Delete backup files after updating.
|
||||||
|
Task.Run(Updater.CleanupUpdate);
|
||||||
|
|
||||||
|
// Hook unhandled exception and process exit events.
|
||||||
|
AppDomain.CurrentDomain.UnhandledException += (sender, e)
|
||||||
|
=> Program.ProcessUnhandledException(sender, e.ExceptionObject as Exception, e.IsTerminating);
|
||||||
|
AppDomain.CurrentDomain.ProcessExit += (_, _) => Program.Exit();
|
||||||
|
|
||||||
|
// Initialize the configuration.
|
||||||
|
ConfigurationState.Initialize();
|
||||||
|
|
||||||
|
// Initialize Discord integration.
|
||||||
|
DiscordIntegrationModule.Initialize();
|
||||||
|
|
||||||
|
// Logging system information.
|
||||||
|
Program.PrintSystemInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static InputConfig HandlePlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index)
|
||||||
|
{
|
||||||
|
if (inputId == null)
|
||||||
|
{
|
||||||
|
if (index == PlayerIndex.Player1)
|
||||||
|
{
|
||||||
|
Logger.Info?.Print(LogClass.Application, $"{index} not configured, defaulting to default keyboard.");
|
||||||
|
|
||||||
|
// Default to keyboard
|
||||||
|
inputId = "0";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Info?.Print(LogClass.Application, $"{index} not configured");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IGamepad gamepad = _inputManager.KeyboardDriver.GetGamepad(inputId);
|
||||||
|
|
||||||
|
bool isKeyboard = true;
|
||||||
|
|
||||||
|
if (gamepad == null)
|
||||||
|
{
|
||||||
|
gamepad = _inputManager.GamepadDriver.GetGamepad(inputId);
|
||||||
|
isKeyboard = false;
|
||||||
|
|
||||||
|
if (gamepad == null)
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, $"{index} gamepad not found (\"{inputId}\")");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string gamepadName = gamepad.Name;
|
||||||
|
|
||||||
|
gamepad.Dispose();
|
||||||
|
|
||||||
|
InputConfig config;
|
||||||
|
|
||||||
|
if (inputProfileName == null || inputProfileName.Equals("default"))
|
||||||
|
{
|
||||||
|
if (isKeyboard)
|
||||||
|
{
|
||||||
|
config = new StandardKeyboardInputConfig
|
||||||
|
{
|
||||||
|
Version = InputConfig.CurrentVersion,
|
||||||
|
Backend = InputBackendType.WindowKeyboard,
|
||||||
|
Id = null,
|
||||||
|
ControllerType = ControllerType.JoyconPair,
|
||||||
|
LeftJoycon = new LeftJoyconCommonConfig<Key>
|
||||||
|
{
|
||||||
|
DpadUp = Key.Up,
|
||||||
|
DpadDown = Key.Down,
|
||||||
|
DpadLeft = Key.Left,
|
||||||
|
DpadRight = Key.Right,
|
||||||
|
ButtonMinus = Key.Minus,
|
||||||
|
ButtonL = Key.E,
|
||||||
|
ButtonZl = Key.Q,
|
||||||
|
ButtonSl = Key.Unbound,
|
||||||
|
ButtonSr = Key.Unbound,
|
||||||
|
},
|
||||||
|
|
||||||
|
LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
|
||||||
|
{
|
||||||
|
StickUp = Key.W,
|
||||||
|
StickDown = Key.S,
|
||||||
|
StickLeft = Key.A,
|
||||||
|
StickRight = Key.D,
|
||||||
|
StickButton = Key.F,
|
||||||
|
},
|
||||||
|
|
||||||
|
RightJoycon = new RightJoyconCommonConfig<Key>
|
||||||
|
{
|
||||||
|
ButtonA = Key.Z,
|
||||||
|
ButtonB = Key.X,
|
||||||
|
ButtonX = Key.C,
|
||||||
|
ButtonY = Key.V,
|
||||||
|
ButtonPlus = Key.Plus,
|
||||||
|
ButtonR = Key.U,
|
||||||
|
ButtonZr = Key.O,
|
||||||
|
ButtonSl = Key.Unbound,
|
||||||
|
ButtonSr = Key.Unbound,
|
||||||
|
},
|
||||||
|
|
||||||
|
RightJoyconStick = new JoyconConfigKeyboardStick<Key>
|
||||||
|
{
|
||||||
|
StickUp = Key.I,
|
||||||
|
StickDown = Key.K,
|
||||||
|
StickLeft = Key.J,
|
||||||
|
StickRight = Key.L,
|
||||||
|
StickButton = Key.H,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool isNintendoStyle = gamepadName.Contains("Nintendo");
|
||||||
|
|
||||||
|
config = new StandardControllerInputConfig
|
||||||
|
{
|
||||||
|
Version = InputConfig.CurrentVersion,
|
||||||
|
Backend = InputBackendType.GamepadSDL2,
|
||||||
|
Id = null,
|
||||||
|
ControllerType = ControllerType.JoyconPair,
|
||||||
|
DeadzoneLeft = 0.1f,
|
||||||
|
DeadzoneRight = 0.1f,
|
||||||
|
RangeLeft = 1.0f,
|
||||||
|
RangeRight = 1.0f,
|
||||||
|
TriggerThreshold = 0.5f,
|
||||||
|
LeftJoycon = new LeftJoyconCommonConfig<ConfigGamepadInputId>
|
||||||
|
{
|
||||||
|
DpadUp = ConfigGamepadInputId.DpadUp,
|
||||||
|
DpadDown = ConfigGamepadInputId.DpadDown,
|
||||||
|
DpadLeft = ConfigGamepadInputId.DpadLeft,
|
||||||
|
DpadRight = ConfigGamepadInputId.DpadRight,
|
||||||
|
ButtonMinus = ConfigGamepadInputId.Minus,
|
||||||
|
ButtonL = ConfigGamepadInputId.LeftShoulder,
|
||||||
|
ButtonZl = ConfigGamepadInputId.LeftTrigger,
|
||||||
|
ButtonSl = ConfigGamepadInputId.Unbound,
|
||||||
|
ButtonSr = ConfigGamepadInputId.Unbound,
|
||||||
|
},
|
||||||
|
|
||||||
|
LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
|
||||||
|
{
|
||||||
|
Joystick = ConfigStickInputId.Left,
|
||||||
|
StickButton = ConfigGamepadInputId.LeftStick,
|
||||||
|
InvertStickX = false,
|
||||||
|
InvertStickY = false,
|
||||||
|
Rotate90CW = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
|
||||||
|
{
|
||||||
|
ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B,
|
||||||
|
ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A,
|
||||||
|
ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y,
|
||||||
|
ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X,
|
||||||
|
ButtonPlus = ConfigGamepadInputId.Plus,
|
||||||
|
ButtonR = ConfigGamepadInputId.RightShoulder,
|
||||||
|
ButtonZr = ConfigGamepadInputId.RightTrigger,
|
||||||
|
ButtonSl = ConfigGamepadInputId.Unbound,
|
||||||
|
ButtonSr = ConfigGamepadInputId.Unbound,
|
||||||
|
},
|
||||||
|
|
||||||
|
RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
|
||||||
|
{
|
||||||
|
Joystick = ConfigStickInputId.Right,
|
||||||
|
StickButton = ConfigGamepadInputId.RightStick,
|
||||||
|
InvertStickX = false,
|
||||||
|
InvertStickY = false,
|
||||||
|
Rotate90CW = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
Motion = new StandardMotionConfigController
|
||||||
|
{
|
||||||
|
MotionBackend = MotionInputBackendType.GamepadDriver,
|
||||||
|
EnableMotion = true,
|
||||||
|
Sensitivity = 100,
|
||||||
|
GyroDeadzone = 1,
|
||||||
|
},
|
||||||
|
Rumble = new RumbleConfigController
|
||||||
|
{
|
||||||
|
StrongRumble = 1f,
|
||||||
|
WeakRumble = 1f,
|
||||||
|
EnableRumble = false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string profileBasePath;
|
||||||
|
|
||||||
|
if (isKeyboard)
|
||||||
|
{
|
||||||
|
profileBasePath = Path.Combine(AppDataManager.ProfilesDirPath, "keyboard");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
profileBasePath = Path.Combine(AppDataManager.ProfilesDirPath, "controller");
|
||||||
|
}
|
||||||
|
|
||||||
|
string path = Path.Combine(profileBasePath, inputProfileName + ".json");
|
||||||
|
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, $"Input profile \"{inputProfileName}\" not found for \"{inputId}\"");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
config = JsonHelper.DeserializeFromFile(path, _serializerContext.InputConfig);
|
||||||
|
}
|
||||||
|
catch (JsonException)
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, $"Input profile \"{inputProfileName}\" parsing failed for \"{inputId}\"");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Id = inputId;
|
||||||
|
config.PlayerIndex = index;
|
||||||
|
|
||||||
|
string inputTypeName = isKeyboard ? "Keyboard" : "Gamepad";
|
||||||
|
|
||||||
|
Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} configured with {inputTypeName} \"{config.Id}\"");
|
||||||
|
|
||||||
|
// If both stick ranges are 0 (usually indicative of an outdated profile load) then both sticks will be set to 1.0.
|
||||||
|
if (config is StandardControllerInputConfig controllerConfig)
|
||||||
|
{
|
||||||
|
if (controllerConfig.RangeLeft <= 0.0f && controllerConfig.RangeRight <= 0.0f)
|
||||||
|
{
|
||||||
|
controllerConfig.RangeLeft = 1.0f;
|
||||||
|
controllerConfig.RangeRight = 1.0f;
|
||||||
|
|
||||||
|
Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} stick range reset. Save the profile now to update your configuration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IRenderer CreateRenderer(Options options, WindowBase window)
|
||||||
|
{
|
||||||
|
if (options.GraphicsBackend == GraphicsBackend.Vulkan && window is VulkanWindow vulkanWindow)
|
||||||
|
{
|
||||||
|
string preferredGpuId = string.Empty;
|
||||||
|
Vk api = Vk.GetApi();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(options.PreferredGPUVendor))
|
||||||
|
{
|
||||||
|
string preferredGpuVendor = options.PreferredGPUVendor.ToLowerInvariant();
|
||||||
|
var devices = VulkanRenderer.GetPhysicalDevices(api);
|
||||||
|
|
||||||
|
foreach (var device in devices)
|
||||||
|
{
|
||||||
|
if (device.Vendor.ToLowerInvariant() == preferredGpuVendor)
|
||||||
|
{
|
||||||
|
preferredGpuId = device.Id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VulkanRenderer(
|
||||||
|
api,
|
||||||
|
(instance, vk) => new SurfaceKHR((ulong)(vulkanWindow.CreateWindowSurface(instance.Handle))),
|
||||||
|
vulkanWindow.GetRequiredInstanceExtensions,
|
||||||
|
preferredGpuId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.GraphicsBackend == GraphicsBackend.Metal && window is MetalWindow metalWindow && OperatingSystem.IsMacOS())
|
||||||
|
{
|
||||||
|
return new MetalRenderer(metalWindow.GetLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OpenGLRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options)
|
||||||
|
{
|
||||||
|
BackendThreading threadingMode = options.BackendThreading;
|
||||||
|
|
||||||
|
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,
|
||||||
|
window,
|
||||||
|
options.SystemLanguage,
|
||||||
|
options.SystemRegion,
|
||||||
|
options.VSyncMode,
|
||||||
|
!options.DisableDockedMode,
|
||||||
|
!options.DisablePTC,
|
||||||
|
options.EnableInternetAccess,
|
||||||
|
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
|
||||||
|
options.FsGlobalAccessLogMode,
|
||||||
|
options.SystemTimeOffset,
|
||||||
|
options.SystemTimeZone,
|
||||||
|
options.MemoryManagerMode,
|
||||||
|
options.IgnoreMissingServices,
|
||||||
|
options.AspectRatio,
|
||||||
|
options.AudioVolume,
|
||||||
|
options.UseHypervisor ?? true,
|
||||||
|
options.MultiplayerLanInterfaceId,
|
||||||
|
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
|
||||||
|
false,
|
||||||
|
string.Empty,
|
||||||
|
string.Empty,
|
||||||
|
options.CustomVSyncInterval);
|
||||||
|
|
||||||
|
return new Switch(configuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,10 @@
|
|||||||
using CommandLine;
|
using CommandLine;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using LibHac.Tools.FsSystem;
|
using Ryujinx.Ava;
|
||||||
using Ryujinx.Audio.Backends.SDL2;
|
using Ryujinx.Ava.Utilities.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;
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller.Motion;
|
|
||||||
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
|
||||||
using Ryujinx.Common.GraphicsDriver;
|
using Ryujinx.Common.GraphicsDriver;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Logging.Targets;
|
using Ryujinx.Common.Logging.Targets;
|
||||||
@ -15,16 +12,9 @@ using Ryujinx.Common.SystemInterop;
|
|||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Cpu;
|
using Ryujinx.Cpu;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading;
|
|
||||||
using Ryujinx.Graphics.Gpu;
|
using Ryujinx.Graphics.Gpu;
|
||||||
using Ryujinx.Graphics.Gpu.Shader;
|
using Ryujinx.Graphics.Gpu.Shader;
|
||||||
using Ryujinx.Graphics.Metal;
|
|
||||||
using Ryujinx.Graphics.OpenGL;
|
|
||||||
using Ryujinx.Graphics.Vulkan;
|
|
||||||
using Ryujinx.Graphics.Vulkan.MoltenVK;
|
using Ryujinx.Graphics.Vulkan.MoltenVK;
|
||||||
using Ryujinx.Headless.SDL2.Metal;
|
|
||||||
using Ryujinx.Headless.SDL2.OpenGL;
|
|
||||||
using Ryujinx.Headless.SDL2.Vulkan;
|
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
@ -33,22 +23,15 @@ using Ryujinx.Input;
|
|||||||
using Ryujinx.Input.HLE;
|
using Ryujinx.Input.HLE;
|
||||||
using Ryujinx.Input.SDL2;
|
using Ryujinx.Input.SDL2;
|
||||||
using Ryujinx.SDL2.Common;
|
using Ryujinx.SDL2.Common;
|
||||||
using Silk.NET.Vulkan;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
|
|
||||||
using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
|
||||||
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
|
||||||
|
|
||||||
namespace Ryujinx.Headless.SDL2
|
namespace Ryujinx.Headless
|
||||||
{
|
{
|
||||||
class Program
|
public partial class HeadlessRyujinx
|
||||||
{
|
{
|
||||||
public static string Version { get; private set; }
|
|
||||||
|
|
||||||
private static VirtualFileSystem _virtualFileSystem;
|
private static VirtualFileSystem _virtualFileSystem;
|
||||||
private static ContentManager _contentManager;
|
private static ContentManager _contentManager;
|
||||||
private static AccountManager _accountManager;
|
private static AccountManager _accountManager;
|
||||||
@ -58,20 +41,18 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
private static Switch _emulationContext;
|
private static Switch _emulationContext;
|
||||||
private static WindowBase _window;
|
private static WindowBase _window;
|
||||||
private static WindowsMultimediaTimerResolution _windowsMultimediaTimerResolution;
|
private static WindowsMultimediaTimerResolution _windowsMultimediaTimerResolution;
|
||||||
private static List<InputConfig> _inputConfiguration;
|
private static List<InputConfig> _inputConfiguration = [];
|
||||||
private static bool _enableKeyboard;
|
private static bool _enableKeyboard;
|
||||||
private static bool _enableMouse;
|
private static bool _enableMouse;
|
||||||
|
|
||||||
private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||||
|
|
||||||
static void Main(string[] args)
|
public static void Entrypoint(string[] args)
|
||||||
{
|
{
|
||||||
Version = ReleaseInformation.Version;
|
|
||||||
|
|
||||||
// Make process DPI aware for proper window sizing on high-res screens.
|
// Make process DPI aware for proper window sizing on high-res screens.
|
||||||
ForceDpiAware.Windows();
|
ForceDpiAware.Windows();
|
||||||
|
|
||||||
Console.Title = $"Ryujinx Console {Version} (Headless SDL2)";
|
Console.Title = $"Ryujinx Console {Program.Version} (Headless)";
|
||||||
|
|
||||||
if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
|
if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
|
||||||
{
|
{
|
||||||
@ -99,7 +80,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
}
|
}
|
||||||
|
|
||||||
Parser.Default.ParseArguments<Options>(args)
|
Parser.Default.ParseArguments<Options>(args)
|
||||||
.WithParsed(Load)
|
.WithParsed(options => Load(args, options))
|
||||||
.WithNotParsed(errors =>
|
.WithNotParsed(errors =>
|
||||||
{
|
{
|
||||||
Logger.Error?.PrintMsg(LogClass.Application, "Error parsing command-line arguments:");
|
Logger.Error?.PrintMsg(LogClass.Application, "Error parsing command-line arguments:");
|
||||||
@ -108,238 +89,80 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InputConfig HandlePlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index)
|
public static void ReloadConfig(string customConfigPath = null)
|
||||||
{
|
{
|
||||||
if (inputId == null)
|
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
|
||||||
|
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
|
||||||
|
|
||||||
|
string configurationPath = null;
|
||||||
|
|
||||||
|
// Now load the configuration as the other subsystems are now registered
|
||||||
|
if (customConfigPath != null && File.Exists(customConfigPath))
|
||||||
{
|
{
|
||||||
if (index == PlayerIndex.Player1)
|
configurationPath = customConfigPath;
|
||||||
{
|
}
|
||||||
Logger.Info?.Print(LogClass.Application, $"{index} not configured, defaulting to default keyboard.");
|
else if (File.Exists(localConfigurationPath))
|
||||||
|
{
|
||||||
// Default to keyboard
|
configurationPath = localConfigurationPath;
|
||||||
inputId = "0";
|
}
|
||||||
}
|
else if (File.Exists(appDataConfigurationPath))
|
||||||
else
|
{
|
||||||
{
|
configurationPath = appDataConfigurationPath;
|
||||||
Logger.Info?.Print(LogClass.Application, $"{index} not configured");
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IGamepad gamepad = _inputManager.KeyboardDriver.GetGamepad(inputId);
|
if (configurationPath == null)
|
||||||
|
|
||||||
bool isKeyboard = true;
|
|
||||||
|
|
||||||
if (gamepad == null)
|
|
||||||
{
|
{
|
||||||
gamepad = _inputManager.GamepadDriver.GetGamepad(inputId);
|
// No configuration, we load the default values and save it to disk
|
||||||
isKeyboard = false;
|
configurationPath = appDataConfigurationPath;
|
||||||
|
Logger.Notice.Print(LogClass.Application, $"No configuration file found. Saving default configuration to: {configurationPath}");
|
||||||
|
|
||||||
if (gamepad == null)
|
ConfigurationState.Instance.LoadDefault();
|
||||||
{
|
ConfigurationState.Instance.ToFileFormat().SaveConfig(configurationPath);
|
||||||
Logger.Error?.Print(LogClass.Application, $"{index} gamepad not found (\"{inputId}\")");
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string gamepadName = gamepad.Name;
|
|
||||||
|
|
||||||
gamepad.Dispose();
|
|
||||||
|
|
||||||
InputConfig config;
|
|
||||||
|
|
||||||
if (inputProfileName == null || inputProfileName.Equals("default"))
|
|
||||||
{
|
|
||||||
if (isKeyboard)
|
|
||||||
{
|
|
||||||
config = new StandardKeyboardInputConfig
|
|
||||||
{
|
|
||||||
Version = InputConfig.CurrentVersion,
|
|
||||||
Backend = InputBackendType.WindowKeyboard,
|
|
||||||
Id = null,
|
|
||||||
ControllerType = ControllerType.JoyconPair,
|
|
||||||
LeftJoycon = new LeftJoyconCommonConfig<Key>
|
|
||||||
{
|
|
||||||
DpadUp = Key.Up,
|
|
||||||
DpadDown = Key.Down,
|
|
||||||
DpadLeft = Key.Left,
|
|
||||||
DpadRight = Key.Right,
|
|
||||||
ButtonMinus = Key.Minus,
|
|
||||||
ButtonL = Key.E,
|
|
||||||
ButtonZl = Key.Q,
|
|
||||||
ButtonSl = Key.Unbound,
|
|
||||||
ButtonSr = Key.Unbound,
|
|
||||||
},
|
|
||||||
|
|
||||||
LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
|
|
||||||
{
|
|
||||||
StickUp = Key.W,
|
|
||||||
StickDown = Key.S,
|
|
||||||
StickLeft = Key.A,
|
|
||||||
StickRight = Key.D,
|
|
||||||
StickButton = Key.F,
|
|
||||||
},
|
|
||||||
|
|
||||||
RightJoycon = new RightJoyconCommonConfig<Key>
|
|
||||||
{
|
|
||||||
ButtonA = Key.Z,
|
|
||||||
ButtonB = Key.X,
|
|
||||||
ButtonX = Key.C,
|
|
||||||
ButtonY = Key.V,
|
|
||||||
ButtonPlus = Key.Plus,
|
|
||||||
ButtonR = Key.U,
|
|
||||||
ButtonZr = Key.O,
|
|
||||||
ButtonSl = Key.Unbound,
|
|
||||||
ButtonSr = Key.Unbound,
|
|
||||||
},
|
|
||||||
|
|
||||||
RightJoyconStick = new JoyconConfigKeyboardStick<Key>
|
|
||||||
{
|
|
||||||
StickUp = Key.I,
|
|
||||||
StickDown = Key.K,
|
|
||||||
StickLeft = Key.J,
|
|
||||||
StickRight = Key.L,
|
|
||||||
StickButton = Key.H,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool isNintendoStyle = gamepadName.Contains("Nintendo");
|
|
||||||
|
|
||||||
config = new StandardControllerInputConfig
|
|
||||||
{
|
|
||||||
Version = InputConfig.CurrentVersion,
|
|
||||||
Backend = InputBackendType.GamepadSDL2,
|
|
||||||
Id = null,
|
|
||||||
ControllerType = ControllerType.JoyconPair,
|
|
||||||
DeadzoneLeft = 0.1f,
|
|
||||||
DeadzoneRight = 0.1f,
|
|
||||||
RangeLeft = 1.0f,
|
|
||||||
RangeRight = 1.0f,
|
|
||||||
TriggerThreshold = 0.5f,
|
|
||||||
LeftJoycon = new LeftJoyconCommonConfig<ConfigGamepadInputId>
|
|
||||||
{
|
|
||||||
DpadUp = ConfigGamepadInputId.DpadUp,
|
|
||||||
DpadDown = ConfigGamepadInputId.DpadDown,
|
|
||||||
DpadLeft = ConfigGamepadInputId.DpadLeft,
|
|
||||||
DpadRight = ConfigGamepadInputId.DpadRight,
|
|
||||||
ButtonMinus = ConfigGamepadInputId.Minus,
|
|
||||||
ButtonL = ConfigGamepadInputId.LeftShoulder,
|
|
||||||
ButtonZl = ConfigGamepadInputId.LeftTrigger,
|
|
||||||
ButtonSl = ConfigGamepadInputId.Unbound,
|
|
||||||
ButtonSr = ConfigGamepadInputId.Unbound,
|
|
||||||
},
|
|
||||||
|
|
||||||
LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
|
|
||||||
{
|
|
||||||
Joystick = ConfigStickInputId.Left,
|
|
||||||
StickButton = ConfigGamepadInputId.LeftStick,
|
|
||||||
InvertStickX = false,
|
|
||||||
InvertStickY = false,
|
|
||||||
Rotate90CW = false,
|
|
||||||
},
|
|
||||||
|
|
||||||
RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
|
|
||||||
{
|
|
||||||
ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B,
|
|
||||||
ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A,
|
|
||||||
ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y,
|
|
||||||
ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X,
|
|
||||||
ButtonPlus = ConfigGamepadInputId.Plus,
|
|
||||||
ButtonR = ConfigGamepadInputId.RightShoulder,
|
|
||||||
ButtonZr = ConfigGamepadInputId.RightTrigger,
|
|
||||||
ButtonSl = ConfigGamepadInputId.Unbound,
|
|
||||||
ButtonSr = ConfigGamepadInputId.Unbound,
|
|
||||||
},
|
|
||||||
|
|
||||||
RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
|
|
||||||
{
|
|
||||||
Joystick = ConfigStickInputId.Right,
|
|
||||||
StickButton = ConfigGamepadInputId.RightStick,
|
|
||||||
InvertStickX = false,
|
|
||||||
InvertStickY = false,
|
|
||||||
Rotate90CW = false,
|
|
||||||
},
|
|
||||||
|
|
||||||
Motion = new StandardMotionConfigController
|
|
||||||
{
|
|
||||||
MotionBackend = MotionInputBackendType.GamepadDriver,
|
|
||||||
EnableMotion = true,
|
|
||||||
Sensitivity = 100,
|
|
||||||
GyroDeadzone = 1,
|
|
||||||
},
|
|
||||||
Rumble = new RumbleConfigController
|
|
||||||
{
|
|
||||||
StrongRumble = 1f,
|
|
||||||
WeakRumble = 1f,
|
|
||||||
EnableRumble = false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string profileBasePath;
|
Logger.Notice.Print(LogClass.Application, $"Loading configuration from: {configurationPath}");
|
||||||
|
|
||||||
if (isKeyboard)
|
if (ConfigurationFileFormat.TryLoad(configurationPath, out ConfigurationFileFormat configurationFileFormat))
|
||||||
{
|
{
|
||||||
profileBasePath = Path.Combine(AppDataManager.ProfilesDirPath, "keyboard");
|
ConfigurationState.Instance.Load(configurationFileFormat, configurationPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
profileBasePath = Path.Combine(AppDataManager.ProfilesDirPath, "controller");
|
Logger.Warning?.PrintMsg(LogClass.Application, $"Failed to load config! Loading the default config instead.\nFailed config location: {configurationPath}");
|
||||||
}
|
|
||||||
|
|
||||||
string path = Path.Combine(profileBasePath, inputProfileName + ".json");
|
ConfigurationState.Instance.LoadDefault();
|
||||||
|
|
||||||
if (!File.Exists(path))
|
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, $"Input profile \"{inputProfileName}\" not found for \"{inputId}\"");
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
config = JsonHelper.DeserializeFromFile(path, _serializerContext.InputConfig);
|
|
||||||
}
|
|
||||||
catch (JsonException)
|
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, $"Input profile \"{inputProfileName}\" parsing failed for \"{inputId}\"");
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Id = inputId;
|
|
||||||
config.PlayerIndex = index;
|
|
||||||
|
|
||||||
string inputTypeName = isKeyboard ? "Keyboard" : "Gamepad";
|
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} configured with {inputTypeName} \"{config.Id}\"");
|
|
||||||
|
|
||||||
// If both stick ranges are 0 (usually indicative of an outdated profile load) then both sticks will be set to 1.0.
|
|
||||||
if (config is StandardControllerInputConfig controllerConfig)
|
|
||||||
{
|
|
||||||
if (controllerConfig.RangeLeft <= 0.0f && controllerConfig.RangeRight <= 0.0f)
|
|
||||||
{
|
|
||||||
controllerConfig.RangeLeft = 1.0f;
|
|
||||||
controllerConfig.RangeRight = 1.0f;
|
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} stick range reset. Save the profile now to update your configuration");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load(Options option)
|
static void Load(string[] originalArgs, Options option)
|
||||||
{
|
{
|
||||||
|
Initialize();
|
||||||
|
|
||||||
|
bool useLastUsedProfile = false;
|
||||||
|
|
||||||
|
if (option.InheritConfig)
|
||||||
|
{
|
||||||
|
option.InheritMainConfig(originalArgs, ConfigurationState.Instance, out useLastUsedProfile);
|
||||||
|
}
|
||||||
|
|
||||||
AppDataManager.Initialize(option.BaseDataDir);
|
AppDataManager.Initialize(option.BaseDataDir);
|
||||||
|
|
||||||
|
if (useLastUsedProfile && AccountSaveDataManager.GetLastUsedUser().TryGet(out var profile))
|
||||||
|
option.UserProfile = profile.Name;
|
||||||
|
|
||||||
|
// Check if keys exists.
|
||||||
|
if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys")))
|
||||||
|
{
|
||||||
|
if (!(AppDataManager.Mode == AppDataManager.LaunchMode.UserProfile && File.Exists(Path.Combine(AppDataManager.KeysDirPathUser, "prod.keys"))))
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, "Keys not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReloadConfig();
|
||||||
|
|
||||||
_virtualFileSystem = VirtualFileSystem.CreateInstance();
|
_virtualFileSystem = VirtualFileSystem.CreateInstance();
|
||||||
_libHacHorizonManager = new LibHacHorizonManager();
|
_libHacHorizonManager = new LibHacHorizonManager();
|
||||||
|
|
||||||
@ -354,7 +177,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
|
|
||||||
_inputManager = new InputManager(new SDL2KeyboardDriver(), new SDL2GamepadDriver());
|
_inputManager = new InputManager(new SDL2KeyboardDriver(), new SDL2GamepadDriver());
|
||||||
|
|
||||||
GraphicsConfig.EnableShaderCache = true;
|
GraphicsConfig.EnableShaderCache = !option.DisableShaderCache;
|
||||||
|
|
||||||
if (OperatingSystem.IsMacOS())
|
if (OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
@ -365,15 +188,13 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IGamepad gamepad;
|
|
||||||
|
|
||||||
if (option.ListInputIds)
|
if (option.ListInputIds)
|
||||||
{
|
{
|
||||||
Logger.Info?.Print(LogClass.Application, "Input Ids:");
|
Logger.Info?.Print(LogClass.Application, "Input Ids:");
|
||||||
|
|
||||||
foreach (string id in _inputManager.KeyboardDriver.GamepadsIds)
|
foreach (string id in _inputManager.KeyboardDriver.GamepadsIds)
|
||||||
{
|
{
|
||||||
gamepad = _inputManager.KeyboardDriver.GetGamepad(id);
|
IGamepad gamepad = _inputManager.KeyboardDriver.GetGamepad(id);
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")");
|
Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")");
|
||||||
|
|
||||||
@ -382,7 +203,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
|
|
||||||
foreach (string id in _inputManager.GamepadDriver.GamepadsIds)
|
foreach (string id in _inputManager.GamepadDriver.GamepadsIds)
|
||||||
{
|
{
|
||||||
gamepad = _inputManager.GamepadDriver.GetGamepad(id);
|
IGamepad gamepad = _inputManager.GamepadDriver.GetGamepad(id);
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")");
|
Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")");
|
||||||
|
|
||||||
@ -399,7 +220,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_inputConfiguration = new List<InputConfig>();
|
_inputConfiguration ??= [];
|
||||||
_enableKeyboard = option.EnableKeyboard;
|
_enableKeyboard = option.EnableKeyboard;
|
||||||
_enableMouse = option.EnableMouse;
|
_enableMouse = option.EnableMouse;
|
||||||
|
|
||||||
@ -423,6 +244,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8);
|
LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8);
|
||||||
LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld);
|
LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld);
|
||||||
|
|
||||||
|
|
||||||
if (_inputConfiguration.Count == 0)
|
if (_inputConfiguration.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -433,7 +255,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
Logger.SetEnable(LogLevel.Stub, !option.LoggingDisableStub);
|
Logger.SetEnable(LogLevel.Stub, !option.LoggingDisableStub);
|
||||||
Logger.SetEnable(LogLevel.Info, !option.LoggingDisableInfo);
|
Logger.SetEnable(LogLevel.Info, !option.LoggingDisableInfo);
|
||||||
Logger.SetEnable(LogLevel.Warning, !option.LoggingDisableWarning);
|
Logger.SetEnable(LogLevel.Warning, !option.LoggingDisableWarning);
|
||||||
Logger.SetEnable(LogLevel.Error, option.LoggingEnableError);
|
Logger.SetEnable(LogLevel.Error, !option.LoggingDisableError);
|
||||||
Logger.SetEnable(LogLevel.Trace, option.LoggingEnableTrace);
|
Logger.SetEnable(LogLevel.Trace, option.LoggingEnableTrace);
|
||||||
Logger.SetEnable(LogLevel.Guest, !option.LoggingDisableGuest);
|
Logger.SetEnable(LogLevel.Guest, !option.LoggingDisableGuest);
|
||||||
Logger.SetEnable(LogLevel.AccessLog, option.LoggingEnableFsAccessLog);
|
Logger.SetEnable(LogLevel.AccessLog, option.LoggingEnableFsAccessLog);
|
||||||
@ -522,88 +344,6 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IRenderer CreateRenderer(Options options, WindowBase window)
|
|
||||||
{
|
|
||||||
if (options.GraphicsBackend == GraphicsBackend.Vulkan && window is VulkanWindow vulkanWindow)
|
|
||||||
{
|
|
||||||
string preferredGpuId = string.Empty;
|
|
||||||
Vk api = Vk.GetApi();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(options.PreferredGPUVendor))
|
|
||||||
{
|
|
||||||
string preferredGpuVendor = options.PreferredGPUVendor.ToLowerInvariant();
|
|
||||||
var devices = VulkanRenderer.GetPhysicalDevices(api);
|
|
||||||
|
|
||||||
foreach (var device in devices)
|
|
||||||
{
|
|
||||||
if (device.Vendor.ToLowerInvariant() == preferredGpuVendor)
|
|
||||||
{
|
|
||||||
preferredGpuId = device.Id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new VulkanRenderer(
|
|
||||||
api,
|
|
||||||
(instance, vk) => new SurfaceKHR((ulong)(vulkanWindow.CreateWindowSurface(instance.Handle))),
|
|
||||||
vulkanWindow.GetRequiredInstanceExtensions,
|
|
||||||
preferredGpuId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.GraphicsBackend == GraphicsBackend.Metal && window is MetalWindow metalWindow && OperatingSystem.IsMacOS())
|
|
||||||
{
|
|
||||||
return new MetalRenderer(metalWindow.GetLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new OpenGLRenderer();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options)
|
|
||||||
{
|
|
||||||
BackendThreading threadingMode = options.BackendThreading;
|
|
||||||
|
|
||||||
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,
|
|
||||||
window,
|
|
||||||
options.SystemLanguage,
|
|
||||||
options.SystemRegion,
|
|
||||||
options.VSyncMode,
|
|
||||||
!options.DisableDockedMode,
|
|
||||||
!options.DisablePTC,
|
|
||||||
options.EnableInternetAccess,
|
|
||||||
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
|
|
||||||
options.FsGlobalAccessLogMode,
|
|
||||||
options.SystemTimeOffset,
|
|
||||||
options.SystemTimeZone,
|
|
||||||
options.MemoryManagerMode,
|
|
||||||
options.IgnoreMissingServices,
|
|
||||||
options.AspectRatio,
|
|
||||||
options.AudioVolume,
|
|
||||||
options.UseHypervisor ?? true,
|
|
||||||
options.MultiplayerLanInterfaceId,
|
|
||||||
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
|
|
||||||
false,
|
|
||||||
string.Empty,
|
|
||||||
string.Empty,
|
|
||||||
options.CustomVSyncInterval);
|
|
||||||
|
|
||||||
return new Switch(configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ExecutionEntrypoint()
|
private static void ExecutionEntrypoint()
|
||||||
{
|
{
|
||||||
if (OperatingSystem.IsWindows())
|
if (OperatingSystem.IsWindows())
|
@ -5,7 +5,7 @@ using SharpMetal.QuartzCore;
|
|||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
using static SDL2.SDL;
|
using static SDL2.SDL;
|
||||||
|
|
||||||
namespace Ryujinx.Headless.SDL2.Metal
|
namespace Ryujinx.Headless
|
||||||
{
|
{
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
class MetalWindow : WindowBase
|
class MetalWindow : WindowBase
|
@ -7,7 +7,7 @@ using Ryujinx.Input.HLE;
|
|||||||
using System;
|
using System;
|
||||||
using static SDL2.SDL;
|
using static SDL2.SDL;
|
||||||
|
|
||||||
namespace Ryujinx.Headless.SDL2.OpenGL
|
namespace Ryujinx.Headless
|
||||||
{
|
{
|
||||||
class OpenGLWindow : WindowBase
|
class OpenGLWindow : WindowBase
|
||||||
{
|
{
|
@ -1,14 +1,169 @@
|
|||||||
using CommandLine;
|
using CommandLine;
|
||||||
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
|
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace Ryujinx.Headless.SDL2
|
namespace Ryujinx.Headless
|
||||||
{
|
{
|
||||||
public class Options
|
public class Options
|
||||||
{
|
{
|
||||||
|
public void InheritMainConfig(string[] originalArgs, ConfigurationState configurationState, out bool needsProfileSet)
|
||||||
|
{
|
||||||
|
needsProfileSet = NeedsOverride(nameof(UserProfile));
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(IsFullscreen)))
|
||||||
|
IsFullscreen = configurationState.UI.StartFullscreen;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(EnableKeyboard)))
|
||||||
|
EnableKeyboard = configurationState.Hid.EnableKeyboard;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(EnableMouse)))
|
||||||
|
EnableMouse = configurationState.Hid.EnableMouse;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(HideCursorMode)))
|
||||||
|
HideCursorMode = configurationState.HideCursor;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(DisablePTC)))
|
||||||
|
DisablePTC = !configurationState.System.EnablePtc;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(EnableInternetAccess)))
|
||||||
|
EnableInternetAccess = configurationState.System.EnableInternetAccess;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(DisableFsIntegrityChecks)))
|
||||||
|
DisableFsIntegrityChecks = configurationState.System.EnableFsIntegrityChecks;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(FsGlobalAccessLogMode)))
|
||||||
|
FsGlobalAccessLogMode = configurationState.System.FsGlobalAccessLogMode;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(VSyncMode)))
|
||||||
|
VSyncMode = configurationState.Graphics.VSyncMode;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(CustomVSyncInterval)))
|
||||||
|
CustomVSyncInterval = configurationState.Graphics.CustomVSyncInterval;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(DisableShaderCache)))
|
||||||
|
DisableShaderCache = !configurationState.Graphics.EnableShaderCache;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(EnableTextureRecompression)))
|
||||||
|
EnableTextureRecompression = configurationState.Graphics.EnableTextureRecompression;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(DisableDockedMode)))
|
||||||
|
DisableDockedMode = !configurationState.System.EnableDockedMode;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(SystemLanguage)))
|
||||||
|
SystemLanguage = (SystemLanguage)(int)configurationState.System.Language.Value;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(SystemRegion)))
|
||||||
|
SystemRegion = (RegionCode)(int)configurationState.System.Region.Value;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(SystemTimeZone)))
|
||||||
|
SystemTimeZone = configurationState.System.TimeZone;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(SystemTimeOffset)))
|
||||||
|
SystemTimeOffset = configurationState.System.SystemTimeOffset;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(MemoryManagerMode)))
|
||||||
|
MemoryManagerMode = configurationState.System.MemoryManagerMode;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(AudioVolume)))
|
||||||
|
AudioVolume = configurationState.System.AudioVolume;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(UseHypervisor)) && OperatingSystem.IsMacOS())
|
||||||
|
UseHypervisor = configurationState.System.UseHypervisor;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(MultiplayerLanInterfaceId)))
|
||||||
|
MultiplayerLanInterfaceId = configurationState.Multiplayer.LanInterfaceId;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(DisableFileLog)))
|
||||||
|
DisableFileLog = !configurationState.Logger.EnableFileLog;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(LoggingEnableDebug)))
|
||||||
|
LoggingEnableDebug = configurationState.Logger.EnableDebug;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(LoggingDisableStub)))
|
||||||
|
LoggingDisableStub = !configurationState.Logger.EnableStub;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(LoggingDisableInfo)))
|
||||||
|
LoggingDisableInfo = !configurationState.Logger.EnableInfo;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(LoggingDisableWarning)))
|
||||||
|
LoggingDisableWarning = !configurationState.Logger.EnableWarn;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(LoggingDisableError)))
|
||||||
|
LoggingDisableError = !configurationState.Logger.EnableError;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(LoggingEnableTrace)))
|
||||||
|
LoggingEnableTrace = configurationState.Logger.EnableTrace;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(LoggingDisableGuest)))
|
||||||
|
LoggingDisableGuest = !configurationState.Logger.EnableGuest;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(LoggingEnableFsAccessLog)))
|
||||||
|
LoggingEnableFsAccessLog = configurationState.Logger.EnableFsAccessLog;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(LoggingGraphicsDebugLevel)))
|
||||||
|
LoggingGraphicsDebugLevel = configurationState.Logger.GraphicsDebugLevel;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(ResScale)))
|
||||||
|
ResScale = configurationState.Graphics.ResScale;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(MaxAnisotropy)))
|
||||||
|
MaxAnisotropy = configurationState.Graphics.MaxAnisotropy;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(AspectRatio)))
|
||||||
|
AspectRatio = configurationState.Graphics.AspectRatio;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(BackendThreading)))
|
||||||
|
BackendThreading = configurationState.Graphics.BackendThreading;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(DisableMacroHLE)))
|
||||||
|
DisableMacroHLE = !configurationState.Graphics.EnableMacroHLE;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(GraphicsShadersDumpPath)))
|
||||||
|
GraphicsShadersDumpPath = configurationState.Graphics.ShadersDumpPath;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(GraphicsBackend)))
|
||||||
|
GraphicsBackend = configurationState.Graphics.GraphicsBackend;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(AntiAliasing)))
|
||||||
|
AntiAliasing = configurationState.Graphics.AntiAliasing;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(ScalingFilter)))
|
||||||
|
ScalingFilter = configurationState.Graphics.ScalingFilter;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(ScalingFilterLevel)))
|
||||||
|
ScalingFilterLevel = configurationState.Graphics.ScalingFilterLevel;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(DramSize)))
|
||||||
|
DramSize = configurationState.System.DramSize;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(IgnoreMissingServices)))
|
||||||
|
IgnoreMissingServices = configurationState.System.IgnoreMissingServices;
|
||||||
|
|
||||||
|
if (NeedsOverride(nameof(IgnoreControllerApplet)))
|
||||||
|
IgnoreControllerApplet = configurationState.IgnoreApplet;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
|
||||||
|
|
||||||
|
string OptionName(string propertyName) =>
|
||||||
|
typeof(Options)!.GetProperty(propertyName)!.GetCustomAttribute<OptionAttribute>()!.LongName;
|
||||||
|
}
|
||||||
|
|
||||||
// General
|
// General
|
||||||
|
|
||||||
|
[Option("use-main-config", Required = false, Default = false, HelpText = "Use the settings from what was configured via the UI.")]
|
||||||
|
public bool InheritConfig { get; set; }
|
||||||
|
|
||||||
[Option("root-data-dir", Required = false, HelpText = "Set the custom folder path for Ryujinx data.")]
|
[Option("root-data-dir", Required = false, HelpText = "Set the custom folder path for Ryujinx data.")]
|
||||||
public string BaseDataDir { get; set; }
|
public string BaseDataDir { get; set; }
|
||||||
|
|
||||||
@ -95,10 +250,10 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
[Option("hide-cursor", Required = false, Default = HideCursorMode.OnIdle, HelpText = "Change when the cursor gets hidden.")]
|
[Option("hide-cursor", Required = false, Default = HideCursorMode.OnIdle, HelpText = "Change when the cursor gets hidden.")]
|
||||||
public HideCursorMode HideCursorMode { get; set; }
|
public HideCursorMode HideCursorMode { get; set; }
|
||||||
|
|
||||||
[Option("list-input-profiles", Required = false, HelpText = "List inputs profiles.")]
|
[Option("list-input-profiles", Required = false, HelpText = "List input profiles.")]
|
||||||
public bool ListInputProfiles { get; set; }
|
public bool ListInputProfiles { get; set; }
|
||||||
|
|
||||||
[Option("list-inputs-ids", Required = false, HelpText = "List inputs ids.")]
|
[Option("list-input-ids", Required = false, HelpText = "List input IDs.")]
|
||||||
public bool ListInputIds { get; set; }
|
public bool ListInputIds { get; set; }
|
||||||
|
|
||||||
// System
|
// System
|
||||||
@ -172,7 +327,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
public bool LoggingDisableWarning { get; set; }
|
public bool LoggingDisableWarning { get; set; }
|
||||||
|
|
||||||
[Option("disable-error-logs", Required = false, HelpText = "Disables printing error log messages.")]
|
[Option("disable-error-logs", Required = false, HelpText = "Disables printing error log messages.")]
|
||||||
public bool LoggingEnableError { get; set; }
|
public bool LoggingDisableError { get; set; }
|
||||||
|
|
||||||
[Option("enable-trace-logs", Required = false, Default = false, HelpText = "Enables printing trace log messages.")]
|
[Option("enable-trace-logs", Required = false, Default = false, HelpText = "Enables printing trace log messages.")]
|
||||||
public bool LoggingEnableTrace { get; set; }
|
public bool LoggingEnableTrace { get; set; }
|
||||||
@ -215,7 +370,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
[Option("anti-aliasing", Required = false, Default = AntiAliasing.None, HelpText = "Set the type of anti aliasing being used. [None|Fxaa|SmaaLow|SmaaMedium|SmaaHigh|SmaaUltra]")]
|
[Option("anti-aliasing", Required = false, Default = AntiAliasing.None, HelpText = "Set the type of anti aliasing being used. [None|Fxaa|SmaaLow|SmaaMedium|SmaaHigh|SmaaUltra]")]
|
||||||
public AntiAliasing AntiAliasing { get; set; }
|
public AntiAliasing AntiAliasing { get; set; }
|
||||||
|
|
||||||
[Option("scaling-filter", Required = false, Default = ScalingFilter.Bilinear, HelpText = "Set the scaling filter. [Bilinear|Nearest|Fsr]")]
|
[Option("scaling-filter", Required = false, Default = ScalingFilter.Bilinear, HelpText = "Set the scaling filter. [Bilinear|Nearest|Fsr|Area]")]
|
||||||
public ScalingFilter ScalingFilter { get; set; }
|
public ScalingFilter ScalingFilter { get; set; }
|
||||||
|
|
||||||
[Option("scaling-filter-level", Required = false, Default = 0, HelpText = "Set the scaling filter intensity (currently only applies to FSR). [0-100]")]
|
[Option("scaling-filter-level", Required = false, Default = 0, HelpText = "Set the scaling filter intensity (currently only applies to FSR). [0-100]")]
|
BIN
src/Ryujinx/Headless/Ryujinx.bmp
Normal file
After Width: | Height: | Size: 3.9 KiB |
@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Headless.SDL2
|
namespace Ryujinx.Headless
|
||||||
{
|
{
|
||||||
class StatusUpdatedEventArgs(
|
class StatusUpdatedEventArgs(
|
||||||
string vSyncMode,
|
string vSyncMode,
|
@ -6,7 +6,7 @@ using System;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using static SDL2.SDL;
|
using static SDL2.SDL;
|
||||||
|
|
||||||
namespace Ryujinx.Headless.SDL2.Vulkan
|
namespace Ryujinx.Headless
|
||||||
{
|
{
|
||||||
class VulkanWindow : WindowBase
|
class VulkanWindow : WindowBase
|
||||||
{
|
{
|
@ -1,5 +1,6 @@
|
|||||||
using Humanizer;
|
using Humanizer;
|
||||||
using LibHac.Tools.Fs;
|
using LibHac.Tools.Fs;
|
||||||
|
using Ryujinx.Ava;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
@ -26,7 +27,7 @@ using AntiAliasing = Ryujinx.Common.Configuration.AntiAliasing;
|
|||||||
using ScalingFilter = Ryujinx.Common.Configuration.ScalingFilter;
|
using ScalingFilter = Ryujinx.Common.Configuration.ScalingFilter;
|
||||||
using Switch = Ryujinx.HLE.Switch;
|
using Switch = Ryujinx.HLE.Switch;
|
||||||
|
|
||||||
namespace Ryujinx.Headless.SDL2
|
namespace Ryujinx.Headless
|
||||||
{
|
{
|
||||||
abstract partial class WindowBase : IHostUIHandler, IDisposable
|
abstract partial class WindowBase : IHostUIHandler, IDisposable
|
||||||
{
|
{
|
||||||
@ -136,7 +137,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
|
|
||||||
private void SetWindowIcon()
|
private void SetWindowIcon()
|
||||||
{
|
{
|
||||||
Stream iconStream = typeof(WindowBase).Assembly.GetManifestResourceStream("Ryujinx.Headless.SDL2.Ryujinx.bmp");
|
Stream iconStream = typeof(Program).Assembly.GetManifestResourceStream("HeadlessLogo");
|
||||||
byte[] iconBytes = new byte[iconStream!.Length];
|
byte[] iconBytes = new byte[iconStream!.Length];
|
||||||
|
|
||||||
if (iconStream.Read(iconBytes, 0, iconBytes.Length) != iconBytes.Length)
|
if (iconStream.Read(iconBytes, 0, iconBytes.Length) != iconBytes.Length)
|
||||||
@ -254,12 +255,12 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
|
|
||||||
private void SetAntiAliasing()
|
private void SetAntiAliasing()
|
||||||
{
|
{
|
||||||
Renderer?.Window.SetAntiAliasing((Graphics.GAL.AntiAliasing)AntiAliasing);
|
Renderer?.Window.SetAntiAliasing(AntiAliasing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetScalingFilter()
|
private void SetScalingFilter()
|
||||||
{
|
{
|
||||||
Renderer?.Window.SetScalingFilter((Graphics.GAL.ScalingFilter)ScalingFilter);
|
Renderer?.Window.SetScalingFilter(ScalingFilter);
|
||||||
Renderer?.Window.SetScalingFilterLevel(ScalingFilterLevel);
|
Renderer?.Window.SetScalingFilterLevel(ScalingFilterLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +319,7 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
Device.VSyncMode.ToString(),
|
Device.VSyncMode.ToString(),
|
||||||
dockedMode,
|
dockedMode,
|
||||||
Device.Configuration.AspectRatio.ToText(),
|
Device.Configuration.AspectRatio.ToText(),
|
||||||
$"Game: {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)",
|
$"{Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)",
|
||||||
$"FIFO: {Device.Statistics.GetFifoPercent():0.00} %",
|
$"FIFO: {Device.Statistics.GetFifoPercent():0.00} %",
|
||||||
$"GPU: {_gpuDriverName}"));
|
$"GPU: {_gpuDriverName}"));
|
||||||
|
|
@ -8,18 +8,18 @@ using Projektanker.Icons.Avalonia.MaterialDesign;
|
|||||||
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.AppLibrary;
|
||||||
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
|
using Ryujinx.Ava.Utilities.SystemInfo;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.GraphicsDriver;
|
using Ryujinx.Common.GraphicsDriver;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.SystemInterop;
|
using Ryujinx.Common.SystemInterop;
|
||||||
using Ryujinx.Graphics.Vulkan.MoltenVK;
|
using Ryujinx.Graphics.Vulkan.MoltenVK;
|
||||||
|
using Ryujinx.Headless;
|
||||||
using Ryujinx.SDL2.Common;
|
using Ryujinx.SDL2.Common;
|
||||||
using Ryujinx.UI.App.Common;
|
|
||||||
using Ryujinx.UI.Common;
|
|
||||||
using Ryujinx.UI.Common.Configuration;
|
|
||||||
using Ryujinx.UI.Common.Helper;
|
|
||||||
using Ryujinx.UI.Common.SystemInfo;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -53,6 +53,12 @@ namespace Ryujinx.Ava
|
|||||||
|
|
||||||
PreviewerDetached = true;
|
PreviewerDetached = true;
|
||||||
|
|
||||||
|
if (args.Length > 0 && args[0] is "--no-gui" or "nogui")
|
||||||
|
{
|
||||||
|
HeadlessRyujinx.Entrypoint(args[1..]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Initialize(args);
|
Initialize(args);
|
||||||
|
|
||||||
LoggerAdapter.Register();
|
LoggerAdapter.Register();
|
||||||
@ -110,9 +116,6 @@ namespace Ryujinx.Ava
|
|||||||
// Setup base data directory.
|
// Setup base data directory.
|
||||||
AppDataManager.Initialize(CommandLineState.BaseDirPathArg);
|
AppDataManager.Initialize(CommandLineState.BaseDirPathArg);
|
||||||
|
|
||||||
// Set the delegate for localizing the word "never" in the UI
|
|
||||||
ApplicationData.LocalizedNever = () => LocaleManager.Instance[LocaleKeys.Never];
|
|
||||||
|
|
||||||
// Initialize the configuration.
|
// Initialize the configuration.
|
||||||
ConfigurationState.Initialize();
|
ConfigurationState.Initialize();
|
||||||
|
|
||||||
@ -223,7 +226,7 @@ namespace Ryujinx.Ava
|
|||||||
UseHardwareAcceleration = CommandLineState.OverrideHardwareAcceleration.Value;
|
UseHardwareAcceleration = CommandLineState.OverrideHardwareAcceleration.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PrintSystemInfo()
|
internal static void PrintSystemInfo()
|
||||||
{
|
{
|
||||||
Logger.Notice.Print(LogClass.Application, $"{RyujinxApp.FullAppName} Version: {Version}");
|
Logger.Notice.Print(LogClass.Application, $"{RyujinxApp.FullAppName} Version: {Version}");
|
||||||
SystemInfo.Gather().Print();
|
SystemInfo.Gather().Print();
|
||||||
@ -240,7 +243,7 @@ namespace Ryujinx.Ava
|
|||||||
: $"Launch Mode: {AppDataManager.Mode}");
|
: $"Launch Mode: {AppDataManager.Mode}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessUnhandledException(object sender, Exception ex, bool isTerminating)
|
internal static void ProcessUnhandledException(object sender, Exception ex, bool isTerminating)
|
||||||
{
|
{
|
||||||
Logger.Log log = Logger.Error ?? Logger.Notice;
|
Logger.Log log = Logger.Error ?? Logger.Notice;
|
||||||
string message = $"Unhandled exception caught: {ex}";
|
string message = $"Unhandled exception caught: {ex}";
|
||||||
@ -255,7 +258,7 @@ namespace Ryujinx.Ava
|
|||||||
Exit();
|
Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Exit()
|
internal static void Exit()
|
||||||
{
|
{
|
||||||
DiscordIntegrationModule.Exit();
|
DiscordIntegrationModule.Exit();
|
||||||
|
|
||||||
|
@ -47,6 +47,8 @@
|
|||||||
<PackageReference Include="Avalonia.Markup.Xaml.Loader" />
|
<PackageReference Include="Avalonia.Markup.Xaml.Loader" />
|
||||||
<PackageReference Include="Avalonia.Svg" />
|
<PackageReference Include="Avalonia.Svg" />
|
||||||
<PackageReference Include="Avalonia.Svg.Skia" />
|
<PackageReference Include="Avalonia.Svg.Skia" />
|
||||||
|
<PackageReference Include="CommandLineParser" />
|
||||||
|
<PackageReference Include="DiscordRichPresence" />
|
||||||
<PackageReference Include="DynamicData" />
|
<PackageReference Include="DynamicData" />
|
||||||
<PackageReference Include="FluentAvaloniaUI" />
|
<PackageReference Include="FluentAvaloniaUI" />
|
||||||
<PackageReference Include="Projektanker.Icons.Avalonia" />
|
<PackageReference Include="Projektanker.Icons.Avalonia" />
|
||||||
@ -56,6 +58,7 @@
|
|||||||
<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" />
|
||||||
<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'" />
|
||||||
|
<PackageReference Include="securifybv.ShellLink" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan" />
|
<PackageReference Include="Silk.NET.Vulkan" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
|
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
|
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
|
||||||
@ -66,6 +69,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj" />
|
<ProjectReference Include="..\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj" />
|
<ProjectReference Include="..\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj" />
|
||||||
|
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Metal\Ryujinx.Graphics.Metal.csproj" />
|
<ProjectReference Include="..\Ryujinx.Graphics.Metal\Ryujinx.Graphics.Metal.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Input\Ryujinx.Input.csproj" />
|
<ProjectReference Include="..\Ryujinx.Input\Ryujinx.Input.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Input.SDL2\Ryujinx.Input.SDL2.csproj" />
|
<ProjectReference Include="..\Ryujinx.Input.SDL2\Ryujinx.Input.SDL2.csproj" />
|
||||||
@ -74,9 +78,7 @@
|
|||||||
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.HLE\Ryujinx.HLE.csproj" />
|
<ProjectReference Include="..\Ryujinx.HLE\Ryujinx.HLE.csproj" />
|
||||||
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
|
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
|
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj" />
|
|
||||||
<ProjectReference Include="..\Ryujinx.UI.LocaleGenerator\Ryujinx.UI.LocaleGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
<ProjectReference Include="..\Ryujinx.UI.LocaleGenerator\Ryujinx.UI.LocaleGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
@ -127,12 +129,34 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="..\..\distribution\linux\shortcut-template.desktop">
|
||||||
|
<Link>Assets\ShortcutFiles\shortcut-template.desktop</Link>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="..\..\distribution\macos\shortcut-launch-script.sh">
|
||||||
|
<Link>Assets\ShortcutFiles\shortcut-launch-script.sh</Link>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="..\..\distribution\macos\shortcut-template.plist">
|
||||||
|
<Link>Assets\ShortcutFiles\shortcut-template.plist</Link>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Assets\locales.json" />
|
<EmbeddedResource Include="Assets\locales.json" />
|
||||||
<EmbeddedResource Include="Assets\Styles\Styles.xaml" />
|
<EmbeddedResource Include="Assets\Styles\Styles.xaml" />
|
||||||
<EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />
|
<EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />
|
||||||
<EmbeddedResource Include="Assets\Icons\Controller_JoyConPair.svg" />
|
<EmbeddedResource Include="Assets\Icons\Controller_JoyConPair.svg" />
|
||||||
<EmbeddedResource Include="Assets\Icons\Controller_JoyConRight.svg" />
|
<EmbeddedResource Include="Assets\Icons\Controller_JoyConRight.svg" />
|
||||||
<EmbeddedResource Include="Assets\Icons\Controller_ProCon.svg" />
|
<EmbeddedResource Include="Assets\Icons\Controller_ProCon.svg" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Icon_NCA.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Icon_NRO.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Icon_NSO.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Icon_NSP.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Icon_XCI.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Logo_Amiibo.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Logo_Discord_Dark.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Logo_Discord_Light.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Logo_GitHub_Dark.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Logo_GitHub_Light.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Logo_Ryujinx.png" />
|
||||||
|
<EmbeddedResource Include="Assets\UIImages\Logo_Ryujinx_AntiAlias.png" />
|
||||||
|
<EmbeddedResource Include="Headless\Ryujinx.bmp" LogicalName="HeadlessLogo" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AdditionalFiles Include="Assets\locales.json" />
|
<AdditionalFiles Include="Assets\locales.json" />
|
||||||
|
@ -11,10 +11,10 @@ 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.Configuration;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.UI.Common.Configuration;
|
|
||||||
using Ryujinx.UI.Common.Helper;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
@ -5,12 +5,12 @@ using Ryujinx.Ava.Common.Locale;
|
|||||||
using Ryujinx.Ava.UI.Controls;
|
using Ryujinx.Ava.UI.Controls;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
|
using Ryujinx.Ava.Utilities.Configuration;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using Ryujinx.HLE.HOS.Applets;
|
using Ryujinx.HLE.HOS.Applets;
|
||||||
using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
||||||
using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
|
using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
|
||||||
using Ryujinx.HLE.UI;
|
using Ryujinx.HLE.UI;
|
||||||
using Ryujinx.UI.Common.Configuration;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
Height="80"
|
Height="80"
|
||||||
MinWidth="50"
|
MinWidth="50"
|
||||||
Margin="5,10,20,10"
|
Margin="5,10,20,10"
|
||||||
Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
|
Source="resm:Ryujinx.Assets.UIImages.Logo_Ryujinx.png?assembly=Ryujinx" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
MinWidth="50"
|
MinWidth="50"
|
||||||
Margin="5,10,20,10"
|
Margin="5,10,20,10"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.UI.Common" />
|
Source="resm:Ryujinx.Assets.UIImages.Logo_Ryujinx.png?assembly=Ryujinx" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
|
@ -10,10 +10,11 @@ using Ryujinx.Ava.Common.Locale;
|
|||||||
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;
|
||||||
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
using Ryujinx.UI.App.Common;
|
|
||||||
using Ryujinx.UI.Common.Helper;
|
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -3,7 +3,7 @@ using Avalonia.Input;
|
|||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.UI.App.Common;
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Controls
|
namespace Ryujinx.Ava.UI.Controls
|
||||||
|
@ -5,7 +5,7 @@ using Avalonia.Interactivity;
|
|||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.UI.App.Common;
|
using Ryujinx.Ava.Utilities.AppLibrary;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|