Compare commits
2 Commits
Canary-1.2
...
feature/av
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ef57edfd1 | ||
|
|
1360ef2ec8 |
23
.github/workflows/build.yml
vendored
23
.github/workflows/build.yml
vendored
@@ -64,9 +64,14 @@ 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
|
||||||
@@ -114,6 +119,13 @@ 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
|
||||||
@@ -159,9 +171,20 @@ 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'
|
||||||
|
|||||||
42
.github/workflows/canary.yml
vendored
42
.github/workflows/canary.yml
vendored
@@ -21,9 +21,9 @@ env:
|
|||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
RYUJINX_BASE_VERSION: "1.2"
|
RYUJINX_BASE_VERSION: "1.2"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
|
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
|
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
|
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Canary-Releases"
|
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx-Canary"
|
||||||
RELEASE: 1
|
RELEASE: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -43,8 +43,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
github.rest.git.createRef({
|
github.rest.git.createRef({
|
||||||
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}",
|
owner: context.repo.owner,
|
||||||
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}",
|
repo: context.repo.repo,
|
||||||
ref: 'refs/tags/Canary-${{ steps.version_info.outputs.build_version }}',
|
ref: 'refs/tags/Canary-${{ steps.version_info.outputs.build_version }}',
|
||||||
sha: context.sha
|
sha: context.sha
|
||||||
})
|
})
|
||||||
@@ -64,7 +64,7 @@ jobs:
|
|||||||
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||||
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||||
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||||
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
| macOS | [Canary macOS artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||||
|
|
||||||
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}
|
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
@@ -116,6 +116,7 @@ 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'
|
||||||
@@ -124,6 +125,11 @@ 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
|
||||||
@@ -134,6 +140,12 @@ 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)
|
||||||
@@ -179,21 +191,21 @@ 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,release_output/*AppImage*"
|
#artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: |
|
body: |
|
||||||
# Canary builds:
|
# 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.
|
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 |
|
| Platform | Artifact |
|
||||||
|--|--|
|
|--|--|
|
||||||
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
| Windows 64-bit | 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 | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
| Linux 64-bit | 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 | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
| Linux ARM 64-bit | 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 | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
| macOS | 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/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}
|
"**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/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
|
||||||
@@ -250,11 +262,15 @@ 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"
|
artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: ""
|
body: ""
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
|
|||||||
12
.github/workflows/nightly_pr_comment.yml
vendored
12
.github/workflows/nightly_pr_comment.yml
vendored
@@ -37,17 +37,21 @@ jobs:
|
|||||||
if (!artifacts.length) {
|
if (!artifacts.length) {
|
||||||
return core.error(`No artifacts found`);
|
return core.error(`No artifacts found`);
|
||||||
}
|
}
|
||||||
let body = `*You need to be logged into GitHub to download these files.*\n\nDownload the artifacts for this pull request:\n`;
|
let body = `Download the artifacts for this pull request:\n`;
|
||||||
|
let hidden_headless_artifacts = `\n\n <details><summary>GUI-less</summary>\n`;
|
||||||
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
||||||
for (const art of artifacts) {
|
for (const art of artifacts) {
|
||||||
const url = `https://github.com/Ryubing/Ryujinx/actions/runs/${run_id}/artifacts/${art.id}`;
|
|
||||||
if(art.name.includes('Debug')) {
|
if(art.name.includes('Debug')) {
|
||||||
hidden_debug_artifacts += `\n* [${art.name}](${url})`;
|
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}](${url})`;
|
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});
|
||||||
|
|||||||
45
.github/workflows/release.yml
vendored
45
.github/workflows/release.yml
vendored
@@ -21,7 +21,7 @@ env:
|
|||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
RYUJINX_BASE_VERSION: "1.2"
|
RYUJINX_BASE_VERSION: "1.2"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
|
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx"
|
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx"
|
||||||
RELEASE: 1
|
RELEASE: 1
|
||||||
|
|
||||||
@@ -42,8 +42,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
github.rest.git.createRef({
|
github.rest.git.createRef({
|
||||||
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}",
|
owner: context.repo.owner,
|
||||||
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}",
|
repo: context.repo.repo,
|
||||||
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
||||||
sha: context.sha
|
sha: context.sha
|
||||||
})
|
})
|
||||||
@@ -54,13 +54,13 @@ jobs:
|
|||||||
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: |
|
||||||
# Stable builds:
|
# Regular builds:
|
||||||
| Platform | Artifact |
|
| Platform | Artifact |
|
||||||
|--|--|
|
|--|--|
|
||||||
| Windows 64-bit | [Stable 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) |
|
| 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 | [Stable 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 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 | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
| Linux ARM 64-bit | [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 | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
| macOS | [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 }}
|
**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
|
||||||
@@ -112,6 +112,7 @@ 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'
|
||||||
@@ -120,6 +121,11 @@ 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)
|
||||||
@@ -166,6 +172,11 @@ 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
|
||||||
@@ -175,15 +186,15 @@ jobs:
|
|||||||
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: |
|
||||||
# Stable builds:
|
# Regular builds:
|
||||||
| Platform | Artifact |
|
| Platform | Artifact |
|
||||||
|--|--|
|
|--|--|
|
||||||
| Windows 64-bit | [Stable 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) |
|
| 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 | [Stable 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 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 | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
| Linux ARM 64-bit | 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 | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
| macOS | 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/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
|
"**Full Changelog**: https://github.com/${{ 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
|
||||||
@@ -240,11 +251,15 @@ 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"
|
artifacts: "publish/*.tar.gz, publish_headless/*.tar.gz"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: ""
|
body: ""
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
||||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
|
|
||||||
<PackageVersion Include="Concentus" Version="2.2.0" />
|
<PackageVersion Include="Concentus" Version="2.2.0" />
|
||||||
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
|
||||||
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
<PackageVersion Include="DynamicData" Version="9.0.4" />
|
||||||
@@ -42,10 +41,10 @@
|
|||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||||
<PackageVersion Include="Gommon" Version="2.7.0" />
|
<PackageVersion Include="Gommon" Version="2.6.8" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
<PackageVersion Include="SharpMetal" Version="1.0.0-preview21" />
|
<PackageVersion Include="SharpMetal" Version="1.0.0-preview20" />
|
||||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.21.0" />
|
<PackageVersion Include="Silk.NET.Vulkan" Version="2.21.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.21.0" />
|
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.21.0" />
|
||||||
|
|||||||
28
Ryujinx.sln
28
Ryujinx.sln
@@ -57,10 +57,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "src\
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Headless.SDL2", "src\Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}"
|
||||||
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
|
||||||
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}"
|
||||||
@@ -76,16 +80,11 @@ EndProject
|
|||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Generators", "src\Ryujinx.Horizon.Kernel.Generators\Ryujinx.Horizon.Kernel.Generators.csproj", "{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Generators", "src\Ryujinx.Horizon.Kernel.Generators\Ryujinx.Horizon.Kernel.Generators.csproj", "{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.Metal", "src\Ryujinx.Graphics.Metal\Ryujinx.Graphics.Metal.csproj", "{C08931FA-1191-417A-864F-3882D93E683B}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.Metal", "src\Ryujinx.Graphics.Metal\Ryujinx.Graphics.Metal.csproj", "{C08931FA-1191-417A-864F-3882D93E683B}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E} = {A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E} = {A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.Metal.SharpMetalExtensions", "src/Ryujinx.Graphics.Metal.SharpMetalExtensions\Ryujinx.Graphics.Metal.SharpMetalExtensions.csproj", "{81EA598C-DBA1-40B0-8DA4-4796B78F2037}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
@@ -95,6 +94,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
.github\workflows\release.yml = .github\workflows\release.yml
|
.github\workflows\release.yml = .github\workflows\release.yml
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -209,6 +210,10 @@ 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
|
||||||
@@ -217,6 +222,10 @@ Global
|
|||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@@ -249,16 +258,13 @@ Global
|
|||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ mkdir -p AppDir/usr/bin
|
|||||||
|
|
||||||
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
|
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
|
||||||
cp distribution/linux/appimage/AppRun AppDir/AppRun
|
cp distribution/linux/appimage/AppRun AppDir/AppRun
|
||||||
cp distribution/misc/Logo.svg AppDir/Ryujinx.svg
|
cp src/Ryujinx.UI.Common/Resources/Logo_Ryujinx.png AppDir/Ryujinx.svg
|
||||||
|
|
||||||
|
|
||||||
cp -r "$BUILDDIR"/* AppDir/usr/bin/
|
cp -r "$BUILDDIR"/* AppDir/usr/bin/
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using Humanizer;
|
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
@@ -59,8 +58,8 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
{
|
{
|
||||||
_ptc = ptc;
|
_ptc = ptc;
|
||||||
|
|
||||||
_timer = new Timer(SaveInterval.Seconds());
|
_timer = new Timer(SaveInterval * 1000d);
|
||||||
_timer.Elapsed += TimerElapsed;
|
_timer.Elapsed += PreSave;
|
||||||
|
|
||||||
_outerHeaderMagic = BinaryPrimitives.ReadUInt64LittleEndian(EncodingCache.UTF8NoBOM.GetBytes(OuterHeaderMagicString).AsSpan());
|
_outerHeaderMagic = BinaryPrimitives.ReadUInt64LittleEndian(EncodingCache.UTF8NoBOM.GetBytes(OuterHeaderMagicString).AsSpan());
|
||||||
|
|
||||||
@@ -73,9 +72,6 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
Enabled = false;
|
Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TimerElapsed(object _, ElapsedEventArgs __)
|
|
||||||
=> new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start();
|
|
||||||
|
|
||||||
public void AddEntry(ulong address, ExecutionMode mode, bool highCq)
|
public void AddEntry(ulong address, ExecutionMode mode, bool highCq)
|
||||||
{
|
{
|
||||||
if (IsAddressInStaticCodeRange(address))
|
if (IsAddressInStaticCodeRange(address))
|
||||||
@@ -266,7 +262,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
compressedStream.SetLength(0L);
|
compressedStream.SetLength(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreSave()
|
private void PreSave(object source, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
_waitEvent.Reset();
|
_waitEvent.Reset();
|
||||||
|
|
||||||
@@ -432,7 +428,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
{
|
{
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
|
|
||||||
_timer.Elapsed -= TimerElapsed;
|
_timer.Elapsed -= PreSave;
|
||||||
_timer.Dispose();
|
_timer.Dispose();
|
||||||
|
|
||||||
Wait();
|
Wait();
|
||||||
|
|||||||
@@ -9,12 +9,20 @@ namespace Ryujinx.Audio.Backends.Dummy
|
|||||||
{
|
{
|
||||||
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
|
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
|
||||||
{
|
{
|
||||||
private readonly ManualResetEvent _updateRequiredEvent = new(false);
|
private readonly ManualResetEvent _updateRequiredEvent;
|
||||||
private readonly ManualResetEvent _pauseEvent = new(true);
|
private readonly ManualResetEvent _pauseEvent;
|
||||||
|
|
||||||
public static bool IsSupported => true;
|
public static bool IsSupported => true;
|
||||||
|
|
||||||
public float Volume { get; set; } = 1f;
|
public float Volume { get; set; }
|
||||||
|
|
||||||
|
public DummyHardwareDeviceDriver()
|
||||||
|
{
|
||||||
|
_updateRequiredEvent = new ManualResetEvent(false);
|
||||||
|
_pauseEvent = new ManualResetEvent(true);
|
||||||
|
|
||||||
|
Volume = 1f;
|
||||||
|
}
|
||||||
|
|
||||||
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
|
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
|
||||||
{
|
{
|
||||||
@@ -52,7 +60,7 @@ namespace Ryujinx.Audio.Backends.Dummy
|
|||||||
Dispose(true);
|
Dispose(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Ryujinx.BuildValidationTasks
|
|
||||||
{
|
|
||||||
public interface IValidationTask
|
|
||||||
{
|
|
||||||
public bool Execute(string projectPath, bool isGitRunner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
73
src/Ryujinx.BuildValidationTasks/LocaleValidationTask.cs
Normal file
73
src/Ryujinx.BuildValidationTasks/LocaleValidationTask.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Build.Utilities;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
|
||||||
|
namespace Ryujinx.BuildValidationTasks
|
||||||
|
{
|
||||||
|
public class LocaleValidationTask : Task
|
||||||
|
{
|
||||||
|
public override bool Execute()
|
||||||
|
{
|
||||||
|
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
||||||
|
|
||||||
|
if (path.Split(["src"], StringSplitOptions.None).Length == 1)
|
||||||
|
{
|
||||||
|
//i assume that we are in a build directory in the solution dir
|
||||||
|
path = new FileInfo(path).Directory!.Parent!.GetDirectories("src")[0].GetDirectories("Ryujinx")[0].GetDirectories("Assets")[0].GetFiles("locales.json")[0].FullName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = path.Split(["src"], StringSplitOptions.None)[0];
|
||||||
|
path = new FileInfo(path).Directory!.GetDirectories("src")[0].GetDirectories("Ryujinx")[0].GetDirectories("Assets")[0].GetFiles("locales.json")[0].FullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
string data;
|
||||||
|
|
||||||
|
using (StreamReader sr = new(path))
|
||||||
|
{
|
||||||
|
data = sr.ReadToEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalesJson json = JsonConvert.DeserializeObject<LocalesJson>(data);
|
||||||
|
|
||||||
|
for (int i = 0; i < json.Locales.Count; i++)
|
||||||
|
{
|
||||||
|
LocalesEntry locale = json.Locales[i];
|
||||||
|
|
||||||
|
foreach (string langCode in json.Languages.Where(it => !locale.Translations.ContainsKey(it)))
|
||||||
|
{
|
||||||
|
locale.Translations.Add(langCode, string.Empty);
|
||||||
|
Log.LogMessage(MessageImportance.High, $"Added '{langCode}' to Locale '{locale.ID}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
locale.Translations = locale.Translations.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||||
|
json.Locales[i] = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
string jsonString = JsonConvert.SerializeObject(json, Formatting.Indented);
|
||||||
|
|
||||||
|
using (StreamWriter sw = new(path))
|
||||||
|
{
|
||||||
|
sw.Write(jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LocalesJson
|
||||||
|
{
|
||||||
|
public List<string> Languages { get; set; }
|
||||||
|
public List<LocalesEntry> Locales { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LocalesEntry
|
||||||
|
{
|
||||||
|
public string ID { get; set; }
|
||||||
|
public Dictionary<string, string> Translations { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Encodings.Web;
|
|
||||||
|
|
||||||
namespace Ryujinx.BuildValidationTasks
|
|
||||||
{
|
|
||||||
public class LocalesValidationTask : IValidationTask
|
|
||||||
{
|
|
||||||
public LocalesValidationTask() { }
|
|
||||||
|
|
||||||
public bool Execute(string projectPath, bool isGitRunner)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Running Locale Validation Task...");
|
|
||||||
|
|
||||||
string path = projectPath + "src/Ryujinx/Assets/locales.json";
|
|
||||||
string data;
|
|
||||||
|
|
||||||
using (StreamReader sr = new(path))
|
|
||||||
{
|
|
||||||
data = sr.ReadToEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalesJson json;
|
|
||||||
|
|
||||||
if (isGitRunner && data.Contains("\r\n"))
|
|
||||||
throw new FormatException("locales.json is using CRLF line endings! It should be using LF line endings, build locally to fix...");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
json = JsonSerializer.Deserialize<LocalesJson>(data);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (JsonException e)
|
|
||||||
{
|
|
||||||
throw new JsonException(e.Message); //shorter and easier stacktrace
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool encounteredIssue = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < json.Locales.Count; i++)
|
|
||||||
{
|
|
||||||
LocalesEntry locale = json.Locales[i];
|
|
||||||
|
|
||||||
foreach (string langCode in json.Languages.Where(lang => !locale.Translations.ContainsKey(lang)))
|
|
||||||
{
|
|
||||||
encounteredIssue = true;
|
|
||||||
|
|
||||||
if (!isGitRunner)
|
|
||||||
{
|
|
||||||
locale.Translations.Add(langCode, string.Empty);
|
|
||||||
Console.WriteLine($"Added '{langCode}' to Locale '{locale.ID}'");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Missing '{langCode}' in Locale '{locale.ID}'!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string langCode in json.Languages.Where(lang => locale.Translations.ContainsKey(lang) && lang != "en_US" && locale.Translations[lang] == locale.Translations["en_US"]))
|
|
||||||
{
|
|
||||||
encounteredIssue = true;
|
|
||||||
|
|
||||||
if (!isGitRunner)
|
|
||||||
{
|
|
||||||
locale.Translations[langCode] = string.Empty;
|
|
||||||
Console.WriteLine($"Lanugage '{langCode}' is a duplicate of en_US in Locale '{locale.ID}'! Resetting it...");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Lanugage '{langCode}' is a duplicate of en_US in Locale '{locale.ID}'!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
locale.Translations = locale.Translations.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
|
|
||||||
json.Locales[i] = locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isGitRunner && encounteredIssue)
|
|
||||||
throw new JsonException("1 or more locales are invalid!");
|
|
||||||
|
|
||||||
JsonSerializerOptions jsonOptions = new JsonSerializerOptions()
|
|
||||||
{
|
|
||||||
WriteIndented = true,
|
|
||||||
NewLine = "\n",
|
|
||||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
|
||||||
};
|
|
||||||
|
|
||||||
string jsonString = JsonSerializer.Serialize(json, jsonOptions);
|
|
||||||
|
|
||||||
using (StreamWriter sw = new(path))
|
|
||||||
{
|
|
||||||
sw.Write(jsonString);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine("Finished Locale Validation Task!");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LocalesJson
|
|
||||||
{
|
|
||||||
public List<string> Languages { get; set; }
|
|
||||||
public List<LocalesEntry> Locales { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LocalesEntry
|
|
||||||
{
|
|
||||||
public string ID { get; set; }
|
|
||||||
public Dictionary<string, string> Translations { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Ryujinx.BuildValidationTasks
|
|
||||||
{
|
|
||||||
public class Program
|
|
||||||
{
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
// Display the number of command line arguments.
|
|
||||||
if (args.Length == 0)
|
|
||||||
throw new ArgumentException("Error: too few arguments!");
|
|
||||||
|
|
||||||
string path = args[0];
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(path))
|
|
||||||
throw new ArgumentException("Error: path is null or empty!");
|
|
||||||
|
|
||||||
if (!Path.Exists(path))
|
|
||||||
throw new FileLoadException($"path {{{path}}} does not exist!");
|
|
||||||
|
|
||||||
path = Path.GetFullPath(path);
|
|
||||||
|
|
||||||
if (!Directory.GetDirectories(path).Contains($"{path}src"))
|
|
||||||
throw new FileLoadException($"path {{{path}}} is not a valid ryujinx project!");
|
|
||||||
|
|
||||||
bool isGitRunner = path.Contains("runner") || path.Contains("D:\\a\\Ryujinx\\Ryujinx");
|
|
||||||
if (isGitRunner)
|
|
||||||
Console.WriteLine("Is Git Runner!");
|
|
||||||
|
|
||||||
// Run tasks
|
|
||||||
// Pass extra info needed in the task constructors
|
|
||||||
new LocalesValidationTask().Execute(path, isGitRunner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Target Name="PostBuildTarget" AfterTargets="AfterBuild">
|
<ItemGroup>
|
||||||
<Message Text="Running Validation Project" Importance="high" />
|
<PackageReference Include="Microsoft.Build.Utilities.Core" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
|
<UsingTask TaskName="Ryujinx.BuildValidationTasks.LocaleValidationTask" TaskFactory="TaskHostFactory" AssemblyFile="$(OutDir)Ryujinx.BuildValidationTasks.dll" />
|
||||||
Command="dotnet Ryujinx.BuildValidationTasks.dll "$(ProjectDir)..\..\\""
|
|
||||||
ConsoleToMsBuild="true"
|
<Target Name="LocalesJsonValidation" AfterTargets="AfterRebuild">
|
||||||
Condition="'$(RuntimeIdentifier)' == ''"
|
<LocaleValidationTask />
|
||||||
/>
|
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -36,8 +36,6 @@ namespace Ryujinx.Common.Configuration
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static float ToFloatY(this AspectRatio aspectRatio)
|
public static float ToFloatY(this AspectRatio aspectRatio)
|
||||||
{
|
{
|
||||||
return aspectRatio switch
|
return aspectRatio switch
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
using Gommon;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Configuration
|
|
||||||
{
|
|
||||||
[Flags]
|
|
||||||
public enum DirtyHack : byte
|
|
||||||
{
|
|
||||||
Xc2MenuSoftlockFix = 1,
|
|
||||||
ShaderTranslationDelay = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly struct EnabledDirtyHack(DirtyHack hack, int value)
|
|
||||||
{
|
|
||||||
public DirtyHack Hack => hack;
|
|
||||||
public int Value => value;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ulong Pack() => Raw.PackBitFields(PackedFormat);
|
|
||||||
|
|
||||||
public static EnabledDirtyHack Unpack(ulong packedHack)
|
|
||||||
{
|
|
||||||
var unpackedFields = packedHack.UnpackBitFields(PackedFormat);
|
|
||||||
if (unpackedFields is not [var hack, var value])
|
|
||||||
throw new ArgumentException(nameof(packedHack));
|
|
||||||
|
|
||||||
return new EnabledDirtyHack((DirtyHack)hack, (int)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private uint[] Raw => [(uint)Hack, (uint)Value.CoerceAtLeast(0)];
|
|
||||||
|
|
||||||
public static readonly byte[] PackedFormat = [8, 32];
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DirtyHacks : Dictionary<DirtyHack, int>
|
|
||||||
{
|
|
||||||
public DirtyHacks(IEnumerable<EnabledDirtyHack> hacks)
|
|
||||||
=> hacks.ForEach(edh => Add(edh.Hack, edh.Value));
|
|
||||||
|
|
||||||
public DirtyHacks(ulong[] packedHacks) : this(packedHacks.Select(EnabledDirtyHack.Unpack)) {}
|
|
||||||
|
|
||||||
public ulong[] PackEntries()
|
|
||||||
=> Entries.Select(it => it.Pack()).ToArray();
|
|
||||||
|
|
||||||
public EnabledDirtyHack[] Entries
|
|
||||||
=> this
|
|
||||||
.Select(it => new EnabledDirtyHack(it.Key, it.Value))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
public static implicit operator DirtyHacks(EnabledDirtyHack[] hacks) => new(hacks);
|
|
||||||
public static implicit operator DirtyHacks(ulong[] packedHacks) => new(packedHacks);
|
|
||||||
|
|
||||||
public new int this[DirtyHack hack] => TryGetValue(hack, out var value) ? value : -1;
|
|
||||||
|
|
||||||
public bool IsEnabled(DirtyHack hack) => ContainsKey(hack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,5 @@ namespace Ryujinx.Common.Configuration
|
|||||||
Bilinear,
|
Bilinear,
|
||||||
Nearest,
|
Nearest,
|
||||||
Fsr,
|
Fsr,
|
||||||
Area,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ namespace Ryujinx.Common
|
|||||||
public static class StreamExtensions
|
public static class StreamExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes an int span to this stream.
|
/// Writes a <see cref="ReadOnlySpan{int}" /> to this stream.
|
||||||
///
|
///
|
||||||
/// This default implementation converts each buffer value to a stack-allocated
|
/// This default implementation converts each buffer value to a stack-allocated
|
||||||
/// byte array, then writes it to the Stream using <see cref="Stream.Write(ReadOnlySpan{byte})" />.
|
/// byte array, then writes it to the Stream using <cref="System.Stream.Write(byte[])" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">The stream to be written to</param>
|
/// <param name="stream">The stream to be written to</param>
|
||||||
/// <param name="buffer">The buffer of values to be written</param>
|
/// <param name="buffer">The buffer of values to be written</param>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ 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;
|
||||||
|
|
||||||
@@ -159,15 +158,20 @@ 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,7 +27,11 @@ namespace Ryujinx.Common.Logging.Targets
|
|||||||
|
|
||||||
private readonly int _overflowTimeout;
|
private readonly int _overflowTimeout;
|
||||||
|
|
||||||
string ILogTarget.Name => _target.Name;
|
string ILogTarget.Name { get => _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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,35 +40,5 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
return (value >> 32) | (value << 32);
|
return (value >> 32) | (value << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Never actually written bit packing logic before, so I looked it up.
|
|
||||||
// This code is from https://gist.github.com/Alan-FGR/04938e93e2bffdf5802ceb218a37c195
|
|
||||||
|
|
||||||
public static ulong PackBitFields(this uint[] values, byte[] bitFields)
|
|
||||||
{
|
|
||||||
ulong retVal = values[0]; //we set the first value right away
|
|
||||||
for (int f = 1; f < values.Length; f++)
|
|
||||||
{
|
|
||||||
retVal <<= bitFields[f]; // we shift the previous value
|
|
||||||
retVal += values[f];// and add our current value
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static uint[] UnpackBitFields(this ulong packed, byte[] bitFields)
|
|
||||||
{
|
|
||||||
int fields = bitFields.Length - 1; // number of fields to unpack
|
|
||||||
uint[] retArr = new uint[fields + 1]; // init return array
|
|
||||||
int curPos = 0; // current field bit position (start)
|
|
||||||
int lastEnd; // position where last field ended
|
|
||||||
for (int f = fields; f >= 0; f--) // loop from last
|
|
||||||
{
|
|
||||||
lastEnd = curPos; // we store where the last value ended
|
|
||||||
curPos += bitFields[f]; // we get where the current value starts
|
|
||||||
int leftShift = 64 - curPos; // we figure how much left shift we gotta apply for the other numbers to overflow into oblivion
|
|
||||||
retArr[f] = (uint)((packed << leftShift) >> leftShift + lastEnd); // we do magic
|
|
||||||
}
|
|
||||||
return retArr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/Ryujinx.Graphics.GAL/AntiAliasing.cs
Normal file
12
src/Ryujinx.Graphics.GAL/AntiAliasing.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
namespace Ryujinx.Graphics.GAL
|
||||||
|
{
|
||||||
|
public enum AntiAliasing
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Fxaa,
|
||||||
|
SmaaLow,
|
||||||
|
SmaaMedium,
|
||||||
|
SmaaHigh,
|
||||||
|
SmaaUltra,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL
|
namespace Ryujinx.Graphics.GAL
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Window;
|
using Ryujinx.Graphics.GAL.Multithreading.Commands.Window;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||||
|
|||||||
10
src/Ryujinx.Graphics.GAL/UpscaleType.cs
Normal file
10
src/Ryujinx.Graphics.GAL/UpscaleType.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Ryujinx.Graphics.GAL
|
||||||
|
{
|
||||||
|
public enum ScalingFilter
|
||||||
|
{
|
||||||
|
Bilinear,
|
||||||
|
Nearest,
|
||||||
|
Fsr,
|
||||||
|
Area,
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/Ryujinx.Graphics.GAL/VSyncMode.cs
Normal file
9
src/Ryujinx.Graphics.GAL/VSyncMode.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Ryujinx.Graphics.GAL
|
||||||
|
{
|
||||||
|
public enum VSyncMode
|
||||||
|
{
|
||||||
|
Switch,
|
||||||
|
Unbounded,
|
||||||
|
Custom
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using Ryujinx.Graphics.Device;
|
using Ryujinx.Graphics.Device;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
||||||
@@ -92,13 +91,6 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Enabled dirty hacks.
|
|
||||||
/// Used for workarounds to emulator bugs we can't fix/don't know how to fix yet.
|
|
||||||
/// </summary>
|
|
||||||
internal DirtyHacks DirtyHacks { get; }
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Host hardware capabilities.
|
/// Host hardware capabilities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -121,7 +113,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// Creates a new instance of the GPU emulation context.
|
/// Creates a new instance of the GPU emulation context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="renderer">Host renderer</param>
|
/// <param name="renderer">Host renderer</param>
|
||||||
public GpuContext(IRenderer renderer, DirtyHacks hacks)
|
public GpuContext(IRenderer renderer)
|
||||||
{
|
{
|
||||||
Renderer = renderer;
|
Renderer = renderer;
|
||||||
|
|
||||||
@@ -144,8 +136,6 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
|
|
||||||
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
||||||
|
|
||||||
DirtyHacks = hacks;
|
|
||||||
|
|
||||||
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
@@ -367,9 +366,6 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_context.DirtyHacks.IsEnabled(DirtyHack.ShaderTranslationDelay))
|
|
||||||
Thread.Sleep(_context.DirtyHacks[DirtyHack.ShaderTranslationDelay]);
|
|
||||||
|
|
||||||
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
||||||
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
using SharpMetal;
|
|
||||||
using SharpMetal.Foundation;
|
|
||||||
using SharpMetal.ObjectiveCCore;
|
|
||||||
using SharpMetal.QuartzCore;
|
|
||||||
using System.Runtime.Versioning;
|
|
||||||
// ReSharper disable InconsistentNaming
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Metal.SharpMetalExtensions
|
|
||||||
{
|
|
||||||
[SupportedOSPlatform("macOS")]
|
|
||||||
public static class CAMetalLayerExtensions
|
|
||||||
{
|
|
||||||
private static readonly Selector sel_developerHUDProperties = "developerHUDProperties";
|
|
||||||
private static readonly Selector sel_setDeveloperHUDProperties = "setDeveloperHUDProperties:";
|
|
||||||
|
|
||||||
public static NSDictionary GetDeveloperHudProperties(this CAMetalLayer metalLayer)
|
|
||||||
=> new(ObjectiveCRuntime.IntPtr_objc_msgSend(metalLayer.NativePtr, sel_developerHUDProperties));
|
|
||||||
|
|
||||||
public static void SetDeveloperHudProperties(this CAMetalLayer metalLayer, NSDictionary dictionary)
|
|
||||||
=> ObjectiveCRuntime.objc_msgSend(metalLayer.NativePtr, sel_setDeveloperHUDProperties, dictionary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
using SharpMetal.Foundation;
|
|
||||||
using SharpMetal.ObjectiveCCore;
|
|
||||||
using System.Runtime.Versioning;
|
|
||||||
// ReSharper disable InconsistentNaming
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Metal.SharpMetalExtensions
|
|
||||||
{
|
|
||||||
[SupportedOSPlatform("macOS")]
|
|
||||||
public static class NSHelper
|
|
||||||
{
|
|
||||||
private static readonly Selector sel_getCStringMaxLengthEncoding = "getCString:maxLength:encoding:";
|
|
||||||
private static readonly Selector sel_stringWithUTF8String = "stringWithUTF8String:";
|
|
||||||
|
|
||||||
public static unsafe string ToDotNetString(this NSString source)
|
|
||||||
{
|
|
||||||
char[] sourceBuffer = new char[source.Length];
|
|
||||||
fixed (char* pSourceBuffer = sourceBuffer)
|
|
||||||
{
|
|
||||||
ObjectiveC.bool_objc_msgSend(source,
|
|
||||||
sel_getCStringMaxLengthEncoding,
|
|
||||||
pSourceBuffer,
|
|
||||||
source.MaximumLengthOfBytes(NSStringEncoding.UTF16) + 1,
|
|
||||||
(ulong)NSStringEncoding.UTF16);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new string(sourceBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NSString ToNSString(this string source)
|
|
||||||
=> new(ObjectiveC.IntPtr_objc_msgSend(new ObjectiveCClass(nameof(NSString)), sel_stringWithUTF8String, source));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="SharpMetal" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -5,9 +5,12 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.GAL\Ryujinx.Graphics.GAL.csproj" />
|
<ProjectReference Include="..\Ryujinx.Graphics.GAL\Ryujinx.Graphics.GAL.csproj" />
|
||||||
<ProjectReference Include="..\Ryujinx.Graphics.Metal.SharpMetalExtensions\Ryujinx.Graphics.Metal.SharpMetalExtensions.csproj" />
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="SharpMetal" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Metal.Effects;
|
using Ryujinx.Graphics.Metal.Effects;
|
||||||
@@ -15,7 +14,7 @@ namespace Ryujinx.Graphics.Metal
|
|||||||
public bool ScreenCaptureRequested { get; set; }
|
public bool ScreenCaptureRequested { get; set; }
|
||||||
|
|
||||||
private readonly MetalRenderer _renderer;
|
private readonly MetalRenderer _renderer;
|
||||||
private CAMetalLayer _metalLayer;
|
private readonly CAMetalLayer _metalLayer;
|
||||||
|
|
||||||
private int _width;
|
private int _width;
|
||||||
private int _height;
|
private int _height;
|
||||||
@@ -23,14 +22,12 @@ namespace Ryujinx.Graphics.Metal
|
|||||||
private int _requestedWidth;
|
private int _requestedWidth;
|
||||||
private int _requestedHeight;
|
private int _requestedHeight;
|
||||||
|
|
||||||
|
// private bool _vsyncEnabled;
|
||||||
private AntiAliasing _currentAntiAliasing;
|
private AntiAliasing _currentAntiAliasing;
|
||||||
private bool _updateEffect;
|
private bool _updateEffect;
|
||||||
private IPostProcessingEffect _effect;
|
private IPostProcessingEffect _effect;
|
||||||
private IScalingFilter _scalingFilter;
|
private IScalingFilter _scalingFilter;
|
||||||
private bool _isLinear;
|
private bool _isLinear;
|
||||||
|
|
||||||
public bool IsVSyncEnabled => _metalLayer.DisplaySyncEnabled;
|
|
||||||
|
|
||||||
// private float _scalingFilterLevel;
|
// private float _scalingFilterLevel;
|
||||||
private bool _updateScalingFilter;
|
private bool _updateScalingFilter;
|
||||||
private ScalingFilter _currentScalingFilter;
|
private ScalingFilter _currentScalingFilter;
|
||||||
@@ -42,7 +39,7 @@ namespace Ryujinx.Graphics.Metal
|
|||||||
_metalLayer = metalLayer;
|
_metalLayer = metalLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResizeIfNeeded()
|
private unsafe void ResizeIfNeeded()
|
||||||
{
|
{
|
||||||
if (_requestedWidth != 0 && _requestedHeight != 0)
|
if (_requestedWidth != 0 && _requestedHeight != 0)
|
||||||
{
|
{
|
||||||
@@ -56,7 +53,7 @@ namespace Ryujinx.Graphics.Metal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
public unsafe void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
||||||
{
|
{
|
||||||
if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex)
|
if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex)
|
||||||
{
|
{
|
||||||
@@ -143,7 +140,7 @@ namespace Ryujinx.Graphics.Metal
|
|||||||
|
|
||||||
public void ChangeVSyncMode(VSyncMode vSyncMode)
|
public void ChangeVSyncMode(VSyncMode vSyncMode)
|
||||||
{
|
{
|
||||||
_metalLayer.DisplaySyncEnabled = vSyncMode is VSyncMode.Switch;
|
//_vSyncMode = vSyncMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAntiAliasing(AntiAliasing effect)
|
public void SetAntiAliasing(AntiAliasing effect)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
|
|||||||
{
|
{
|
||||||
internal enum BitDepth
|
internal enum BitDepth
|
||||||
{
|
{
|
||||||
Bits8 = 8, // < 8 bits
|
Bits8 = 8, /**< 8 bits */
|
||||||
Bits10 = 10, // < 10 bits
|
Bits10 = 10, /**< 10 bits */
|
||||||
Bits12 = 12, // < 12 bits
|
Bits12 = 12, /**< 12 bits */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||||||
|
|
||||||
_current = new CounterQueueEvent(this, glType, 0);
|
_current = new CounterQueueEvent(this, glType, 0);
|
||||||
|
|
||||||
_consumerThread = new Thread(EventConsumer) { Name = "CPU.CounterQueue." + (int)type };
|
_consumerThread = new Thread(EventConsumer);
|
||||||
_consumerThread.Start();
|
_consumerThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.OpenGL.Effects;
|
using Ryujinx.Graphics.OpenGL.Effects;
|
||||||
using Ryujinx.Graphics.OpenGL.Effects.Smaa;
|
using Ryujinx.Graphics.OpenGL.Effects.Smaa;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
|
|
||||||
_current = new CounterQueueEvent(this, type, 0);
|
_current = new CounterQueueEvent(this, type, 0);
|
||||||
|
|
||||||
_consumerThread = new Thread(EventConsumer) { Name = "CPU.CounterQueue." + (int)type };
|
_consumerThread = new Thread(EventConsumer);
|
||||||
_consumerThread.Start();
|
_consumerThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Gommon;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
@@ -891,12 +890,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private void PrintGpuInformation()
|
private void PrintGpuInformation()
|
||||||
{
|
{
|
||||||
string gpuInfoMessage = $"{GpuRenderer} ({GpuVersion})";
|
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
|
||||||
if (!GpuRenderer.StartsWithIgnoreCase(GpuVendor))
|
|
||||||
gpuInfoMessage = gpuInfoMessage.Prepend(GpuVendor);
|
|
||||||
|
|
||||||
Logger.Notice.Print(LogClass.Gpu, gpuInfoMessage);
|
|
||||||
|
|
||||||
Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB");
|
Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Vulkan.Effects;
|
using Ryujinx.Graphics.Vulkan.Effects;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
|||||||
@@ -1034,16 +1034,16 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
switch (fileName)
|
switch (fileName)
|
||||||
{
|
{
|
||||||
case "prod.keys":
|
case "prod.keys":
|
||||||
verified = VerifyKeys(lines, genericPattern);
|
verified = verifyKeys(lines, genericPattern);
|
||||||
break;
|
break;
|
||||||
case "title.keys":
|
case "title.keys":
|
||||||
verified = VerifyKeys(lines, titlePattern);
|
verified = verifyKeys(lines, titlePattern);
|
||||||
break;
|
break;
|
||||||
case "console.keys":
|
case "console.keys":
|
||||||
verified = VerifyKeys(lines, genericPattern);
|
verified = verifyKeys(lines, genericPattern);
|
||||||
break;
|
break;
|
||||||
case "dev.keys":
|
case "dev.keys":
|
||||||
verified = VerifyKeys(lines, genericPattern);
|
verified = verifyKeys(lines, genericPattern);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new FormatException($"Keys file name \"{fileName}\" not supported. Only \"prod.keys\", \"title.keys\", \"console.keys\", \"dev.keys\" are supported.");
|
throw new FormatException($"Keys file name \"{fileName}\" not supported. Only \"prod.keys\", \"title.keys\", \"console.keys\", \"dev.keys\" are supported.");
|
||||||
@@ -1056,20 +1056,18 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
{
|
{
|
||||||
throw new FileNotFoundException($"Keys file not found at \"{filePath}\".");
|
throw new FileNotFoundException($"Keys file not found at \"{filePath}\".");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
private bool verifyKeys(string[] lines, string regex)
|
||||||
|
{
|
||||||
bool VerifyKeys(string[] lines, string regex)
|
foreach (string line in lines)
|
||||||
{
|
{
|
||||||
foreach (string line in lines)
|
if (!Regex.IsMatch(line, regex))
|
||||||
{
|
{
|
||||||
if (!Regex.IsMatch(line, regex))
|
return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AreKeysAlredyPresent(string pathToCheck)
|
public bool AreKeysAlredyPresent(string pathToCheck)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
|
|||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using Ryujinx.HLE.UI;
|
using Ryujinx.HLE.UI;
|
||||||
using System;
|
using System;
|
||||||
|
using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
|
||||||
|
|
||||||
namespace Ryujinx.HLE
|
namespace Ryujinx.HLE
|
||||||
{
|
{
|
||||||
@@ -189,11 +190,6 @@ namespace Ryujinx.HLE
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Action RefreshInputConfig { internal get; set; }
|
public Action RefreshInputConfig { internal get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The desired hacky workarounds.
|
|
||||||
/// </summary>
|
|
||||||
public EnabledDirtyHack[] Hacks { internal get; set; }
|
|
||||||
|
|
||||||
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
|
public HLEConfiguration(VirtualFileSystem virtualFileSystem,
|
||||||
LibHacHorizonManager libHacHorizonManager,
|
LibHacHorizonManager libHacHorizonManager,
|
||||||
ContentManager contentManager,
|
ContentManager contentManager,
|
||||||
@@ -223,8 +219,7 @@ namespace Ryujinx.HLE
|
|||||||
bool multiplayerDisableP2p,
|
bool multiplayerDisableP2p,
|
||||||
string multiplayerLdnPassphrase,
|
string multiplayerLdnPassphrase,
|
||||||
string multiplayerLdnServer,
|
string multiplayerLdnServer,
|
||||||
int customVSyncInterval,
|
int customVSyncInterval)
|
||||||
EnabledDirtyHack[] dirtyHacks = null)
|
|
||||||
{
|
{
|
||||||
VirtualFileSystem = virtualFileSystem;
|
VirtualFileSystem = virtualFileSystem;
|
||||||
LibHacHorizonManager = libHacHorizonManager;
|
LibHacHorizonManager = libHacHorizonManager;
|
||||||
@@ -256,7 +251,6 @@ namespace Ryujinx.HLE
|
|||||||
MultiplayerDisableP2p = multiplayerDisableP2p;
|
MultiplayerDisableP2p = multiplayerDisableP2p;
|
||||||
MultiplayerLdnPassphrase = multiplayerLdnPassphrase;
|
MultiplayerLdnPassphrase = multiplayerLdnPassphrase;
|
||||||
MultiplayerLdnServer = multiplayerLdnServer;
|
MultiplayerLdnServer = multiplayerLdnServer;
|
||||||
Hacks = dirtyHacks ?? [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
|||||||
is64Bits = true;
|
is64Bits = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
HostThread = new Thread(ThreadStart) { Name = "HLE.KThread" };
|
HostThread = new Thread(ThreadStart);
|
||||||
|
|
||||||
Context = owner?.CreateExecutionContext() ?? new ProcessExecutionContext();
|
Context = owner?.CreateExecutionContext() ?? new ProcessExecutionContext();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
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;
|
||||||
@@ -7,13 +6,12 @@ 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
|
||||||
{
|
{
|
||||||
public class AccountSaveDataManager
|
class AccountSaveDataManager
|
||||||
{
|
{
|
||||||
private static readonly string _profilesJsonPath = Path.Join(AppDataManager.BaseDirPath, "system", "Profiles.json");
|
private 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());
|
||||||
|
|
||||||
@@ -51,16 +49,6 @@ 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,9 +1,6 @@
|
|||||||
using LibHac;
|
using LibHac;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Sf;
|
using LibHac.Sf;
|
||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
||||||
{
|
{
|
||||||
@@ -16,8 +13,6 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
|||||||
_baseStorage = SharedRef<LibHac.FsSrv.Sf.IStorage>.CreateMove(ref baseStorage);
|
_baseStorage = SharedRef<LibHac.FsSrv.Sf.IStorage>.CreateMove(ref baseStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const string Xc2TitleId = "0100e95004038000";
|
|
||||||
|
|
||||||
[CommandCmif(0)]
|
[CommandCmif(0)]
|
||||||
// Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer
|
// Read(u64 offset, u64 length) -> buffer<u8, 0x46, 0> buffer
|
||||||
public ResultCode Read(ServiceCtx context)
|
public ResultCode Read(ServiceCtx context)
|
||||||
@@ -39,13 +34,6 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
|||||||
using var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true);
|
using var region = context.Memory.GetWritableRegion(bufferAddress, (int)bufferLen, true);
|
||||||
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
|
Result result = _baseStorage.Get.Read((long)offset, new OutBuffer(region.Memory.Span), (long)size);
|
||||||
|
|
||||||
if (context.Device.DirtyHacks.IsEnabled(DirtyHack.Xc2MenuSoftlockFix) && TitleIDs.CurrentApplication.Value == Xc2TitleId)
|
|
||||||
{
|
|
||||||
// Add a load-bearing sleep to avoid XC2 softlock
|
|
||||||
// https://web.archive.org/web/20240728045136/https://github.com/Ryujinx/Ryujinx/issues/2357
|
|
||||||
Thread.Sleep(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ResultCode)result.Value;
|
return (ResultCode)result.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,10 +114,10 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string usedCharacterStr = Convert.ToHexString(usedCharacter);
|
string usedCharacterStr = BitConverter.ToString(usedCharacter).Replace("-", "");
|
||||||
string variationStr = Convert.ToHexString(variation);
|
string variationStr = BitConverter.ToString(variation).Replace("-", "");
|
||||||
string amiiboIDStr = Convert.ToHexString(amiiboID);
|
string amiiboIDStr = BitConverter.ToString(amiiboID).Replace("-", "");
|
||||||
string setIDStr = Convert.ToHexString(setID);
|
string setIDStr = BitConverter.ToString(setID).Replace("-", "");
|
||||||
string head = usedCharacterStr + variationStr;
|
string head = usedCharacterStr + variationStr;
|
||||||
string tail = amiiboIDStr + setIDStr + "02";
|
string tail = amiiboIDStr + setIDStr + "02";
|
||||||
string finalID = head + tail;
|
string finalID = head + tail;
|
||||||
@@ -289,8 +289,8 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption
|
|||||||
|
|
||||||
private static void LogFinalData(byte[] titleId, byte[] appId, string head, string tail, string finalID, string nickName, DateTime initDateTime, DateTime writeDateTime, ushort settingsValue, ushort writeCounterValue, byte[] applicationAreas)
|
private static void LogFinalData(byte[] titleId, byte[] appId, string head, string tail, string finalID, string nickName, DateTime initDateTime, DateTime writeDateTime, ushort settingsValue, ushort writeCounterValue, byte[] applicationAreas)
|
||||||
{
|
{
|
||||||
Logger.Debug?.Print(LogClass.ServiceNfp, $"Title ID: 0x{Convert.ToHexString(titleId)}");
|
Logger.Debug?.Print(LogClass.ServiceNfp, $"Title ID: 0x{BitConverter.ToString(titleId).Replace("-", "")}");
|
||||||
Logger.Debug?.Print(LogClass.ServiceNfp, $"Application Program ID: 0x{Convert.ToHexString(appId)}");
|
Logger.Debug?.Print(LogClass.ServiceNfp, $"Application Program ID: 0x{BitConverter.ToString(appId).Replace("-", "")}");
|
||||||
Logger.Debug?.Print(LogClass.ServiceNfp, $"Head: {head}");
|
Logger.Debug?.Print(LogClass.ServiceNfp, $"Head: {head}");
|
||||||
Logger.Debug?.Print(LogClass.ServiceNfp, $"Tail: {tail}");
|
Logger.Debug?.Print(LogClass.ServiceNfp, $"Tail: {tail}");
|
||||||
Logger.Debug?.Print(LogClass.ServiceNfp, $"Final ID: {finalID}");
|
Logger.Debug?.Print(LogClass.ServiceNfp, $"Final ID: {finalID}");
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,10 +4,8 @@ using LibHac.Fs.Fsa;
|
|||||||
using LibHac.Loader;
|
using LibHac.Loader;
|
||||||
using LibHac.Ns;
|
using LibHac.Ns;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.Gpu;
|
|
||||||
using Ryujinx.HLE.Loaders.Executables;
|
using Ryujinx.HLE.Loaders.Executables;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
@@ -104,7 +102,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize GPU.
|
// Initialize GPU.
|
||||||
GraphicsConfig.TitleId = programId.ToString("X16");
|
Graphics.Gpu.GraphicsConfig.TitleId = $"{programId:x16}";
|
||||||
device.Gpu.HostInitalized.Set();
|
device.Gpu.HostInitalized.Set();
|
||||||
|
|
||||||
if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible))
|
if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible))
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ using LibHac.Ns;
|
|||||||
using LibHac.Tools.Fs;
|
using LibHac.Tools.Fs;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.Gpu;
|
|
||||||
using Ryujinx.HLE.Loaders.Executables;
|
using Ryujinx.HLE.Loaders.Executables;
|
||||||
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
||||||
using System;
|
using System;
|
||||||
@@ -61,8 +59,6 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
{
|
{
|
||||||
_latestPid = processResult.ProcessId;
|
_latestPid = processResult.ProcessId;
|
||||||
|
|
||||||
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,8 +86,6 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
{
|
{
|
||||||
_latestPid = processResult.ProcessId;
|
_latestPid = processResult.ProcessId;
|
||||||
|
|
||||||
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,8 +113,6 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
if (processResult.ProgramId > 0x01000000000007FF)
|
if (processResult.ProgramId > 0x01000000000007FF)
|
||||||
{
|
{
|
||||||
_latestPid = processResult.ProcessId;
|
_latestPid = processResult.ProcessId;
|
||||||
|
|
||||||
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -140,8 +132,6 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
{
|
{
|
||||||
_latestPid = processResult.ProcessId;
|
_latestPid = processResult.ProcessId;
|
||||||
|
|
||||||
TitleIDs.CurrentApplication.Value = processResult.ProgramIdText;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,17 +183,14 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
if (nacpData.Value.PresenceGroupId != 0)
|
if (nacpData.Value.PresenceGroupId != 0)
|
||||||
{
|
{
|
||||||
programId = nacpData.Value.PresenceGroupId;
|
programId = nacpData.Value.PresenceGroupId;
|
||||||
TitleIDs.CurrentApplication.Value = programId.ToString("X16");
|
|
||||||
}
|
}
|
||||||
else if (nacpData.Value.SaveDataOwnerId != 0)
|
else if (nacpData.Value.SaveDataOwnerId != 0)
|
||||||
{
|
{
|
||||||
programId = nacpData.Value.SaveDataOwnerId;
|
programId = nacpData.Value.SaveDataOwnerId;
|
||||||
TitleIDs.CurrentApplication.Value = programId.ToString("X16");
|
|
||||||
}
|
}
|
||||||
else if (nacpData.Value.AddOnContentBaseId != 0)
|
else if (nacpData.Value.AddOnContentBaseId != 0)
|
||||||
{
|
{
|
||||||
programId = nacpData.Value.AddOnContentBaseId - 0x1000;
|
programId = nacpData.Value.AddOnContentBaseId - 0x1000;
|
||||||
TitleIDs.CurrentApplication.Value = programId.ToString("X16");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +204,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Explicitly null TitleId to disable the shader cache.
|
// Explicitly null TitleId to disable the shader cache.
|
||||||
GraphicsConfig.TitleId = null;
|
Graphics.Gpu.GraphicsConfig.TitleId = null;
|
||||||
_device.Gpu.HostInitalized.Set();
|
_device.Gpu.HostInitalized.Set();
|
||||||
|
|
||||||
ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device,
|
ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using LibHac.Common;
|
|||||||
using LibHac.Ns;
|
using LibHac.Ns;
|
||||||
using Ryujinx.Audio.Backends.CompatLayer;
|
using Ryujinx.Audio.Backends.CompatLayer;
|
||||||
using Ryujinx.Audio.Integration;
|
using Ryujinx.Audio.Integration;
|
||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Graphics.Gpu;
|
using Ryujinx.Graphics.Gpu;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
@@ -18,8 +17,6 @@ namespace Ryujinx.HLE
|
|||||||
{
|
{
|
||||||
public class Switch : IDisposable
|
public class Switch : IDisposable
|
||||||
{
|
{
|
||||||
public static Switch Shared { get; private set; }
|
|
||||||
|
|
||||||
public HLEConfiguration Configuration { get; }
|
public HLEConfiguration Configuration { get; }
|
||||||
public IHardwareDeviceDriver AudioDeviceDriver { get; }
|
public IHardwareDeviceDriver AudioDeviceDriver { get; }
|
||||||
public MemoryBlock Memory { get; }
|
public MemoryBlock Memory { get; }
|
||||||
@@ -40,8 +37,6 @@ namespace Ryujinx.HLE
|
|||||||
|
|
||||||
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
|
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
|
||||||
|
|
||||||
public DirtyHacks DirtyHacks { get; }
|
|
||||||
|
|
||||||
public Switch(HLEConfiguration configuration)
|
public Switch(HLEConfiguration configuration)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(configuration.GpuRenderer);
|
ArgumentNullException.ThrowIfNull(configuration.GpuRenderer);
|
||||||
@@ -57,10 +52,9 @@ namespace Ryujinx.HLE
|
|||||||
: MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Mirrorable;
|
: MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Mirrorable;
|
||||||
|
|
||||||
#pragma warning disable IDE0055 // Disable formatting
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
DirtyHacks = new DirtyHacks(Configuration.Hacks);
|
|
||||||
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
|
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
|
||||||
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
|
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
|
||||||
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks);
|
Gpu = new GpuContext(Configuration.GpuRenderer);
|
||||||
System = new HOS.Horizon(this);
|
System = new HOS.Horizon(this);
|
||||||
Statistics = new PerformanceStatistics();
|
Statistics = new PerformanceStatistics();
|
||||||
Hid = new Hid(this, System.HidStorage);
|
Hid = new Hid(this, System.HidStorage);
|
||||||
@@ -78,11 +72,8 @@ namespace Ryujinx.HLE
|
|||||||
System.EnablePtc = Configuration.EnablePtc;
|
System.EnablePtc = Configuration.EnablePtc;
|
||||||
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
|
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
|
||||||
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
|
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
|
||||||
|
|
||||||
UpdateVSyncInterval();
|
UpdateVSyncInterval();
|
||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
|
|
||||||
Shared = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessFrame()
|
public void ProcessFrame()
|
||||||
@@ -151,9 +142,6 @@ namespace Ryujinx.HLE
|
|||||||
AudioDeviceDriver.Dispose();
|
AudioDeviceDriver.Dispose();
|
||||||
FileSystem.Dispose();
|
FileSystem.Dispose();
|
||||||
Memory.Dispose();
|
Memory.Dispose();
|
||||||
|
|
||||||
TitleIDs.CurrentApplication.Value = null;
|
|
||||||
Shared = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
namespace Ryujinx.Headless.SDL2
|
||||||
{
|
{
|
||||||
/// <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
|
namespace Ryujinx.Headless.SDL2
|
||||||
{
|
{
|
||||||
internal class HeadlessHostUiTheme : IHostUITheme
|
internal class HeadlessHostUiTheme : IHostUITheme
|
||||||
{
|
{
|
||||||
@@ -5,7 +5,7 @@ using SharpMetal.QuartzCore;
|
|||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
using static SDL2.SDL;
|
using static SDL2.SDL;
|
||||||
|
|
||||||
namespace Ryujinx.Headless
|
namespace Ryujinx.Headless.SDL2.Metal
|
||||||
{
|
{
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
class MetalWindow : WindowBase
|
class MetalWindow : WindowBase
|
||||||
@@ -7,7 +7,7 @@ using Ryujinx.Input.HLE;
|
|||||||
using System;
|
using System;
|
||||||
using static SDL2.SDL;
|
using static SDL2.SDL;
|
||||||
|
|
||||||
namespace Ryujinx.Headless
|
namespace Ryujinx.Headless.SDL2.OpenGL
|
||||||
{
|
{
|
||||||
class OpenGLWindow : WindowBase
|
class OpenGLWindow : WindowBase
|
||||||
{
|
{
|
||||||
@@ -1,169 +1,14 @@
|
|||||||
using CommandLine;
|
using CommandLine;
|
||||||
using Gommon;
|
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
|
||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace Ryujinx.Headless
|
namespace Ryujinx.Headless.SDL2
|
||||||
{
|
{
|
||||||
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; }
|
||||||
|
|
||||||
@@ -250,10 +95,10 @@ namespace Ryujinx.Headless
|
|||||||
[Option("hide-cursor", Required = false, Default = HideCursorMode.OnIdle, HelpText = "Change when the cursor gets hidden.")]
|
[Option("hide-cursor", Required = false, Default = HideCursorMode.OnIdle, HelpText = "Change when the cursor gets hidden.")]
|
||||||
public HideCursorMode HideCursorMode { get; set; }
|
public HideCursorMode HideCursorMode { get; set; }
|
||||||
|
|
||||||
[Option("list-input-profiles", Required = false, HelpText = "List input profiles.")]
|
[Option("list-input-profiles", Required = false, HelpText = "List inputs profiles.")]
|
||||||
public bool ListInputProfiles { get; set; }
|
public bool ListInputProfiles { get; set; }
|
||||||
|
|
||||||
[Option("list-input-ids", Required = false, HelpText = "List input IDs.")]
|
[Option("list-inputs-ids", Required = false, HelpText = "List inputs ids.")]
|
||||||
public bool ListInputIds { get; set; }
|
public bool ListInputIds { get; set; }
|
||||||
|
|
||||||
// System
|
// System
|
||||||
@@ -327,7 +172,7 @@ namespace Ryujinx.Headless
|
|||||||
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 LoggingDisableError { get; set; }
|
public bool LoggingEnableError { 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; }
|
||||||
@@ -370,7 +215,7 @@ namespace Ryujinx.Headless
|
|||||||
[Option("anti-aliasing", Required = false, Default = AntiAliasing.None, HelpText = "Set the type of anti aliasing being used. [None|Fxaa|SmaaLow|SmaaMedium|SmaaHigh|SmaaUltra]")]
|
[Option("anti-aliasing", Required = false, Default = AntiAliasing.None, HelpText = "Set the type of anti aliasing being used. [None|Fxaa|SmaaLow|SmaaMedium|SmaaHigh|SmaaUltra]")]
|
||||||
public AntiAliasing AntiAliasing { get; set; }
|
public AntiAliasing AntiAliasing { get; set; }
|
||||||
|
|
||||||
[Option("scaling-filter", Required = false, Default = ScalingFilter.Bilinear, HelpText = "Set the scaling filter. [Bilinear|Nearest|Fsr|Area]")]
|
[Option("scaling-filter", Required = false, Default = ScalingFilter.Bilinear, HelpText = "Set the scaling filter. [Bilinear|Nearest|Fsr]")]
|
||||||
public ScalingFilter ScalingFilter { get; set; }
|
public ScalingFilter ScalingFilter { get; set; }
|
||||||
|
|
||||||
[Option("scaling-filter-level", Required = false, Default = 0, HelpText = "Set the scaling filter intensity (currently only applies to FSR). [0-100]")]
|
[Option("scaling-filter-level", Required = false, Default = 0, HelpText = "Set the scaling filter intensity (currently only applies to FSR). [0-100]")]
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
using CommandLine;
|
using CommandLine;
|
||||||
using Gommon;
|
using Gommon;
|
||||||
using Ryujinx.Ava;
|
using LibHac.Tools.FsSystem;
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
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;
|
||||||
@@ -12,9 +15,16 @@ using Ryujinx.Common.SystemInterop;
|
|||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Cpu;
|
using Ryujinx.Cpu;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using Ryujinx.Graphics.GAL.Multithreading;
|
||||||
using Ryujinx.Graphics.Gpu;
|
using Ryujinx.Graphics.Gpu;
|
||||||
using Ryujinx.Graphics.Gpu.Shader;
|
using Ryujinx.Graphics.Gpu.Shader;
|
||||||
|
using Ryujinx.Graphics.Metal;
|
||||||
|
using Ryujinx.Graphics.OpenGL;
|
||||||
|
using Ryujinx.Graphics.Vulkan;
|
||||||
using Ryujinx.Graphics.Vulkan.MoltenVK;
|
using Ryujinx.Graphics.Vulkan.MoltenVK;
|
||||||
|
using Ryujinx.Headless.SDL2.Metal;
|
||||||
|
using Ryujinx.Headless.SDL2.OpenGL;
|
||||||
|
using Ryujinx.Headless.SDL2.Vulkan;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
@@ -23,15 +33,22 @@ using Ryujinx.Input;
|
|||||||
using Ryujinx.Input.HLE;
|
using Ryujinx.Input.HLE;
|
||||||
using Ryujinx.Input.SDL2;
|
using Ryujinx.Input.SDL2;
|
||||||
using Ryujinx.SDL2.Common;
|
using Ryujinx.SDL2.Common;
|
||||||
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
|
||||||
|
using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||||
|
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
||||||
|
|
||||||
namespace Ryujinx.Headless
|
namespace Ryujinx.Headless.SDL2
|
||||||
{
|
{
|
||||||
public partial class HeadlessRyujinx
|
class Program
|
||||||
{
|
{
|
||||||
|
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;
|
||||||
@@ -41,18 +58,20 @@ namespace Ryujinx.Headless
|
|||||||
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());
|
||||||
|
|
||||||
public static void Entrypoint(string[] args)
|
static void Main(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 {Program.Version} (Headless)";
|
Console.Title = $"Ryujinx Console {Version} (Headless SDL2)";
|
||||||
|
|
||||||
if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
|
if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
|
||||||
{
|
{
|
||||||
@@ -80,7 +99,7 @@ namespace Ryujinx.Headless
|
|||||||
}
|
}
|
||||||
|
|
||||||
Parser.Default.ParseArguments<Options>(args)
|
Parser.Default.ParseArguments<Options>(args)
|
||||||
.WithParsed(options => Load(args, options))
|
.WithParsed(Load)
|
||||||
.WithNotParsed(errors =>
|
.WithNotParsed(errors =>
|
||||||
{
|
{
|
||||||
Logger.Error?.PrintMsg(LogClass.Application, "Error parsing command-line arguments:");
|
Logger.Error?.PrintMsg(LogClass.Application, "Error parsing command-line arguments:");
|
||||||
@@ -89,80 +108,238 @@ namespace Ryujinx.Headless
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ReloadConfig(string customConfigPath = null)
|
private static InputConfig HandlePlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index)
|
||||||
{
|
{
|
||||||
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
|
if (inputId == null)
|
||||||
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
|
|
||||||
|
|
||||||
string configurationPath = null;
|
|
||||||
|
|
||||||
// Now load the configuration as the other subsystems are now registered
|
|
||||||
if (customConfigPath != null && File.Exists(customConfigPath))
|
|
||||||
{
|
{
|
||||||
configurationPath = customConfigPath;
|
if (index == PlayerIndex.Player1)
|
||||||
}
|
|
||||||
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
|
|
||||||
{
|
|
||||||
Logger.Notice.Print(LogClass.Application, $"Loading configuration from: {configurationPath}");
|
|
||||||
|
|
||||||
if (ConfigurationFileFormat.TryLoad(configurationPath, out ConfigurationFileFormat configurationFileFormat))
|
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.Load(configurationFileFormat, configurationPath);
|
Logger.Info?.Print(LogClass.Application, $"{index} not configured, defaulting to default keyboard.");
|
||||||
|
|
||||||
|
// Default to keyboard
|
||||||
|
inputId = "0";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Warning?.PrintMsg(LogClass.Application, $"Failed to load config! Loading the default config instead.\nFailed config location: {configurationPath}");
|
Logger.Info?.Print(LogClass.Application, $"{index} not configured");
|
||||||
|
|
||||||
ConfigurationState.Instance.LoadDefault();
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load(string[] originalArgs, Options option)
|
static void Load(Options option)
|
||||||
{
|
{
|
||||||
Initialize();
|
|
||||||
|
|
||||||
bool useLastUsedProfile = false;
|
|
||||||
|
|
||||||
if (option.InheritConfig)
|
|
||||||
{
|
|
||||||
option.InheritMainConfig(originalArgs, ConfigurationState.Instance, out useLastUsedProfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
AppDataManager.Initialize(option.BaseDataDir);
|
AppDataManager.Initialize(option.BaseDataDir);
|
||||||
|
|
||||||
if (useLastUsedProfile && AccountSaveDataManager.GetLastUsedUser().TryGet(out var profile))
|
|
||||||
option.UserProfile = profile.Name;
|
|
||||||
|
|
||||||
// Check if keys exists.
|
|
||||||
if (!File.Exists(Path.Combine(AppDataManager.KeysDirPath, "prod.keys")))
|
|
||||||
{
|
|
||||||
if (!(AppDataManager.Mode == AppDataManager.LaunchMode.UserProfile && File.Exists(Path.Combine(AppDataManager.KeysDirPathUser, "prod.keys"))))
|
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, "Keys not found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReloadConfig();
|
|
||||||
|
|
||||||
_virtualFileSystem = VirtualFileSystem.CreateInstance();
|
_virtualFileSystem = VirtualFileSystem.CreateInstance();
|
||||||
_libHacHorizonManager = new LibHacHorizonManager();
|
_libHacHorizonManager = new LibHacHorizonManager();
|
||||||
|
|
||||||
@@ -177,7 +354,7 @@ namespace Ryujinx.Headless
|
|||||||
|
|
||||||
_inputManager = new InputManager(new SDL2KeyboardDriver(), new SDL2GamepadDriver());
|
_inputManager = new InputManager(new SDL2KeyboardDriver(), new SDL2GamepadDriver());
|
||||||
|
|
||||||
GraphicsConfig.EnableShaderCache = !option.DisableShaderCache;
|
GraphicsConfig.EnableShaderCache = true;
|
||||||
|
|
||||||
if (OperatingSystem.IsMacOS())
|
if (OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
@@ -188,13 +365,15 @@ namespace Ryujinx.Headless
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
IGamepad gamepad = _inputManager.KeyboardDriver.GetGamepad(id);
|
gamepad = _inputManager.KeyboardDriver.GetGamepad(id);
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")");
|
Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")");
|
||||||
|
|
||||||
@@ -203,7 +382,7 @@ namespace Ryujinx.Headless
|
|||||||
|
|
||||||
foreach (string id in _inputManager.GamepadDriver.GamepadsIds)
|
foreach (string id in _inputManager.GamepadDriver.GamepadsIds)
|
||||||
{
|
{
|
||||||
IGamepad gamepad = _inputManager.GamepadDriver.GetGamepad(id);
|
gamepad = _inputManager.GamepadDriver.GetGamepad(id);
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")");
|
Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")");
|
||||||
|
|
||||||
@@ -220,7 +399,7 @@ namespace Ryujinx.Headless
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_inputConfiguration ??= [];
|
_inputConfiguration = new List<InputConfig>();
|
||||||
_enableKeyboard = option.EnableKeyboard;
|
_enableKeyboard = option.EnableKeyboard;
|
||||||
_enableMouse = option.EnableMouse;
|
_enableMouse = option.EnableMouse;
|
||||||
|
|
||||||
@@ -244,7 +423,6 @@ namespace Ryujinx.Headless
|
|||||||
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;
|
||||||
@@ -255,7 +433,7 @@ namespace Ryujinx.Headless
|
|||||||
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.LoggingDisableError);
|
Logger.SetEnable(LogLevel.Error, option.LoggingEnableError);
|
||||||
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);
|
||||||
@@ -344,6 +522,88 @@ namespace Ryujinx.Headless
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IRenderer CreateRenderer(Options options, WindowBase window)
|
||||||
|
{
|
||||||
|
if (options.GraphicsBackend == GraphicsBackend.Vulkan && window is VulkanWindow vulkanWindow)
|
||||||
|
{
|
||||||
|
string preferredGpuId = string.Empty;
|
||||||
|
Vk api = Vk.GetApi();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(options.PreferredGPUVendor))
|
||||||
|
{
|
||||||
|
string preferredGpuVendor = options.PreferredGPUVendor.ToLowerInvariant();
|
||||||
|
var devices = VulkanRenderer.GetPhysicalDevices(api);
|
||||||
|
|
||||||
|
foreach (var device in devices)
|
||||||
|
{
|
||||||
|
if (device.Vendor.ToLowerInvariant() == preferredGpuVendor)
|
||||||
|
{
|
||||||
|
preferredGpuId = device.Id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VulkanRenderer(
|
||||||
|
api,
|
||||||
|
(instance, vk) => new SurfaceKHR((ulong)(vulkanWindow.CreateWindowSurface(instance.Handle))),
|
||||||
|
vulkanWindow.GetRequiredInstanceExtensions,
|
||||||
|
preferredGpuId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.GraphicsBackend == GraphicsBackend.Metal && window is MetalWindow metalWindow && OperatingSystem.IsMacOS())
|
||||||
|
{
|
||||||
|
return new MetalRenderer(metalWindow.GetLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OpenGLRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options)
|
||||||
|
{
|
||||||
|
BackendThreading threadingMode = options.BackendThreading;
|
||||||
|
|
||||||
|
bool threadedGAL = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading);
|
||||||
|
|
||||||
|
if (threadedGAL)
|
||||||
|
{
|
||||||
|
renderer = new ThreadedRenderer(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
HLEConfiguration configuration = new(_virtualFileSystem,
|
||||||
|
_libHacHorizonManager,
|
||||||
|
_contentManager,
|
||||||
|
_accountManager,
|
||||||
|
_userChannelPersistence,
|
||||||
|
renderer,
|
||||||
|
new SDL2HardwareDeviceDriver(),
|
||||||
|
options.DramSize,
|
||||||
|
window,
|
||||||
|
options.SystemLanguage,
|
||||||
|
options.SystemRegion,
|
||||||
|
options.VSyncMode,
|
||||||
|
!options.DisableDockedMode,
|
||||||
|
!options.DisablePTC,
|
||||||
|
options.EnableInternetAccess,
|
||||||
|
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
|
||||||
|
options.FsGlobalAccessLogMode,
|
||||||
|
options.SystemTimeOffset,
|
||||||
|
options.SystemTimeZone,
|
||||||
|
options.MemoryManagerMode,
|
||||||
|
options.IgnoreMissingServices,
|
||||||
|
options.AspectRatio,
|
||||||
|
options.AudioVolume,
|
||||||
|
options.UseHypervisor ?? true,
|
||||||
|
options.MultiplayerLanInterfaceId,
|
||||||
|
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
|
||||||
|
false,
|
||||||
|
string.Empty,
|
||||||
|
string.Empty,
|
||||||
|
options.CustomVSyncInterval);
|
||||||
|
|
||||||
|
return new Switch(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
private static void ExecutionEntrypoint()
|
private static void ExecutionEntrypoint()
|
||||||
{
|
{
|
||||||
if (OperatingSystem.IsWindows())
|
if (OperatingSystem.IsWindows())
|
||||||
73
src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj
Normal file
73
src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<Version>1.0.0-dirty</Version>
|
||||||
|
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
|
||||||
|
<SigningCertificate Condition=" '$(SigningCertificate)' == '' ">-</SigningCertificate>
|
||||||
|
<TieredPGO>true</TieredPGO>
|
||||||
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="OpenTK.Core" />
|
||||||
|
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
|
||||||
|
<Exec Command="codesign --entitlements '$(ProjectDir)..\..\distribution\macos\entitlements.xml' -f -s $(SigningCertificate) '$(TargetDir)$(TargetName)'" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj" />
|
||||||
|
<ProjectReference Include="..\Ryujinx.Input\Ryujinx.Input.csproj" />
|
||||||
|
<ProjectReference Include="..\Ryujinx.Input.SDL2\Ryujinx.Input.SDL2.csproj" />
|
||||||
|
<ProjectReference Include="..\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj" />
|
||||||
|
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
|
||||||
|
<ProjectReference Include="..\Ryujinx.HLE\Ryujinx.HLE.csproj" />
|
||||||
|
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
|
||||||
|
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" />
|
||||||
|
<ProjectReference Include="..\Ryujinx.Graphics.Metal\Ryujinx.Graphics.Metal.csproj" />
|
||||||
|
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CommandLineParser" />
|
||||||
|
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="..\..\distribution\legal\THIRDPARTY.md">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
<TargetPath>THIRDPARTY.md</TargetPath>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\LICENSE.txt">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
<TargetPath>LICENSE.txt</TargetPath>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'linux-x64' OR '$(RuntimeIdentifier)' == 'linux-arm64' OR ('$(RuntimeIdentifier)' == '' AND $([MSBuild]::IsOSPlatform('Linux')))">
|
||||||
|
<Content Include="..\..\distribution\linux\Ryujinx.sh">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Ryujinx.bmp" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!-- Due to .net core 3.1 embedded resource loading -->
|
||||||
|
<PropertyGroup>
|
||||||
|
<EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
|
||||||
|
<ApplicationIcon>..\Ryujinx\Ryujinx.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
|
||||||
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
|
<PublishTrimmed>true</PublishTrimmed>
|
||||||
|
<TrimMode>partial</TrimMode>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
BIN
src/Ryujinx.Headless.SDL2/Ryujinx.bmp
Normal file
BIN
src/Ryujinx.Headless.SDL2/Ryujinx.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.1 KiB |
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Headless
|
namespace Ryujinx.Headless.SDL2
|
||||||
{
|
{
|
||||||
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
|
namespace Ryujinx.Headless.SDL2.Vulkan
|
||||||
{
|
{
|
||||||
class VulkanWindow : WindowBase
|
class VulkanWindow : WindowBase
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
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;
|
||||||
@@ -27,7 +26,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
|
namespace Ryujinx.Headless.SDL2
|
||||||
{
|
{
|
||||||
abstract partial class WindowBase : IHostUIHandler, IDisposable
|
abstract partial class WindowBase : IHostUIHandler, IDisposable
|
||||||
{
|
{
|
||||||
@@ -137,7 +136,7 @@ namespace Ryujinx.Headless
|
|||||||
|
|
||||||
private void SetWindowIcon()
|
private void SetWindowIcon()
|
||||||
{
|
{
|
||||||
Stream iconStream = typeof(Program).Assembly.GetManifestResourceStream("HeadlessLogo");
|
Stream iconStream = typeof(WindowBase).Assembly.GetManifestResourceStream("Ryujinx.Headless.SDL2.Ryujinx.bmp");
|
||||||
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)
|
||||||
@@ -255,12 +254,12 @@ namespace Ryujinx.Headless
|
|||||||
|
|
||||||
private void SetAntiAliasing()
|
private void SetAntiAliasing()
|
||||||
{
|
{
|
||||||
Renderer?.Window.SetAntiAliasing(AntiAliasing);
|
Renderer?.Window.SetAntiAliasing((Graphics.GAL.AntiAliasing)AntiAliasing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetScalingFilter()
|
private void SetScalingFilter()
|
||||||
{
|
{
|
||||||
Renderer?.Window.SetScalingFilter(ScalingFilter);
|
Renderer?.Window.SetScalingFilter((Graphics.GAL.ScalingFilter)ScalingFilter);
|
||||||
Renderer?.Window.SetScalingFilterLevel(ScalingFilterLevel);
|
Renderer?.Window.SetScalingFilterLevel(ScalingFilterLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +318,7 @@ namespace Ryujinx.Headless
|
|||||||
Device.VSyncMode.ToString(),
|
Device.VSyncMode.ToString(),
|
||||||
dockedMode,
|
dockedMode,
|
||||||
Device.Configuration.AspectRatio.ToText(),
|
Device.Configuration.AspectRatio.ToText(),
|
||||||
$"{Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)",
|
$"Game: {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}"));
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.UI.App.Common
|
||||||
{
|
{
|
||||||
public class ApplicationCountUpdatedEventArgs : EventArgs
|
public class ApplicationCountUpdatedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
@@ -10,14 +10,17 @@ using LibHac.Tools.FsSystem.NcaUtils;
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
||||||
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.UI.App.Common
|
||||||
{
|
{
|
||||||
public class ApplicationData
|
public class ApplicationData
|
||||||
{
|
{
|
||||||
|
public static Func<string> LocalizedNever { get; set; } = () => "Never";
|
||||||
|
|
||||||
public bool Favorite { get; set; }
|
public bool Favorite { get; set; }
|
||||||
public byte[] Icon { get; set; }
|
public byte[] Icon { get; set; }
|
||||||
public string Name { get; set; } = "Unknown";
|
public string Name { get; set; } = "Unknown";
|
||||||
@@ -33,11 +36,9 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
|
public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
|
||||||
|
|
||||||
public bool HasControlHolder => ControlHolder.ByteSpan.Length > 0 && !ControlHolder.ByteSpan.IsZeros();
|
|
||||||
|
|
||||||
public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
|
public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);
|
||||||
|
|
||||||
public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n");
|
public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed)?.Replace(" ", "\n") ?? LocalizedNever();
|
||||||
|
|
||||||
public string FileSizeString => ValueFormatUtils.FormatFileSize(FileSize);
|
public string FileSizeString => ValueFormatUtils.FormatFileSize(FileSize);
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.UI.App.Common
|
||||||
{
|
{
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
[JsonSerializable(typeof(ApplicationMetadata))]
|
[JsonSerializable(typeof(ApplicationMetadata))]
|
||||||
@@ -10,10 +10,6 @@ using LibHac.Ns;
|
|||||||
using LibHac.Tools.Fs;
|
using LibHac.Tools.Fs;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
using Ryujinx.Ava.Common.Models;
|
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
|
||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
|
||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Multiplayer;
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
@@ -23,11 +19,16 @@ using Ryujinx.HLE.HOS.SystemState;
|
|||||||
using Ryujinx.HLE.Loaders.Npdm;
|
using Ryujinx.HLE.Loaders.Npdm;
|
||||||
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
||||||
using Ryujinx.HLE.Utilities;
|
using Ryujinx.HLE.Utilities;
|
||||||
|
using Ryujinx.UI.Common.Configuration;
|
||||||
|
using Ryujinx.UI.Common.Configuration.System;
|
||||||
|
using Ryujinx.UI.Common.Helper;
|
||||||
|
using Ryujinx.UI.Common.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -37,7 +38,7 @@ using MissingKeyException = LibHac.Common.Keys.MissingKeyException;
|
|||||||
using Path = System.IO.Path;
|
using Path = System.IO.Path;
|
||||||
using TimeSpan = System.TimeSpan;
|
using TimeSpan = System.TimeSpan;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.UI.App.Common
|
||||||
{
|
{
|
||||||
public class ApplicationLibrary
|
public class ApplicationLibrary
|
||||||
{
|
{
|
||||||
@@ -75,11 +76,21 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
TitleUpdates = _titleUpdates.AsObservableCache();
|
TitleUpdates = _titleUpdates.AsObservableCache();
|
||||||
DownloadableContents = _downloadableContents.AsObservableCache();
|
DownloadableContents = _downloadableContents.AsObservableCache();
|
||||||
|
|
||||||
_nspIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NSP.png");
|
_nspIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NSP.png");
|
||||||
_xciIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_XCI.png");
|
_xciIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_XCI.png");
|
||||||
_ncaIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NCA.png");
|
_ncaIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NCA.png");
|
||||||
_nroIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NRO.png");
|
_nroIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NRO.png");
|
||||||
_nsoIcon = EmbeddedResources.Read("Ryujinx/Assets.UIImages.Icon_NSO.png");
|
_nsoIcon = GetResourceBytes("Ryujinx.UI.Common.Resources.Icon_NSO.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] GetResourceBytes(string resourceName)
|
||||||
|
{
|
||||||
|
Stream resourceStream = Assembly.GetCallingAssembly().GetManifestResourceStream(resourceName)!;
|
||||||
|
byte[] resourceByteArray = new byte[resourceStream.Length];
|
||||||
|
|
||||||
|
resourceStream.ReadExactly(resourceByteArray);
|
||||||
|
|
||||||
|
return resourceByteArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <exception cref="Ryujinx.HLE.Exceptions.InvalidNpdmException">The npdm file doesn't contain valid data.</exception>
|
/// <exception cref="Ryujinx.HLE.Exceptions.InvalidNpdmException">The npdm file doesn't contain valid data.</exception>
|
||||||
@@ -778,15 +789,16 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
using HttpClient httpClient = new HttpClient();
|
using HttpClient httpClient = new HttpClient();
|
||||||
string ldnGameDataArrayString = await httpClient.GetStringAsync($"https://{ldnWebHost}/api/public_games");
|
string ldnGameDataArrayString = await httpClient.GetStringAsync($"https://{ldnWebHost}/api/public_games");
|
||||||
ldnGameDataArray = JsonHelper.Deserialize(ldnGameDataArrayString, _ldnDataSerializerContext.IEnumerableLdnGameData);
|
ldnGameDataArray = JsonHelper.Deserialize(ldnGameDataArrayString, _ldnDataSerializerContext.IEnumerableLdnGameData);
|
||||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
|
var evt = new LdnGameDataReceivedEventArgs
|
||||||
{
|
{
|
||||||
LdnData = ldnGameDataArray
|
LdnData = ldnGameDataArray
|
||||||
});
|
};
|
||||||
|
LdnGameDataReceived?.Invoke(null, evt);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Application, $"Failed to fetch the public games JSON from the API. Player and game count in the game list will be unavailable.\n{ex.Message}");
|
Logger.Warning?.Print(LogClass.Application, $"Failed to fetch the public games JSON from the API. Player and game count in the game list will be unavailable.\n{ex.Message}");
|
||||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
|
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs()
|
||||||
{
|
{
|
||||||
LdnData = Array.Empty<LdnGameData>()
|
LdnData = Array.Empty<LdnGameData>()
|
||||||
});
|
});
|
||||||
@@ -794,7 +806,7 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs
|
LdnGameDataReceived?.Invoke(null, new LdnGameDataReceivedEventArgs()
|
||||||
{
|
{
|
||||||
LdnData = Array.Empty<LdnGameData>()
|
LdnData = Array.Empty<LdnGameData>()
|
||||||
});
|
});
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.UI.App.Common
|
||||||
{
|
{
|
||||||
public class ApplicationMetadata
|
public class ApplicationMetadata
|
||||||
{
|
{
|
||||||
16
src/Ryujinx.UI.Common/App/LdnGameData.cs
Normal file
16
src/Ryujinx.UI.Common/App/LdnGameData.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ryujinx.UI.App.Common
|
||||||
|
{
|
||||||
|
public struct LdnGameData
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public int PlayerCount { get; set; }
|
||||||
|
public int MaxPlayerCount { get; set; }
|
||||||
|
public string GameName { get; set; }
|
||||||
|
public string TitleId { get; set; }
|
||||||
|
public string Mode { get; set; }
|
||||||
|
public string Status { get; set; }
|
||||||
|
public IEnumerable<string> Players { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.UI.App.Common
|
||||||
{
|
{
|
||||||
public class LdnGameDataReceivedEventArgs : EventArgs
|
public class LdnGameDataReceivedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.AppLibrary
|
namespace Ryujinx.UI.App.Common
|
||||||
{
|
{
|
||||||
[JsonSerializable(typeof(IEnumerable<LdnGameData>))]
|
[JsonSerializable(typeof(IEnumerable<LdnGameData>))]
|
||||||
internal partial class LdnGameDataSerializerContext : JsonSerializerContext;
|
internal partial class LdnGameDataSerializerContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.UI.Common.Configuration
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(TypedStringEnumConverter<AudioBackend>))]
|
[JsonConverter(typeof(TypedStringEnumConverter<AudioBackend>))]
|
||||||
public enum AudioBackend
|
public enum AudioBackend
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
|
||||||
using Ryujinx.Ava.Utilities.Configuration.UI;
|
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
@@ -7,17 +5,19 @@ using Ryujinx.Common.Configuration.Multiplayer;
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
|
using Ryujinx.UI.Common.Configuration.System;
|
||||||
|
using Ryujinx.UI.Common.Configuration.UI;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.UI.Common.Configuration
|
||||||
{
|
{
|
||||||
public class ConfigurationFileFormat
|
public class ConfigurationFileFormat
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current version of the file format
|
/// The current version of the file format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CurrentVersion = 59;
|
public const int CurrentVersion = 57;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the configuration file format
|
/// Version of the configuration file format
|
||||||
@@ -272,7 +272,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
public MemoryManagerMode MemoryManagerMode { get; set; }
|
public MemoryManagerMode MemoryManagerMode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Expands the RAM amount on the emulated system
|
/// Expands the RAM amount on the emulated system from 4GiB to 8GiB
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MemoryConfiguration DramSize { get; set; }
|
public MemoryConfiguration DramSize { get; set; }
|
||||||
|
|
||||||
@@ -430,16 +430,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool UseHypervisor { get; set; }
|
public bool UseHypervisor { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Show toggles for dirty hacks in the UI.
|
|
||||||
/// </summary>
|
|
||||||
public bool ShowDirtyHacks { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The packed values of the enabled dirty hacks.
|
|
||||||
/// </summary>
|
|
||||||
public ulong[] DirtyHacks { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads a configuration file from disk
|
/// Loads a configuration file from disk
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.UI.Common.Configuration
|
||||||
{
|
{
|
||||||
internal static class ConfigurationFileFormatSettings
|
internal static class ConfigurationFileFormatSettings
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.UI.Common.Configuration
|
||||||
{
|
{
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
[JsonSerializable(typeof(ConfigurationFileFormat))]
|
[JsonSerializable(typeof(ConfigurationFileFormat))]
|
||||||
internal partial class ConfigurationJsonSerializerContext : JsonSerializerContext;
|
internal partial class ConfigurationJsonSerializerContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,747 @@
|
|||||||
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
|
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||||
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.HLE;
|
||||||
|
using Ryujinx.UI.Common.Configuration.System;
|
||||||
|
using Ryujinx.UI.Common.Configuration.UI;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ryujinx.UI.Common.Configuration
|
||||||
|
{
|
||||||
|
public partial class ConfigurationState
|
||||||
|
{
|
||||||
|
public void Load(ConfigurationFileFormat configurationFileFormat, string configurationFilePath)
|
||||||
|
{
|
||||||
|
bool configurationFileUpdated = false;
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version is < 0 or > ConfigurationFileFormat.CurrentVersion)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Unsupported configuration version {configurationFileFormat.Version}, loading default.");
|
||||||
|
|
||||||
|
LoadDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 2)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 2.");
|
||||||
|
|
||||||
|
configurationFileFormat.SystemRegion = Region.USA;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 3)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 3.");
|
||||||
|
|
||||||
|
configurationFileFormat.SystemTimeZone = "UTC";
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 4)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 4.");
|
||||||
|
|
||||||
|
configurationFileFormat.MaxAnisotropy = -1;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 5)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 5.");
|
||||||
|
|
||||||
|
configurationFileFormat.SystemTimeOffset = 0;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 8)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 8.");
|
||||||
|
|
||||||
|
configurationFileFormat.EnablePtc = true;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 9)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 9.");
|
||||||
|
|
||||||
|
configurationFileFormat.ColumnSort = new ColumnSort
|
||||||
|
{
|
||||||
|
SortColumnId = 0,
|
||||||
|
SortAscending = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVSyncMode = Key.F1,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 10)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 10.");
|
||||||
|
|
||||||
|
configurationFileFormat.AudioBackend = AudioBackend.OpenAl;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 11)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 11.");
|
||||||
|
|
||||||
|
configurationFileFormat.ResScale = 1;
|
||||||
|
configurationFileFormat.ResScaleCustom = 1.0f;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 12)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 12.");
|
||||||
|
|
||||||
|
configurationFileFormat.LoggingGraphicsDebugLevel = GraphicsDebugLevel.None;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// configurationFileFormat.Version == 13 -> LDN1
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 14)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 14.");
|
||||||
|
|
||||||
|
configurationFileFormat.CheckUpdatesOnStart = true;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 16)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 16.");
|
||||||
|
|
||||||
|
configurationFileFormat.EnableShaderCache = true;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 17)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 17.");
|
||||||
|
|
||||||
|
configurationFileFormat.StartFullscreen = false;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 18)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 18.");
|
||||||
|
|
||||||
|
configurationFileFormat.AspectRatio = AspectRatio.Fixed16x9;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// configurationFileFormat.Version == 19 -> LDN2
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 20)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 20.");
|
||||||
|
|
||||||
|
configurationFileFormat.ShowConfirmExit = true;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 21)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 21.");
|
||||||
|
|
||||||
|
// Initialize network config.
|
||||||
|
|
||||||
|
configurationFileFormat.MultiplayerMode = MultiplayerMode.Disabled;
|
||||||
|
configurationFileFormat.MultiplayerLanInterfaceId = "0";
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 22)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 22.");
|
||||||
|
|
||||||
|
configurationFileFormat.HideCursor = HideCursorMode.Never;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 24)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 24.");
|
||||||
|
|
||||||
|
configurationFileFormat.InputConfig = new List<InputConfig>
|
||||||
|
{
|
||||||
|
new StandardKeyboardInputConfig
|
||||||
|
{
|
||||||
|
Version = InputConfig.CurrentVersion,
|
||||||
|
Backend = InputBackendType.WindowKeyboard,
|
||||||
|
Id = "0",
|
||||||
|
PlayerIndex = PlayerIndex.Player1,
|
||||||
|
ControllerType = ControllerType.ProController,
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 25)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 25.");
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 26)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 26.");
|
||||||
|
|
||||||
|
configurationFileFormat.MemoryManagerMode = MemoryManagerMode.HostMappedUnsafe;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 27)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 27.");
|
||||||
|
|
||||||
|
configurationFileFormat.EnableMouse = false;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 28)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 28.");
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVSyncMode = Key.F1,
|
||||||
|
Screenshot = Key.F8,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 29)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 29.");
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVSyncMode = Key.F1,
|
||||||
|
Screenshot = Key.F8,
|
||||||
|
ShowUI = Key.F4,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 30)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 30.");
|
||||||
|
|
||||||
|
foreach (InputConfig config in configurationFileFormat.InputConfig)
|
||||||
|
{
|
||||||
|
if (config is StandardControllerInputConfig controllerConfig)
|
||||||
|
{
|
||||||
|
controllerConfig.Rumble = new RumbleConfigController
|
||||||
|
{
|
||||||
|
EnableRumble = false,
|
||||||
|
StrongRumble = 1f,
|
||||||
|
WeakRumble = 1f,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 31)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 31.");
|
||||||
|
|
||||||
|
configurationFileFormat.BackendThreading = BackendThreading.Auto;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 32)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 32.");
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
||||||
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
|
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
||||||
|
Pause = Key.F5,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 33)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 33.");
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
||||||
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
|
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
||||||
|
Pause = configurationFileFormat.Hotkeys.Pause,
|
||||||
|
ToggleMute = Key.F2,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileFormat.AudioVolume = 1;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 34)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 34.");
|
||||||
|
|
||||||
|
configurationFileFormat.EnableInternetAccess = false;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 35)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 35.");
|
||||||
|
|
||||||
|
foreach (InputConfig config in configurationFileFormat.InputConfig)
|
||||||
|
{
|
||||||
|
if (config is StandardControllerInputConfig controllerConfig)
|
||||||
|
{
|
||||||
|
controllerConfig.RangeLeft = 1.0f;
|
||||||
|
controllerConfig.RangeRight = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 36)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 36.");
|
||||||
|
|
||||||
|
configurationFileFormat.LoggingEnableTrace = false;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 37)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 37.");
|
||||||
|
|
||||||
|
configurationFileFormat.ShowConsole = true;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 38)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 38.");
|
||||||
|
|
||||||
|
configurationFileFormat.BaseStyle = "Dark";
|
||||||
|
configurationFileFormat.GameListViewMode = 0;
|
||||||
|
configurationFileFormat.ShowNames = true;
|
||||||
|
configurationFileFormat.GridSize = 2;
|
||||||
|
configurationFileFormat.LanguageCode = "en_US";
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 39)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 39.");
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
||||||
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
|
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
||||||
|
Pause = configurationFileFormat.Hotkeys.Pause,
|
||||||
|
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
|
||||||
|
ResScaleUp = Key.Unbound,
|
||||||
|
ResScaleDown = Key.Unbound,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 40)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 40.");
|
||||||
|
|
||||||
|
configurationFileFormat.GraphicsBackend = GraphicsBackend.OpenGl;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 41)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 41.");
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
||||||
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
|
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
||||||
|
Pause = configurationFileFormat.Hotkeys.Pause,
|
||||||
|
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
|
||||||
|
ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
|
||||||
|
ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
|
||||||
|
VolumeUp = Key.Unbound,
|
||||||
|
VolumeDown = Key.Unbound,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 42)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 42.");
|
||||||
|
|
||||||
|
configurationFileFormat.EnableMacroHLE = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 43)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 43.");
|
||||||
|
|
||||||
|
configurationFileFormat.UseHypervisor = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 44)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 44.");
|
||||||
|
|
||||||
|
configurationFileFormat.AntiAliasing = AntiAliasing.None;
|
||||||
|
configurationFileFormat.ScalingFilter = ScalingFilter.Bilinear;
|
||||||
|
configurationFileFormat.ScalingFilterLevel = 80;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 45)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 45.");
|
||||||
|
|
||||||
|
configurationFileFormat.ShownFileTypes = new ShownFileTypes
|
||||||
|
{
|
||||||
|
NSP = true,
|
||||||
|
PFS0 = true,
|
||||||
|
XCI = true,
|
||||||
|
NCA = true,
|
||||||
|
NRO = true,
|
||||||
|
NSO = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 46)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 46.");
|
||||||
|
|
||||||
|
configurationFileFormat.MultiplayerLanInterfaceId = "0";
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 47)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 47.");
|
||||||
|
|
||||||
|
configurationFileFormat.WindowStartup = new WindowStartup
|
||||||
|
{
|
||||||
|
WindowPositionX = 0,
|
||||||
|
WindowPositionY = 0,
|
||||||
|
WindowSizeHeight = 760,
|
||||||
|
WindowSizeWidth = 1280,
|
||||||
|
WindowMaximized = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 48)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 48.");
|
||||||
|
|
||||||
|
configurationFileFormat.EnableColorSpacePassthrough = false;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 49)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 49.");
|
||||||
|
|
||||||
|
if (OperatingSystem.IsMacOS())
|
||||||
|
{
|
||||||
|
AppDataManager.FixMacOSConfigurationFolders();
|
||||||
|
}
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 50)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 50.");
|
||||||
|
|
||||||
|
configurationFileFormat.EnableHardwareAcceleration = true;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 51)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 51.");
|
||||||
|
|
||||||
|
configurationFileFormat.RememberWindowState = true;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 52)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 52.");
|
||||||
|
|
||||||
|
configurationFileFormat.AutoloadDirs = [];
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 53)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 53.");
|
||||||
|
|
||||||
|
configurationFileFormat.EnableLowPowerPtc = false;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 54)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 54.");
|
||||||
|
|
||||||
|
configurationFileFormat.DramSize = MemoryConfiguration.MemoryConfiguration4GiB;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 55)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 55.");
|
||||||
|
|
||||||
|
configurationFileFormat.IgnoreApplet = false;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 56)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 56.");
|
||||||
|
|
||||||
|
configurationFileFormat.ShowTitleBar = !OperatingSystem.IsWindows();
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 57)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 57.");
|
||||||
|
|
||||||
|
configurationFileFormat.VSyncMode = VSyncMode.Switch;
|
||||||
|
configurationFileFormat.EnableCustomVSyncInterval = false;
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVSyncMode = Key.F1,
|
||||||
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
|
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
||||||
|
Pause = configurationFileFormat.Hotkeys.Pause,
|
||||||
|
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
|
||||||
|
ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
|
||||||
|
ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
|
||||||
|
VolumeUp = configurationFileFormat.Hotkeys.VolumeUp,
|
||||||
|
VolumeDown = configurationFileFormat.Hotkeys.VolumeDown,
|
||||||
|
CustomVSyncIntervalIncrement = Key.Unbound,
|
||||||
|
CustomVSyncIntervalDecrement = Key.Unbound,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileFormat.CustomVSyncInterval = 120;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
||||||
|
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
||||||
|
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
||||||
|
Graphics.MaxAnisotropy.Value = configurationFileFormat.MaxAnisotropy;
|
||||||
|
Graphics.AspectRatio.Value = configurationFileFormat.AspectRatio;
|
||||||
|
Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath;
|
||||||
|
Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading;
|
||||||
|
Graphics.GraphicsBackend.Value = configurationFileFormat.GraphicsBackend;
|
||||||
|
Graphics.PreferredGpu.Value = configurationFileFormat.PreferredGpu;
|
||||||
|
Graphics.AntiAliasing.Value = configurationFileFormat.AntiAliasing;
|
||||||
|
Graphics.ScalingFilter.Value = configurationFileFormat.ScalingFilter;
|
||||||
|
Graphics.ScalingFilterLevel.Value = configurationFileFormat.ScalingFilterLevel;
|
||||||
|
Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug;
|
||||||
|
Logger.EnableStub.Value = configurationFileFormat.LoggingEnableStub;
|
||||||
|
Logger.EnableInfo.Value = configurationFileFormat.LoggingEnableInfo;
|
||||||
|
Logger.EnableWarn.Value = configurationFileFormat.LoggingEnableWarn;
|
||||||
|
Logger.EnableError.Value = configurationFileFormat.LoggingEnableError;
|
||||||
|
Logger.EnableTrace.Value = configurationFileFormat.LoggingEnableTrace;
|
||||||
|
Logger.EnableGuest.Value = configurationFileFormat.LoggingEnableGuest;
|
||||||
|
Logger.EnableFsAccessLog.Value = configurationFileFormat.LoggingEnableFsAccessLog;
|
||||||
|
Logger.FilteredClasses.Value = configurationFileFormat.LoggingFilteredClasses;
|
||||||
|
Logger.GraphicsDebugLevel.Value = configurationFileFormat.LoggingGraphicsDebugLevel;
|
||||||
|
System.Language.Value = configurationFileFormat.SystemLanguage;
|
||||||
|
System.Region.Value = configurationFileFormat.SystemRegion;
|
||||||
|
System.TimeZone.Value = configurationFileFormat.SystemTimeZone;
|
||||||
|
System.SystemTimeOffset.Value = configurationFileFormat.SystemTimeOffset;
|
||||||
|
System.EnableDockedMode.Value = configurationFileFormat.DockedMode;
|
||||||
|
EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
|
||||||
|
CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart;
|
||||||
|
ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit;
|
||||||
|
IgnoreApplet.Value = configurationFileFormat.IgnoreApplet;
|
||||||
|
RememberWindowState.Value = configurationFileFormat.RememberWindowState;
|
||||||
|
ShowTitleBar.Value = configurationFileFormat.ShowTitleBar;
|
||||||
|
EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration;
|
||||||
|
HideCursor.Value = configurationFileFormat.HideCursor;
|
||||||
|
Graphics.VSyncMode.Value = configurationFileFormat.VSyncMode;
|
||||||
|
Graphics.EnableCustomVSyncInterval.Value = configurationFileFormat.EnableCustomVSyncInterval;
|
||||||
|
Graphics.CustomVSyncInterval.Value = configurationFileFormat.CustomVSyncInterval;
|
||||||
|
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
|
||||||
|
Graphics.EnableTextureRecompression.Value = configurationFileFormat.EnableTextureRecompression;
|
||||||
|
Graphics.EnableMacroHLE.Value = configurationFileFormat.EnableMacroHLE;
|
||||||
|
Graphics.EnableColorSpacePassthrough.Value = configurationFileFormat.EnableColorSpacePassthrough;
|
||||||
|
System.EnablePtc.Value = configurationFileFormat.EnablePtc;
|
||||||
|
System.EnableLowPowerPtc.Value = configurationFileFormat.EnableLowPowerPtc;
|
||||||
|
System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess;
|
||||||
|
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
|
||||||
|
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
|
||||||
|
System.AudioBackend.Value = configurationFileFormat.AudioBackend;
|
||||||
|
System.AudioVolume.Value = configurationFileFormat.AudioVolume;
|
||||||
|
System.MemoryManagerMode.Value = configurationFileFormat.MemoryManagerMode;
|
||||||
|
System.DramSize.Value = configurationFileFormat.DramSize;
|
||||||
|
System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices;
|
||||||
|
System.UseHypervisor.Value = configurationFileFormat.UseHypervisor;
|
||||||
|
UI.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn;
|
||||||
|
UI.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn;
|
||||||
|
UI.GuiColumns.AppColumn.Value = configurationFileFormat.GuiColumns.AppColumn;
|
||||||
|
UI.GuiColumns.DevColumn.Value = configurationFileFormat.GuiColumns.DevColumn;
|
||||||
|
UI.GuiColumns.VersionColumn.Value = configurationFileFormat.GuiColumns.VersionColumn;
|
||||||
|
UI.GuiColumns.TimePlayedColumn.Value = configurationFileFormat.GuiColumns.TimePlayedColumn;
|
||||||
|
UI.GuiColumns.LastPlayedColumn.Value = configurationFileFormat.GuiColumns.LastPlayedColumn;
|
||||||
|
UI.GuiColumns.FileExtColumn.Value = configurationFileFormat.GuiColumns.FileExtColumn;
|
||||||
|
UI.GuiColumns.FileSizeColumn.Value = configurationFileFormat.GuiColumns.FileSizeColumn;
|
||||||
|
UI.GuiColumns.PathColumn.Value = configurationFileFormat.GuiColumns.PathColumn;
|
||||||
|
UI.ColumnSort.SortColumnId.Value = configurationFileFormat.ColumnSort.SortColumnId;
|
||||||
|
UI.ColumnSort.SortAscending.Value = configurationFileFormat.ColumnSort.SortAscending;
|
||||||
|
UI.GameDirs.Value = configurationFileFormat.GameDirs;
|
||||||
|
UI.AutoloadDirs.Value = configurationFileFormat.AutoloadDirs ?? [];
|
||||||
|
UI.ShownFileTypes.NSP.Value = configurationFileFormat.ShownFileTypes.NSP;
|
||||||
|
UI.ShownFileTypes.PFS0.Value = configurationFileFormat.ShownFileTypes.PFS0;
|
||||||
|
UI.ShownFileTypes.XCI.Value = configurationFileFormat.ShownFileTypes.XCI;
|
||||||
|
UI.ShownFileTypes.NCA.Value = configurationFileFormat.ShownFileTypes.NCA;
|
||||||
|
UI.ShownFileTypes.NRO.Value = configurationFileFormat.ShownFileTypes.NRO;
|
||||||
|
UI.ShownFileTypes.NSO.Value = configurationFileFormat.ShownFileTypes.NSO;
|
||||||
|
UI.LanguageCode.Value = configurationFileFormat.LanguageCode;
|
||||||
|
UI.BaseStyle.Value = configurationFileFormat.BaseStyle;
|
||||||
|
UI.GameListViewMode.Value = configurationFileFormat.GameListViewMode;
|
||||||
|
UI.ShowNames.Value = configurationFileFormat.ShowNames;
|
||||||
|
UI.IsAscendingOrder.Value = configurationFileFormat.IsAscendingOrder;
|
||||||
|
UI.GridSize.Value = configurationFileFormat.GridSize;
|
||||||
|
UI.ApplicationSort.Value = configurationFileFormat.ApplicationSort;
|
||||||
|
UI.StartFullscreen.Value = configurationFileFormat.StartFullscreen;
|
||||||
|
UI.ShowConsole.Value = configurationFileFormat.ShowConsole;
|
||||||
|
UI.WindowStartup.WindowSizeWidth.Value = configurationFileFormat.WindowStartup.WindowSizeWidth;
|
||||||
|
UI.WindowStartup.WindowSizeHeight.Value = configurationFileFormat.WindowStartup.WindowSizeHeight;
|
||||||
|
UI.WindowStartup.WindowPositionX.Value = configurationFileFormat.WindowStartup.WindowPositionX;
|
||||||
|
UI.WindowStartup.WindowPositionY.Value = configurationFileFormat.WindowStartup.WindowPositionY;
|
||||||
|
UI.WindowStartup.WindowMaximized.Value = configurationFileFormat.WindowStartup.WindowMaximized;
|
||||||
|
Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard;
|
||||||
|
Hid.EnableMouse.Value = configurationFileFormat.EnableMouse;
|
||||||
|
Hid.Hotkeys.Value = configurationFileFormat.Hotkeys;
|
||||||
|
Hid.InputConfig.Value = configurationFileFormat.InputConfig ?? [];
|
||||||
|
|
||||||
|
Multiplayer.LanInterfaceId.Value = configurationFileFormat.MultiplayerLanInterfaceId;
|
||||||
|
Multiplayer.Mode.Value = configurationFileFormat.MultiplayerMode;
|
||||||
|
Multiplayer.DisableP2p.Value = configurationFileFormat.MultiplayerDisableP2p;
|
||||||
|
Multiplayer.LdnPassphrase.Value = configurationFileFormat.MultiplayerLdnPassphrase;
|
||||||
|
Multiplayer.LdnServer.Value = configurationFileFormat.LdnServer;
|
||||||
|
|
||||||
|
if (configurationFileUpdated)
|
||||||
|
{
|
||||||
|
ToFileFormat().SaveConfig(configurationFilePath);
|
||||||
|
|
||||||
|
Ryujinx.Common.Logging.Logger.Notice.Print(LogClass.Application, $"Configuration file updated to version {ConfigurationFileFormat.CurrentVersion}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,15 @@
|
|||||||
using ARMeilleure;
|
using ARMeilleure;
|
||||||
using Gommon;
|
|
||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
|
||||||
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.Multiplayer;
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
using Ryujinx.Common.Helper;
|
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
|
using Ryujinx.UI.Common.Configuration.System;
|
||||||
|
using Ryujinx.UI.Common.Helper;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using RyuLogger = Ryujinx.Common.Logging.Logger;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.UI.Common.Configuration
|
||||||
{
|
{
|
||||||
public partial class ConfigurationState
|
public partial class ConfigurationState
|
||||||
{
|
{
|
||||||
@@ -620,67 +617,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HacksSection
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Show toggles for dirty hacks in the UI.
|
|
||||||
/// </summary>
|
|
||||||
public ReactiveObject<bool> ShowDirtyHacks { get; private set; }
|
|
||||||
|
|
||||||
public ReactiveObject<bool> Xc2MenuSoftlockFix { get; private set; }
|
|
||||||
|
|
||||||
public ReactiveObject<bool> EnableShaderTranslationDelay { get; private set; }
|
|
||||||
|
|
||||||
public ReactiveObject<int> ShaderTranslationDelay { get; private set; }
|
|
||||||
|
|
||||||
public HacksSection()
|
|
||||||
{
|
|
||||||
ShowDirtyHacks = new ReactiveObject<bool>();
|
|
||||||
Xc2MenuSoftlockFix = new ReactiveObject<bool>();
|
|
||||||
Xc2MenuSoftlockFix.Event += HackChanged;
|
|
||||||
EnableShaderTranslationDelay = new ReactiveObject<bool>();
|
|
||||||
EnableShaderTranslationDelay.Event += HackChanged;
|
|
||||||
ShaderTranslationDelay = new ReactiveObject<int>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HackChanged(object sender, ReactiveEventArgs<bool> rxe)
|
|
||||||
{
|
|
||||||
var newHacks = EnabledHacks.Select(x => x.Hack)
|
|
||||||
.JoinToString(", ");
|
|
||||||
|
|
||||||
if (newHacks != _lastHackCollection)
|
|
||||||
{
|
|
||||||
RyuLogger.Info?.Print(LogClass.Configuration,
|
|
||||||
$"EnabledDirtyHacks set to: [{newHacks}]", "LogValueChange");
|
|
||||||
|
|
||||||
_lastHackCollection = newHacks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string _lastHackCollection;
|
|
||||||
|
|
||||||
public EnabledDirtyHack[] EnabledHacks
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
List<EnabledDirtyHack> enabledHacks = [];
|
|
||||||
|
|
||||||
if (Xc2MenuSoftlockFix)
|
|
||||||
Apply(DirtyHack.Xc2MenuSoftlockFix);
|
|
||||||
|
|
||||||
if (EnableShaderTranslationDelay)
|
|
||||||
Apply(DirtyHack.ShaderTranslationDelay, ShaderTranslationDelay);
|
|
||||||
|
|
||||||
return enabledHacks.ToArray();
|
|
||||||
|
|
||||||
void Apply(DirtyHack hack, int value = 0)
|
|
||||||
{
|
|
||||||
enabledHacks.Add(new EnabledDirtyHack(hack, value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default configuration instance
|
/// The default configuration instance
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -716,11 +652,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public MultiplayerSection Multiplayer { get; private set; }
|
public MultiplayerSection Multiplayer { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Dirty Hacks section
|
|
||||||
/// </summary>
|
|
||||||
public HacksSection Hacks { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables or disables Discord Rich Presence
|
/// Enables or disables Discord Rich Presence
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -769,7 +700,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
Graphics = new GraphicsSection();
|
Graphics = new GraphicsSection();
|
||||||
Hid = new HidSection();
|
Hid = new HidSection();
|
||||||
Multiplayer = new MultiplayerSection();
|
Multiplayer = new MultiplayerSection();
|
||||||
Hacks = new HacksSection();
|
|
||||||
EnableDiscordIntegration = new ReactiveObject<bool>();
|
EnableDiscordIntegration = new ReactiveObject<bool>();
|
||||||
CheckUpdatesOnStart = new ReactiveObject<bool>();
|
CheckUpdatesOnStart = new ReactiveObject<bool>();
|
||||||
ShowConfirmExit = new ReactiveObject<bool>();
|
ShowConfirmExit = new ReactiveObject<bool>();
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
using Ryujinx.Ava.Utilities.Configuration.System;
|
|
||||||
using Ryujinx.Ava.Utilities.Configuration.UI;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||||
using Ryujinx.Common.Configuration.Multiplayer;
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
using Ryujinx.Graphics.Vulkan;
|
using Ryujinx.Graphics.Vulkan;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
|
using Ryujinx.UI.Common.Configuration.System;
|
||||||
|
using Ryujinx.UI.Common.Configuration.UI;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.UI.Common.Configuration
|
||||||
{
|
{
|
||||||
public partial class ConfigurationState
|
public partial class ConfigurationState
|
||||||
{
|
{
|
||||||
@@ -139,8 +138,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
MultiplayerDisableP2p = Multiplayer.DisableP2p,
|
MultiplayerDisableP2p = Multiplayer.DisableP2p,
|
||||||
MultiplayerLdnPassphrase = Multiplayer.LdnPassphrase,
|
MultiplayerLdnPassphrase = Multiplayer.LdnPassphrase,
|
||||||
LdnServer = Multiplayer.LdnServer,
|
LdnServer = Multiplayer.LdnServer,
|
||||||
ShowDirtyHacks = Hacks.ShowDirtyHacks,
|
|
||||||
DirtyHacks = Hacks.EnabledHacks.Select(it => it.Pack()).ToArray(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return configurationFile;
|
return configurationFile;
|
||||||
12
src/Ryujinx.UI.Common/Configuration/FileTypes.cs
Normal file
12
src/Ryujinx.UI.Common/Configuration/FileTypes.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
namespace Ryujinx.UI.Common
|
||||||
|
{
|
||||||
|
public enum FileTypes
|
||||||
|
{
|
||||||
|
NSP,
|
||||||
|
PFS0,
|
||||||
|
XCI,
|
||||||
|
NCA,
|
||||||
|
NRO,
|
||||||
|
NSO
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ using Ryujinx.Common.Logging.Targets;
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
namespace Ryujinx.UI.Common.Configuration
|
||||||
{
|
{
|
||||||
public static class LoggerModule
|
public static class LoggerModule
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration.System
|
namespace Ryujinx.UI.Common.Configuration.System
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(TypedStringEnumConverter<Language>))]
|
[JsonConverter(typeof(TypedStringEnumConverter<Language>))]
|
||||||
public enum Language
|
public enum Language
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration.System
|
namespace Ryujinx.UI.Common.Configuration.System
|
||||||
{
|
{
|
||||||
[JsonConverter(typeof(TypedStringEnumConverter<Region>))]
|
[JsonConverter(typeof(TypedStringEnumConverter<Region>))]
|
||||||
public enum Region
|
public enum Region
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Ryujinx.Ava.Utilities.Configuration.UI
|
namespace Ryujinx.UI.Common.Configuration.UI
|
||||||
{
|
{
|
||||||
public struct ColumnSort
|
public struct ColumnSort
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Ryujinx.Ava.Utilities.Configuration.UI
|
namespace Ryujinx.UI.Common.Configuration.UI
|
||||||
{
|
{
|
||||||
public struct GuiColumns
|
public struct GuiColumns
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Ryujinx.Ava.Utilities.Configuration.UI
|
namespace Ryujinx.UI.Common.Configuration.UI
|
||||||
{
|
{
|
||||||
public struct ShownFileTypes
|
public struct ShownFileTypes
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Ryujinx.Ava.Utilities.Configuration.UI
|
namespace Ryujinx.UI.Common.Configuration.UI
|
||||||
{
|
{
|
||||||
public struct WindowStartup
|
public struct WindowStartup
|
||||||
{
|
{
|
||||||
@@ -1,51 +1,129 @@
|
|||||||
using Gommon;
|
using DiscordRPC;
|
||||||
using Ryujinx.Common.Configuration;
|
using Humanizer;
|
||||||
using System;
|
using Humanizer.Localisation;
|
||||||
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.HLE.Loaders.Processes;
|
||||||
|
using Ryujinx.UI.App.Common;
|
||||||
|
using Ryujinx.UI.Common.Configuration;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.Common
|
namespace Ryujinx.UI.Common
|
||||||
{
|
{
|
||||||
public static class TitleIDs
|
public static class DiscordIntegrationModule
|
||||||
{
|
{
|
||||||
public static ReactiveObject<Optional<string>> CurrentApplication { get; set; } = new();
|
public static Timestamps StartedAt { get; set; }
|
||||||
|
|
||||||
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
|
private static string VersionString
|
||||||
|
=> (ReleaseInformation.IsCanaryBuild ? "Canary " : string.Empty) + $"v{ReleaseInformation.Version}";
|
||||||
|
|
||||||
|
private static readonly string _description =
|
||||||
|
ReleaseInformation.IsValid
|
||||||
|
? $"{VersionString} {ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelSourceRepo}@{ReleaseInformation.BuildGitHash}"
|
||||||
|
: "dev build";
|
||||||
|
|
||||||
|
private const string ApplicationId = "1293250299716173864";
|
||||||
|
|
||||||
|
private const int ApplicationByteLimit = 128;
|
||||||
|
private const string Ellipsis = "…";
|
||||||
|
|
||||||
|
private static DiscordRpcClient _discordClient;
|
||||||
|
private static RichPresence _discordPresenceMain;
|
||||||
|
|
||||||
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
switch (currentBackend)
|
_discordPresenceMain = new RichPresence
|
||||||
{
|
{
|
||||||
case GraphicsBackend.OpenGl when OperatingSystem.IsMacOS():
|
Assets = new Assets
|
||||||
return GraphicsBackend.Vulkan;
|
{
|
||||||
case GraphicsBackend.Vulkan or GraphicsBackend.OpenGl or GraphicsBackend.Metal:
|
LargeImageKey = "ryujinx",
|
||||||
return currentBackend;
|
LargeImageText = TruncateToByteLength(_description)
|
||||||
}
|
},
|
||||||
|
Details = "Main Menu",
|
||||||
|
State = "Idling",
|
||||||
|
Timestamps = StartedAt
|
||||||
|
};
|
||||||
|
|
||||||
if (!(OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture is Architecture.Arm64))
|
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
|
||||||
return GraphicsBackend.Vulkan;
|
|
||||||
|
|
||||||
return GreatMetalTitles.ContainsIgnoreCase(titleId) ? GraphicsBackend.Metal : GraphicsBackend.Vulkan;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly string[] GreatMetalTitles =
|
private static void Update(object sender, ReactiveEventArgs<bool> evnt)
|
||||||
[
|
{
|
||||||
"01006f8002326000", // Animal Crossings: New Horizons
|
if (evnt.OldValue != evnt.NewValue)
|
||||||
"01009bf0072d4000", // Captain Toad: Treasure Tracker
|
{
|
||||||
"0100a5c00d162000", // Cuphead
|
// If the integration was active, disable it and unload everything
|
||||||
"010023800d64a000", // Deltarune
|
if (evnt.OldValue)
|
||||||
"010028600EBDA000", // Mario 3D World
|
{
|
||||||
"0100152000022000", // Mario Kart 8 Deluxe
|
_discordClient?.Dispose();
|
||||||
"01005CA01580E000", // Persona 5
|
|
||||||
"0100187003A36000", // Pokémon: Let's Go, Evoli!
|
|
||||||
"010003f003a34000", // Pokémon: Let's Go, Pikachu!
|
|
||||||
"01008C0016544000", // Sea of Stars
|
|
||||||
"01006A800016E000", // Smash Ultimate
|
|
||||||
"0100000000010000", // Super Mario Odyessy
|
|
||||||
];
|
|
||||||
|
|
||||||
public static string GetDiscordGameAsset(string titleId)
|
_discordClient = null;
|
||||||
=> DiscordGameAssetKeys.Contains(titleId) ? titleId : "game";
|
}
|
||||||
|
|
||||||
public static readonly string[] DiscordGameAssetKeys =
|
// If we need to activate it and the client isn't active, initialize it
|
||||||
|
if (evnt.NewValue && _discordClient == null)
|
||||||
|
{
|
||||||
|
_discordClient = new DiscordRpcClient(ApplicationId);
|
||||||
|
|
||||||
|
_discordClient.Initialize();
|
||||||
|
_discordClient.SetPresence(_discordPresenceMain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResult procRes)
|
||||||
|
{
|
||||||
|
_discordClient?.SetPresence(new RichPresence
|
||||||
|
{
|
||||||
|
Assets = new Assets
|
||||||
|
{
|
||||||
|
LargeImageKey = _discordGameAssetKeys.Contains(procRes.ProgramIdText) ? procRes.ProgramIdText : "game",
|
||||||
|
LargeImageText = TruncateToByteLength($"{appMeta.Title} (v{procRes.DisplayVersion})"),
|
||||||
|
SmallImageKey = "ryujinx",
|
||||||
|
SmallImageText = TruncateToByteLength(_description)
|
||||||
|
},
|
||||||
|
Details = TruncateToByteLength($"Playing {appMeta.Title}"),
|
||||||
|
State = appMeta.LastPlayed.HasValue && appMeta.TimePlayed.TotalSeconds > 5
|
||||||
|
? $"Total play time: {appMeta.TimePlayed.Humanize(2, false, maxUnit: TimeUnit.Hour)}"
|
||||||
|
: "Never played",
|
||||||
|
Timestamps = Timestamps.Now
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SwitchToMainState() => _discordClient?.SetPresence(_discordPresenceMain);
|
||||||
|
|
||||||
|
private static string TruncateToByteLength(string input)
|
||||||
|
{
|
||||||
|
if (Encoding.UTF8.GetByteCount(input) <= ApplicationByteLimit)
|
||||||
|
{
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the length to trim the string to guarantee we have space for the trailing ellipsis.
|
||||||
|
int trimLimit = ApplicationByteLimit - Encoding.UTF8.GetByteCount(Ellipsis);
|
||||||
|
|
||||||
|
// Make sure the string is long enough to perform the basic trim.
|
||||||
|
// Amount of bytes != Length of the string
|
||||||
|
if (input.Length > trimLimit)
|
||||||
|
{
|
||||||
|
// Basic trim to best case scenario of 1 byte characters.
|
||||||
|
input = input[..trimLimit];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (Encoding.UTF8.GetByteCount(input) > trimLimit)
|
||||||
|
{
|
||||||
|
// Remove one character from the end of the string at a time.
|
||||||
|
input = input[..^1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return input.TrimEnd() + Ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Exit()
|
||||||
|
{
|
||||||
|
_discordClient?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly string[] _discordGameAssetKeys =
|
||||||
[
|
[
|
||||||
"010055d009f78000", // Fire Emblem: Three Houses
|
"010055d009f78000", // Fire Emblem: Three Houses
|
||||||
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
||||||
@@ -1,19 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using static Ryujinx.UI.Common.Configuration.ConfigurationState.UISection;
|
||||||
|
|
||||||
using static Ryujinx.Ava.Utilities.Configuration.ConfigurationState.UISection;
|
namespace Ryujinx.UI.Common
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities.Configuration
|
|
||||||
{
|
{
|
||||||
public enum FileTypes
|
|
||||||
{
|
|
||||||
NSP,
|
|
||||||
PFS0,
|
|
||||||
XCI,
|
|
||||||
NCA,
|
|
||||||
NRO,
|
|
||||||
NSO
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class FileTypesExtensions
|
public static class FileTypesExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -21,7 +10,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type">The name of the <see cref="ShownFileTypeSettings"/> parameter to get the value of.</param>
|
/// <param name="type">The name of the <see cref="ShownFileTypeSettings"/> parameter to get the value of.</param>
|
||||||
/// <param name="config">The config instance to get the value from.</param>
|
/// <param name="config">The config instance to get the value from.</param>
|
||||||
/// <returns>The current value of the setting. Value is <see langword="true"/> if the file type is to be shown on the games list, <see langword="false"/> otherwise.</returns>
|
/// <returns>The current value of the setting. Value is <see langword="true"/> if the file type is the be shown on the games list, <see langword="false"/> otherwise.</returns>
|
||||||
public static bool GetConfigValue(this FileTypes type, ShownFileTypeSettings config) => type switch
|
public static bool GetConfigValue(this FileTypes type, ShownFileTypeSettings config) => type switch
|
||||||
{
|
{
|
||||||
FileTypes.NSP => config.NSP.Value,
|
FileTypes.NSP => config.NSP.Value,
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
public static class CommandLineState
|
public static class CommandLineState
|
||||||
{
|
{
|
||||||
@@ -3,7 +3,7 @@ using System;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Helper
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
public static partial class ConsoleHelper
|
public static partial class ConsoleHelper
|
||||||
{
|
{
|
||||||
@@ -3,18 +3,18 @@ using LibHac.Fs;
|
|||||||
using LibHac.Fs.Fsa;
|
using LibHac.Fs.Fsa;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
using Ryujinx.Ava.Common.Models;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.Utilities;
|
using Ryujinx.HLE.Utilities;
|
||||||
|
using Ryujinx.UI.Common.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Path = System.IO.Path;
|
using Path = System.IO.Path;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
public static class DownloadableContentsHelper
|
public static class DownloadableContentsHelper
|
||||||
{
|
{
|
||||||
@@ -8,7 +8,7 @@ using System.Linq;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Helper
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
public static partial class FileAssociationHelper
|
public static partial class FileAssociationHelper
|
||||||
{
|
{
|
||||||
@@ -132,7 +132,7 @@ namespace Ryujinx.Common.Helper
|
|||||||
|
|
||||||
if (uninstall)
|
if (uninstall)
|
||||||
{
|
{
|
||||||
// If the types don't already exist, there's nothing to do, and we can call this operation successful.
|
// If the types don't already exist, there's nothing to do and we can call this operation successful.
|
||||||
if (!AreMimeTypesRegisteredWindows())
|
if (!AreMimeTypesRegisteredWindows())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -3,7 +3,7 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Helper
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
[SupportedOSPlatform("linux")]
|
[SupportedOSPlatform("linux")]
|
||||||
public static class LinuxHelper
|
public static class LinuxHelper
|
||||||
@@ -2,7 +2,7 @@ using System;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Helper
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
public static partial class ObjectiveC
|
public static partial class ObjectiveC
|
||||||
@@ -5,7 +5,7 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.Common.Helper
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
public static partial class OpenHelper
|
public static partial class OpenHelper
|
||||||
{
|
{
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.UI;
|
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ensure installation validity
|
/// Ensure installation validity
|
||||||
@@ -7,7 +7,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
public static class ShortcutHelper
|
public static class ShortcutHelper
|
||||||
{
|
{
|
||||||
@@ -31,7 +31,7 @@ namespace Ryujinx.Ava.Utilities
|
|||||||
private static void CreateShortcutLinux(string applicationFilePath, string applicationId, byte[] iconData, string iconPath, string desktopPath, string cleanedAppName)
|
private static void CreateShortcutLinux(string applicationFilePath, string applicationId, byte[] iconData, string iconPath, string desktopPath, string cleanedAppName)
|
||||||
{
|
{
|
||||||
string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx.sh");
|
string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx.sh");
|
||||||
var desktopFile = EmbeddedResources.ReadAllText("Ryujinx/Assets/ShortcutFiles/shortcut-template.desktop");
|
var desktopFile = EmbeddedResources.ReadAllText("Ryujinx.UI.Common/shortcut-template.desktop");
|
||||||
iconPath += ".png";
|
iconPath += ".png";
|
||||||
|
|
||||||
var image = SKBitmap.Decode(iconData);
|
var image = SKBitmap.Decode(iconData);
|
||||||
@@ -47,8 +47,8 @@ namespace Ryujinx.Ava.Utilities
|
|||||||
private static void CreateShortcutMacos(string appFilePath, string applicationId, byte[] iconData, string desktopPath, string cleanedAppName)
|
private static void CreateShortcutMacos(string appFilePath, string applicationId, byte[] iconData, string desktopPath, string cleanedAppName)
|
||||||
{
|
{
|
||||||
string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx");
|
string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx");
|
||||||
var plistFile = EmbeddedResources.ReadAllText("Ryujinx/Assets/ShortcutFiles/shortcut-template.plist");
|
var plistFile = EmbeddedResources.ReadAllText("Ryujinx.UI.Common/shortcut-template.plist");
|
||||||
var shortcutScript = EmbeddedResources.ReadAllText("Ryujinx/Assets/ShortcutFiles/shortcut-launch-script.sh");
|
var shortcutScript = EmbeddedResources.ReadAllText("Ryujinx.UI.Common/shortcut-launch-script.sh");
|
||||||
// Macos .App folder
|
// Macos .App folder
|
||||||
string contentFolderPath = Path.Combine("/Applications", cleanedAppName + ".app", "Contents");
|
string contentFolderPath = Path.Combine("/Applications", cleanedAppName + ".app", "Contents");
|
||||||
string scriptFolderPath = Path.Combine(contentFolderPath, "MacOS");
|
string scriptFolderPath = Path.Combine(contentFolderPath, "MacOS");
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using Ryujinx.HLE.Loaders.Processes;
|
using Ryujinx.HLE.Loaders.Processes;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
public static class TitleHelper
|
public static class TitleHelper
|
||||||
{
|
{
|
||||||
@@ -6,14 +6,14 @@ using LibHac.Ncm;
|
|||||||
using LibHac.Ns;
|
using LibHac.Ns;
|
||||||
using LibHac.Tools.FsSystem;
|
using LibHac.Tools.FsSystem;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
using Ryujinx.Ava.Common.Models;
|
|
||||||
using Ryujinx.Ava.Utilities.Configuration;
|
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
||||||
using Ryujinx.HLE.Utilities;
|
using Ryujinx.HLE.Utilities;
|
||||||
|
using Ryujinx.UI.Common.Configuration;
|
||||||
|
using Ryujinx.UI.Common.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -22,7 +22,7 @@ using Path = System.IO.Path;
|
|||||||
using SpanHelpers = LibHac.Common.SpanHelpers;
|
using SpanHelpers = LibHac.Common.SpanHelpers;
|
||||||
using TitleUpdateMetadata = Ryujinx.Common.Configuration.TitleUpdateMetadata;
|
using TitleUpdateMetadata = Ryujinx.Common.Configuration.TitleUpdateMetadata;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
public static class TitleUpdatesHelper
|
public static class TitleUpdatesHelper
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
using Ryujinx.Ava.Common.Locale;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Utilities
|
namespace Ryujinx.UI.Common.Helper
|
||||||
{
|
{
|
||||||
public static class ValueFormatUtils
|
public static class ValueFormatUtils
|
||||||
{
|
{
|
||||||
@@ -76,7 +75,7 @@ namespace Ryujinx.Ava.Utilities
|
|||||||
{
|
{
|
||||||
culture ??= CultureInfo.CurrentCulture;
|
culture ??= CultureInfo.CurrentCulture;
|
||||||
|
|
||||||
return utcDateTime?.ToLocalTime().ToString(culture) ?? LocaleManager.Instance[LocaleKeys.Never];
|
return utcDateTime?.ToLocalTime().ToString(culture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -2,7 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Common.Models.Amiibo
|
namespace Ryujinx.UI.Common.Models.Amiibo
|
||||||
{
|
{
|
||||||
public struct AmiiboApi : IEquatable<AmiiboApi>
|
public struct AmiiboApi : IEquatable<AmiiboApi>
|
||||||
{
|
{
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user