Compare commits
12 Commits
Canary-1.2
...
refactor/a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66fdad6d64 | ||
|
|
657bd4a7d0 | ||
|
|
d3a6a8f66e | ||
|
|
12a506a644 | ||
|
|
6f56690c1c | ||
|
|
1398dad67c | ||
|
|
2fc58d58a5 | ||
|
|
75fa7c7d4d | ||
|
|
a477658b85 | ||
|
|
338777055f | ||
|
|
90db9a962d | ||
|
|
4a545a00c6 |
23
.github/workflows/build.yml
vendored
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'
|
|
||||||
|
|||||||
62
.github/workflows/canary.yml
vendored
62
.github/workflows/canary.yml
vendored
@@ -54,19 +54,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: "Canary ${{ steps.version_info.outputs.build_version }}"
|
name: "Canary ${{ steps.version_info.outputs.build_version }}"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: |
|
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
|
||||||
# Canary builds:
|
|
||||||
|
|
||||||
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ github.repository }}/releases/latest) instead if that sounds like something you don't want to deal with.
|
|
||||||
|
|
||||||
| Platform | Artifact |
|
|
||||||
|--|--|
|
|
||||||
| Windows 64 bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
|
||||||
| Linux 64 bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
|
||||||
| Linux arm 64 bit | [Canary Linux arm Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
|
||||||
| macOS | [Canary macOS artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
|
||||||
|
|
||||||
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}
|
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
||||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||||
@@ -116,7 +104,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 +112,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 +122,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,21 +167,9 @@ 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: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
|
||||||
# Canary builds:
|
|
||||||
|
|
||||||
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/GreemDev/Ryujinx/releases/latest) instead if that sounds like something you don't want to deal with.
|
|
||||||
|
|
||||||
| Platform | Artifact |
|
|
||||||
|--|--|
|
|
||||||
| Windows 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip |
|
|
||||||
| Linux 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz |
|
|
||||||
| Linux arm 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz |
|
|
||||||
| Macos | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz |
|
|
||||||
|
|
||||||
"**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
|
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
replacesArtifacts: true
|
replacesArtifacts: true
|
||||||
@@ -262,29 +226,13 @@ 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: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
|
||||||
# Canary builds:
|
|
||||||
|
|
||||||
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/GreemDev/Ryujinx/releases/latest) instead if that sounds like something you don't want to deal with.
|
|
||||||
|
|
||||||
| Platform | Artifact |
|
|
||||||
|--|--|
|
|
||||||
| Windows 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip |
|
|
||||||
| Linux 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz |
|
|
||||||
| Linux arm 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz |
|
|
||||||
| Macos | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz |
|
|
||||||
|
|
||||||
"**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
|
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
replacesArtifacts: true
|
replacesArtifacts: true
|
||||||
|
|||||||
5
.github/workflows/nightly_pr_comment.yml
vendored
5
.github/workflows/nightly_pr_comment.yml
vendored
@@ -38,20 +38,15 @@ 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) {
|
||||||
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}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
||||||
} 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}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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});
|
||||||
|
|||||||
50
.github/workflows/release.yml
vendored
50
.github/workflows/release.yml
vendored
@@ -53,16 +53,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: |
|
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
|
||||||
# Regular builds:
|
|
||||||
| Platform | Artifact |
|
|
||||||
|--|--|
|
|
||||||
| Windows 64 bit | [Release Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
|
||||||
| Linux 64 bit | [Release Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
|
||||||
| Linux arm 64 bit | [Release Linux arm Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
|
||||||
| macOS | [Release macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
|
||||||
|
|
||||||
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
|
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
||||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||||
@@ -112,7 +103,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 +111,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 +157,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
|
||||||
@@ -185,16 +165,7 @@ jobs:
|
|||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*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: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
|
||||||
# Regular builds:
|
|
||||||
| Platform | Artifact |
|
|
||||||
|--|--|
|
|
||||||
| Windows 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip |
|
|
||||||
| Linux 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz |
|
|
||||||
| Linux arm 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz |
|
|
||||||
| Macos | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz |
|
|
||||||
|
|
||||||
"**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
|
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
replacesArtifacts: true
|
replacesArtifacts: true
|
||||||
@@ -251,26 +222,13 @@ 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: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
|
||||||
# Regular builds:
|
|
||||||
| Platform | Artifact |
|
|
||||||
|--|--|
|
|
||||||
| Windows 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip |
|
|
||||||
| Linux 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz |
|
|
||||||
| Linux arm 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz |
|
|
||||||
| Macos | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz |
|
|
||||||
|
|
||||||
"**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
|
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
replacesArtifacts: true
|
replacesArtifacts: true
|
||||||
|
|||||||
@@ -57,8 +57,6 @@ 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}"
|
||||||
@@ -204,10 +202,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
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,73 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<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.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>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.1 KiB |
@@ -1,4 +1,5 @@
|
|||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Configuration.System
|
namespace Ryujinx.UI.Common.Configuration.System
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -555,9 +555,9 @@
|
|||||||
"AboutGithubUrlTooltipMessage": "클릭하면 기본 브라우저에서 Ryujinx GitHub 페이지가 열립니다.",
|
"AboutGithubUrlTooltipMessage": "클릭하면 기본 브라우저에서 Ryujinx GitHub 페이지가 열립니다.",
|
||||||
"AboutDiscordUrlTooltipMessage": "클릭하면 기본 브라우저에서 Ryujinx 디스코드 서버 초대장이 열립니다.",
|
"AboutDiscordUrlTooltipMessage": "클릭하면 기본 브라우저에서 Ryujinx 디스코드 서버 초대장이 열립니다.",
|
||||||
"AboutRyujinxAboutTitle": "정보 :",
|
"AboutRyujinxAboutTitle": "정보 :",
|
||||||
"AboutRyujinxAboutContent": "Ryujinx는 Nintendo Switch™용 에뮬레이터입니다.\n모든 최신 소식을 Discord에서 확인하세요.\n기여에 관심이 있는 개발자는 GitHub 또는 Discord에서 자세한 내용을 확인할 수 있습니다.",
|
"AboutRyujinxAboutContent": "Ryujinx is an emulator for the Nintendo Switch™.\nGet all the latest news in our Discord.\nDevelopers interested in contributing can find out more on our GitHub or Discord.",
|
||||||
"AboutRyujinxMaintainersTitle": "유지 관리 :",
|
"AboutRyujinxMaintainersTitle": "유지 관리 :",
|
||||||
"AboutRyujinxFormerMaintainersTitle": "이전 관리자 :",
|
"AboutRyujinxFormerMaintainersTitle": "Formerly Maintained By:",
|
||||||
"AboutRyujinxMaintainersContentTooltipMessage": "클릭하면 기본 브라우저에서 기여자 페이지가 열립니다.",
|
"AboutRyujinxMaintainersContentTooltipMessage": "클릭하면 기본 브라우저에서 기여자 페이지가 열립니다.",
|
||||||
"AmiiboSeriesLabel": "Amiibo 시리즈",
|
"AmiiboSeriesLabel": "Amiibo 시리즈",
|
||||||
"AmiiboCharacterLabel": "캐릭터",
|
"AmiiboCharacterLabel": "캐릭터",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"Language": "Українська",
|
"Language": "Українська",
|
||||||
"MenuBarFileOpenApplet": "Відкрити аплет",
|
"MenuBarFileOpenApplet": "Відкрити аплет",
|
||||||
"MenuBarFileOpenAppletOpenMiiApplet": "Аплет для редагування Mii",
|
"MenuBarFileOpenAppletOpenMiiApplet": "Mii Edit Applet",
|
||||||
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Відкрити аплет Mii Editor в автономному режимі",
|
"MenuBarFileOpenAppletOpenMiiAppletToolTip": "Відкрити аплет Mii Editor в автономному режимі",
|
||||||
"SettingsTabInputDirectMouseAccess": "Прямий доступ мишею",
|
"SettingsTabInputDirectMouseAccess": "Прямий доступ мишею",
|
||||||
"SettingsTabSystemMemoryManagerMode": "Режим диспетчера пам’яті:",
|
"SettingsTabSystemMemoryManagerMode": "Режим диспетчера пам’яті:",
|
||||||
@@ -11,10 +11,10 @@
|
|||||||
"SettingsTabSystemUseHypervisor": "Використовувати гіпервізор",
|
"SettingsTabSystemUseHypervisor": "Використовувати гіпервізор",
|
||||||
"MenuBarFile": "_Файл",
|
"MenuBarFile": "_Файл",
|
||||||
"MenuBarFileOpenFromFile": "_Завантажити програму з файлу",
|
"MenuBarFileOpenFromFile": "_Завантажити програму з файлу",
|
||||||
"MenuBarFileOpenFromFileError": "У вибраному файлі не знайдено жодних додатків.",
|
"MenuBarFileOpenFromFileError": "No applications found in selected file.",
|
||||||
"MenuBarFileOpenUnpacked": "Завантажити _розпаковану гру",
|
"MenuBarFileOpenUnpacked": "Завантажити _розпаковану гру",
|
||||||
"MenuBarFileLoadDlcFromFolder": "Завантажити DLC з теки",
|
"MenuBarFileLoadDlcFromFolder": "Load DLC From Folder",
|
||||||
"MenuBarFileLoadTitleUpdatesFromFolder": "Завантажити оновлення заголовків з теки",
|
"MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder",
|
||||||
"MenuBarFileOpenEmuFolder": "Відкрити теку Ryujinx",
|
"MenuBarFileOpenEmuFolder": "Відкрити теку Ryujinx",
|
||||||
"MenuBarFileOpenLogsFolder": "Відкрити теку журналів змін",
|
"MenuBarFileOpenLogsFolder": "Відкрити теку журналів змін",
|
||||||
"MenuBarFileExit": "_Вихід",
|
"MenuBarFileExit": "_Вихід",
|
||||||
@@ -37,9 +37,9 @@
|
|||||||
"MenuBarToolsManageFileTypes": "Керувати типами файлів",
|
"MenuBarToolsManageFileTypes": "Керувати типами файлів",
|
||||||
"MenuBarToolsInstallFileTypes": "Установити типи файлів",
|
"MenuBarToolsInstallFileTypes": "Установити типи файлів",
|
||||||
"MenuBarToolsUninstallFileTypes": "Видалити типи файлів",
|
"MenuBarToolsUninstallFileTypes": "Видалити типи файлів",
|
||||||
"MenuBarToolsXCITrimmer": "Обрізати XCI файли",
|
"MenuBarToolsXCITrimmer": "Trim XCI Files",
|
||||||
"MenuBarView": "_Вид",
|
"MenuBarView": "_View",
|
||||||
"MenuBarViewWindow": "Розмір вікна",
|
"MenuBarViewWindow": "Window Size",
|
||||||
"MenuBarViewWindow720": "720p",
|
"MenuBarViewWindow720": "720p",
|
||||||
"MenuBarViewWindow1080": "1080p",
|
"MenuBarViewWindow1080": "1080p",
|
||||||
"MenuBarHelp": "_Допомога",
|
"MenuBarHelp": "_Допомога",
|
||||||
@@ -89,11 +89,11 @@
|
|||||||
"GameListContextMenuOpenModsDirectoryToolTip": "Відкриває каталог, який містить модифікації Додатків",
|
"GameListContextMenuOpenModsDirectoryToolTip": "Відкриває каталог, який містить модифікації Додатків",
|
||||||
"GameListContextMenuOpenSdModsDirectory": "Відкрити каталог модифікацій Atmosphere",
|
"GameListContextMenuOpenSdModsDirectory": "Відкрити каталог модифікацій Atmosphere",
|
||||||
"GameListContextMenuOpenSdModsDirectoryToolTip": "Відкриває альтернативний каталог SD-карти Atmosphere, що містить модифікації Додатків. Корисно для модифікацій, зроблених для реального обладнання.",
|
"GameListContextMenuOpenSdModsDirectoryToolTip": "Відкриває альтернативний каталог SD-карти Atmosphere, що містить модифікації Додатків. Корисно для модифікацій, зроблених для реального обладнання.",
|
||||||
"GameListContextMenuTrimXCI": "Перевірка та Нарізка XCI Файлів",
|
"GameListContextMenuTrimXCI": "Check and Trim XCI File",
|
||||||
"GameListContextMenuTrimXCIToolTip": "Перевірка та Нарізка XCI Файлів для збереження місця на диску",
|
"GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space",
|
||||||
"StatusBarGamesLoaded": "{0}/{1} ігор завантажено",
|
"StatusBarGamesLoaded": "{0}/{1} ігор завантажено",
|
||||||
"StatusBarSystemVersion": "Версія системи: {0}",
|
"StatusBarSystemVersion": "Версія системи: {0}",
|
||||||
"StatusBarXCIFileTrimming": "Обрізано XCI Файлів '{0}'",
|
"StatusBarXCIFileTrimming": "Trimming XCI File '{0}'",
|
||||||
"LinuxVmMaxMapCountDialogTitle": "Виявлено низьку межу для відображення памʼяті",
|
"LinuxVmMaxMapCountDialogTitle": "Виявлено низьку межу для відображення памʼяті",
|
||||||
"LinuxVmMaxMapCountDialogTextPrimary": "Бажаєте збільшити значення vm.max_map_count на {0}",
|
"LinuxVmMaxMapCountDialogTextPrimary": "Бажаєте збільшити значення vm.max_map_count на {0}",
|
||||||
"LinuxVmMaxMapCountDialogTextSecondary": "Деякі ігри можуть спробувати створити більше відображень памʼяті, ніж дозволено наразі. Ryujinx завершить роботу, щойно цей ліміт буде перевищено.",
|
"LinuxVmMaxMapCountDialogTextSecondary": "Деякі ігри можуть спробувати створити більше відображень памʼяті, ніж дозволено наразі. Ryujinx завершить роботу, щойно цей ліміт буде перевищено.",
|
||||||
@@ -107,15 +107,15 @@
|
|||||||
"SettingsTabGeneralEnableDiscordRichPresence": "Увімкнути розширену присутність Discord",
|
"SettingsTabGeneralEnableDiscordRichPresence": "Увімкнути розширену присутність Discord",
|
||||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Перевіряти наявність оновлень під час запуску",
|
"SettingsTabGeneralCheckUpdatesOnLaunch": "Перевіряти наявність оновлень під час запуску",
|
||||||
"SettingsTabGeneralShowConfirmExitDialog": "Показати діалогове вікно «Підтвердити вихід».",
|
"SettingsTabGeneralShowConfirmExitDialog": "Показати діалогове вікно «Підтвердити вихід».",
|
||||||
"SettingsTabGeneralRememberWindowState": "Запам'ятати Розмір/Позицію вікна",
|
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||||
"SettingsTabGeneralShowTitleBar": "Показувати рядок заголовка (Потрібен перезапуск)",
|
"SettingsTabGeneralShowTitleBar": "Show Title Bar (Requires restart)",
|
||||||
"SettingsTabGeneralHideCursor": "Сховати вказівник:",
|
"SettingsTabGeneralHideCursor": "Сховати вказівник:",
|
||||||
"SettingsTabGeneralHideCursorNever": "Ніколи",
|
"SettingsTabGeneralHideCursorNever": "Ніколи",
|
||||||
"SettingsTabGeneralHideCursorOnIdle": "Сховати у режимі очікування",
|
"SettingsTabGeneralHideCursorOnIdle": "Сховати у режимі очікування",
|
||||||
"SettingsTabGeneralHideCursorAlways": "Завжди",
|
"SettingsTabGeneralHideCursorAlways": "Завжди",
|
||||||
"SettingsTabGeneralGameDirectories": "Тека ігор",
|
"SettingsTabGeneralGameDirectories": "Тека ігор",
|
||||||
"SettingsTabGeneralAutoloadDirectories": "Автозавантаження каталогів DLC/Оновлень",
|
"SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories",
|
||||||
"SettingsTabGeneralAutoloadNote": "DLC та Оновлення, які посилаються на відсутні файли, будуть автоматично вимкнуті.",
|
"SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically",
|
||||||
"SettingsTabGeneralAdd": "Додати",
|
"SettingsTabGeneralAdd": "Додати",
|
||||||
"SettingsTabGeneralRemove": "Видалити",
|
"SettingsTabGeneralRemove": "Видалити",
|
||||||
"SettingsTabSystem": "Система",
|
"SettingsTabSystem": "Система",
|
||||||
@@ -148,18 +148,7 @@
|
|||||||
"SettingsTabSystemSystemLanguageTraditionalChinese": "Традиційна китайська",
|
"SettingsTabSystemSystemLanguageTraditionalChinese": "Традиційна китайська",
|
||||||
"SettingsTabSystemSystemTimeZone": "Часовий пояс системи:",
|
"SettingsTabSystemSystemTimeZone": "Часовий пояс системи:",
|
||||||
"SettingsTabSystemSystemTime": "Час системи:",
|
"SettingsTabSystemSystemTime": "Час системи:",
|
||||||
"SettingsTabSystemVSyncMode": "Вертикальна синхронізація (VSync):",
|
"SettingsTabSystemEnableVsync": "Вертикальна синхронізація",
|
||||||
"SettingsTabSystemEnableCustomVSyncInterval": "Увімкнути користувацьку частоту оновлення (Експериментально)",
|
|
||||||
"SettingsTabSystemVSyncModeSwitch": "Switch",
|
|
||||||
"SettingsTabSystemVSyncModeUnbounded": "Безмежна",
|
|
||||||
"SettingsTabSystemVSyncModeCustom": "Користувацька",
|
|
||||||
"SettingsTabSystemVSyncModeTooltip": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень.",
|
|
||||||
"SettingsTabSystemVSyncModeTooltipCustom": "Емульована вертикальна синхронізація. 'Switch' емулює частоту оновлення Switch 60 Гц. 'Безмежна' — частота оновлення не матиме обмежень. 'Користувацька' емулює вказану користувацьку частоту оновлення.",
|
|
||||||
"SettingsTabSystemEnableCustomVSyncIntervalTooltip": "Дозволяє користувачу вказати емульовану частоту оновлення. У деяких іграх це може прискорити або сповільнити логіку гри. У інших іграх це може дозволити обмежити FPS на певні кратні частоти оновлення або призвести до непередбачуваної поведінки. Це експериментальна функція, без гарантій того, як це вплине на ігровий процес. \n\nЗалиште ВИМКНЕНИМ, якщо не впевнені.",
|
|
||||||
"SettingsTabSystemCustomVSyncIntervalValueTooltip": "Цільове значення користувацької частоти оновлення.",
|
|
||||||
"SettingsTabSystemCustomVSyncIntervalSliderTooltip": "Користувацька частота оновлення, як відсоток від стандартної частоти оновлення Switch.",
|
|
||||||
"SettingsTabSystemCustomVSyncIntervalPercentage": "Користувацька частота оновлення %:",
|
|
||||||
"SettingsTabSystemCustomVSyncIntervalValue": "Значення користувацька частота оновлення:",
|
|
||||||
"SettingsTabSystemEnablePptc": "PPTC (профільований постійний кеш перекладу)",
|
"SettingsTabSystemEnablePptc": "PPTC (профільований постійний кеш перекладу)",
|
||||||
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
|
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC",
|
||||||
"SettingsTabSystemEnableFsIntegrityChecks": "Перевірка цілісності FS",
|
"SettingsTabSystemEnableFsIntegrityChecks": "Перевірка цілісності FS",
|
||||||
@@ -170,11 +159,11 @@
|
|||||||
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
||||||
"SettingsTabSystemHacks": "Хитрощі",
|
"SettingsTabSystemHacks": "Хитрощі",
|
||||||
"SettingsTabSystemHacksNote": " (може викликати нестабільність)",
|
"SettingsTabSystemHacksNote": " (може викликати нестабільність)",
|
||||||
"SettingsTabSystemDramSize": "Використовувати альтернативне розташування пам'яті (для розробників)",
|
"SettingsTabSystemDramSize": "Використовувати альтернативне розташування пам'яті (розробники)",
|
||||||
"SettingsTabSystemDramSize4GiB": "4Гб",
|
"SettingsTabSystemDramSize4GiB": "4GiB",
|
||||||
"SettingsTabSystemDramSize6GiB": "6Гб",
|
"SettingsTabSystemDramSize6GiB": "6GiB",
|
||||||
"SettingsTabSystemDramSize8GiB": "8Гб",
|
"SettingsTabSystemDramSize8GiB": "8GiB",
|
||||||
"SettingsTabSystemDramSize12GiB": "12Гб",
|
"SettingsTabSystemDramSize12GiB": "12GiB",
|
||||||
"SettingsTabSystemIgnoreMissingServices": "Ігнорувати відсутні служби",
|
"SettingsTabSystemIgnoreMissingServices": "Ігнорувати відсутні служби",
|
||||||
"SettingsTabSystemIgnoreApplet": "Ігнорувати Аплет",
|
"SettingsTabSystemIgnoreApplet": "Ігнорувати Аплет",
|
||||||
"SettingsTabGraphics": "Графіка",
|
"SettingsTabGraphics": "Графіка",
|
||||||
@@ -212,8 +201,8 @@
|
|||||||
"SettingsTabLoggingEnableGuestLogs": "Увімкнути журнали гостей",
|
"SettingsTabLoggingEnableGuestLogs": "Увімкнути журнали гостей",
|
||||||
"SettingsTabLoggingEnableFsAccessLogs": "Увімкнути журнали доступу Fs",
|
"SettingsTabLoggingEnableFsAccessLogs": "Увімкнути журнали доступу Fs",
|
||||||
"SettingsTabLoggingFsGlobalAccessLogMode": "Режим журналу глобального доступу Fs:",
|
"SettingsTabLoggingFsGlobalAccessLogMode": "Режим журналу глобального доступу Fs:",
|
||||||
"SettingsTabLoggingDeveloperOptions": "Параметри розробника (УВАГА: шкодить продуктивності!)",
|
"SettingsTabLoggingDeveloperOptions": "Параметри розробника (УВАГА: знизиться продуктивність)",
|
||||||
"SettingsTabLoggingDeveloperOptionsNote": "УВАГА: Зміна параметрів нижче негативно впливає на продуктивність",
|
"SettingsTabLoggingDeveloperOptionsNote": "УВАГА: Знижує продуктивність",
|
||||||
"SettingsTabLoggingGraphicsBackendLogLevel": "Рівень журналу графічного сервера:",
|
"SettingsTabLoggingGraphicsBackendLogLevel": "Рівень журналу графічного сервера:",
|
||||||
"SettingsTabLoggingGraphicsBackendLogLevelNone": "Немає",
|
"SettingsTabLoggingGraphicsBackendLogLevelNone": "Немає",
|
||||||
"SettingsTabLoggingGraphicsBackendLogLevelError": "Помилка",
|
"SettingsTabLoggingGraphicsBackendLogLevelError": "Помилка",
|
||||||
@@ -302,29 +291,29 @@
|
|||||||
"ControllerSettingsMotionGyroDeadzone": "Мертва зона гіроскопа:",
|
"ControllerSettingsMotionGyroDeadzone": "Мертва зона гіроскопа:",
|
||||||
"ControllerSettingsSave": "Зберегти",
|
"ControllerSettingsSave": "Зберегти",
|
||||||
"ControllerSettingsClose": "Закрити",
|
"ControllerSettingsClose": "Закрити",
|
||||||
"KeyUnknown": "Невідома",
|
"KeyUnknown": "Unknown",
|
||||||
"KeyShiftLeft": "Shift Лівий",
|
"KeyShiftLeft": "Shift Left",
|
||||||
"KeyShiftRight": "Shift Правий",
|
"KeyShiftRight": "Shift Right",
|
||||||
"KeyControlLeft": "Ctrl Лівий",
|
"KeyControlLeft": "Ctrl Left",
|
||||||
"KeyMacControlLeft": "⌃ Лівий",
|
"KeyMacControlLeft": "⌃ Left",
|
||||||
"KeyControlRight": "Ctrl Правий",
|
"KeyControlRight": "Ctrl Right",
|
||||||
"KeyMacControlRight": "⌃ Правий",
|
"KeyMacControlRight": "⌃ Right",
|
||||||
"KeyAltLeft": "Alt Лівий",
|
"KeyAltLeft": "Alt Left",
|
||||||
"KeyMacAltLeft": "⌥ Лівий",
|
"KeyMacAltLeft": "⌥ Left",
|
||||||
"KeyAltRight": "Alt Правий",
|
"KeyAltRight": "Alt Right",
|
||||||
"KeyMacAltRight": "⌥ Правий",
|
"KeyMacAltRight": "⌥ Right",
|
||||||
"KeyWinLeft": "⊞ Лівий",
|
"KeyWinLeft": "⊞ Left",
|
||||||
"KeyMacWinLeft": "⌘ Лівий",
|
"KeyMacWinLeft": "⌘ Left",
|
||||||
"KeyWinRight": "⊞ Правий",
|
"KeyWinRight": "⊞ Right",
|
||||||
"KeyMacWinRight": "⌘ Правий",
|
"KeyMacWinRight": "⌘ Right",
|
||||||
"KeyMenu": "Menu",
|
"KeyMenu": "Menu",
|
||||||
"KeyUp": "Up",
|
"KeyUp": "Up",
|
||||||
"KeyDown": "Down",
|
"KeyDown": "Down",
|
||||||
"KeyLeft": "Вліво",
|
"KeyLeft": "Left",
|
||||||
"KeyRight": "Вправо",
|
"KeyRight": "Right",
|
||||||
"KeyEnter": "Enter",
|
"KeyEnter": "Enter",
|
||||||
"KeyEscape": "Escape",
|
"KeyEscape": "Escape",
|
||||||
"KeySpace": "Пробіл",
|
"KeySpace": "Space",
|
||||||
"KeyTab": "Tab",
|
"KeyTab": "Tab",
|
||||||
"KeyBackSpace": "Backspace",
|
"KeyBackSpace": "Backspace",
|
||||||
"KeyInsert": "Insert",
|
"KeyInsert": "Insert",
|
||||||
@@ -338,7 +327,7 @@
|
|||||||
"KeyPrintScreen": "Print Screen",
|
"KeyPrintScreen": "Print Screen",
|
||||||
"KeyPause": "Pause",
|
"KeyPause": "Pause",
|
||||||
"KeyNumLock": "Num Lock",
|
"KeyNumLock": "Num Lock",
|
||||||
"KeyClear": "Очистити",
|
"KeyClear": "Clear",
|
||||||
"KeyKeypad0": "Keypad 0",
|
"KeyKeypad0": "Keypad 0",
|
||||||
"KeyKeypad1": "Keypad 1",
|
"KeyKeypad1": "Keypad 1",
|
||||||
"KeyKeypad2": "Keypad 2",
|
"KeyKeypad2": "Keypad 2",
|
||||||
@@ -377,17 +366,17 @@
|
|||||||
"KeyPeriod": ".",
|
"KeyPeriod": ".",
|
||||||
"KeySlash": "/",
|
"KeySlash": "/",
|
||||||
"KeyBackSlash": "\\",
|
"KeyBackSlash": "\\",
|
||||||
"KeyUnbound": "Відв'язати",
|
"KeyUnbound": "Unbound",
|
||||||
"GamepadLeftStick": "L Кнопка Стіку",
|
"GamepadLeftStick": "L Stick Button",
|
||||||
"GamepadRightStick": "R Кнопка Стіку",
|
"GamepadRightStick": "R Stick Button",
|
||||||
"GamepadLeftShoulder": "Лівий Бампер",
|
"GamepadLeftShoulder": "Left Shoulder",
|
||||||
"GamepadRightShoulder": "Правий Бампер",
|
"GamepadRightShoulder": "Right Shoulder",
|
||||||
"GamepadLeftTrigger": "Лівий Тригер",
|
"GamepadLeftTrigger": "Left Trigger",
|
||||||
"GamepadRightTrigger": "Правий Тригер",
|
"GamepadRightTrigger": "Right Trigger",
|
||||||
"GamepadDpadUp": "Вверх",
|
"GamepadDpadUp": "Up",
|
||||||
"GamepadDpadDown": "Вниз",
|
"GamepadDpadDown": "Down",
|
||||||
"GamepadDpadLeft": "Вліво",
|
"GamepadDpadLeft": "Left",
|
||||||
"GamepadDpadRight": "Вправо",
|
"GamepadDpadRight": "Right",
|
||||||
"GamepadMinus": "-",
|
"GamepadMinus": "-",
|
||||||
"GamepadPlus": "+",
|
"GamepadPlus": "+",
|
||||||
"GamepadGuide": "Guide",
|
"GamepadGuide": "Guide",
|
||||||
@@ -397,12 +386,12 @@
|
|||||||
"GamepadPaddle3": "Paddle 3",
|
"GamepadPaddle3": "Paddle 3",
|
||||||
"GamepadPaddle4": "Paddle 4",
|
"GamepadPaddle4": "Paddle 4",
|
||||||
"GamepadTouchpad": "Touchpad",
|
"GamepadTouchpad": "Touchpad",
|
||||||
"GamepadSingleLeftTrigger0": "Лівий Тригер 0",
|
"GamepadSingleLeftTrigger0": "Left Trigger 0",
|
||||||
"GamepadSingleRightTrigger0": "Правий Тригер 0",
|
"GamepadSingleRightTrigger0": "Right Trigger 0",
|
||||||
"GamepadSingleLeftTrigger1": "Лівий Тригер 1",
|
"GamepadSingleLeftTrigger1": "Left Trigger 1",
|
||||||
"GamepadSingleRightTrigger1": "Правий Тригер 1",
|
"GamepadSingleRightTrigger1": "Right Trigger 1",
|
||||||
"StickLeft": "Лівий Стік",
|
"StickLeft": "Left Stick",
|
||||||
"StickRight": "Правий Стік",
|
"StickRight": "Right Stick",
|
||||||
"UserProfilesSelectedUserProfile": "Вибраний профіль користувача:",
|
"UserProfilesSelectedUserProfile": "Вибраний профіль користувача:",
|
||||||
"UserProfilesSaveProfileName": "Зберегти ім'я профілю",
|
"UserProfilesSaveProfileName": "Зберегти ім'я профілю",
|
||||||
"UserProfilesChangeProfileImage": "Змінити зображення профілю",
|
"UserProfilesChangeProfileImage": "Змінити зображення профілю",
|
||||||
@@ -419,8 +408,8 @@
|
|||||||
"InputDialogTitle": "Діалог введення",
|
"InputDialogTitle": "Діалог введення",
|
||||||
"InputDialogOk": "Гаразд",
|
"InputDialogOk": "Гаразд",
|
||||||
"InputDialogCancel": "Скасувати",
|
"InputDialogCancel": "Скасувати",
|
||||||
"InputDialogCancelling": "Скасування",
|
"InputDialogCancelling": "Cancelling",
|
||||||
"InputDialogClose": "Закрити",
|
"InputDialogClose": "Close",
|
||||||
"InputDialogAddNewProfileTitle": "Виберіть ім'я профілю",
|
"InputDialogAddNewProfileTitle": "Виберіть ім'я профілю",
|
||||||
"InputDialogAddNewProfileHeader": "Будь ласка, введіть ім'я профілю",
|
"InputDialogAddNewProfileHeader": "Будь ласка, введіть ім'я профілю",
|
||||||
"InputDialogAddNewProfileSubtext": "(Макс. довжина: {0})",
|
"InputDialogAddNewProfileSubtext": "(Макс. довжина: {0})",
|
||||||
@@ -428,7 +417,7 @@
|
|||||||
"AvatarSetBackgroundColor": "Встановити колір фону",
|
"AvatarSetBackgroundColor": "Встановити колір фону",
|
||||||
"AvatarClose": "Закрити",
|
"AvatarClose": "Закрити",
|
||||||
"ControllerSettingsLoadProfileToolTip": "Завантажити профіль",
|
"ControllerSettingsLoadProfileToolTip": "Завантажити профіль",
|
||||||
"ControllerSettingsViewProfileToolTip": "Показати профіль",
|
"ControllerSettingsViewProfileToolTip": "View Profile",
|
||||||
"ControllerSettingsAddProfileToolTip": "Додати профіль",
|
"ControllerSettingsAddProfileToolTip": "Додати профіль",
|
||||||
"ControllerSettingsRemoveProfileToolTip": "Видалити профіль",
|
"ControllerSettingsRemoveProfileToolTip": "Видалити профіль",
|
||||||
"ControllerSettingsSaveProfileToolTip": "Зберегти профіль",
|
"ControllerSettingsSaveProfileToolTip": "Зберегти профіль",
|
||||||
@@ -438,7 +427,7 @@
|
|||||||
"GameListContextMenuToggleFavorite": "Перемкнути вибране",
|
"GameListContextMenuToggleFavorite": "Перемкнути вибране",
|
||||||
"GameListContextMenuToggleFavoriteToolTip": "Перемкнути улюблений статус гри",
|
"GameListContextMenuToggleFavoriteToolTip": "Перемкнути улюблений статус гри",
|
||||||
"SettingsTabGeneralTheme": "Тема:",
|
"SettingsTabGeneralTheme": "Тема:",
|
||||||
"SettingsTabGeneralThemeAuto": "Авто.",
|
"SettingsTabGeneralThemeAuto": "Auto",
|
||||||
"SettingsTabGeneralThemeDark": "Темна",
|
"SettingsTabGeneralThemeDark": "Темна",
|
||||||
"SettingsTabGeneralThemeLight": "Світла",
|
"SettingsTabGeneralThemeLight": "Світла",
|
||||||
"ControllerSettingsConfigureGeneral": "Налаштування",
|
"ControllerSettingsConfigureGeneral": "Налаштування",
|
||||||
@@ -457,7 +446,7 @@
|
|||||||
"DialogExitSubMessage": "Усі незбережені дані буде втрачено!",
|
"DialogExitSubMessage": "Усі незбережені дані буде втрачено!",
|
||||||
"DialogMessageCreateSaveErrorMessage": "Під час створення вказаних даних збереження сталася помилка: {0}",
|
"DialogMessageCreateSaveErrorMessage": "Під час створення вказаних даних збереження сталася помилка: {0}",
|
||||||
"DialogMessageFindSaveErrorMessage": "Під час пошуку вказаних даних збереження сталася помилка: {0}",
|
"DialogMessageFindSaveErrorMessage": "Під час пошуку вказаних даних збереження сталася помилка: {0}",
|
||||||
"FolderDialogExtractTitle": "Виберіть теку для видобування",
|
"FolderDialogExtractTitle": "Виберіть папку для видобування",
|
||||||
"DialogNcaExtractionMessage": "Видобування розділу {0} з {1}...",
|
"DialogNcaExtractionMessage": "Видобування розділу {0} з {1}...",
|
||||||
"DialogNcaExtractionTitle": "Екстрактор розділів NCA",
|
"DialogNcaExtractionTitle": "Екстрактор розділів NCA",
|
||||||
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Помилка видобування. Основний NCA не був присутній у вибраному файлі.",
|
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Помилка видобування. Основний NCA не був присутній у вибраному файлі.",
|
||||||
@@ -472,7 +461,7 @@
|
|||||||
"DialogUpdaterExtractionMessage": "Видобування оновлення...",
|
"DialogUpdaterExtractionMessage": "Видобування оновлення...",
|
||||||
"DialogUpdaterRenamingMessage": "Перейменування оновлення...",
|
"DialogUpdaterRenamingMessage": "Перейменування оновлення...",
|
||||||
"DialogUpdaterAddingFilesMessage": "Додавання нового оновлення...",
|
"DialogUpdaterAddingFilesMessage": "Додавання нового оновлення...",
|
||||||
"DialogUpdaterShowChangelogMessage": "Показати список змін",
|
"DialogUpdaterShowChangelogMessage": "Show Changelog",
|
||||||
"DialogUpdaterCompleteMessage": "Оновлення завершено!",
|
"DialogUpdaterCompleteMessage": "Оновлення завершено!",
|
||||||
"DialogUpdaterRestartMessage": "Перезапустити Ryujinx зараз?",
|
"DialogUpdaterRestartMessage": "Перезапустити Ryujinx зараз?",
|
||||||
"DialogUpdaterNoInternetMessage": "Ви не підключені до Інтернету!",
|
"DialogUpdaterNoInternetMessage": "Ви не підключені до Інтернету!",
|
||||||
@@ -521,12 +510,12 @@
|
|||||||
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Встановлення прошивки...",
|
"DialogFirmwareInstallerFirmwareInstallWaitMessage": "Встановлення прошивки...",
|
||||||
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Версію системи {0} успішно встановлено.",
|
"DialogFirmwareInstallerFirmwareInstallSuccessMessage": "Версію системи {0} успішно встановлено.",
|
||||||
"DialogKeysInstallerKeysNotFoundErrorMessage": "An invalid Keys file was found in {0}",
|
"DialogKeysInstallerKeysNotFoundErrorMessage": "An invalid Keys file was found in {0}",
|
||||||
"DialogKeysInstallerKeysInstallTitle": "Встановлення Ключів",
|
"DialogKeysInstallerKeysInstallTitle": "Install Keys",
|
||||||
"DialogKeysInstallerKeysInstallMessage": "Новий файл Ключів буде встановлено",
|
"DialogKeysInstallerKeysInstallMessage": "New Keys file will be installed.",
|
||||||
"DialogKeysInstallerKeysInstallSubMessage": "\n\nЦе замінить собою поточні файли Ключів.",
|
"DialogKeysInstallerKeysInstallSubMessage": "\n\nThis may replace some of the current installed Keys.",
|
||||||
"DialogKeysInstallerKeysInstallConfirmMessage": "\n\nВи хочете продовжити?",
|
"DialogKeysInstallerKeysInstallConfirmMessage": "\n\nDo you want to continue?",
|
||||||
"DialogKeysInstallerKeysInstallWaitMessage": "Встановлення Ключів...",
|
"DialogKeysInstallerKeysInstallWaitMessage": "Installing Keys...",
|
||||||
"DialogKeysInstallerKeysInstallSuccessMessage": "Нові ключі встановлено.",
|
"DialogKeysInstallerKeysInstallSuccessMessage": "New Keys file successfully installed.",
|
||||||
"DialogUserProfileDeletionWarningMessage": "Якщо вибраний профіль буде видалено, інші профілі не відкриватимуться",
|
"DialogUserProfileDeletionWarningMessage": "Якщо вибраний профіль буде видалено, інші профілі не відкриватимуться",
|
||||||
"DialogUserProfileDeletionConfirmMessage": "Ви хочете видалити вибраний профіль",
|
"DialogUserProfileDeletionConfirmMessage": "Ви хочете видалити вибраний профіль",
|
||||||
"DialogUserProfileUnsavedChangesTitle": "Увага — Незбережені зміни",
|
"DialogUserProfileUnsavedChangesTitle": "Увага — Незбережені зміни",
|
||||||
@@ -561,14 +550,14 @@
|
|||||||
"MenuBarOptionsPauseEmulation": "Пауза",
|
"MenuBarOptionsPauseEmulation": "Пауза",
|
||||||
"MenuBarOptionsResumeEmulation": "Продовжити",
|
"MenuBarOptionsResumeEmulation": "Продовжити",
|
||||||
"AboutUrlTooltipMessage": "Натисніть, щоб відкрити сайт Ryujinx у браузері за замовчування.",
|
"AboutUrlTooltipMessage": "Натисніть, щоб відкрити сайт Ryujinx у браузері за замовчування.",
|
||||||
"AboutDisclaimerMessage": "Ryujinx жодним чином не пов’язаний з Nintendo™,\nчи будь-яким із їхніх партнерів.",
|
"AboutDisclaimerMessage": "Ryujinx жодним чином не пов’язано з Nintendo™,\nчи будь-яким із їхніх партнерів.",
|
||||||
"AboutAmiiboDisclaimerMessage": "AmiiboAPI (www.amiiboapi.com) використовується в нашій емуляції Amiibo.",
|
"AboutAmiiboDisclaimerMessage": "AmiiboAPI (www.amiiboapi.com) використовується в нашій емуляції Amiibo.",
|
||||||
"AboutGithubUrlTooltipMessage": "Натисніть, щоб відкрити сторінку GitHub Ryujinx у браузері за замовчуванням.",
|
"AboutGithubUrlTooltipMessage": "Натисніть, щоб відкрити сторінку GitHub Ryujinx у браузері за замовчуванням.",
|
||||||
"AboutDiscordUrlTooltipMessage": "Натисніть, щоб відкрити запрошення на сервер Discord Ryujinx у браузері за замовчуванням.",
|
"AboutDiscordUrlTooltipMessage": "Натисніть, щоб відкрити запрошення на сервер Discord Ryujinx у браузері за замовчуванням.",
|
||||||
"AboutRyujinxAboutTitle": "Про програму:",
|
"AboutRyujinxAboutTitle": "Про програму:",
|
||||||
"AboutRyujinxAboutContent": "Ryujinx — це емулятор для Nintendo Switch™.\nОтримуйте всі останні новини в нашому Discord.\nРозробники, які хочуть зробити внесок, можуть дізнатися більше на нашому GitHub або в Discord.",
|
"AboutRyujinxAboutContent": "Ryujinx is an emulator for the Nintendo Switch™.\nGet all the latest news in our Discord.\nDevelopers interested in contributing can find out more on our GitHub or Discord.",
|
||||||
"AboutRyujinxMaintainersTitle": "Підтримується:",
|
"AboutRyujinxMaintainersTitle": "Підтримується:",
|
||||||
"AboutRyujinxFormerMaintainersTitle": "Минулі розробники:",
|
"AboutRyujinxFormerMaintainersTitle": "Formerly Maintained By:",
|
||||||
"AboutRyujinxMaintainersContentTooltipMessage": "Натисніть, щоб відкрити сторінку співавторів у вашому браузері за замовчування.",
|
"AboutRyujinxMaintainersContentTooltipMessage": "Натисніть, щоб відкрити сторінку співавторів у вашому браузері за замовчування.",
|
||||||
"AmiiboSeriesLabel": "Серія Amiibo",
|
"AmiiboSeriesLabel": "Серія Amiibo",
|
||||||
"AmiiboCharacterLabel": "Персонаж",
|
"AmiiboCharacterLabel": "Персонаж",
|
||||||
@@ -596,9 +585,9 @@
|
|||||||
"AddGameDirBoxTooltip": "Введіть каталог ігор, щоб додати до списку",
|
"AddGameDirBoxTooltip": "Введіть каталог ігор, щоб додати до списку",
|
||||||
"AddGameDirTooltip": "Додати каталог гри до списку",
|
"AddGameDirTooltip": "Додати каталог гри до списку",
|
||||||
"RemoveGameDirTooltip": "Видалити вибраний каталог гри",
|
"RemoveGameDirTooltip": "Видалити вибраний каталог гри",
|
||||||
"AddAutoloadDirBoxTooltip": "Введіть шлях автозавантаження для додавання до списку",
|
"AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list",
|
||||||
"AddAutoloadDirTooltip": "Додайте шлях автозавантаження для додавання до списку",
|
"AddAutoloadDirTooltip": "Add an autoload directory to the list",
|
||||||
"RemoveAutoloadDirTooltip": "Видалити вибраний каталог автозавантаження",
|
"RemoveAutoloadDirTooltip": "Remove selected autoload directory",
|
||||||
"CustomThemeCheckTooltip": "Використовуйте користувацьку тему Avalonia для графічного інтерфейсу, щоб змінити вигляд меню емулятора",
|
"CustomThemeCheckTooltip": "Використовуйте користувацьку тему Avalonia для графічного інтерфейсу, щоб змінити вигляд меню емулятора",
|
||||||
"CustomThemePathTooltip": "Шлях до користувацької теми графічного інтерфейсу",
|
"CustomThemePathTooltip": "Шлях до користувацької теми графічного інтерфейсу",
|
||||||
"CustomThemeBrowseTooltip": "Огляд користувацької теми графічного інтерфейсу",
|
"CustomThemeBrowseTooltip": "Огляд користувацької теми графічного інтерфейсу",
|
||||||
@@ -611,7 +600,7 @@
|
|||||||
"TimeTooltip": "Змінити час системи",
|
"TimeTooltip": "Змінити час системи",
|
||||||
"VSyncToggleTooltip": "Емульована вертикальна синхронізація консолі. По суті, обмежувач кадрів для більшості ігор; його вимкнення може призвести до того, що ігри працюватимуть на вищій швидкості, екрани завантаження триватимуть довше чи зупинятимуться.\n\nМожна перемикати в грі гарячою клавішею (За умовчанням F1). Якщо ви плануєте вимкнути функцію, рекомендуємо зробити це через гарячу клавішу.\n\nЗалиште увімкненим, якщо не впевнені.",
|
"VSyncToggleTooltip": "Емульована вертикальна синхронізація консолі. По суті, обмежувач кадрів для більшості ігор; його вимкнення може призвести до того, що ігри працюватимуть на вищій швидкості, екрани завантаження триватимуть довше чи зупинятимуться.\n\nМожна перемикати в грі гарячою клавішею (За умовчанням F1). Якщо ви плануєте вимкнути функцію, рекомендуємо зробити це через гарячу клавішу.\n\nЗалиште увімкненим, якщо не впевнені.",
|
||||||
"PptcToggleTooltip": "Зберігає перекладені функції JIT, щоб їх не потрібно було перекладати кожного разу, коли гра завантажується.\n\nЗменшує заїкання та значно прискорює час завантаження після першого завантаження гри.\n\nЗалиште увімкненим, якщо не впевнені.",
|
"PptcToggleTooltip": "Зберігає перекладені функції JIT, щоб їх не потрібно було перекладати кожного разу, коли гра завантажується.\n\nЗменшує заїкання та значно прискорює час завантаження після першого завантаження гри.\n\nЗалиште увімкненим, якщо не впевнені.",
|
||||||
"LowPowerPptcToggleTooltip": "Завантажувати PPTC використовуючи третину від кількості ядер.",
|
"LowPowerPptcToggleTooltip": "Load the PPTC using a third of the amount of cores.",
|
||||||
"FsIntegrityToggleTooltip": "Перевіряє наявність пошкоджених файлів під час завантаження гри, і якщо виявлено пошкоджені файли, показує помилку хешу в журналі.\n\nНе впливає на продуктивність і призначений для усунення несправностей.\n\nЗалиште увімкненим, якщо не впевнені.",
|
"FsIntegrityToggleTooltip": "Перевіряє наявність пошкоджених файлів під час завантаження гри, і якщо виявлено пошкоджені файли, показує помилку хешу в журналі.\n\nНе впливає на продуктивність і призначений для усунення несправностей.\n\nЗалиште увімкненим, якщо не впевнені.",
|
||||||
"AudioBackendTooltip": "Змінює серверну частину, яка використовується для відтворення аудіо.\n\nSDL2 є кращим, тоді як OpenAL і SoundIO використовуються як резервні варіанти. Dummy не матиме звуку.\n\nВстановіть SDL2, якщо не впевнені.",
|
"AudioBackendTooltip": "Змінює серверну частину, яка використовується для відтворення аудіо.\n\nSDL2 є кращим, тоді як OpenAL і SoundIO використовуються як резервні варіанти. Dummy не матиме звуку.\n\nВстановіть SDL2, якщо не впевнені.",
|
||||||
"MemoryManagerTooltip": "Змінює спосіб відображення та доступу до гостьової пам’яті. Значно впливає на продуктивність емульованого ЦП.\n\nВстановіть «Неперевірений хост», якщо не впевнені.",
|
"MemoryManagerTooltip": "Змінює спосіб відображення та доступу до гостьової пам’яті. Значно впливає на продуктивність емульованого ЦП.\n\nВстановіть «Неперевірений хост», якщо не впевнені.",
|
||||||
@@ -644,10 +633,10 @@
|
|||||||
"DebugLogTooltip": "Друкує повідомлення журналу налагодження на консолі.\n\nВикористовуйте це лише за спеціальною вказівкою співробітника, оскільки це ускладнить читання журналів і погіршить роботу емулятора.",
|
"DebugLogTooltip": "Друкує повідомлення журналу налагодження на консолі.\n\nВикористовуйте це лише за спеціальною вказівкою співробітника, оскільки це ускладнить читання журналів і погіршить роботу емулятора.",
|
||||||
"LoadApplicationFileTooltip": "Відкриває файловий провідник, щоб вибрати для завантаження сумісний файл Switch",
|
"LoadApplicationFileTooltip": "Відкриває файловий провідник, щоб вибрати для завантаження сумісний файл Switch",
|
||||||
"LoadApplicationFolderTooltip": "Відкриває файловий провідник, щоб вибрати сумісну з комутатором розпаковану програму для завантаження",
|
"LoadApplicationFolderTooltip": "Відкриває файловий провідник, щоб вибрати сумісну з комутатором розпаковану програму для завантаження",
|
||||||
"LoadDlcFromFolderTooltip": "Відкрийте провідник файлів, щоб вибрати одну або кілька папок для масового завантаження DLC",
|
"LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from",
|
||||||
"LoadTitleUpdatesFromFolderTooltip": "Відкрийте провідник файлів, щоб вибрати одну або кілька папок для масового завантаження оновлень заголовків",
|
"LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from",
|
||||||
"OpenRyujinxFolderTooltip": "Відкриває теку файлової системи Ryujinx",
|
"OpenRyujinxFolderTooltip": "Відкриває папку файлової системи Ryujinx",
|
||||||
"OpenRyujinxLogsTooltip": "Відкриває теку, куди записуються журнали",
|
"OpenRyujinxLogsTooltip": "Відкриває папку, куди записуються журнали",
|
||||||
"ExitTooltip": "Виходить з Ryujinx",
|
"ExitTooltip": "Виходить з Ryujinx",
|
||||||
"OpenSettingsTooltip": "Відкриває вікно налаштувань",
|
"OpenSettingsTooltip": "Відкриває вікно налаштувань",
|
||||||
"OpenProfileManagerTooltip": "Відкриває вікно диспетчера профілів користувачів",
|
"OpenProfileManagerTooltip": "Відкриває вікно диспетчера профілів користувачів",
|
||||||
@@ -675,6 +664,7 @@
|
|||||||
"SettingsTabNetworkConnection": "Підключення до мережі",
|
"SettingsTabNetworkConnection": "Підключення до мережі",
|
||||||
"SettingsTabCpuCache": "Кеш ЦП",
|
"SettingsTabCpuCache": "Кеш ЦП",
|
||||||
"SettingsTabCpuMemory": "Пам'ять ЦП",
|
"SettingsTabCpuMemory": "Пам'ять ЦП",
|
||||||
|
"DialogUpdaterFlatpakNotSupportedMessage": "Будь ласка, оновіть Ryujinx через FlatHub.",
|
||||||
"UpdaterDisabledWarningTitle": "Програму оновлення вимкнено!",
|
"UpdaterDisabledWarningTitle": "Програму оновлення вимкнено!",
|
||||||
"ControllerSettingsRotate90": "Повернути на 90° за годинниковою стрілкою",
|
"ControllerSettingsRotate90": "Повернути на 90° за годинниковою стрілкою",
|
||||||
"IconSize": "Розмір значка",
|
"IconSize": "Розмір значка",
|
||||||
@@ -696,14 +686,14 @@
|
|||||||
"OpenSetupGuideMessage": "Відкрити посібник із налаштування",
|
"OpenSetupGuideMessage": "Відкрити посібник із налаштування",
|
||||||
"NoUpdate": "Немає оновлень",
|
"NoUpdate": "Немає оновлень",
|
||||||
"TitleUpdateVersionLabel": "Версія {0} - {1}",
|
"TitleUpdateVersionLabel": "Версія {0} - {1}",
|
||||||
"TitleBundledUpdateVersionLabel": "Комплектні: Версія {0}",
|
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
|
||||||
"TitleBundledDlcLabel": "Комплектні:",
|
"TitleBundledDlcLabel": "Bundled:",
|
||||||
"TitleXCIStatusPartialLabel": "Часткові",
|
"TitleXCIStatusPartialLabel": "Partial",
|
||||||
"TitleXCIStatusTrimmableLabel": "Необрізані",
|
"TitleXCIStatusTrimmableLabel": "Untrimmed",
|
||||||
"TitleXCIStatusUntrimmableLabel": "Обрізані",
|
"TitleXCIStatusUntrimmableLabel": "Trimmed",
|
||||||
"TitleXCIStatusFailedLabel": "(Невдача)",
|
"TitleXCIStatusFailedLabel": "(Failed)",
|
||||||
"TitleXCICanSaveLabel": "Зберегти {0:n0} Мб",
|
"TitleXCICanSaveLabel": "Save {0:n0} Mb",
|
||||||
"TitleXCISavingLabel": "Збережено {0:n0} Мб",
|
"TitleXCISavingLabel": "Saved {0:n0} Mb",
|
||||||
"RyujinxInfo": "Ryujin x - Інформація",
|
"RyujinxInfo": "Ryujin x - Інформація",
|
||||||
"RyujinxConfirm": "Ryujinx - Підтвердження",
|
"RyujinxConfirm": "Ryujinx - Підтвердження",
|
||||||
"FileDialogAllTypes": "Всі типи",
|
"FileDialogAllTypes": "Всі типи",
|
||||||
@@ -711,8 +701,8 @@
|
|||||||
"SwkbdMinCharacters": "Мінімальна кількість символів: {0}",
|
"SwkbdMinCharacters": "Мінімальна кількість символів: {0}",
|
||||||
"SwkbdMinRangeCharacters": "Має бути {0}-{1} символів",
|
"SwkbdMinRangeCharacters": "Має бути {0}-{1} символів",
|
||||||
"CabinetTitle": "Cabinet Dialog",
|
"CabinetTitle": "Cabinet Dialog",
|
||||||
"CabinetDialog": "Вкажіть Ваше нове ім'я Amiibo",
|
"CabinetDialog": "Enter your Amiibo's new name",
|
||||||
"CabinetScanDialog": "Будь ласка, проскануйте Ваш Amiibo.",
|
"CabinetScanDialog": "Please scan your Amiibo now.",
|
||||||
"SoftwareKeyboard": "Програмна клавіатура",
|
"SoftwareKeyboard": "Програмна клавіатура",
|
||||||
"SoftwareKeyboardModeNumeric": "Повинно бути лише 0-9 або “.”",
|
"SoftwareKeyboardModeNumeric": "Повинно бути лише 0-9 або “.”",
|
||||||
"SoftwareKeyboardModeAlphabet": "Повинно бути лише не CJK-символи",
|
"SoftwareKeyboardModeAlphabet": "Повинно бути лише не CJK-символи",
|
||||||
@@ -740,15 +730,12 @@
|
|||||||
"AllSupportedFormats": "Усі підтримувані формати",
|
"AllSupportedFormats": "Усі підтримувані формати",
|
||||||
"RyujinxUpdater": "Програма оновлення Ryujinx",
|
"RyujinxUpdater": "Програма оновлення Ryujinx",
|
||||||
"SettingsTabHotkeys": "Гарячі клавіші клавіатури",
|
"SettingsTabHotkeys": "Гарячі клавіші клавіатури",
|
||||||
"SettingsTabHotkeysToggleVSyncModeHotkey": "Перемкнути VSync режим:",
|
|
||||||
"SettingsTabHotkeysHotkeys": "Гарячі клавіші клавіатури",
|
"SettingsTabHotkeysHotkeys": "Гарячі клавіші клавіатури",
|
||||||
"SettingsTabHotkeysToggleVsyncHotkey": "Увімк/вимк вертикальну синхронізацію:",
|
"SettingsTabHotkeysToggleVsyncHotkey": "Увімк/вимк вертикальну синхронізацію:",
|
||||||
"SettingsTabHotkeysScreenshotHotkey": "Знімок екрана:",
|
"SettingsTabHotkeysScreenshotHotkey": "Знімок екрана:",
|
||||||
"SettingsTabHotkeysShowUiHotkey": "Показати інтерфейс:",
|
"SettingsTabHotkeysShowUiHotkey": "Показати інтерфейс:",
|
||||||
"SettingsTabHotkeysPauseHotkey": "Пауза:",
|
"SettingsTabHotkeysPauseHotkey": "Пауза:",
|
||||||
"SettingsTabHotkeysToggleMuteHotkey": "Вимкнути звук:",
|
"SettingsTabHotkeysToggleMuteHotkey": "Вимкнути звук:",
|
||||||
"SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey": "Підвищити користувацьку частоту оновлення",
|
|
||||||
"SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey": "Понизити користувацьку частоту оновлення",
|
|
||||||
"ControllerMotionTitle": "Налаштування керування рухом",
|
"ControllerMotionTitle": "Налаштування керування рухом",
|
||||||
"ControllerRumbleTitle": "Налаштування вібрації",
|
"ControllerRumbleTitle": "Налаштування вібрації",
|
||||||
"SettingsSelectThemeFileDialogTitle": "Виберіть файл теми",
|
"SettingsSelectThemeFileDialogTitle": "Виберіть файл теми",
|
||||||
@@ -761,53 +748,53 @@
|
|||||||
"SelectDlcDialogTitle": "Виберіть файли DLC",
|
"SelectDlcDialogTitle": "Виберіть файли DLC",
|
||||||
"SelectUpdateDialogTitle": "Виберіть файли оновлення",
|
"SelectUpdateDialogTitle": "Виберіть файли оновлення",
|
||||||
"SelectModDialogTitle": "Виберіть теку з модами",
|
"SelectModDialogTitle": "Виберіть теку з модами",
|
||||||
"TrimXCIFileDialogTitle": "Перевірити та Обрізати XCI файл",
|
"TrimXCIFileDialogTitle": "Check and Trim XCI File",
|
||||||
"TrimXCIFileDialogPrimaryText": "Ця функція спочатку перевірить вільний простір, а потім обрізатиме файл XCI для економії місця на диску.",
|
"TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.",
|
||||||
"TrimXCIFileDialogSecondaryText": "Поточний розмір файла: {0:n} MB\nРозмір файлів гри: {1:n} MB\nЕкономія місця: {2:n} MB",
|
"TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB",
|
||||||
"TrimXCIFileNoTrimNecessary": "XCI файл не потребує обрізання. Перевірте журнали для додаткової інформації",
|
"TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details",
|
||||||
"TrimXCIFileNoUntrimPossible": "XCI файл не може бути обрізаний. Перевірте журнали для додаткової інформації",
|
"TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details",
|
||||||
"TrimXCIFileReadOnlyFileCannotFix": "XCI файл Тільки для Читання і не може бути прочитаним. Перевірте журнали додаткової інформації",
|
"TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details",
|
||||||
"TrimXCIFileFileSizeChanged": "Розмір файлу XCI змінився з моменту сканування. Перевірте, чи не записується файл, та спробуйте знову",
|
"TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.",
|
||||||
"TrimXCIFileFreeSpaceCheckFailed": "Файл XCI містить дані в зоні вільного простору, тому обрізка небезпечна",
|
"TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim",
|
||||||
"TrimXCIFileInvalidXCIFile": "XCI Файл містить недійсні дані. Перевірте журнали для додаткової інформації",
|
"TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details",
|
||||||
"TrimXCIFileFileIOWriteError": "XCI Файл файл не вдалося відкрити для запису. Перевірте журнали для додаткової інформації",
|
"TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details",
|
||||||
"TrimXCIFileFailedPrimaryText": "Не вдалося обрізати файл XCI",
|
"TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed",
|
||||||
"TrimXCIFileCancelled": "Операція перервана",
|
"TrimXCIFileCancelled": "The operation was cancelled",
|
||||||
"TrimXCIFileFileUndertermined": "Операція не проводилася",
|
"TrimXCIFileFileUndertermined": "No operation was performed",
|
||||||
"UserProfileWindowTitle": "Менеджер профілів користувачів",
|
"UserProfileWindowTitle": "Менеджер профілів користувачів",
|
||||||
"CheatWindowTitle": "Менеджер читів",
|
"CheatWindowTitle": "Менеджер читів",
|
||||||
"DlcWindowTitle": "Менеджер вмісту для завантаження",
|
"DlcWindowTitle": "Менеджер вмісту для завантаження",
|
||||||
"ModWindowTitle": "Керувати модами для {0} ({1})",
|
"ModWindowTitle": "Керувати модами для {0} ({1})",
|
||||||
"UpdateWindowTitle": "Менеджер оновлення назв",
|
"UpdateWindowTitle": "Менеджер оновлення назв",
|
||||||
"XCITrimmerWindowTitle": "Обрізка XCI Файлів",
|
"XCITrimmerWindowTitle": "XCI File Trimmer",
|
||||||
"XCITrimmerTitleStatusCount": "{0} з {1} тайтл(ів) обрано",
|
"XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected",
|
||||||
"XCITrimmerTitleStatusCountWithFilter": "{0} з {1} тайтл(ів) обрано ({2} відображається)",
|
"XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)",
|
||||||
"XCITrimmerTitleStatusTrimming": "Обрізка {0} тайтл(ів)...",
|
"XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...",
|
||||||
"XCITrimmerTitleStatusUntrimming": "Необрізаних {0} тайтл(ів)...",
|
"XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...",
|
||||||
"XCITrimmerTitleStatusFailed": "Невдача",
|
"XCITrimmerTitleStatusFailed": "Failed",
|
||||||
"XCITrimmerPotentialSavings": "Потенційна економія",
|
"XCITrimmerPotentialSavings": "Potential Savings",
|
||||||
"XCITrimmerActualSavings": "Зекономлено",
|
"XCITrimmerActualSavings": "Actual Savings",
|
||||||
"XCITrimmerSavingsMb": "{0:n0} Мб",
|
"XCITrimmerSavingsMb": "{0:n0} Mb",
|
||||||
"XCITrimmerSelectDisplayed": "Вибрати показане",
|
"XCITrimmerSelectDisplayed": "Select Shown",
|
||||||
"XCITrimmerDeselectDisplayed": "Скасувати вибір показаного",
|
"XCITrimmerDeselectDisplayed": "Deselect Shown",
|
||||||
"XCITrimmerSortName": "Заголовок",
|
"XCITrimmerSortName": "Title",
|
||||||
"XCITrimmerSortSaved": "Економія місця",
|
"XCITrimmerSortSaved": "Space Savings",
|
||||||
"XCITrimmerTrim": "Обрізка",
|
"XCITrimmerTrim": "Trim",
|
||||||
"XCITrimmerUntrim": "Зшивання",
|
"XCITrimmerUntrim": "Untrim",
|
||||||
"UpdateWindowUpdateAddedMessage": "{0} нове оновлення додано",
|
"UpdateWindowUpdateAddedMessage": "{0} new update(s) added",
|
||||||
"UpdateWindowBundledContentNotice": "Вбудовані оновлення не можуть бути видалені, лише вимкнені.",
|
"UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.",
|
||||||
"CheatWindowHeading": "Коди доступні для {0} [{1}]",
|
"CheatWindowHeading": "Коди доступні для {0} [{1}]",
|
||||||
"BuildId": "ID збірки:",
|
"BuildId": "ID збірки:",
|
||||||
"DlcWindowBundledContentNotice": "Вбудований DLC не може бути видаленим, лише вимкненим.",
|
"DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.",
|
||||||
"DlcWindowHeading": "{0} DLC доступно",
|
"DlcWindowHeading": "{0} DLC(s) available",
|
||||||
"DlcWindowDlcAddedMessage": "{0} нового завантажувального вмісту додано",
|
"DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added",
|
||||||
"AutoloadDlcAddedMessage": "{0} нового завантажувального вмісту додано",
|
"AutoloadDlcAddedMessage": "{0} new downloadable content(s) added",
|
||||||
"AutoloadDlcRemovedMessage": "{0} відсутнього завантажувального вмісту видалено",
|
"AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed",
|
||||||
"AutoloadUpdateAddedMessage": "{0} нових оновлень додано",
|
"AutoloadUpdateAddedMessage": "{0} new update(s) added",
|
||||||
"AutoloadUpdateRemovedMessage": "{0} відсутніх оновлень видалено",
|
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
|
||||||
"ModWindowHeading": "{0} мод(ів)",
|
"ModWindowHeading": "{0} мод(ів)",
|
||||||
"UserProfilesEditProfile": "Редагувати вибране",
|
"UserProfilesEditProfile": "Редагувати вибране",
|
||||||
"Continue": "Продовжити",
|
"Continue": "Continue",
|
||||||
"Cancel": "Скасувати",
|
"Cancel": "Скасувати",
|
||||||
"Save": "Зберегти",
|
"Save": "Зберегти",
|
||||||
"Discard": "Скасувати",
|
"Discard": "Скасувати",
|
||||||
@@ -845,7 +832,7 @@
|
|||||||
"Name": "Назва",
|
"Name": "Назва",
|
||||||
"Size": "Розмір",
|
"Size": "Розмір",
|
||||||
"Search": "Пошук",
|
"Search": "Пошук",
|
||||||
"UserProfilesRecoverLostAccounts": "Відновлення профілів",
|
"UserProfilesRecoverLostAccounts": "Відновлення втрачених облікових записів",
|
||||||
"Recover": "Відновити",
|
"Recover": "Відновити",
|
||||||
"UserProfilesRecoverHeading": "Знайдено збереження для наступних облікових записів",
|
"UserProfilesRecoverHeading": "Знайдено збереження для наступних облікових записів",
|
||||||
"UserProfilesRecoverEmptyList": "Немає профілів для відновлення",
|
"UserProfilesRecoverEmptyList": "Немає профілів для відновлення",
|
||||||
@@ -877,15 +864,15 @@
|
|||||||
"MultiplayerModeDisabled": "Вимкнено",
|
"MultiplayerModeDisabled": "Вимкнено",
|
||||||
"MultiplayerModeLdnMitm": "ldn_mitm",
|
"MultiplayerModeLdnMitm": "ldn_mitm",
|
||||||
"MultiplayerModeLdnRyu": "RyuLDN",
|
"MultiplayerModeLdnRyu": "RyuLDN",
|
||||||
"MultiplayerDisableP2P": "Вимкнути хостинг P2P мережі (може збільшити затримку)",
|
"MultiplayerDisableP2P": "Disable P2P Network Hosting (may increase latency)",
|
||||||
"MultiplayerDisableP2PTooltip": "Вимкнути хостинг P2P мережі, піри будуть підключатися через майстер-сервер замість прямого з'єднання з вами.",
|
"MultiplayerDisableP2PTooltip": "Disable P2P network hosting, peers will proxy through the master server instead of connecting to you directly.",
|
||||||
"LdnPassphrase": "Мережевий пароль:",
|
"LdnPassphrase": "Network Passphrase:",
|
||||||
"LdnPassphraseTooltip": "Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
"LdnPassphraseTooltip": "You will only be able to see hosted games with the same passphrase as you.",
|
||||||
"LdnPassphraseInputTooltip": "Введіть пароль у форматі Ryujinx-<8 символів>. Ви зможете бачити лише ті ігри, які мають такий самий пароль, як і у вас.",
|
"LdnPassphraseInputTooltip": "Enter a passphrase in the format Ryujinx-<8 hex chars>. You will only be able to see hosted games with the same passphrase as you.",
|
||||||
"LdnPassphraseInputPublic": "(публічний)",
|
"LdnPassphraseInputPublic": "(public)",
|
||||||
"GenLdnPass": "Згенерувати випадкову",
|
"GenLdnPass": "Generate Random",
|
||||||
"GenLdnPassTooltip": "Генерує новий пароль, яким можна поділитися з іншими гравцями.",
|
"GenLdnPassTooltip": "Generates a new passphrase, which can be shared with other players.",
|
||||||
"ClearLdnPass": "Очистити",
|
"ClearLdnPass": "Clear",
|
||||||
"ClearLdnPassTooltip": "Очищає поточну пароль, повертаючись до публічної мережі.",
|
"ClearLdnPassTooltip": "Clears the current passphrase, returning to the public network.",
|
||||||
"InvalidLdnPassphrase": "Невірний пароль! Має бути в форматі \"Ryujinx-<8 символів>\""
|
"InvalidLdnPassphrase": "Invalid Passphrase! Must be in the format \"Ryujinx-<8 hex chars>\""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
361
src/Ryujinx/Headless/HeadlessRyujinx.Init.cs
Normal file
361
src/Ryujinx/Headless/HeadlessRyujinx.Init.cs
Normal file
@@ -0,0 +1,361 @@
|
|||||||
|
using DiscordRPC;
|
||||||
|
using LibHac.Tools.FsSystem;
|
||||||
|
using Ryujinx.Audio.Backends.SDL2;
|
||||||
|
using Ryujinx.Ava;
|
||||||
|
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.OpenGL;
|
||||||
|
using Ryujinx.Graphics.Vulkan;
|
||||||
|
using Ryujinx.HLE;
|
||||||
|
using Ryujinx.Input;
|
||||||
|
using Ryujinx.UI.Common;
|
||||||
|
using Ryujinx.UI.Common.Configuration;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,9 @@
|
|||||||
using CommandLine;
|
using CommandLine;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using LibHac.Tools.FsSystem;
|
using Ryujinx.Ava;
|
||||||
using Ryujinx.Audio.Backends.SDL2;
|
|
||||||
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,14 +11,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.OpenGL;
|
|
||||||
using Ryujinx.Graphics.Vulkan;
|
|
||||||
using Ryujinx.Graphics.Vulkan.MoltenVK;
|
using Ryujinx.Graphics.Vulkan.MoltenVK;
|
||||||
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;
|
||||||
@@ -31,22 +22,16 @@ 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 Ryujinx.UI.Common.Configuration;
|
||||||
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;
|
||||||
@@ -56,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())
|
||||||
{
|
{
|
||||||
@@ -97,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:");
|
||||||
@@ -106,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);
|
||||||
if (index == PlayerIndex.Player1)
|
|
||||||
{
|
|
||||||
Logger.Info?.Print(LogClass.Application, $"{index} not configured, defaulting to default keyboard.");
|
|
||||||
|
|
||||||
// Default to keyboard
|
string configurationPath = null;
|
||||||
inputId = "0";
|
|
||||||
|
// Now load the configuration as the other subsystems are now registered
|
||||||
|
if (customConfigPath != null && File.Exists(customConfigPath))
|
||||||
|
{
|
||||||
|
configurationPath = customConfigPath;
|
||||||
|
}
|
||||||
|
else if (File.Exists(localConfigurationPath))
|
||||||
|
{
|
||||||
|
configurationPath = localConfigurationPath;
|
||||||
|
}
|
||||||
|
else if (File.Exists(appDataConfigurationPath))
|
||||||
|
{
|
||||||
|
configurationPath = appDataConfigurationPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationPath == null)
|
||||||
|
{
|
||||||
|
// No configuration, we load the default values and save it to disk
|
||||||
|
configurationPath = appDataConfigurationPath;
|
||||||
|
Logger.Notice.Print(LogClass.Application, $"No configuration file found. Saving default configuration to: {configurationPath}");
|
||||||
|
|
||||||
|
ConfigurationState.Instance.LoadDefault();
|
||||||
|
ConfigurationState.Instance.ToFileFormat().SaveConfig(configurationPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Info?.Print(LogClass.Application, $"{index} not configured");
|
Logger.Notice.Print(LogClass.Application, $"Loading configuration from: {configurationPath}");
|
||||||
|
|
||||||
return null;
|
if (ConfigurationFileFormat.TryLoad(configurationPath, out ConfigurationFileFormat configurationFileFormat))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IGamepad gamepad = _inputManager.KeyboardDriver.GetGamepad(inputId);
|
|
||||||
|
|
||||||
bool isKeyboard = true;
|
|
||||||
|
|
||||||
if (gamepad == null)
|
|
||||||
{
|
{
|
||||||
gamepad = _inputManager.GamepadDriver.GetGamepad(inputId);
|
ConfigurationState.Instance.Load(configurationFileFormat, configurationPath);
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
bool isNintendoStyle = gamepadName.Contains("Nintendo");
|
Logger.Warning?.PrintMsg(LogClass.Application, $"Failed to load config! Loading the default config instead.\nFailed config location: {configurationPath}");
|
||||||
|
|
||||||
config = new StandardControllerInputConfig
|
ConfigurationState.Instance.LoadDefault();
|
||||||
{
|
|
||||||
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;
|
static void Load(string[] originalArgs, Options option)
|
||||||
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)
|
Initialize();
|
||||||
{
|
|
||||||
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");
|
bool useLastUsedProfile = false;
|
||||||
}
|
|
||||||
|
if (option.InheritConfig)
|
||||||
|
{
|
||||||
|
option.InheritMainConfig(originalArgs, ConfigurationState.Instance, out useLastUsedProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Load(Options option)
|
|
||||||
{
|
|
||||||
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();
|
||||||
|
|
||||||
@@ -352,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())
|
||||||
{
|
{
|
||||||
@@ -363,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}\")");
|
||||||
|
|
||||||
@@ -380,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}\")");
|
||||||
|
|
||||||
@@ -397,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;
|
||||||
|
|
||||||
@@ -421,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;
|
||||||
@@ -431,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);
|
||||||
@@ -515,83 +339,6 @@ namespace Ryujinx.Headless.SDL2
|
|||||||
: new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet);
|
: new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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())
|
||||||
@@ -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.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 Ryujinx.UI.Common.Configuration;
|
||||||
|
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; }
|
||||||
|
|
||||||
@@ -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; }
|
||||||
BIN
src/Ryujinx/Headless/Ryujinx.bmp
Normal file
BIN
src/Ryujinx/Headless/Ryujinx.bmp
Normal file
Binary file not shown.
|
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)
|
||||||
@@ -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}"));
|
||||||
|
|
||||||
@@ -14,6 +14,7 @@ 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.App.Common;
|
||||||
using Ryujinx.UI.Common;
|
using Ryujinx.UI.Common;
|
||||||
@@ -53,6 +54,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();
|
||||||
@@ -222,7 +229,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, $"{App.FullAppName} Version: {Version}");
|
Logger.Notice.Print(LogClass.Application, $"{App.FullAppName} Version: {Version}");
|
||||||
SystemInfo.Gather().Print();
|
SystemInfo.Gather().Print();
|
||||||
@@ -239,7 +246,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}";
|
||||||
@@ -254,7 +261,7 @@ namespace Ryujinx.Ava
|
|||||||
Exit();
|
Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Exit()
|
internal static void Exit()
|
||||||
{
|
{
|
||||||
DiscordIntegrationModule.Exit();
|
DiscordIntegrationModule.Exit();
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
<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="DynamicData" />
|
<PackageReference Include="DynamicData" />
|
||||||
<PackageReference Include="FluentAvaloniaUI" />
|
<PackageReference Include="FluentAvaloniaUI" />
|
||||||
<PackageReference Include="Projektanker.Icons.Avalonia" />
|
<PackageReference Include="Projektanker.Icons.Avalonia" />
|
||||||
@@ -162,6 +163,7 @@
|
|||||||
<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="Headless\Ryujinx.bmp" LogicalName="HeadlessLogo" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AdditionalFiles Include="Assets\Locales\en_US.json" />
|
<AdditionalFiles Include="Assets\Locales\en_US.json" />
|
||||||
|
|||||||
Reference in New Issue
Block a user