From 8a064bcd7eb41d1f2f129f6a2586f1d17d01fd1a Mon Sep 17 00:00:00 2001 From: LotP1 <68976644+LotP1@users.noreply.github.com> Date: Tue, 5 Nov 2024 19:34:38 +0100 Subject: [PATCH 01/15] Update README.md (#187) --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f03a1205f..d2ce7ca01 100644 --- a/README.md +++ b/README.md @@ -61,9 +61,9 @@ Use the search function to see if a game has been tested already! To run this emulator, your PC must be equipped with at least 8GiB of RAM; failing to meet this requirement may result in a poor gameplay experience or unexpected crashes. -## Latest build +## Latest release -These builds are compiled automatically for each commit on the master branch. +Releases are compiled automatically for each commit on the master branch. While we strive to ensure optimal stability and performance prior to pushing an update, our automated builds **may be unstable or completely broken**. You can find the latest release [here](https://github.com/GreemDev/Ryujinx/releases/latest). @@ -74,6 +74,7 @@ If you are planning to contribute or just want to learn more about this project ## Building +Building the project is for advanced users. If you wish to build the emulator yourself, follow these steps: ### Step 1 From 0c88b9eff71e75e6578c8a793a7bbe666b6429aa Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 6 Nov 2024 16:48:20 -0600 Subject: [PATCH 02/15] Canary & Release separation. --- .github/workflows/canary.yml | 252 +++++++++++++++++++++++ .github/workflows/release.yml | 4 +- Ryujinx.sln | 17 +- src/Ryujinx.Common/ReleaseInformation.cs | 10 +- 4 files changed, 271 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/canary.yml diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml new file mode 100644 index 000000000..195a3f435 --- /dev/null +++ b/.github/workflows/canary.yml @@ -0,0 +1,252 @@ +name: Canary release job + +on: + workflow_dispatch: + inputs: {} + push: + branches: [ master ] + paths-ignore: + - '.github/**' + - 'docs/**' + - 'assets/**' + - '*.yml' + - '*.json' + - '*.config' + - '*.md' + +concurrency: release + +env: + POWERSHELL_TELEMETRY_OPTOUT: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + RYUJINX_BASE_VERSION: "1.2" + RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary" + RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev" + RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx-Canary" + RELEASE: 1 + +jobs: + tag: + name: Create tag + runs-on: ubuntu-20.04 + steps: + - name: Get version info + id: version_info + run: | + echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT + echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT + shell: bash + + - name: Create tag + uses: actions/github-script@v7 + with: + script: | + github.rest.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}', + sha: context.sha + }) + + - name: Create release + uses: ncipollo/release-action@v1 + with: + name: "Canary ${{ steps.version_info.outputs.build_version }}" + tag: ${{ steps.version_info.outputs.build_version }} + omitBodyDuringUpdate: true + owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} + repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} + token: ${{ secrets.RELEASE_TOKEN }} + + release: + name: Release for ${{ matrix.platform.name }} + runs-on: ${{ matrix.platform.os }} + strategy: + matrix: + platform: + - { name: win-x64, os: windows-latest, zip_os_name: win_x64 } + - { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 } + - { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 } + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + + - name: Overwrite csc problem matcher + run: echo "::add-matcher::.github/csc.json" + + - name: Get version info + id: version_info + run: | + echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT + echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT + echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT + shell: bash + + - name: Configure for release + run: | + sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs + shell: bash + + - name: Create output dir + run: "mkdir release_output" + + - name: Publish + 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 -p:IncludeNativeLibrariesForSelfExtract=true + 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 -p:IncludeNativeLibrariesForSelfExtract=true + + - name: Packing Windows builds + if: matrix.platform.os == 'windows-latest' + run: | + pushd publish_ava + rm publish/libarmeilleure-jitsupport.dylib + 7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish + popd + + pushd publish_sdl2_headless + rm publish/libarmeilleure-jitsupport.dylib + 7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish + popd + shell: bash + + - name: Packing Linux builds + if: matrix.platform.os == 'ubuntu-latest' + run: | + pushd publish_ava + rm publish/libarmeilleure-jitsupport.dylib + chmod +x publish/Ryujinx.sh publish/Ryujinx + tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish + popd + + pushd publish_sdl2_headless + rm publish/libarmeilleure-jitsupport.dylib + chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2 + tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish + popd + shell: bash + + #- name: Build AppImage (Linux) + # if: matrix.platform.os == 'ubuntu-latest' + # run: | + # BUILD_VERSION="${{ steps.version_info.outputs.build_version }}" + # PLATFORM_NAME="${{ matrix.platform.name }}" + + # sudo apt install -y zsync desktop-file-utils appstream + + # mkdir -p tools + # export PATH="$PATH:$(readlink -f tools)" + + # Setup appimagetool + # wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" + # chmod +x tools/appimagetool + # chmod +x distribution/linux/appimage/build-appimage.sh + + # Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name) + # if [ "$PLATFORM_NAME" = "linux-x64" ]; then + # ARCH_NAME=x64 + # export ARCH=x86_64 + # elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then + # ARCH_NAME=arm64 + # export ARCH=aarch64 + # else + # echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME"" + # exit 1 + # fi + + # export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync" + # BUILDDIR=publish_ava OUTDIR=publish_ava_appimage distribution/linux/appimage/build-appimage.sh + + # Add to release output + # pushd publish_ava_appimage + # mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage + # mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync + # popd + # shell: bash + + - name: Pushing new release + uses: ncipollo/release-action@v1 + with: + name: ${{ steps.version_info.outputs.build_version }} + artifacts: "release_output/*.tar.gz,release_output/*.zip" + #artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*" + tag: ${{ steps.version_info.outputs.build_version }} + body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}" + omitBodyDuringUpdate: true + allowUpdates: true + replacesArtifacts: true + owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} + repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} + token: ${{ secrets.RELEASE_TOKEN }} + + macos_release: + name: Release MacOS universal + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + + - name: Setup LLVM 15 + run: | + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 15 + + - name: Install rcodesign + run: | + mkdir -p $HOME/.bin + gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz' + tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1 + rm apple-codesign.tar.gz + mv rcodesign $HOME/.bin/ + echo "$HOME/.bin" >> $GITHUB_PATH + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Get version info + id: version_info + run: | + echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT + echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT + echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT + + - name: Configure for release + run: | + sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs + sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs + shell: bash + + - name: Publish macOS Ryujinx + 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 + + - 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 + + - name: Pushing new release + uses: ncipollo/release-action@v1 + with: + name: "Canary ${{ steps.version_info.outputs.build_version }}" + artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz" + tag: ${{ steps.version_info.outputs.build_version }} + omitBodyDuringUpdate: true + allowUpdates: true + replacesArtifacts: true + owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} + repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} + token: ${{ secrets.RELEASE_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aad32deb6..c3c1e2a28 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: {} push: - branches: [ master ] + branches: [ release ] paths-ignore: - '.github/**' - 'docs/**' @@ -20,7 +20,7 @@ env: POWERSHELL_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1 RYUJINX_BASE_VERSION: "1.2" - RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "master" + RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release" RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev" RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx" RELEASE: 1 diff --git a/Ryujinx.sln b/Ryujinx.sln index eaa28f8dd..d661b903c 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -29,14 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec", "s EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio", "src\Ryujinx.Audio\Ryujinx.Audio.csproj", "{806ACF6D-90B0-45D0-A1AC-5F220F3B3985}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - Directory.Packages.props = Directory.Packages.props - Release Script = .github/workflows/release.yml - Build Script = .github/workflows/build.yml - EndProjectSection -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Memory", "src\Ryujinx.Memory\Ryujinx.Memory.csproj", "{A5E6C691-9E22-4263-8F40-42F002CE66BE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Tests.Memory", "src\Ryujinx.Tests.Memory\Ryujinx.Tests.Memory.csproj", "{D1CC5322-7325-4F6B-9625-194B30BE1296}" @@ -89,6 +81,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Gene EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + Directory.Packages.props = Directory.Packages.props + .github/workflows/release.yml = .github/workflows/release.yml + .github/workflows/canary.yml = .github/workflows/canary.yml + .github/workflows/build.yml = .github/workflows/build.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/src/Ryujinx.Common/ReleaseInformation.cs b/src/Ryujinx.Common/ReleaseInformation.cs index dfba64191..888c57e81 100644 --- a/src/Ryujinx.Common/ReleaseInformation.cs +++ b/src/Ryujinx.Common/ReleaseInformation.cs @@ -5,7 +5,9 @@ namespace Ryujinx.Common // DO NOT EDIT, filled by CI public static class ReleaseInformation { - private const string FlatHubChannelOwner = "flathub"; + private const string FlatHubChannel = "flathub"; + private const string CanaryChannel = "canary"; + private const string ReleaseChannel = "release"; private const string BuildVersion = "%%RYUJINX_BUILD_VERSION%%"; public const string BuildGitHash = "%%RYUJINX_BUILD_GIT_HASH%%"; @@ -24,7 +26,11 @@ namespace Ryujinx.Common !ReleaseChannelRepo.StartsWith("%%") && !ConfigFileName.StartsWith("%%"); - public static bool IsFlatHubBuild => IsValid && ReleaseChannelOwner.Equals(FlatHubChannelOwner); + public static bool IsFlatHubBuild => IsValid && ReleaseChannelOwner.Equals(FlatHubChannel); + + public static bool IsCanaryBuild => IsValid && ReleaseChannelOwner.Equals(CanaryChannel); + + public static bool IsReleaseBuild => IsValid && ReleaseChannelOwner.Equals(ReleaseChannel); public static string Version => IsValid ? BuildVersion : Assembly.GetEntryAssembly()!.GetCustomAttribute()?.InformationalVersion; } From 3e1182af22d7737f0e5d7502bc233566d901cb2e Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 6 Nov 2024 16:55:17 -0600 Subject: [PATCH 03/15] Specify what is a canary tag --- .github/workflows/canary.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index 195a3f435..7db2f5be7 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -44,7 +44,7 @@ jobs: github.rest.git.createRef({ owner: context.repo.owner, repo: context.repo.repo, - ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}', + ref: 'refs/tags/Canary-${{ steps.version_info.outputs.build_version }}', sha: context.sha }) From f4957d2a092af0c59db5f01333d4fb328658d53a Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 6 Nov 2024 17:00:16 -0600 Subject: [PATCH 04/15] Didn't realize you could compare tags and not just releases although that should have been obvious --- .github/workflows/canary.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index 7db2f5be7..638d25a32 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -178,7 +178,7 @@ jobs: artifacts: "release_output/*.tar.gz,release_output/*.zip" #artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*" tag: ${{ steps.version_info.outputs.build_version }} - body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}" + body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}" omitBodyDuringUpdate: true allowUpdates: true replacesArtifacts: true @@ -244,6 +244,7 @@ jobs: name: "Canary ${{ steps.version_info.outputs.build_version }}" artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz" tag: ${{ steps.version_info.outputs.build_version }} + body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}" omitBodyDuringUpdate: true allowUpdates: true replacesArtifacts: true From 683baec1afd91d73a4dd49f649a6f7fc7fc10d97 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 6 Nov 2024 17:04:20 -0600 Subject: [PATCH 05/15] OOPSIE!!!!!!!!! --- .github/workflows/canary.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index 638d25a32..b64fc1d92 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -53,6 +53,7 @@ jobs: with: name: "Canary ${{ steps.version_info.outputs.build_version }}" tag: ${{ steps.version_info.outputs.build_version }} + body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}" omitBodyDuringUpdate: true owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} From 20cc21add60bd850f7ca4e73e8bbc3dff92c862d Mon Sep 17 00:00:00 2001 From: James Duarte Date: Wed, 6 Nov 2024 23:36:02 +0000 Subject: [PATCH 06/15] fix minor grammatical issues in en_US.json (#183) --- src/Ryujinx/Assets/Locales/en_US.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json index 68b48146b..8c2e7db71 100644 --- a/src/Ryujinx/Assets/Locales/en_US.json +++ b/src/Ryujinx/Assets/Locales/en_US.json @@ -439,13 +439,13 @@ "DialogNcaExtractionMessage": "Extracting {0} section from {1}...", "DialogNcaExtractionTitle": "Ryujinx - NCA Section Extractor", "DialogNcaExtractionMainNcaNotFoundErrorMessage": "Extraction failure. The main NCA was not present in the selected file.", - "DialogNcaExtractionCheckLogErrorMessage": "Extraction failure. Read the log file for further information.", + "DialogNcaExtractionCheckLogErrorMessage": "Extraction failed. Please check the log file for more details.", "DialogNcaExtractionSuccessMessage": "Extraction completed successfully.", - "DialogUpdaterConvertFailedMessage": "Failed to convert the current Ryujinx version.", - "DialogUpdaterCancelUpdateMessage": "Cancelling Update!", - "DialogUpdaterAlreadyOnLatestVersionMessage": "You are already using the most updated version of Ryujinx!", - "DialogUpdaterFailedToGetVersionMessage": "An error has occurred when trying to get release information from GitHub Release. This can be caused if a new release is being compiled by GitHub Actions. Try again in a few minutes.", - "DialogUpdaterConvertFailedGithubMessage": "Failed to convert the received Ryujinx version from Github Release.", + "DialogUpdaterConvertFailedMessage": "Unable to convert the current Ryujinx version.", + "DialogUpdaterCancelUpdateMessage": "Update canceled!", + "DialogUpdaterAlreadyOnLatestVersionMessage": "You are already using the latest version of Ryujinx!", + "DialogUpdaterFailedToGetVersionMessage": "An error occurred while trying to retrieve release information from GitHub. This may happen if a new release is currently being compiled by GitHub Actions. Please try again in a few minutes.", + "DialogUpdaterConvertFailedGithubMessage": "Failed to convert the Ryujinx version received from GitHub." "DialogUpdaterDownloadingMessage": "Downloading Update...", "DialogUpdaterExtractionMessage": "Extracting Update...", "DialogUpdaterRenamingMessage": "Renaming Update...", @@ -455,7 +455,7 @@ "DialogUpdaterNoInternetMessage": "You are not connected to the Internet!", "DialogUpdaterNoInternetSubMessage": "Please verify that you have a working Internet connection!", "DialogUpdaterDirtyBuildMessage": "You Cannot update a Dirty build of Ryujinx!", - "DialogUpdaterDirtyBuildSubMessage": "Please download Ryujinx at https://https://github.com/GreemDev/Ryujinx/releases/ if you are looking for a supported version.", + "DialogUpdaterDirtyBuildSubMessage": "Please download Ryujinx at https://github.com/GreemDev/Ryujinx/releases/ if you are looking for a supported version.", "DialogRestartRequiredMessage": "Restart Required", "DialogThemeRestartMessage": "Theme has been saved. A restart is needed to apply the theme.", "DialogThemeRestartSubMessage": "Do you want to restart", From 47b81458095453e435a6c5530b9b2a7833df108a Mon Sep 17 00:00:00 2001 From: Luke Warner <65521430+LukeWarnut@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:36:30 -0500 Subject: [PATCH 07/15] Fix fullscreen when using 'Show Title Bar' (#150) --- src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs | 2 ++ src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 88a24c34d..7fd1ad104 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -1776,6 +1776,7 @@ namespace Ryujinx.Ava.UI.ViewModels if (WindowState is not WindowState.Normal) { WindowState = WindowState.Normal; + Window.TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar; if (IsGameRunning) { @@ -1785,6 +1786,7 @@ namespace Ryujinx.Ava.UI.ViewModels else { WindowState = WindowState.FullScreen; + Window.TitleBar.ExtendsContentIntoTitleBar = true; if (IsGameRunning) { diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml index fe8b64eb6..94e035022 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml @@ -12,13 +12,13 @@ - - - + Date: Thu, 7 Nov 2024 09:37:30 +1000 Subject: [PATCH 08/15] Add ability to trim and untrim XCI files from the application context menu AND in Bulk (#105) --- src/Ryujinx.Common/Logging/LogClass.cs | 1 + .../Logging/XCIFileTrimmerLog.cs | 30 + .../Utilities/XCIFileTrimmer.cs | 524 +++++++++++++++++ .../IpcServiceGenerator.cs | 2 + .../Models/XCITrimmerFileModel.cs | 55 ++ src/Ryujinx/Assets/Locales/en_US.json | 40 ++ src/Ryujinx/Assets/Styles/Styles.xaml | 14 +- .../Common/XCIFileTrimmerMainWindowLog.cs | 24 + src/Ryujinx/Common/XCIFileTrimmerWindowLog.cs | 23 + .../UI/Controls/ApplicationContextMenu.axaml | 6 + .../Controls/ApplicationContextMenu.axaml.cs | 13 + .../UI/Helpers/AvaloniaListExtensions.cs | 62 ++ .../XCITrimmerFileSpaceSavingsConverter.cs | 48 ++ .../Helpers/XCITrimmerFileStatusConverter.cs | 46 ++ .../XCITrimmerFileStatusDetailConverter.cs | 42 ++ .../XCITrimmerOperationOutcomeHelper.cs | 36 ++ .../UI/ViewModels/MainWindowViewModel.cs | 119 ++++ .../UI/ViewModels/XCITrimmerViewModel.cs | 541 ++++++++++++++++++ .../UI/Views/Main/MainMenuBarView.axaml | 2 + .../UI/Views/Main/MainMenuBarView.axaml.cs | 2 + .../UI/Views/Main/MainStatusBarView.axaml | 13 +- src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml | 354 ++++++++++++ .../UI/Windows/XCITrimmerWindow.axaml.cs | 101 ++++ 23 files changed, 2095 insertions(+), 3 deletions(-) create mode 100644 src/Ryujinx.Common/Logging/XCIFileTrimmerLog.cs create mode 100644 src/Ryujinx.Common/Utilities/XCIFileTrimmer.cs create mode 100644 src/Ryujinx.UI.Common/Models/XCITrimmerFileModel.cs create mode 100644 src/Ryujinx/Common/XCIFileTrimmerMainWindowLog.cs create mode 100644 src/Ryujinx/Common/XCIFileTrimmerWindowLog.cs create mode 100644 src/Ryujinx/UI/Helpers/AvaloniaListExtensions.cs create mode 100644 src/Ryujinx/UI/Helpers/XCITrimmerFileSpaceSavingsConverter.cs create mode 100644 src/Ryujinx/UI/Helpers/XCITrimmerFileStatusConverter.cs create mode 100644 src/Ryujinx/UI/Helpers/XCITrimmerFileStatusDetailConverter.cs create mode 100644 src/Ryujinx/UI/Helpers/XCITrimmerOperationOutcomeHelper.cs create mode 100644 src/Ryujinx/UI/ViewModels/XCITrimmerViewModel.cs create mode 100644 src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml create mode 100644 src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml.cs diff --git a/src/Ryujinx.Common/Logging/LogClass.cs b/src/Ryujinx.Common/Logging/LogClass.cs index 1b404a06a..a4117580e 100644 --- a/src/Ryujinx.Common/Logging/LogClass.cs +++ b/src/Ryujinx.Common/Logging/LogClass.cs @@ -72,5 +72,6 @@ namespace Ryujinx.Common.Logging TamperMachine, UI, Vic, + XCIFileTrimmer } } diff --git a/src/Ryujinx.Common/Logging/XCIFileTrimmerLog.cs b/src/Ryujinx.Common/Logging/XCIFileTrimmerLog.cs new file mode 100644 index 000000000..fb11432b0 --- /dev/null +++ b/src/Ryujinx.Common/Logging/XCIFileTrimmerLog.cs @@ -0,0 +1,30 @@ +using Ryujinx.Common.Utilities; + +namespace Ryujinx.Common.Logging +{ + public class XCIFileTrimmerLog : XCIFileTrimmer.ILog + { + public virtual void Progress(long current, long total, string text, bool complete) + { + } + + public void Write(XCIFileTrimmer.LogType logType, string text) + { + switch (logType) + { + case XCIFileTrimmer.LogType.Info: + Logger.Notice.Print(LogClass.XCIFileTrimmer, text); + break; + case XCIFileTrimmer.LogType.Warn: + Logger.Warning?.Print(LogClass.XCIFileTrimmer, text); + break; + case XCIFileTrimmer.LogType.Error: + Logger.Error?.Print(LogClass.XCIFileTrimmer, text); + break; + case XCIFileTrimmer.LogType.Progress: + Logger.Info?.Print(LogClass.XCIFileTrimmer, text); + break; + } + } + } +} diff --git a/src/Ryujinx.Common/Utilities/XCIFileTrimmer.cs b/src/Ryujinx.Common/Utilities/XCIFileTrimmer.cs new file mode 100644 index 000000000..050e78d1e --- /dev/null +++ b/src/Ryujinx.Common/Utilities/XCIFileTrimmer.cs @@ -0,0 +1,524 @@ +// Uncomment the line below to ensure XCIFileTrimmer does not modify files +//#define XCI_TRIMMER_READ_ONLY_MODE + +using Gommon; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading; + +namespace Ryujinx.Common.Utilities +{ + public sealed class XCIFileTrimmer + { + private const long BytesInAMegabyte = 1024 * 1024; + private const int BufferSize = 8 * (int)BytesInAMegabyte; + + private const long CartSizeMBinFormattedGB = 952; + private const int CartKeyAreaSize = 0x1000; + private const byte PaddingByte = 0xFF; + private const int HeaderFilePos = 0x100; + private const int CartSizeFilePos = 0x10D; + private const int DataSizeFilePos = 0x118; + private const string HeaderMagicValue = "HEAD"; + + /// + /// Cartridge Sizes (ByteIdentifier, SizeInGB) + /// + private static readonly Dictionary _cartSizesGB = new() + { + { 0xFA, 1 }, + { 0xF8, 2 }, + { 0xF0, 4 }, + { 0xE0, 8 }, + { 0xE1, 16 }, + { 0xE2, 32 } + }; + + private static long RecordsToByte(long records) + { + return 512 + (records * 512); + } + + public static bool CanTrim(string filename, ILog log = null) + { + if (Path.GetExtension(filename).Equals(".XCI", StringComparison.InvariantCultureIgnoreCase)) + { + var trimmer = new XCIFileTrimmer(filename, log); + return trimmer.CanBeTrimmed; + } + + return false; + } + + public static bool CanUntrim(string filename, ILog log = null) + { + if (Path.GetExtension(filename).Equals(".XCI", StringComparison.InvariantCultureIgnoreCase)) + { + var trimmer = new XCIFileTrimmer(filename, log); + return trimmer.CanBeUntrimmed; + } + + return false; + } + + private ILog _log; + private string _filename; + private FileStream _fileStream; + private BinaryReader _binaryReader; + private long _offsetB, _dataSizeB, _cartSizeB, _fileSizeB; + private bool _fileOK = true; + private bool _freeSpaceChecked = false; + private bool _freeSpaceValid = false; + + public enum OperationOutcome + { + Undetermined, + InvalidXCIFile, + NoTrimNecessary, + NoUntrimPossible, + FreeSpaceCheckFailed, + FileIOWriteError, + ReadOnlyFileCannotFix, + FileSizeChanged, + Successful, + Cancelled + } + + public enum LogType + { + Info, + Warn, + Error, + Progress + } + + public interface ILog + { + public void Write(LogType logType, string text); + public void Progress(long current, long total, string text, bool complete); + } + + public bool FileOK => _fileOK; + public bool Trimmed => _fileOK && FileSizeB < UntrimmedFileSizeB; + public bool ContainsKeyArea => _offsetB != 0; + public bool CanBeTrimmed => _fileOK && FileSizeB > TrimmedFileSizeB; + public bool CanBeUntrimmed => _fileOK && FileSizeB < UntrimmedFileSizeB; + public bool FreeSpaceChecked => _fileOK && _freeSpaceChecked; + public bool FreeSpaceValid => _fileOK && _freeSpaceValid; + public long DataSizeB => _dataSizeB; + public long CartSizeB => _cartSizeB; + public long FileSizeB => _fileSizeB; + public long DiskSpaceSavedB => CartSizeB - FileSizeB; + public long DiskSpaceSavingsB => CartSizeB - DataSizeB; + public long TrimmedFileSizeB => _offsetB + _dataSizeB; + public long UntrimmedFileSizeB => _offsetB + _cartSizeB; + + public ILog Log + { + get => _log; + set => _log = value; + } + + public String Filename + { + get => _filename; + set + { + _filename = value; + Reset(); + } + } + + public long Pos + { + get => _fileStream.Position; + set => _fileStream.Position = value; + } + + public XCIFileTrimmer(string path, ILog log = null) + { + Log = log; + Filename = path; + ReadHeader(); + } + + public void CheckFreeSpace(CancellationToken? cancelToken = null) + { + if (FreeSpaceChecked) + return; + + try + { + if (CanBeTrimmed) + { + _freeSpaceValid = false; + + OpenReaders(); + + try + { + Pos = TrimmedFileSizeB; + bool freeSpaceValid = true; + long readSizeB = FileSizeB - TrimmedFileSizeB; + + Stopwatch timedSw = Lambda.Timed(() => + { + freeSpaceValid = CheckPadding(readSizeB, cancelToken); + }); + + if (timedSw.Elapsed.TotalSeconds > 0) + { + Log?.Write(LogType.Info, $"Checked at {readSizeB / (double)XCIFileTrimmer.BytesInAMegabyte / timedSw.Elapsed.TotalSeconds:N} Mb/sec"); + } + + if (freeSpaceValid) + Log?.Write(LogType.Info, "Free space is valid"); + + _freeSpaceValid = freeSpaceValid; + } + finally + { + CloseReaders(); + } + + } + else + { + Log?.Write(LogType.Warn, "There is no free space to check."); + _freeSpaceValid = false; + } + } + finally + { + _freeSpaceChecked = true; + } + } + + private bool CheckPadding(long readSizeB, CancellationToken? cancelToken = null) + { + long maxReads = readSizeB / XCIFileTrimmer.BufferSize; + long read = 0; + var buffer = new byte[BufferSize]; + + while (true) + { + if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested) + { + return false; + } + + int bytes = _fileStream.Read(buffer, 0, XCIFileTrimmer.BufferSize); + if (bytes == 0) + break; + + Log?.Progress(read, maxReads, "Verifying file can be trimmed", false); + if (buffer.Take(bytes).AsParallel().Any(b => b != XCIFileTrimmer.PaddingByte)) + { + Log?.Write(LogType.Warn, "Free space is NOT valid"); + return false; + } + + read++; + } + + return true; + } + + private void Reset() + { + _freeSpaceChecked = false; + _freeSpaceValid = false; + ReadHeader(); + } + + public OperationOutcome Trim(CancellationToken? cancelToken = null) + { + if (!FileOK) + { + return OperationOutcome.InvalidXCIFile; + } + + if (!CanBeTrimmed) + { + return OperationOutcome.NoTrimNecessary; + } + + if (!FreeSpaceChecked) + { + CheckFreeSpace(cancelToken); + } + + if (!FreeSpaceValid) + { + if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested) + { + return OperationOutcome.Cancelled; + } + else + { + return OperationOutcome.FreeSpaceCheckFailed; + } + } + + Log?.Write(LogType.Info, "Trimming..."); + + try + { + var info = new FileInfo(Filename); + if ((info.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) + { + try + { + Log?.Write(LogType.Info, "Attempting to remove ReadOnly attribute"); + File.SetAttributes(Filename, info.Attributes & ~FileAttributes.ReadOnly); + } + catch (Exception e) + { + Log?.Write(LogType.Error, e.ToString()); + return OperationOutcome.ReadOnlyFileCannotFix; + } + } + + if (info.Length != FileSizeB) + { + Log?.Write(LogType.Error, "File size has changed, cannot safely trim."); + return OperationOutcome.FileSizeChanged; + } + + var outfileStream = new FileStream(_filename, FileMode.Open, FileAccess.Write, FileShare.Write); + + try + { + +#if !XCI_TRIMMER_READ_ONLY_MODE + outfileStream.SetLength(TrimmedFileSizeB); +#endif + return OperationOutcome.Successful; + } + finally + { + outfileStream.Close(); + Reset(); + } + } + catch (Exception e) + { + Log?.Write(LogType.Error, e.ToString()); + return OperationOutcome.FileIOWriteError; + } + } + + public OperationOutcome Untrim(CancellationToken? cancelToken = null) + { + if (!FileOK) + { + return OperationOutcome.InvalidXCIFile; + } + + if (!CanBeUntrimmed) + { + return OperationOutcome.NoUntrimPossible; + } + + try + { + Log?.Write(LogType.Info, "Untrimming..."); + + var info = new FileInfo(Filename); + if ((info.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) + { + try + { + Log?.Write(LogType.Info, "Attempting to remove ReadOnly attribute"); + File.SetAttributes(Filename, info.Attributes & ~FileAttributes.ReadOnly); + } + catch (Exception e) + { + Log?.Write(LogType.Error, e.ToString()); + return OperationOutcome.ReadOnlyFileCannotFix; + } + } + + if (info.Length != FileSizeB) + { + Log?.Write(LogType.Error, "File size has changed, cannot safely untrim."); + return OperationOutcome.FileSizeChanged; + } + + var outfileStream = new FileStream(_filename, FileMode.Append, FileAccess.Write, FileShare.Write); + long bytesToWriteB = UntrimmedFileSizeB - FileSizeB; + + try + { + Stopwatch timedSw = Lambda.Timed(() => + { + WritePadding(outfileStream, bytesToWriteB, cancelToken); + }); + + if (timedSw.Elapsed.TotalSeconds > 0) + { + Log?.Write(LogType.Info, $"Wrote at {bytesToWriteB / (double)XCIFileTrimmer.BytesInAMegabyte / timedSw.Elapsed.TotalSeconds:N} Mb/sec"); + } + + if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested) + { + return OperationOutcome.Cancelled; + } + else + { + return OperationOutcome.Successful; + } + } + finally + { + outfileStream.Close(); + Reset(); + } + } + catch (Exception e) + { + Log?.Write(LogType.Error, e.ToString()); + return OperationOutcome.FileIOWriteError; + } + } + + private void WritePadding(FileStream outfileStream, long bytesToWriteB, CancellationToken? cancelToken = null) + { + long bytesLeftToWriteB = bytesToWriteB; + long writes = bytesLeftToWriteB / XCIFileTrimmer.BufferSize; + int write = 0; + + try + { + var buffer = new byte[BufferSize]; + Array.Fill(buffer, XCIFileTrimmer.PaddingByte); + + while (bytesLeftToWriteB > 0) + { + if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested) + { + return; + } + + long bytesToWrite = Math.Min(XCIFileTrimmer.BufferSize, bytesLeftToWriteB); + +#if !XCI_TRIMMER_READ_ONLY_MODE + outfileStream.Write(buffer, 0, (int)bytesToWrite); +#endif + + bytesLeftToWriteB -= bytesToWrite; + Log?.Progress(write, writes, "Writing padding data...", false); + write++; + } + } + finally + { + Log?.Progress(write, writes, "Writing padding data...", true); + } + } + + private void OpenReaders() + { + if (_binaryReader == null) + { + _fileStream = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.Read); + _binaryReader = new BinaryReader(_fileStream); + } + } + + private void CloseReaders() + { + if (_binaryReader != null && _binaryReader.BaseStream != null) + _binaryReader.Close(); + _binaryReader = null; + _fileStream = null; + GC.Collect(); + } + + private void ReadHeader() + { + try + { + OpenReaders(); + + try + { + // Attempt without key area + bool success = CheckAndReadHeader(false); + + if (!success) + { + // Attempt with key area + success = CheckAndReadHeader(true); + } + + _fileOK = success; + } + finally + { + CloseReaders(); + } + } + catch (Exception ex) + { + Log?.Write(LogType.Error, ex.Message); + _fileOK = false; + _dataSizeB = 0; + _cartSizeB = 0; + _fileSizeB = 0; + _offsetB = 0; + } + } + + private bool CheckAndReadHeader(bool assumeKeyArea) + { + // Read file size + _fileSizeB = _fileStream.Length; + if (_fileSizeB < 32 * 1024) + { + Log?.Write(LogType.Error, "The source file doesn't look like an XCI file as the data size is too small"); + return false; + } + + // Setup offset + _offsetB = (long)(assumeKeyArea ? XCIFileTrimmer.CartKeyAreaSize : 0); + + // Check header + Pos = _offsetB + XCIFileTrimmer.HeaderFilePos; + string head = System.Text.Encoding.ASCII.GetString(_binaryReader.ReadBytes(4)); + if (head != XCIFileTrimmer.HeaderMagicValue) + { + if (!assumeKeyArea) + { + Log?.Write(LogType.Warn, $"Incorrect header found, file mat contain a key area..."); + } + else + { + Log?.Write(LogType.Error, "The source file doesn't look like an XCI file as the header is corrupted"); + } + + return false; + } + + // Read Cart Size + Pos = _offsetB + XCIFileTrimmer.CartSizeFilePos; + byte cartSizeId = _binaryReader.ReadByte(); + if (!_cartSizesGB.TryGetValue(cartSizeId, out long cartSizeNGB)) + { + Log?.Write(LogType.Error, $"The source file doesn't look like an XCI file as the Cartridge Size is incorrect (0x{cartSizeId:X2})"); + return false; + } + _cartSizeB = cartSizeNGB * XCIFileTrimmer.CartSizeMBinFormattedGB * XCIFileTrimmer.BytesInAMegabyte; + + // Read data size + Pos = _offsetB + XCIFileTrimmer.DataSizeFilePos; + long records = (long)BitConverter.ToUInt32(_binaryReader.ReadBytes(4), 0); + _dataSizeB = RecordsToByte(records); + + return true; + } + } +} diff --git a/src/Ryujinx.HLE.Generators/IpcServiceGenerator.cs b/src/Ryujinx.HLE.Generators/IpcServiceGenerator.cs index 5dcd49af5..5cac4d13a 100644 --- a/src/Ryujinx.HLE.Generators/IpcServiceGenerator.cs +++ b/src/Ryujinx.HLE.Generators/IpcServiceGenerator.cs @@ -13,6 +13,7 @@ namespace Ryujinx.HLE.Generators var syntaxReceiver = (ServiceSyntaxReceiver)context.SyntaxReceiver; CodeGenerator generator = new CodeGenerator(); + generator.AppendLine("#nullable enable"); generator.AppendLine("using System;"); generator.EnterScope($"namespace Ryujinx.HLE.HOS.Services.Sm"); generator.EnterScope($"partial class IUserInterface"); @@ -58,6 +59,7 @@ namespace Ryujinx.HLE.Generators generator.LeaveScope(); generator.LeaveScope(); + generator.AppendLine("#nullable disable"); context.AddSource($"IUserInterface.g.cs", generator.ToString()); } diff --git a/src/Ryujinx.UI.Common/Models/XCITrimmerFileModel.cs b/src/Ryujinx.UI.Common/Models/XCITrimmerFileModel.cs new file mode 100644 index 000000000..05fa82920 --- /dev/null +++ b/src/Ryujinx.UI.Common/Models/XCITrimmerFileModel.cs @@ -0,0 +1,55 @@ +using Ryujinx.Common.Logging; +using Ryujinx.Common.Utilities; +using Ryujinx.UI.App.Common; + +namespace Ryujinx.UI.Common.Models +{ + public record XCITrimmerFileModel( + string Name, + string Path, + bool Trimmable, + bool Untrimmable, + long PotentialSavingsB, + long CurrentSavingsB, + int? PercentageProgress, + XCIFileTrimmer.OperationOutcome ProcessingOutcome) + { + public static XCITrimmerFileModel FromApplicationData(ApplicationData applicationData, XCIFileTrimmerLog logger) + { + var trimmer = new XCIFileTrimmer(applicationData.Path, logger); + + return new XCITrimmerFileModel( + applicationData.Name, + applicationData.Path, + trimmer.CanBeTrimmed, + trimmer.CanBeUntrimmed, + trimmer.DiskSpaceSavingsB, + trimmer.DiskSpaceSavedB, + null, + XCIFileTrimmer.OperationOutcome.Undetermined + ); + } + + public bool IsFailed + { + get + { + return ProcessingOutcome != XCIFileTrimmer.OperationOutcome.Undetermined && + ProcessingOutcome != XCIFileTrimmer.OperationOutcome.Successful; + } + } + + public virtual bool Equals(XCITrimmerFileModel obj) + { + if (obj == null) + return false; + else + return this.Path == obj.Path; + } + + public override int GetHashCode() + { + return this.Path.GetHashCode(); + } + } +} diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json index 8c2e7db71..c2ea29b9a 100644 --- a/src/Ryujinx/Assets/Locales/en_US.json +++ b/src/Ryujinx/Assets/Locales/en_US.json @@ -33,6 +33,7 @@ "MenuBarToolsManageFileTypes": "Manage file types", "MenuBarToolsInstallFileTypes": "Install file types", "MenuBarToolsUninstallFileTypes": "Uninstall file types", + "MenuBarToolsXCITrimmer": "Trim XCI Files", "MenuBarView": "_View", "MenuBarViewWindow": "Window Size", "MenuBarViewWindow720": "720p", @@ -84,8 +85,11 @@ "GameListContextMenuOpenModsDirectoryToolTip": "Opens the directory which contains Application's Mods", "GameListContextMenuOpenSdModsDirectory": "Open Atmosphere Mods Directory", "GameListContextMenuOpenSdModsDirectoryToolTip": "Opens the alternative SD card Atmosphere directory which contains Application's Mods. Useful for mods that are packaged for real hardware.", + "GameListContextMenuTrimXCI": "Check and Trim XCI File", + "GameListContextMenuTrimXCIToolTip": "Check and Trim XCI File to Save Disk Space", "StatusBarGamesLoaded": "{0}/{1} Games Loaded", "StatusBarSystemVersion": "System Version: {0}", + "StatusBarXCIFileTrimming": "Trimming XCI File '{0}'", "LinuxVmMaxMapCountDialogTitle": "Low limit for memory mappings detected", "LinuxVmMaxMapCountDialogTextPrimary": "Would you like to increase the value of vm.max_map_count to {0}", "LinuxVmMaxMapCountDialogTextSecondary": "Some games might try to create more memory mappings than currently allowed. Ryujinx will crash as soon as this limit gets exceeded.", @@ -400,6 +404,8 @@ "InputDialogTitle": "Input Dialog", "InputDialogOk": "OK", "InputDialogCancel": "Cancel", + "InputDialogCancelling": "Cancelling", + "InputDialogClose": "Close", "InputDialogAddNewProfileTitle": "Choose the Profile Name", "InputDialogAddNewProfileHeader": "Please Enter a Profile Name", "InputDialogAddNewProfileSubtext": "(Max Length: {0})", @@ -468,6 +474,7 @@ "DialogUninstallFileTypesSuccessMessage": "Successfully uninstalled file types!", "DialogUninstallFileTypesErrorMessage": "Failed to uninstall file types.", "DialogOpenSettingsWindowLabel": "Open Settings Window", + "DialogOpenXCITrimmerWindowLabel": "XCI Trimmer Window", "DialogControllerAppletTitle": "Controller Applet", "DialogMessageDialogErrorExceptionMessage": "Error displaying Message Dialog: {0}", "DialogSoftwareKeyboardErrorExceptionMessage": "Error displaying Software Keyboard: {0}", @@ -670,6 +677,12 @@ "TitleUpdateVersionLabel": "Version {0}", "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", "TitleBundledDlcLabel": "Bundled:", + "TitleXCIStatusPartialLabel": "Partial", + "TitleXCIStatusTrimmableLabel": "Untrimmed", + "TitleXCIStatusUntrimmableLabel": "Trimmed", + "TitleXCIStatusFailedLabel": "(Failed)", + "TitleXCICanSaveLabel": "Save {0:n0} Mb", + "TitleXCISavingLabel": "Saved {0:n0} Mb", "RyujinxInfo": "Ryujinx - Info", "RyujinxConfirm": "Ryujinx - Confirmation", "FileDialogAllTypes": "All types", @@ -722,11 +735,37 @@ "SelectDlcDialogTitle": "Select DLC files", "SelectUpdateDialogTitle": "Select update files", "SelectModDialogTitle": "Select mod directory", + "TrimXCIFileDialogTitle": "Check and Trim XCI File", + "TrimXCIFileDialogPrimaryText": "This function will first check the empty space and then trim the XCI File to save disk space.", + "TrimXCIFileDialogSecondaryText": "Current File Size: {0:n} MB\nGame Data Size: {1:n} MB\nDisk Space Savings: {2:n} MB", + "TrimXCIFileNoTrimNecessary": "XCI File does not need to be trimmed. Check logs for further details", + "TrimXCIFileNoUntrimPossible": "XCI File cannot be untrimmed. Check logs for further details", + "TrimXCIFileReadOnlyFileCannotFix": "XCI File is Read Only and could not be made writable. Check logs for further details", + "TrimXCIFileFileSizeChanged": "XCI File has changed in size since it was scanned. Please check the file is not being written to and try again.", + "TrimXCIFileFreeSpaceCheckFailed": "XCI File has data in the free space area, it is not safe to trim", + "TrimXCIFileInvalidXCIFile": "XCI File contains invalid data. Check logs for further details", + "TrimXCIFileFileIOWriteError": "XCI File could not be opened for writing. Check logs for further details", + "TrimXCIFileFailedPrimaryText": "Trimming of the XCI file failed", + "TrimXCIFileCancelled": "The operation was cancelled", + "TrimXCIFileFileUndertermined": "No operation was performed", "UserProfileWindowTitle": "User Profiles Manager", "CheatWindowTitle": "Cheats Manager", "DlcWindowTitle": "Manage Downloadable Content for {0} ({1})", "ModWindowTitle": "Manage Mods for {0} ({1})", "UpdateWindowTitle": "Title Update Manager", + "XCITrimmerWindowTitle": "XCI File Trimmer", + "XCITrimmerTitleStatusCount": "{0} of {1} Title(s) Selected", + "XCITrimmerTitleStatusCountWithFilter": "{0} of {1} Title(s) Selected ({2} displayed)", + "XCITrimmerTitleStatusTrimming": "Trimming {0} Title(s)...", + "XCITrimmerTitleStatusUntrimming": "Untrimming {0} Title(s)...", + "XCITrimmerTitleStatusFailed": "Failed", + "XCITrimmerPotentialSavings": "Potential Savings", + "XCITrimmerActualSavings": "Actual Savings", + "XCITrimmerSavingsMb": "{0:n0} Mb", + "XCITrimmerSelectDisplayed": "Select Shown", + "XCITrimmerDeselectDisplayed": "Deselect Shown", + "XCITrimmerSortName": "Title", + "XCITrimmerSortSaved": "Space Savings", "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "Cheats Available for {0} [{1}]", @@ -740,6 +779,7 @@ "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} Mod(s)", "UserProfilesEditProfile": "Edit Selected", + "Continue": "Continue", "Cancel": "Cancel", "Save": "Save", "Discard": "Discard", diff --git a/src/Ryujinx/Assets/Styles/Styles.xaml b/src/Ryujinx/Assets/Styles/Styles.xaml index b3a6f59c8..05212a7dd 100644 --- a/src/Ryujinx/Assets/Styles/Styles.xaml +++ b/src/Ryujinx/Assets/Styles/Styles.xaml @@ -43,6 +43,10 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml.cs b/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml.cs new file mode 100644 index 000000000..580ebc9da --- /dev/null +++ b/src/Ryujinx/UI/Windows/XCITrimmerWindow.axaml.cs @@ -0,0 +1,101 @@ +using Avalonia.Controls; +using Avalonia.Interactivity; +using Avalonia.Styling; +using FluentAvalonia.UI.Controls; +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.UI.Common.Models; +using System; +using System.Threading.Tasks; + +namespace Ryujinx.Ava.UI.Windows +{ + public partial class XCITrimmerWindow : UserControl + { + public XCITrimmerViewModel ViewModel; + + public XCITrimmerWindow() + { + DataContext = this; + + InitializeComponent(); + } + + public XCITrimmerWindow(MainWindowViewModel mainWindowViewModel) + { + DataContext = ViewModel = new XCITrimmerViewModel(mainWindowViewModel); + + InitializeComponent(); + } + + public static async Task Show(MainWindowViewModel mainWindowViewModel) + { + ContentDialog contentDialog = new() + { + PrimaryButtonText = "", + SecondaryButtonText = "", + CloseButtonText = "", + Content = new XCITrimmerWindow(mainWindowViewModel), + Title = string.Format(LocaleManager.Instance[LocaleKeys.XCITrimmerWindowTitle]), + }; + + Style bottomBorder = new(x => x.OfType().Name("DialogSpace").Child().OfType()); + bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false)); + + contentDialog.Styles.Add(bottomBorder); + + await contentDialog.ShowAsync(); + } + + private void Trim(object sender, RoutedEventArgs e) + { + ViewModel.TrimSelected(); + } + + private void Untrim(object sender, RoutedEventArgs e) + { + ViewModel.UntrimSelected(); + } + + private void Close(object sender, RoutedEventArgs e) + { + ((ContentDialog)Parent).Hide(); + } + + private void Cancel(Object sender, RoutedEventArgs e) + { + ViewModel.Cancel = true; + } + + public void Sort_Checked(object sender, RoutedEventArgs args) + { + if (sender is RadioButton { Tag: string sortField }) + ViewModel.SortingField = Enum.Parse(sortField); + } + + public void Order_Checked(object sender, RoutedEventArgs args) + { + if (sender is RadioButton { Tag: string sortOrder }) + ViewModel.SortingAscending = sortOrder is "Ascending"; + } + + private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + foreach (var content in e.AddedItems) + { + if (content is XCITrimmerFileModel applicationData) + { + ViewModel.Select(applicationData); + } + } + + foreach (var content in e.RemovedItems) + { + if (content is XCITrimmerFileModel applicationData) + { + ViewModel.Deselect(applicationData); + } + } + } + } +} From 75f714488e46fc7181b65dbd9ff433e39fc5339b Mon Sep 17 00:00:00 2001 From: GabCoolGuy Date: Thu, 7 Nov 2024 00:57:12 +0100 Subject: [PATCH 09/15] Add many missing locales to all languages (#160) * Added many missing locales --- src/Ryujinx/Assets/Locales/ar_SA.json | 22 ++++++++++++++++++++++ src/Ryujinx/Assets/Locales/de_DE.json | 22 ++++++++++++++++++++++ src/Ryujinx/Assets/Locales/el_GR.json | 22 ++++++++++++++++++++++ src/Ryujinx/Assets/Locales/en_US.json | 2 +- src/Ryujinx/Assets/Locales/es_ES.json | 21 +++++++++++++++++++++ src/Ryujinx/Assets/Locales/fr_FR.json | 10 +++++----- src/Ryujinx/Assets/Locales/he_IL.json | 22 ++++++++++++++++++++++ src/Ryujinx/Assets/Locales/it_IT.json | 2 +- src/Ryujinx/Assets/Locales/ja_JP.json | 21 +++++++++++++++++++++ src/Ryujinx/Assets/Locales/ko_KR.json | 22 ++++++++++++++++++++++ src/Ryujinx/Assets/Locales/pl_PL.json | 22 ++++++++++++++++++++++ src/Ryujinx/Assets/Locales/ru_RU.json | 22 ++++++++++++++++++++++ src/Ryujinx/Assets/Locales/th_TH.json | 4 +++- src/Ryujinx/Assets/Locales/tr_TR.json | 24 +++++++++++++++++++++++- src/Ryujinx/Assets/Locales/uk_UA.json | 22 ++++++++++++++++++++++ src/Ryujinx/Assets/Locales/zh_CN.json | 4 +++- src/Ryujinx/Assets/Locales/zh_TW.json | 22 ++++++++++++++++++++++ 17 files changed, 276 insertions(+), 10 deletions(-) diff --git a/src/Ryujinx/Assets/Locales/ar_SA.json b/src/Ryujinx/Assets/Locales/ar_SA.json index 22e270901..f2720b669 100644 --- a/src/Ryujinx/Assets/Locales/ar_SA.json +++ b/src/Ryujinx/Assets/Locales/ar_SA.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "استخدم مراقب الأجهزة الافتراضية", "MenuBarFile": "_ملف", "MenuBarFileOpenFromFile": "_تحميل تطبيق من ملف", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "تحميل لُعْبَة غير محزومة", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "‫فتح مجلد Ryujinx", "MenuBarFileOpenLogsFolder": "فتح مجلد السجلات", "MenuBarFileExit": "_خروج", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "عند الخمول", "SettingsTabGeneralHideCursorAlways": "دائما", "SettingsTabGeneralGameDirectories": "مجلدات الألعاب", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "إضافة", "SettingsTabGeneralRemove": "إزالة", "SettingsTabSystem": "النظام", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "تعيين كمفضل", "GameListContextMenuToggleFavoriteToolTip": "تبديل الحالة المفضلة للعبة", "SettingsTabGeneralTheme": "السمة:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "داكن", "SettingsTabGeneralThemeLight": "فاتح", "ControllerSettingsConfigureGeneral": "ضبط", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "أدخل مجلد اللعبة لإضافته إلى القائمة", "AddGameDirTooltip": "إضافة مجلد اللعبة إلى القائمة", "RemoveGameDirTooltip": "إزالة مجلد اللعبة المحدد", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "استخدم سمة أفالونيا المخصصة لواجهة المستخدم الرسومية لتغيير مظهر قوائم المحاكي", "CustomThemePathTooltip": "مسار سمة واجهة المستخدم المخصصة", "CustomThemeBrowseTooltip": "تصفح للحصول على سمة واجهة المستخدم المخصصة", @@ -606,6 +615,8 @@ "DebugLogTooltip": "طباعة رسائل سجل التصحيح في وحدة التحكم.\n\nاستخدم هذا فقط إذا طلب منك أحد الموظفين تحديدًا ذلك، لأنه سيجعل من الصعب قراءة السجلات وسيؤدي إلى تدهور أداء المحاكي.", "LoadApplicationFileTooltip": "افتح مستكشف الملفات لاختيار ملف متوافق مع سويتش لتحميله", "LoadApplicationFolderTooltip": "افتح مستكشف الملفات لاختيار تطبيق متوافق مع سويتش للتحميل", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "فتح مجلد نظام ملفات ريوجينكس", "OpenRyujinxLogsTooltip": "يفتح المجلد الذي تتم كتابة السجلات إليه", "ExitTooltip": "الخروج من ريوجينكس", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "فتح دليل الإعداد", "NoUpdate": "لا يوجد تحديث", "TitleUpdateVersionLabel": "الإصدار: {0}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "ريوجينكس - معلومات", "RyujinxConfirm": "ريوجينكس - تأكيد", "FileDialogAllTypes": "كل الأنواع", @@ -714,9 +727,17 @@ "DlcWindowTitle": "إدارة المحتوى القابل للتنزيل لـ {0} ({1})", "ModWindowTitle": "إدارة التعديلات لـ {0} ({1})", "UpdateWindowTitle": "مدير تحديث العنوان", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "الغش متوفر لـ {0} [{1}]", "BuildId": "معرف البناء:", + "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowHeading": "المحتويات القابلة للتنزيل {0}", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} تعديل", "UserProfilesEditProfile": "تعديل المحدد", "Cancel": "إلغاء", @@ -767,6 +788,7 @@ "GraphicsScalingFilterBilinear": "Bilinear", "GraphicsScalingFilterNearest": "Nearest", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "المستوى", "GraphicsScalingFilterLevelTooltip": "اضبط مستوى وضوح FSR 1.0. الأعلى هو أكثر وضوحا.", "SmaaLow": "SMAA منخفض", diff --git a/src/Ryujinx/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json index 94e372e2e..4004ec325 100644 --- a/src/Ryujinx/Assets/Locales/de_DE.json +++ b/src/Ryujinx/Assets/Locales/de_DE.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "Hypervisor verwenden", "MenuBarFile": "_Datei", "MenuBarFileOpenFromFile": "Datei _öffnen", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "_Entpacktes Spiel öffnen", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "Ryujinx-Ordner öffnen", "MenuBarFileOpenLogsFolder": "Logs-Ordner öffnen", "MenuBarFileExit": "_Beenden", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "Mauszeiger bei Inaktivität ausblenden", "SettingsTabGeneralHideCursorAlways": "Immer", "SettingsTabGeneralGameDirectories": "Spielverzeichnisse", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "Hinzufügen", "SettingsTabGeneralRemove": "Entfernen", "SettingsTabSystem": "System", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "Als Favoriten hinzufügen/entfernen", "GameListContextMenuToggleFavoriteToolTip": "Aktiviert den Favoriten-Status des Spiels", "SettingsTabGeneralTheme": "Design:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "Dunkel", "SettingsTabGeneralThemeLight": "Hell", "ControllerSettingsConfigureGeneral": "Konfigurieren", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "Gibt das Spielverzeichnis an, das der Liste hinzuzufügt wird", "AddGameDirTooltip": "Fügt ein neues Spielverzeichnis hinzu", "RemoveGameDirTooltip": "Entfernt das ausgewähltes Spielverzeichnis", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "Verwende ein eigenes Design für die Emulator-Benutzeroberfläche", "CustomThemePathTooltip": "Gibt den Pfad zum Design für die Emulator-Benutzeroberfläche an", "CustomThemeBrowseTooltip": "Ermöglicht die Suche nach einem benutzerdefinierten Design für die Emulator-Benutzeroberfläche", @@ -606,6 +615,8 @@ "DebugLogTooltip": "Ausgabe von Debug-Logs in der Konsole.\n\nVerwende diese Option nur auf ausdrückliche Anweisung von Ryujinx Entwicklern, da sie das Lesen der Protokolle erschwert und die Leistung des Emulators verschlechtert.", "LoadApplicationFileTooltip": "Öffnet die Dateiauswahl um Datei zu laden, welche mit der Switch kompatibel ist", "LoadApplicationFolderTooltip": "Öffnet die Dateiauswahl um ein Spiel zu laden, welches mit der Switch kompatibel ist", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "Öffnet den Ordner, der das Ryujinx Dateisystem enthält", "OpenRyujinxLogsTooltip": "Öffnet den Ordner, in welchem die Logs gespeichert werden", "ExitTooltip": "Beendet Ryujinx", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "Öffne den 'Setup Guide'", "NoUpdate": "Kein Update", "TitleUpdateVersionLabel": "Version {0} - {1}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "Ryujinx - Info", "RyujinxConfirm": "Ryujinx - Bestätigung", "FileDialogAllTypes": "Alle Typen", @@ -714,9 +727,17 @@ "DlcWindowTitle": "Spiel-DLC verwalten", "ModWindowTitle": "Manage Mods for {0} ({1})", "UpdateWindowTitle": "Spiel-Updates verwalten", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "Cheats verfügbar für {0} [{1}]", + "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "BuildId": "BuildId:", "DlcWindowHeading": "DLC verfügbar für {0} [{1}]", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} Mod(s)", "UserProfilesEditProfile": "Profil bearbeiten", "Cancel": "Abbrechen", @@ -767,6 +788,7 @@ "GraphicsScalingFilterBilinear": "Bilinear", "GraphicsScalingFilterNearest": "Nächstes", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "Stufe", "GraphicsScalingFilterLevelTooltip": "FSR 1.0 Schärfelevel festlegen. Höher ist schärfer.", "SmaaLow": "SMAA Niedrig", diff --git a/src/Ryujinx/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json index 89389d337..56940ffc9 100644 --- a/src/Ryujinx/Assets/Locales/el_GR.json +++ b/src/Ryujinx/Assets/Locales/el_GR.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "Χρήση Hypervisor", "MenuBarFile": "_Αρχείο", "MenuBarFileOpenFromFile": "_Φόρτωση Αρχείου Εφαρμογής", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "Φόρτωση Απακετάριστου _Παιχνιδιού", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "Άνοιγμα Φακέλου Ryujinx", "MenuBarFileOpenLogsFolder": "Άνοιγμα Φακέλου Καταγραφής", "MenuBarFileExit": "_Έξοδος", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "Απόκρυψη Δρομέα στην Αδράνεια", "SettingsTabGeneralHideCursorAlways": "Πάντα", "SettingsTabGeneralGameDirectories": "Τοποθεσίες παιχνιδιών", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "Προσθήκη", "SettingsTabGeneralRemove": "Αφαίρεση", "SettingsTabSystem": "Σύστημα", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "Εναλλαγή Αγαπημένου", "GameListContextMenuToggleFavoriteToolTip": "Εναλλαγή της Κατάστασης Αγαπημένο του Παιχνιδιού", "SettingsTabGeneralTheme": "Theme:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "Dark", "SettingsTabGeneralThemeLight": "Light", "ControllerSettingsConfigureGeneral": "Παραμέτρων", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "Εισαγάγετε μία τοποθεσία παιχνιδιών για προσθήκη στη λίστα", "AddGameDirTooltip": "Προσθέστε μία τοποθεσία παιχνιδιών στη λίστα", "RemoveGameDirTooltip": "Αφαιρέστε την επιλεγμένη τοποθεσία παιχνιδιών", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "Ενεργοποίηση ή απενεργοποίηση προσαρμοσμένων θεμάτων στο GUI", "CustomThemePathTooltip": "Διαδρομή προς το προσαρμοσμένο θέμα GUI", "CustomThemeBrowseTooltip": "Αναζητήστε ένα προσαρμοσμένο θέμα GUI", @@ -606,6 +615,8 @@ "DebugLogTooltip": "Ενεργοποιεί την εκτύπωση μηνυμάτων αρχείου καταγραφής εντοπισμού σφαλμάτων", "LoadApplicationFileTooltip": "Ανοίξτε έναν επιλογέα αρχείων για να επιλέξετε ένα αρχείο συμβατό με το Switch για φόρτωση", "LoadApplicationFolderTooltip": "Ανοίξτε έναν επιλογέα αρχείων για να επιλέξετε μία μη συσκευασμένη εφαρμογή, συμβατή με το Switch για φόρτωση", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "Ανοίξτε το φάκελο συστήματος αρχείων Ryujinx", "OpenRyujinxLogsTooltip": "Ανοίξτε το φάκελο στον οποίο διατηρούνται τα αρχεία καταγραφής", "ExitTooltip": "Έξοδος από το Ryujinx", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "Ανοίξτε τον Οδηγό Εγκατάστασης.", "NoUpdate": "Καμία Eνημέρωση", "TitleUpdateVersionLabel": "Version {0} - {1}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "Ryujinx - Πληροφορίες", "RyujinxConfirm": "Ryujinx - Επιβεβαίωση", "FileDialogAllTypes": "Όλοι οι τύποι", @@ -714,9 +727,17 @@ "DlcWindowTitle": "Downloadable Content Manager", "ModWindowTitle": "Manage Mods for {0} ({1})", "UpdateWindowTitle": "Διαχειριστής Ενημερώσεων Τίτλου", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "Διαθέσιμα Cheats για {0} [{1}]", "BuildId": "BuildId:", + "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowHeading": "{0} Downloadable Content(s) available for {1} ({2})", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} Mod(s)", "UserProfilesEditProfile": "Επεξεργασία Επιλεγμένων", "Cancel": "Ακύρωση", @@ -767,6 +788,7 @@ "GraphicsScalingFilterBilinear": "Bilinear", "GraphicsScalingFilterNearest": "Nearest", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "Επίπεδο", "GraphicsScalingFilterLevelTooltip": "Set FSR 1.0 sharpening level. Higher is sharper.", "SmaaLow": "Χαμηλό SMAA", diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json index c2ea29b9a..f0b10c945 100644 --- a/src/Ryujinx/Assets/Locales/en_US.json +++ b/src/Ryujinx/Assets/Locales/en_US.json @@ -771,7 +771,7 @@ "CheatWindowHeading": "Cheats Available for {0} [{1}]", "BuildId": "BuildId:", "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", - "DlcWindowHeading": "{0} Downloadable Content(s)", + "DlcWindowHeading": "{0} Downloadable Content(s) available for {1} ({2})", "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json index d6eb8017a..bbc86ed0c 100644 --- a/src/Ryujinx/Assets/Locales/es_ES.json +++ b/src/Ryujinx/Assets/Locales/es_ES.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "Usar hipervisor", "MenuBarFile": "_Archivo", "MenuBarFileOpenFromFile": "_Cargar aplicación desde un archivo", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "Cargar juego _desempaquetado", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "Abrir carpeta de Ryujinx", "MenuBarFileOpenLogsFolder": "Abrir carpeta de registros", "MenuBarFileExit": "_Salir", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "Ocultar cursor cuando esté inactivo", "SettingsTabGeneralHideCursorAlways": "Siempre", "SettingsTabGeneralGameDirectories": "Carpetas de juegos", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "Agregar", "SettingsTabGeneralRemove": "Quitar", "SettingsTabSystem": "Sistema", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "Marcar favorito", "GameListContextMenuToggleFavoriteToolTip": "Marca o desmarca el juego como favorito", "SettingsTabGeneralTheme": "Tema:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "Oscuro", "SettingsTabGeneralThemeLight": "Claro", "ControllerSettingsConfigureGeneral": "Configurar", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "Elige un directorio de juegos para mostrar en la ventana principal", "AddGameDirTooltip": "Agrega un directorio de juegos a la lista", "RemoveGameDirTooltip": "Quita el directorio seleccionado de la lista", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "Activa o desactiva los temas personalizados para la interfaz", "CustomThemePathTooltip": "Carpeta que contiene los temas personalizados para la interfaz", "CustomThemeBrowseTooltip": "Busca un tema personalizado para la interfaz", @@ -606,6 +615,8 @@ "DebugLogTooltip": "Escribe mensajes de debug en la consola\n\nActiva esto solo si un miembro del equipo te lo pide expresamente, pues hará que el registro sea difícil de leer y empeorará el rendimiento del emulador.", "LoadApplicationFileTooltip": "Abre el explorador de archivos para elegir un archivo compatible con Switch para cargar", "LoadApplicationFolderTooltip": "Abre el explorador de archivos para elegir un archivo desempaquetado y compatible con Switch para cargar", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "Abre la carpeta de sistema de Ryujinx", "OpenRyujinxLogsTooltip": "Abre la carpeta en la que se guardan los registros", "ExitTooltip": "Cierra Ryujinx", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "Abrir la guía de instalación", "NoUpdate": "No actualizado", "TitleUpdateVersionLabel": "Versión {0} - {1}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "Ryujinx - Info", "RyujinxConfirm": "Ryujinx - Confirmación", "FileDialogAllTypes": "Todos los tipos", @@ -714,9 +727,16 @@ "DlcWindowTitle": "Administrar contenido descargable", "ModWindowTitle": "Manage Mods for {0} ({1})", "UpdateWindowTitle": "Administrar actualizaciones", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "Cheats disponibles para {0} [{1}]", "BuildId": "Id de compilación:", "DlcWindowHeading": "Contenido descargable disponible para {0} [{1}]", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} Mod(s)", "UserProfilesEditProfile": "Editar selección", "Cancel": "Cancelar", @@ -767,6 +787,7 @@ "GraphicsScalingFilterBilinear": "Bilinear\n", "GraphicsScalingFilterNearest": "Cercano", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "Nivel", "GraphicsScalingFilterLevelTooltip": "Ajuste el nivel de nitidez FSR 1.0. Mayor es más nítido.", "SmaaLow": "SMAA Bajo", diff --git a/src/Ryujinx/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json index df8adac00..0c673f719 100644 --- a/src/Ryujinx/Assets/Locales/fr_FR.json +++ b/src/Ryujinx/Assets/Locales/fr_FR.json @@ -100,7 +100,7 @@ "SettingsTabGeneralCheckUpdatesOnLaunch": "Vérifier les mises à jour au démarrage", "SettingsTabGeneralShowConfirmExitDialog": "Afficher le message de \"Confirmation de sortie\"", "SettingsTabGeneralRememberWindowState": "Mémoriser la taille/position de la fenêtre", - "SettingsTabGeneralShowTitleBar": "Show Title Bar (Requires restart)", + "SettingsTabGeneralShowTitleBar": "Afficher Barre de Titre (Nécessite redémarrage)", "SettingsTabGeneralHideCursor": "Masquer le Curseur :", "SettingsTabGeneralHideCursorNever": "Jamais", "SettingsTabGeneralHideCursorOnIdle": "Masquer le curseur si inactif", @@ -151,7 +151,7 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Hacks", "SettingsTabSystemHacksNote": "Cela peut causer des instabilités", - "SettingsTabSystemDramSize": "Taille de la DRAM:", + "SettingsTabSystemDramSize": "Taille de la DRAM :", "SettingsTabSystemDramSize4GiB": "4GiO", "SettingsTabSystemDramSize6GiB": "6GiO", "SettingsTabSystemDramSize8GiB": "8GiO", @@ -181,7 +181,7 @@ "SettingsTabGraphicsAspectRatio32x9": "32:9", "SettingsTabGraphicsAspectRatioStretch": "Étirer pour remplir la fenêtre", "SettingsTabGraphicsDeveloperOptions": "Options développeur", - "SettingsTabGraphicsShaderDumpPath": "Chemin du dossier de copie des shaders:", + "SettingsTabGraphicsShaderDumpPath": "Chemin du dossier de copie des shaders :", "SettingsTabLogging": "Journaux", "SettingsTabLoggingLogging": "Journaux", "SettingsTabLoggingEnableLoggingToFile": "Activer la sauvegarde des journaux vers un fichier", @@ -387,7 +387,7 @@ "UserProfilesSelectedUserProfile": "Profil utilisateur sélectionné :", "UserProfilesSaveProfileName": "Enregistrer le nom du profil", "UserProfilesChangeProfileImage": "Changer l'image du profil", - "UserProfilesAvailableUserProfiles": "Profils utilisateurs disponibles:", + "UserProfilesAvailableUserProfiles": "Profils utilisateurs disponibles :", "UserProfilesAddNewProfile": "Créer un profil", "UserProfilesDelete": "Supprimer", "UserProfilesClose": "Fermer", @@ -669,7 +669,7 @@ "NoUpdate": "Aucune mise à jour", "TitleUpdateVersionLabel": "Version {0}", "TitleBundledUpdateVersionLabel": "Inclus avec le jeu: Version {0}", - "TitleBundledDlcLabel": "Inclus avec le jeu:", + "TitleBundledDlcLabel": "Inclus avec le jeu :", "RyujinxInfo": "Ryujinx - Info", "RyujinxConfirm": "Ryujinx - Confirmation", "FileDialogAllTypes": "Tous les types", diff --git a/src/Ryujinx/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json index eb7ccf322..cac3fbf53 100644 --- a/src/Ryujinx/Assets/Locales/he_IL.json +++ b/src/Ryujinx/Assets/Locales/he_IL.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "השתמש ב Hypervisor", "MenuBarFile": "_קובץ", "MenuBarFileOpenFromFile": "_טען יישום מקובץ", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "טען משחק _שאינו ארוז", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "פתח את תיקיית ריוג'ינקס", "MenuBarFileOpenLogsFolder": "פתח את תיקיית קבצי הלוג", "MenuBarFileExit": "_יציאה", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "במצב סרק", "SettingsTabGeneralHideCursorAlways": "תמיד", "SettingsTabGeneralGameDirectories": "תקיות משחקים", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "הוסף", "SettingsTabGeneralRemove": "הסר", "SettingsTabSystem": "מערכת", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "למתג העדפה", "GameListContextMenuToggleFavoriteToolTip": "למתג סטטוס העדפה של משחק", "SettingsTabGeneralTheme": "ערכת נושא:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "כהה", "SettingsTabGeneralThemeLight": "בהיר", "ControllerSettingsConfigureGeneral": "הגדר", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "הזן תקיית משחקים כדי להוסיף לרשימה", "AddGameDirTooltip": "הוסף תקיית משחקים לרשימה", "RemoveGameDirTooltip": "הסר את תקיית המשחקים שנבחרה", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "השתמש בעיצוב מותאם אישית של אבלוניה עבור ה-ממשק הגראפי כדי לשנות את המראה של תפריטי האמולטור", "CustomThemePathTooltip": "נתיב לערכת נושא לממשק גראפי מותאם אישית", "CustomThemeBrowseTooltip": "חפש עיצוב ממשק גראפי מותאם אישית", @@ -606,6 +615,8 @@ "DebugLogTooltip": "מדפיס הודעות יומן ניפוי באגים בשורת הפקודות.", "LoadApplicationFileTooltip": "פתח סייר קבצים כדי לבחור קובץ תואם סוויץ' לטעינה", "LoadApplicationFolderTooltip": "פתח סייר קבצים כדי לבחור יישום תואם סוויץ', לא ארוז לטעינה.", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "פתח את תיקיית מערכת הקבצים ריוג'ינקס", "OpenRyujinxLogsTooltip": "פותח את התיקיה שאליה נכתבים רישומים", "ExitTooltip": "צא מריוג'ינקס", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "פתח מדריך התקנה", "NoUpdate": "אין עדכון", "TitleUpdateVersionLabel": "גרסה {0}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "ריוג'ינקס - מידע", "RyujinxConfirm": "ריוג'ינקס - אישור", "FileDialogAllTypes": "כל הסוגים", @@ -714,9 +727,17 @@ "DlcWindowTitle": "נהל הרחבות משחק עבור {0} ({1})", "ModWindowTitle": "Manage Mods for {0} ({1})", "UpdateWindowTitle": "נהל עדכוני משחקים", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "צ'יטים זמינים עבור {0} [{1}]", "BuildId": "מזהה בניה:", + "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowHeading": "{0} הרחבות משחק", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} מוד(ים)", "UserProfilesEditProfile": "ערוך נבחר/ים", "Cancel": "בטל", @@ -767,6 +788,7 @@ "GraphicsScalingFilterBilinear": "Bilinear", "GraphicsScalingFilterNearest": "Nearest", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "רמה", "GraphicsScalingFilterLevelTooltip": "Set FSR 1.0 sharpening level. Higher is sharper.", "SmaaLow": "SMAA נמוך", diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json index 87c8e6bab..419a5dd2b 100644 --- a/src/Ryujinx/Assets/Locales/it_IT.json +++ b/src/Ryujinx/Assets/Locales/it_IT.json @@ -788,12 +788,12 @@ "GraphicsScalingFilterBilinear": "Bilineare", "GraphicsScalingFilterNearest": "Nearest", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "Livello", "GraphicsScalingFilterLevelTooltip": "Imposta il livello di nitidezza di FSR 1.0. Valori più alti comportano una maggiore nitidezza.", "SmaaLow": "SMAA Basso", "SmaaMedium": "SMAA Medio", "SmaaHigh": "SMAA Alto", - "GraphicsScalingFilterArea": "Area", "SmaaUltra": "SMAA Ultra", "UserEditorTitle": "Modificare L'Utente", "UserEditorTitleCreate": "Crea Un Utente", diff --git a/src/Ryujinx/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json index d43dedc2a..b2c0a506e 100644 --- a/src/Ryujinx/Assets/Locales/ja_JP.json +++ b/src/Ryujinx/Assets/Locales/ja_JP.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "ハイパーバイザーを使用", "MenuBarFile": "ファイル(_F)", "MenuBarFileOpenFromFile": "ファイルからアプリケーションをロード(_L)", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "展開されたゲームをロード", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "Ryujinx フォルダを開く", "MenuBarFileOpenLogsFolder": "ログフォルダを開く", "MenuBarFileExit": "終了(_E)", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "アイドル時", "SettingsTabGeneralHideCursorAlways": "常時", "SettingsTabGeneralGameDirectories": "ゲームディレクトリ", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "追加", "SettingsTabGeneralRemove": "削除", "SettingsTabSystem": "システム", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "お気に入りを切り替え", "GameListContextMenuToggleFavoriteToolTip": "ゲームをお気に入りに含めるかどうかを切り替えます", "SettingsTabGeneralTheme": "テーマ:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "ダーク", "SettingsTabGeneralThemeLight": "ライト", "ControllerSettingsConfigureGeneral": "設定", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "リストに追加するゲームディレクトリを入力します", "AddGameDirTooltip": "リストにゲームディレクトリを追加します", "RemoveGameDirTooltip": "選択したゲームディレクトリを削除します", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "エミュレータのメニュー外観を変更するためカスタム Avalonia テーマを使用します", "CustomThemePathTooltip": "カスタム GUI テーマのパスです", "CustomThemeBrowseTooltip": "カスタム GUI テーマを参照します", @@ -606,6 +615,8 @@ "DebugLogTooltip": "デバッグログメッセージをコンソールに出力します.\n\nログが読みづらくなり,エミュレータのパフォーマンスが低下するため,開発者から特別な指示がある場合のみ使用してください.", "LoadApplicationFileTooltip": "ロードする Switch 互換のファイルを選択するためファイルエクスプローラを開きます", "LoadApplicationFolderTooltip": "ロードする Switch 互換の展開済みアプリケーションを選択するためファイルエクスプローラを開きます", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "Ryujinx ファイルシステムフォルダを開きます", "OpenRyujinxLogsTooltip": "ログが格納されるフォルダを開きます", "ExitTooltip": "Ryujinx を終了します", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "セットアップガイドを開く", "NoUpdate": "アップデートなし", "TitleUpdateVersionLabel": "バージョン {0} - {1}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "Ryujinx - 情報", "RyujinxConfirm": "Ryujinx - 確認", "FileDialogAllTypes": "すべての種別", @@ -714,9 +727,16 @@ "DlcWindowTitle": "DLC 管理", "ModWindowTitle": "Manage Mods for {0} ({1})", "UpdateWindowTitle": "アップデート管理", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "利用可能なチート {0} [{1}]", "BuildId": "ビルドID:", "DlcWindowHeading": "利用可能な DLC {0} [{1}]", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} Mod(s)", "UserProfilesEditProfile": "編集", "Cancel": "キャンセル", @@ -767,6 +787,7 @@ "GraphicsScalingFilterBilinear": "Bilinear", "GraphicsScalingFilterNearest": "Nearest", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "レベル", "GraphicsScalingFilterLevelTooltip": "FSR 1.0のシャープ化レベルを設定します. 高い値ほどシャープになります.", "SmaaLow": "SMAA Low", diff --git a/src/Ryujinx/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json index 6e5a7f187..bce762d19 100644 --- a/src/Ryujinx/Assets/Locales/ko_KR.json +++ b/src/Ryujinx/Assets/Locales/ko_KR.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "하이퍼바이저 사용하기", "MenuBarFile": "_파일", "MenuBarFileOpenFromFile": "_파일에서 응용 프로그램 불러오기", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "_압축을 푼 게임 불러오기", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "Ryujinx 폴더 열기", "MenuBarFileOpenLogsFolder": "로그 폴더 열기", "MenuBarFileExit": "_종료", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "유휴 상태", "SettingsTabGeneralHideCursorAlways": "언제나", "SettingsTabGeneralGameDirectories": "게임 디렉터리", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "추가", "SettingsTabGeneralRemove": "제거", "SettingsTabSystem": "시스템", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "즐겨찾기 전환", "GameListContextMenuToggleFavoriteToolTip": "게임 즐겨찾기 상태 전환", "SettingsTabGeneralTheme": "테마:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "어두운 테마", "SettingsTabGeneralThemeLight": "밝은 테마", "ControllerSettingsConfigureGeneral": "구성", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "목록에 추가할 게임 디렉터리 입력", "AddGameDirTooltip": "목록에 게임 디렉터리 추가", "RemoveGameDirTooltip": "선택한 게임 디렉터리 제거", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "GUI에 사용자 지정 Avalonia 테마를 사용하여 에뮬레이터 메뉴의 모양 변경", "CustomThemePathTooltip": "사용자 정의 GUI 테마 경로", "CustomThemeBrowseTooltip": "사용자 정의 GUI 테마 찾아보기", @@ -606,6 +615,8 @@ "DebugLogTooltip": "콘솔에 디버그 로그 메시지를 인쇄합니다.\n\n로그를 읽기 어렵게 만들고 에뮬레이터 성능을 악화시키므로 직원이 구체적으로 지시한 경우에만 사용하세요.", "LoadApplicationFileTooltip": "파일 탐색기를 열어 불러올 스위치 호환 파일 선택", "LoadApplicationFolderTooltip": "파일 탐색기를 열어 불러올 스위치 호환 압축 해제 응용 프로그램 선택", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "Ryujinx 파일 시스템 폴더 열기", "OpenRyujinxLogsTooltip": "로그가 기록된 폴더 열기", "ExitTooltip": "Ryujinx 종료", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "설정 가이드 열기", "NoUpdate": "업데이트 없음", "TitleUpdateVersionLabel": "버전 {0}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "Ryujinx - 정보", "RyujinxConfirm": "Ryujinx - 확인", "FileDialogAllTypes": "모든 유형", @@ -714,9 +727,17 @@ "DlcWindowTitle": "{0} ({1})의 다운로드 가능한 콘텐츠 관리", "ModWindowTitle": "{0} ({1})의 Mod 관리", "UpdateWindowTitle": "타이틀 업데이트 관리자", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "{0} [{1}]에 사용할 수 있는 치트", "BuildId": "빌드ID :", + "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowHeading": "{0} 내려받기 가능한 콘텐츠", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} Mod(s)", "UserProfilesEditProfile": "선택된 항목 편집", "Cancel": "취소", @@ -767,6 +788,7 @@ "GraphicsScalingFilterBilinear": "Bilinear", "GraphicsScalingFilterNearest": "Nearest", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "수준", "GraphicsScalingFilterLevelTooltip": "FSR 1.0의 샤프닝 레벨을 설정하세요. 높을수록 더 또렷해집니다.", "SmaaLow": "SMAA 낮음", diff --git a/src/Ryujinx/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json index a377979bd..5a276a7c5 100644 --- a/src/Ryujinx/Assets/Locales/pl_PL.json +++ b/src/Ryujinx/Assets/Locales/pl_PL.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "Użyj Hipernadzorcy", "MenuBarFile": "_Plik", "MenuBarFileOpenFromFile": "_Załaduj aplikację z pliku", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "Załaduj _rozpakowaną grę", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "Otwórz folder Ryujinx", "MenuBarFileOpenLogsFolder": "Otwórz folder plików dziennika zdarzeń", "MenuBarFileExit": "_Wyjdź", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "Gdy bezczynny", "SettingsTabGeneralHideCursorAlways": "Zawsze", "SettingsTabGeneralGameDirectories": "Katalogi gier", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "Dodaj", "SettingsTabGeneralRemove": "Usuń", "SettingsTabSystem": "System", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "Przełącz na ulubione", "GameListContextMenuToggleFavoriteToolTip": "Przełącz status Ulubionej Gry", "SettingsTabGeneralTheme": "Motyw:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "Ciemny", "SettingsTabGeneralThemeLight": "Jasny", "ControllerSettingsConfigureGeneral": "Konfiguruj", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "Wprowadź katalog gier aby dodać go do listy", "AddGameDirTooltip": "Dodaj katalog gier do listy", "RemoveGameDirTooltip": "Usuń wybrany katalog gier", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "Użyj niestandardowego motywu Avalonia dla GUI, aby zmienić wygląd menu emulatora", "CustomThemePathTooltip": "Ścieżka do niestandardowego motywu GUI", "CustomThemeBrowseTooltip": "Wyszukaj niestandardowy motyw GUI", @@ -606,6 +615,8 @@ "DebugLogTooltip": "Wyświetla komunikaty dziennika debugowania w konsoli.\n\nUżywaj tego tylko na wyraźne polecenie członka załogi, ponieważ utrudni to odczytanie dzienników i pogorszy wydajność emulatora.", "LoadApplicationFileTooltip": "Otwórz eksplorator plików, aby wybrać plik kompatybilny z Switch do wczytania", "LoadApplicationFolderTooltip": "Otwórz eksplorator plików, aby wybrać zgodną z Switch, rozpakowaną aplikację do załadowania", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "Otwórz folder systemu plików Ryujinx", "OpenRyujinxLogsTooltip": "Otwiera folder, w którym zapisywane są logi", "ExitTooltip": "Wyjdź z Ryujinx", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "Otwórz Podręcznik Konfiguracji", "NoUpdate": "Brak Aktualizacji", "TitleUpdateVersionLabel": "Wersja {0} - {1}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "Ryujinx - Info", "RyujinxConfirm": "Ryujinx - Potwierdzenie", "FileDialogAllTypes": "Wszystkie typy", @@ -714,9 +727,17 @@ "DlcWindowTitle": "Menedżer Zawartości do Pobrania", "ModWindowTitle": "Zarządzaj modami dla {0} ({1})", "UpdateWindowTitle": "Menedżer Aktualizacji Tytułu", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "Kody Dostępne dla {0} [{1}]", "BuildId": "Identyfikator wersji:", + "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowHeading": "{0} Zawartości do Pobrania dostępna dla {1} ({2})", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} Mod(y/ów)", "UserProfilesEditProfile": "Edytuj Zaznaczone", "Cancel": "Anuluj", @@ -767,6 +788,7 @@ "GraphicsScalingFilterBilinear": "Dwuliniowe", "GraphicsScalingFilterNearest": "Najbliższe", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "Poziom", "GraphicsScalingFilterLevelTooltip": "Ustaw poziom ostrzeżenia FSR 1.0. Wyższy jest ostrzejszy.", "SmaaLow": "SMAA Niskie", diff --git a/src/Ryujinx/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json index 8b9d39302..4980a9a5d 100644 --- a/src/Ryujinx/Assets/Locales/ru_RU.json +++ b/src/Ryujinx/Assets/Locales/ru_RU.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "Использовать Hypervisor", "MenuBarFile": "_Файл", "MenuBarFileOpenFromFile": "_Добавить приложение из файла", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "Добавить _распакованную игру", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "Открыть папку Ryujinx", "MenuBarFileOpenLogsFolder": "Открыть папку с логами", "MenuBarFileExit": "_Выход", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "В простое", "SettingsTabGeneralHideCursorAlways": "Всегда", "SettingsTabGeneralGameDirectories": "Папки с играми", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "Добавить", "SettingsTabGeneralRemove": "Удалить", "SettingsTabSystem": "Система", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "Добавить в избранное", "GameListContextMenuToggleFavoriteToolTip": "Добавляет игру в избранное и помечает звездочкой", "SettingsTabGeneralTheme": "Тема:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "Темная", "SettingsTabGeneralThemeLight": "Светлая", "ControllerSettingsConfigureGeneral": "Настройка", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "Введите путь к папке с играми для добавления ее в список выше", "AddGameDirTooltip": "Добавить папку с играми в список", "RemoveGameDirTooltip": "Удалить выбранную папку игры", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "Включить или отключить пользовательские темы", "CustomThemePathTooltip": "Путь к пользовательской теме для интерфейса", "CustomThemeBrowseTooltip": "Просмотр пользовательской темы интерфейса", @@ -606,6 +615,8 @@ "DebugLogTooltip": "Выводит журнал сообщений отладки в консоли.\n\nИспользуйте только в случае просьбы разработчика, так как включение этой функции затруднит чтение журналов и ухудшит работу эмулятора.", "LoadApplicationFileTooltip": "Открывает файловый менеджер для выбора файла, совместимого с Nintendo Switch.", "LoadApplicationFolderTooltip": "Открывает файловый менеджер для выбора распакованного приложения, совместимого с Nintendo Switch.", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "Открывает папку с файлами Ryujinx. ", "OpenRyujinxLogsTooltip": "Открывает папку в которую записываются логи", "ExitTooltip": "Выйти из Ryujinx", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "Открыть руководство по установке", "NoUpdate": "Без обновлений", "TitleUpdateVersionLabel": "Version {0} - {1}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "Ryujinx - Информация", "RyujinxConfirm": "Ryujinx - Подтверждение", "FileDialogAllTypes": "Все типы", @@ -714,9 +727,17 @@ "DlcWindowTitle": "Управление DLC для {0} ({1})", "ModWindowTitle": "Управление модами для {0} ({1})", "UpdateWindowTitle": "Менеджер обновлений игр", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "Доступные читы для {0} [{1}]", "BuildId": "ID версии:", + "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowHeading": "{0} DLC", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "Моды для {0} ", "UserProfilesEditProfile": "Изменить выбранные", "Cancel": "Отмена", @@ -767,6 +788,7 @@ "GraphicsScalingFilterBilinear": "Билинейная", "GraphicsScalingFilterNearest": "Ступенчатая", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "Уровень", "GraphicsScalingFilterLevelTooltip": "Выбор режима работы FSR 1.0. Выше - четче.", "SmaaLow": "SMAA Низкое", diff --git a/src/Ryujinx/Assets/Locales/th_TH.json b/src/Ryujinx/Assets/Locales/th_TH.json index 9e267dc9e..16c2d9455 100644 --- a/src/Ryujinx/Assets/Locales/th_TH.json +++ b/src/Ryujinx/Assets/Locales/th_TH.json @@ -107,6 +107,7 @@ "SettingsTabGeneralHideCursorAlways": "ตลอดเวลา", "SettingsTabGeneralGameDirectories": "ไดเรกทอรี่ของเกม", "SettingsTabGeneralAutoloadDirectories": "โหลดไดเรกทอรี DLC/ไฟล์อัปเดต อัตโนมัติ", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "เพิ่ม", "SettingsTabGeneralRemove": "เอาออก", "SettingsTabSystem": "ระบบ", @@ -734,8 +735,9 @@ "DlcWindowHeading": "{0} DLC ที่สามารถดาวน์โหลดได้", "DlcWindowDlcAddedMessage": "{0} DLC ใหม่ที่เพิ่มเข้ามา", "AutoloadDlcAddedMessage": "{0} ใหม่ที่เพิ่มเข้ามา", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadUpdateAddedMessage": "{0} อัพเดตใหม่ที่เพิ่มเข้ามา", - "AutoloadDlcAndUpdateAddedMessage": "{0} DLC ใหม่ที่เพิ่มเข้ามาและ {1} อัพเดตใหม่ที่เพิ่มเข้ามา", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} ม็อด", "UserProfilesEditProfile": "แก้ไขที่เลือกแล้ว", "Cancel": "ยกเลิก", diff --git a/src/Ryujinx/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json index 1360a122e..d26ca18b7 100644 --- a/src/Ryujinx/Assets/Locales/tr_TR.json +++ b/src/Ryujinx/Assets/Locales/tr_TR.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "Hypervisor Kullan", "MenuBarFile": "_Dosya", "MenuBarFileOpenFromFile": "_Dosyadan Uygulama Aç", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "_Sıkıştırılmamış Oyun Aç", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "Ryujinx Klasörünü aç", "MenuBarFileOpenLogsFolder": "Logs Klasörünü aç", "MenuBarFileExit": "_Çıkış", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "Hareketsiz Durumda", "SettingsTabGeneralHideCursorAlways": "Her Zaman", "SettingsTabGeneralGameDirectories": "Oyun Dizinleri", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "Ekle", "SettingsTabGeneralRemove": "Kaldır", "SettingsTabSystem": "Sistem", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "Favori Ayarla", "GameListContextMenuToggleFavoriteToolTip": "Oyunu Favorilere Ekle/Çıkar", "SettingsTabGeneralTheme": "Tema:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "Karanlık", "SettingsTabGeneralThemeLight": "Aydınlık", "ControllerSettingsConfigureGeneral": "Ayarla", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "Listeye eklemek için oyun dizini seçin", "AddGameDirTooltip": "Listeye oyun dizini ekle", "RemoveGameDirTooltip": "Seçili oyun dizinini kaldır", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "Emülatör pencerelerinin görünümünü değiştirmek için özel bir Avalonia teması kullan", "CustomThemePathTooltip": "Özel arayüz temasının yolu", "CustomThemeBrowseTooltip": "Özel arayüz teması için göz at", @@ -606,6 +615,8 @@ "DebugLogTooltip": "Debug log mesajlarını konsola yazdırır.\n\nBu seçeneği yalnızca geliştirici üyemiz belirtirse aktifleştirin, çünkü bu seçenek log dosyasını okumayı zorlaştırır ve emülatörün performansını düşürür.", "LoadApplicationFileTooltip": "Switch ile uyumlu bir dosya yüklemek için dosya tarayıcısını açar", "LoadApplicationFolderTooltip": "Switch ile uyumlu ayrıştırılmamış bir uygulama yüklemek için dosya tarayıcısını açar", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "Ryujinx dosya sistem klasörünü açar", "OpenRyujinxLogsTooltip": "Log dosyalarının bulunduğu klasörü açar", "ExitTooltip": "Ryujinx'ten çıkış yapmayı sağlar", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "Kurulum Kılavuzunu Aç", "NoUpdate": "Güncelleme Yok", "TitleUpdateVersionLabel": "Sürüm {0} - {1}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "Ryujinx - Bilgi", "RyujinxConfirm": "Ryujinx - Doğrulama", "FileDialogAllTypes": "Tüm türler", @@ -714,9 +727,17 @@ "DlcWindowTitle": "Oyun DLC'lerini Yönet", "ModWindowTitle": "Manage Mods for {0} ({1})", "UpdateWindowTitle": "Oyun Güncellemelerini Yönet", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "{0} için Hile mevcut [{1}]", "BuildId": "BuildId:", - "DlcWindowHeading": "{0} için DLC mevcut [{1}]", + "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", + "DlcWindowHeading": "{0} Downloadable Content(s) available for {1} ({2})", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} Mod(lar)", "UserProfilesEditProfile": "Seçiliyi Düzenle", "Cancel": "İptal", @@ -767,6 +788,7 @@ "GraphicsScalingFilterBilinear": "Bilinear", "GraphicsScalingFilterNearest": "Nearest", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "Seviye", "GraphicsScalingFilterLevelTooltip": "Set FSR 1.0 sharpening level. Higher is sharper.", "SmaaLow": "Düşük SMAA", diff --git a/src/Ryujinx/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json index 2fe5758b5..0a4f251fe 100644 --- a/src/Ryujinx/Assets/Locales/uk_UA.json +++ b/src/Ryujinx/Assets/Locales/uk_UA.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "Використовувати гіпервізор", "MenuBarFile": "_Файл", "MenuBarFileOpenFromFile": "_Завантажити програму з файлу", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "Завантажити _розпаковану гру", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "Відкрити теку Ryujinx", "MenuBarFileOpenLogsFolder": "Відкрити теку журналів змін", "MenuBarFileExit": "_Вихід", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "Сховати у режимі очікування", "SettingsTabGeneralHideCursorAlways": "Завжди", "SettingsTabGeneralGameDirectories": "Тека ігор", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "Додати", "SettingsTabGeneralRemove": "Видалити", "SettingsTabSystem": "Система", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "Перемкнути вибране", "GameListContextMenuToggleFavoriteToolTip": "Перемкнути улюблений статус гри", "SettingsTabGeneralTheme": "Тема:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "Темна", "SettingsTabGeneralThemeLight": "Світла", "ControllerSettingsConfigureGeneral": "Налаштування", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "Введіть каталог ігор, щоб додати до списку", "AddGameDirTooltip": "Додати каталог гри до списку", "RemoveGameDirTooltip": "Видалити вибраний каталог гри", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "Використовуйте користувацьку тему Avalonia для графічного інтерфейсу, щоб змінити вигляд меню емулятора", "CustomThemePathTooltip": "Шлях до користувацької теми графічного інтерфейсу", "CustomThemeBrowseTooltip": "Огляд користувацької теми графічного інтерфейсу", @@ -606,6 +615,8 @@ "DebugLogTooltip": "Друкує повідомлення журналу налагодження на консолі.\n\nВикористовуйте це лише за спеціальною вказівкою співробітника, оскільки це ускладнить читання журналів і погіршить роботу емулятора.", "LoadApplicationFileTooltip": "Відкриває файловий провідник, щоб вибрати для завантаження сумісний файл Switch", "LoadApplicationFolderTooltip": "Відкриває файловий провідник, щоб вибрати сумісну з комутатором розпаковану програму для завантаження", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "Відкриває папку файлової системи Ryujinx", "OpenRyujinxLogsTooltip": "Відкриває папку, куди записуються журнали", "ExitTooltip": "Виходить з Ryujinx", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "Відкрити посібник із налаштування", "NoUpdate": "Немає оновлень", "TitleUpdateVersionLabel": "Версія {0} - {1}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "Ryujin x - Інформація", "RyujinxConfirm": "Ryujinx - Підтвердження", "FileDialogAllTypes": "Всі типи", @@ -714,9 +727,17 @@ "DlcWindowTitle": "Менеджер вмісту для завантаження", "ModWindowTitle": "Керувати модами для {0} ({1})", "UpdateWindowTitle": "Менеджер оновлення назв", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "Коди доступні для {0} [{1}]", "BuildId": "ID збірки:", + "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowHeading": "Вміст для завантаження, доступний для {1} ({2}): {0}", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} мод(ів)", "UserProfilesEditProfile": "Редагувати вибране", "Cancel": "Скасувати", @@ -767,6 +788,7 @@ "GraphicsScalingFilterBilinear": "Білінійний", "GraphicsScalingFilterNearest": "Найближчий", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "Рівень", "GraphicsScalingFilterLevelTooltip": "Встановити рівень різкості в FSR 1.0. Чим вище - тим різкіше.", "SmaaLow": "SMAA Низький", diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json index e0fd15922..d1f3c13e3 100644 --- a/src/Ryujinx/Assets/Locales/zh_CN.json +++ b/src/Ryujinx/Assets/Locales/zh_CN.json @@ -107,6 +107,7 @@ "SettingsTabGeneralHideCursorAlways": "始终隐藏", "SettingsTabGeneralGameDirectories": "游戏目录", "SettingsTabGeneralAutoloadDirectories": "自动加载DLC/游戏更新目录", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "添加", "SettingsTabGeneralRemove": "删除", "SettingsTabSystem": "系统", @@ -734,8 +735,9 @@ "DlcWindowHeading": "{0} 个 DLC", "DlcWindowDlcAddedMessage": "{0} 个DLC被添加", "AutoloadDlcAddedMessage": "{0} 个DLC被添加", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", "AutoloadUpdateAddedMessage": "{0} 个游戏更新被添加", - "AutoloadDlcAndUpdateAddedMessage": "{0} 个DLC和{1} 个游戏更新被添加", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} Mod(s)", "UserProfilesEditProfile": "编辑所选", "Cancel": "取消", diff --git a/src/Ryujinx/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json index e7cf35e5f..e67fcf566 100644 --- a/src/Ryujinx/Assets/Locales/zh_TW.json +++ b/src/Ryujinx/Assets/Locales/zh_TW.json @@ -10,7 +10,10 @@ "SettingsTabSystemUseHypervisor": "使用 Hypervisor", "MenuBarFile": "檔案(_F)", "MenuBarFileOpenFromFile": "從檔案載入應用程式(_L)", + "MenuBarFileOpenFromFileError": "No applications found in selected file.", "MenuBarFileOpenUnpacked": "載入未封裝的遊戲(_U)", + "MenuBarFileLoadDlcFromFolder": "Load DLC From Folder", + "MenuBarFileLoadTitleUpdatesFromFolder": "Load Title Updates From Folder", "MenuBarFileOpenEmuFolder": "開啟 Ryujinx 資料夾", "MenuBarFileOpenLogsFolder": "開啟日誌資料夾", "MenuBarFileExit": "結束(_E)", @@ -103,6 +106,8 @@ "SettingsTabGeneralHideCursorOnIdle": "閒置時", "SettingsTabGeneralHideCursorAlways": "總是", "SettingsTabGeneralGameDirectories": "遊戲資料夾", + "SettingsTabGeneralAutoloadDirectories": "Autoload DLC/Updates Directories", + "SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically", "SettingsTabGeneralAdd": "新增", "SettingsTabGeneralRemove": "刪除", "SettingsTabSystem": "系統", @@ -411,6 +416,7 @@ "GameListContextMenuToggleFavorite": "加入/移除為我的最愛", "GameListContextMenuToggleFavoriteToolTip": "切換遊戲的我的最愛狀態", "SettingsTabGeneralTheme": "佈景主題:", + "SettingsTabGeneralThemeAuto": "Auto", "SettingsTabGeneralThemeDark": "深色", "SettingsTabGeneralThemeLight": "淺色", "ControllerSettingsConfigureGeneral": "配置", @@ -561,6 +567,9 @@ "AddGameDirBoxTooltip": "輸入要新增到清單中的遊戲資料夾", "AddGameDirTooltip": "新增遊戲資料夾到清單中", "RemoveGameDirTooltip": "移除選取的遊戲資料夾", + "AddAutoloadDirBoxTooltip": "Enter an autoload directory to add to the list", + "AddAutoloadDirTooltip": "Add an autoload directory to the list", + "RemoveAutoloadDirTooltip": "Remove selected autoload directory", "CustomThemeCheckTooltip": "為圖形使用者介面使用自訂 Avalonia 佈景主題,變更模擬器功能表的外觀", "CustomThemePathTooltip": "自訂 GUI 佈景主題的路徑", "CustomThemeBrowseTooltip": "瀏覽自訂 GUI 佈景主題", @@ -606,6 +615,8 @@ "DebugLogTooltip": "在控制台中輸出偵錯日誌訊息。\n\n只有在人員特別指示的情況下才能使用,因為這會導致日誌難以閱讀,並降低模擬器效能。", "LoadApplicationFileTooltip": "開啟檔案總管,選擇與 Switch 相容的檔案來載入", "LoadApplicationFolderTooltip": "開啟檔案總管,選擇與 Switch 相容且未封裝的應用程式來載入", + "LoadDlcFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load DLC from", + "LoadTitleUpdatesFromFolderTooltip": "Open a file explorer to choose one or more folders to bulk load title updates from", "OpenRyujinxFolderTooltip": "開啟 Ryujinx 檔案系統資料夾", "OpenRyujinxLogsTooltip": "開啟日誌被寫入的資料夾", "ExitTooltip": "結束 Ryujinx", @@ -657,6 +668,8 @@ "OpenSetupGuideMessage": "開啟設定指南", "NoUpdate": "沒有更新", "TitleUpdateVersionLabel": "版本 {0}", + "TitleBundledUpdateVersionLabel": "Bundled: Version {0}", + "TitleBundledDlcLabel": "Bundled:", "RyujinxInfo": "Ryujinx - 資訊", "RyujinxConfirm": "Ryujinx - 確認", "FileDialogAllTypes": "全部類型", @@ -714,9 +727,17 @@ "DlcWindowTitle": "管理 {0} 的可下載內容 ({1})", "ModWindowTitle": "管理 {0} 的模組 ({1})", "UpdateWindowTitle": "遊戲更新管理員", + "UpdateWindowUpdateAddedMessage": "{0} new update(s) added", + "UpdateWindowBundledContentNotice": "Bundled updates cannot be removed, only disabled.", "CheatWindowHeading": "可用於 {0} [{1}] 的密技", "BuildId": "組建識別碼:", + "DlcWindowBundledContentNotice": "Bundled DLC cannot be removed, only disabled.", "DlcWindowHeading": "{0} 個可下載內容", + "DlcWindowDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcAddedMessage": "{0} new downloadable content(s) added", + "AutoloadDlcRemovedMessage": "{0} missing downloadable content(s) removed", + "AutoloadUpdateAddedMessage": "{0} new update(s) added", + "AutoloadUpdateRemovedMessage": "{0} missing update(s) removed", "ModWindowHeading": "{0} 模組", "UserProfilesEditProfile": "編輯所選", "Cancel": "取消", @@ -767,6 +788,7 @@ "GraphicsScalingFilterBilinear": "雙線性 (Bilinear)", "GraphicsScalingFilterNearest": "近鄰性 (Nearest)", "GraphicsScalingFilterFsr": "FSR", + "GraphicsScalingFilterArea": "Area", "GraphicsScalingFilterLevelLabel": "日誌等級", "GraphicsScalingFilterLevelTooltip": "設定 FSR 1.0 銳化等級。越高越清晰。", "SmaaLow": "低階 SMAA", From 36c374cc7a36336f89a094510bf7c2a6b4989321 Mon Sep 17 00:00:00 2001 From: Kekschen <52585984+Kek5chen@users.noreply.github.com> Date: Thu, 7 Nov 2024 01:18:59 +0100 Subject: [PATCH 10/15] fix: remove --deep (#188) --- distribution/macos/create_app_bundle.sh | 4 ++-- distribution/macos/create_macos_build_ava.sh | 4 ++-- distribution/macos/create_macos_build_headless.sh | 4 ++-- src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj | 4 ++-- src/Ryujinx/Ryujinx.csproj | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/distribution/macos/create_app_bundle.sh b/distribution/macos/create_app_bundle.sh index 0fa54eadd..e4397da84 100755 --- a/distribution/macos/create_app_bundle.sh +++ b/distribution/macos/create_app_bundle.sh @@ -46,5 +46,5 @@ then rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$APP_BUNDLE_DIRECTORY" else echo "Usign codesign for ad-hoc signing" - codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$APP_BUNDLE_DIRECTORY" -fi \ No newline at end of file + codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$APP_BUNDLE_DIRECTORY" +fi diff --git a/distribution/macos/create_macos_build_ava.sh b/distribution/macos/create_macos_build_ava.sh index 6785cbb23..80bd6662c 100755 --- a/distribution/macos/create_macos_build_ava.sh +++ b/distribution/macos/create_macos_build_ava.sh @@ -99,7 +99,7 @@ then rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$UNIVERSAL_APP_BUNDLE" else echo "Using codesign for ad-hoc signing" - codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$UNIVERSAL_APP_BUNDLE" + codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$UNIVERSAL_APP_BUNDLE" fi echo "Creating archive" @@ -111,4 +111,4 @@ rm "$RELEASE_TAR_FILE_NAME" popd -echo "Done" \ No newline at end of file +echo "Done" diff --git a/distribution/macos/create_macos_build_headless.sh b/distribution/macos/create_macos_build_headless.sh index a439aef45..2715699d0 100755 --- a/distribution/macos/create_macos_build_headless.sh +++ b/distribution/macos/create_macos_build_headless.sh @@ -95,7 +95,7 @@ else echo "Using codesign for ad-hoc signing" for FILE in "$UNIVERSAL_OUTPUT"/*; do if [[ $(file "$FILE") == *"Mach-O"* ]]; then - codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$FILE" + codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$FILE" fi done fi @@ -108,4 +108,4 @@ gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz" rm "$RELEASE_TAR_FILE_NAME" popd -echo "Done" \ No newline at end of file +echo "Done" diff --git a/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj b/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj index 610229544..ebda97b46 100644 --- a/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj +++ b/src/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -17,7 +17,7 @@ - + diff --git a/src/Ryujinx/Ryujinx.csproj b/src/Ryujinx/Ryujinx.csproj index c1c238926..b41ec1cd4 100644 --- a/src/Ryujinx/Ryujinx.csproj +++ b/src/Ryujinx/Ryujinx.csproj @@ -14,7 +14,7 @@ - + From 730ba44043ea352fa53fe38dfe500cadd71ff2bd Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 6 Nov 2024 18:23:21 -0600 Subject: [PATCH 11/15] misc: Canary-specific naming & other small changes I had that I need to push. --- src/Ryujinx/App.axaml.cs | 6 +- .../Common/Markup/BasicMarkupExtension.cs | 37 ++- src/Ryujinx/Common/Markup/MarkupExtensions.cs | 45 +-- src/Ryujinx/Input/AvaloniaKeyboard.cs | 14 +- src/Ryujinx/UI/Applet/AvaHostUIHandler.cs | 6 +- .../UI/Views/Input/KeyboardInputView.axaml.cs | 260 +++++++++--------- .../UI/Views/Main/MainMenuBarView.axaml | 4 +- .../UI/Views/Main/MainMenuBarView.axaml.cs | 8 +- .../UserProfileImageSelectorView.axaml.cs | 3 +- src/Ryujinx/UI/Windows/MainWindow.axaml.cs | 31 +-- src/Ryujinx/Updater.cs | 15 +- 11 files changed, 200 insertions(+), 229 deletions(-) diff --git a/src/Ryujinx/App.axaml.cs b/src/Ryujinx/App.axaml.cs index 509deb34c..15ada201c 100644 --- a/src/Ryujinx/App.axaml.cs +++ b/src/Ryujinx/App.axaml.cs @@ -23,8 +23,10 @@ namespace Ryujinx.Ava { internal static string FormatTitle(LocaleKeys? windowTitleKey = null) => windowTitleKey is null - ? $"Ryujinx {Program.Version}" - : $"Ryujinx {Program.Version} - {LocaleManager.Instance[windowTitleKey.Value]}"; + ? $"{FullAppName} {Program.Version}" + : $"{FullAppName} {Program.Version} - {LocaleManager.Instance[windowTitleKey.Value]}"; + + public static readonly string FullAppName = ReleaseInformation.IsCanaryBuild ? "Ryujinx Canary" : "Ryujinx"; public static MainWindow MainWindow => Current! .ApplicationLifetime.Cast() diff --git a/src/Ryujinx/Common/Markup/BasicMarkupExtension.cs b/src/Ryujinx/Common/Markup/BasicMarkupExtension.cs index 73b298bc7..67c016562 100644 --- a/src/Ryujinx/Common/Markup/BasicMarkupExtension.cs +++ b/src/Ryujinx/Common/Markup/BasicMarkupExtension.cs @@ -2,19 +2,38 @@ using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml.MarkupExtensions; using Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings; +using Gommon; using System; +// ReSharper disable VirtualMemberNeverOverridden.Global +// ReSharper disable MemberCanBeProtected.Global +// ReSharper disable MemberCanBePrivate.Global + +#nullable enable namespace Ryujinx.Ava.Common.Markup { - internal abstract class BasicMarkupExtension : MarkupExtension + internal abstract class BasicMarkupExtension : MarkupExtension { - protected abstract ClrPropertyInfo PropertyInfo { get; } - - public override object ProvideValue(IServiceProvider serviceProvider) => - new CompiledBindingExtension( - new CompiledBindingPathBuilder() - .Property(PropertyInfo, PropertyInfoAccessorFactory.CreateInpcPropertyAccessor) - .Build() - ).ProvideValue(serviceProvider); + public virtual string Name => "Item"; + public virtual Action? Setter => null; + + protected abstract T? GetValue(); + + protected virtual void ConfigureBindingExtension(CompiledBindingExtension _) { } + + private ClrPropertyInfo PropertyInfo => + new(Name, + _ => GetValue(), + Setter as Action, + typeof(T)); + + public override object ProvideValue(IServiceProvider serviceProvider) + => new CompiledBindingExtension( + new CompiledBindingPathBuilder() + .Property(PropertyInfo, PropertyInfoAccessorFactory.CreateInpcPropertyAccessor) + .Build() + ) + .Apply(ConfigureBindingExtension) + .ProvideValue(serviceProvider); } } diff --git a/src/Ryujinx/Common/Markup/MarkupExtensions.cs b/src/Ryujinx/Common/Markup/MarkupExtensions.cs index af917b973..a804792c7 100644 --- a/src/Ryujinx/Common/Markup/MarkupExtensions.cs +++ b/src/Ryujinx/Common/Markup/MarkupExtensions.cs @@ -1,51 +1,24 @@ -using Avalonia.Data.Core; -using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml.MarkupExtensions; -using Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings; using Projektanker.Icons.Avalonia; using Ryujinx.Ava.Common.Locale; -using System; namespace Ryujinx.Ava.Common.Markup { - internal class IconExtension(string iconString) : BasicMarkupExtension + internal class IconExtension(string iconString) : BasicMarkupExtension { - protected override ClrPropertyInfo PropertyInfo - => new( - "Item", - _ => new Icon { Value = iconString }, - null, - typeof(Icon) - ); + protected override Icon GetValue() => new() { Value = iconString }; } - internal class SpinningIconExtension(string iconString) : BasicMarkupExtension + internal class SpinningIconExtension(string iconString) : BasicMarkupExtension { - protected override ClrPropertyInfo PropertyInfo - => new( - "Item", - _ => new Icon { Value = iconString, Animation = IconAnimation.Spin }, - null, - typeof(Icon) - ); + protected override Icon GetValue() => new() { Value = iconString, Animation = IconAnimation.Spin }; } - internal class LocaleExtension(LocaleKeys key) : MarkupExtension + internal class LocaleExtension(LocaleKeys key) : BasicMarkupExtension { - private ClrPropertyInfo PropertyInfo - => new( - "Item", - _ => LocaleManager.Instance[key], - null, - typeof(string) - ); - - public override object ProvideValue(IServiceProvider serviceProvider) => - new CompiledBindingExtension( - new CompiledBindingPathBuilder() - .Property(PropertyInfo, PropertyInfoAccessorFactory.CreateInpcPropertyAccessor) - .Build() - ) { Source = LocaleManager.Instance } - .ProvideValue(serviceProvider); + protected override string GetValue() => LocaleManager.Instance[key]; + + protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension) + => bindingExtension.Source = LocaleManager.Instance; } } diff --git a/src/Ryujinx/Input/AvaloniaKeyboard.cs b/src/Ryujinx/Input/AvaloniaKeyboard.cs index ff88de79e..95d2936f6 100644 --- a/src/Ryujinx/Input/AvaloniaKeyboard.cs +++ b/src/Ryujinx/Input/AvaloniaKeyboard.cs @@ -23,21 +23,15 @@ namespace Ryujinx.Ava.Input public bool IsConnected => true; public GamepadFeaturesFlag Features => GamepadFeaturesFlag.None; - private class ButtonMappingEntry + private class ButtonMappingEntry(GamepadButtonInputId to, Key from) { - public readonly Key From; - public readonly GamepadButtonInputId To; - - public ButtonMappingEntry(GamepadButtonInputId to, Key from) - { - To = to; - From = from; - } + public readonly GamepadButtonInputId To = to; + public readonly Key From = from; } public AvaloniaKeyboard(AvaloniaKeyboardDriver driver, string id, string name) { - _buttonsUserMapping = new List(); + _buttonsUserMapping = []; _driver = driver; Id = id; diff --git a/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs index f09460b1f..1dbf37255 100644 --- a/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs +++ b/src/Ryujinx/UI/Applet/AvaHostUIHandler.cs @@ -127,11 +127,11 @@ namespace Ryujinx.Ava.UI.Applet try { _parent.ViewModel.AppHost.NpadManager.BlockInputUpdates(); - var response = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args); + (UserResult result, string userInput) = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args); - if (response.Result == UserResult.Ok) + if (result == UserResult.Ok) { - inputText = response.Input; + inputText = userInput; okPressed = true; } } diff --git a/src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml.cs index f17c7496c..090d0335c 100644 --- a/src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml.cs @@ -33,7 +33,7 @@ namespace Ryujinx.Ava.UI.Views.Input { base.OnPointerReleased(e); - if (_currentAssigner != null && _currentAssigner.ToggledButton != null && !_currentAssigner.ToggledButton.IsPointerOver) + if (_currentAssigner is { ToggledButton.IsPointerOver: false }) { _currentAssigner.Cancel(); } @@ -41,143 +41,146 @@ namespace Ryujinx.Ava.UI.Views.Input private void Button_IsCheckedChanged(object sender, RoutedEventArgs e) { - if (sender is ToggleButton button) + if (sender is not ToggleButton button) + return; + + if (button.IsChecked is true) { - if ((bool)button.IsChecked) + if (_currentAssigner != null && button == _currentAssigner.ToggledButton) { - if (_currentAssigner != null && button == _currentAssigner.ToggledButton) - { + return; + } + + if (_currentAssigner == null) + { + _currentAssigner = new ButtonKeyAssigner(button); + + Focus(NavigationMethod.Pointer); + + PointerPressed += MouseClick; + + if (DataContext is not KeyboardInputViewModel viewModel) return; - } - if (_currentAssigner == null) + IKeyboard keyboard = + (IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations. + IButtonAssigner assigner = + new KeyboardKeyAssigner((IKeyboard)viewModel.ParentModel.SelectedGamepad); + + _currentAssigner.ButtonAssigned += (_, e) => { - _currentAssigner = new ButtonKeyAssigner(button); - - Focus(NavigationMethod.Pointer); - - PointerPressed += MouseClick; - - var viewModel = (DataContext as KeyboardInputViewModel); - - IKeyboard keyboard = (IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations. - IButtonAssigner assigner = CreateButtonAssigner(); - - _currentAssigner.ButtonAssigned += (sender, e) => + if (e.ButtonValue.HasValue) { - if (e.ButtonValue.HasValue) + var buttonValue = e.ButtonValue.Value; + viewModel.ParentModel.IsModified = true; + + switch (button.Name) { - var buttonValue = e.ButtonValue.Value; - viewModel.ParentModel.IsModified = true; - - switch (button.Name) - { - case "ButtonZl": - viewModel.Config.ButtonZl = buttonValue.AsHidType(); - break; - case "ButtonL": - viewModel.Config.ButtonL = buttonValue.AsHidType(); - break; - case "ButtonMinus": - viewModel.Config.ButtonMinus = buttonValue.AsHidType(); - break; - case "LeftStickButton": - viewModel.Config.LeftStickButton = buttonValue.AsHidType(); - break; - case "LeftStickUp": - viewModel.Config.LeftStickUp = buttonValue.AsHidType(); - break; - case "LeftStickDown": - viewModel.Config.LeftStickDown = buttonValue.AsHidType(); - break; - case "LeftStickRight": - viewModel.Config.LeftStickRight = buttonValue.AsHidType(); - break; - case "LeftStickLeft": - viewModel.Config.LeftStickLeft = buttonValue.AsHidType(); - break; - case "DpadUp": - viewModel.Config.DpadUp = buttonValue.AsHidType(); - break; - case "DpadDown": - viewModel.Config.DpadDown = buttonValue.AsHidType(); - break; - case "DpadLeft": - viewModel.Config.DpadLeft = buttonValue.AsHidType(); - break; - case "DpadRight": - viewModel.Config.DpadRight = buttonValue.AsHidType(); - break; - case "LeftButtonSr": - viewModel.Config.LeftButtonSr = buttonValue.AsHidType(); - break; - case "LeftButtonSl": - viewModel.Config.LeftButtonSl = buttonValue.AsHidType(); - break; - case "RightButtonSr": - viewModel.Config.RightButtonSr = buttonValue.AsHidType(); - break; - case "RightButtonSl": - viewModel.Config.RightButtonSl = buttonValue.AsHidType(); - break; - case "ButtonZr": - viewModel.Config.ButtonZr = buttonValue.AsHidType(); - break; - case "ButtonR": - viewModel.Config.ButtonR = buttonValue.AsHidType(); - break; - case "ButtonPlus": - viewModel.Config.ButtonPlus = buttonValue.AsHidType(); - break; - case "ButtonA": - viewModel.Config.ButtonA = buttonValue.AsHidType(); - break; - case "ButtonB": - viewModel.Config.ButtonB = buttonValue.AsHidType(); - break; - case "ButtonX": - viewModel.Config.ButtonX = buttonValue.AsHidType(); - break; - case "ButtonY": - viewModel.Config.ButtonY = buttonValue.AsHidType(); - break; - case "RightStickButton": - viewModel.Config.RightStickButton = buttonValue.AsHidType(); - break; - case "RightStickUp": - viewModel.Config.RightStickUp = buttonValue.AsHidType(); - break; - case "RightStickDown": - viewModel.Config.RightStickDown = buttonValue.AsHidType(); - break; - case "RightStickRight": - viewModel.Config.RightStickRight = buttonValue.AsHidType(); - break; - case "RightStickLeft": - viewModel.Config.RightStickLeft = buttonValue.AsHidType(); - break; - } + case "ButtonZl": + viewModel.Config.ButtonZl = buttonValue.AsHidType(); + break; + case "ButtonL": + viewModel.Config.ButtonL = buttonValue.AsHidType(); + break; + case "ButtonMinus": + viewModel.Config.ButtonMinus = buttonValue.AsHidType(); + break; + case "LeftStickButton": + viewModel.Config.LeftStickButton = buttonValue.AsHidType(); + break; + case "LeftStickUp": + viewModel.Config.LeftStickUp = buttonValue.AsHidType(); + break; + case "LeftStickDown": + viewModel.Config.LeftStickDown = buttonValue.AsHidType(); + break; + case "LeftStickRight": + viewModel.Config.LeftStickRight = buttonValue.AsHidType(); + break; + case "LeftStickLeft": + viewModel.Config.LeftStickLeft = buttonValue.AsHidType(); + break; + case "DpadUp": + viewModel.Config.DpadUp = buttonValue.AsHidType(); + break; + case "DpadDown": + viewModel.Config.DpadDown = buttonValue.AsHidType(); + break; + case "DpadLeft": + viewModel.Config.DpadLeft = buttonValue.AsHidType(); + break; + case "DpadRight": + viewModel.Config.DpadRight = buttonValue.AsHidType(); + break; + case "LeftButtonSr": + viewModel.Config.LeftButtonSr = buttonValue.AsHidType(); + break; + case "LeftButtonSl": + viewModel.Config.LeftButtonSl = buttonValue.AsHidType(); + break; + case "RightButtonSr": + viewModel.Config.RightButtonSr = buttonValue.AsHidType(); + break; + case "RightButtonSl": + viewModel.Config.RightButtonSl = buttonValue.AsHidType(); + break; + case "ButtonZr": + viewModel.Config.ButtonZr = buttonValue.AsHidType(); + break; + case "ButtonR": + viewModel.Config.ButtonR = buttonValue.AsHidType(); + break; + case "ButtonPlus": + viewModel.Config.ButtonPlus = buttonValue.AsHidType(); + break; + case "ButtonA": + viewModel.Config.ButtonA = buttonValue.AsHidType(); + break; + case "ButtonB": + viewModel.Config.ButtonB = buttonValue.AsHidType(); + break; + case "ButtonX": + viewModel.Config.ButtonX = buttonValue.AsHidType(); + break; + case "ButtonY": + viewModel.Config.ButtonY = buttonValue.AsHidType(); + break; + case "RightStickButton": + viewModel.Config.RightStickButton = buttonValue.AsHidType(); + break; + case "RightStickUp": + viewModel.Config.RightStickUp = buttonValue.AsHidType(); + break; + case "RightStickDown": + viewModel.Config.RightStickDown = buttonValue.AsHidType(); + break; + case "RightStickRight": + viewModel.Config.RightStickRight = buttonValue.AsHidType(); + break; + case "RightStickLeft": + viewModel.Config.RightStickLeft = buttonValue.AsHidType(); + break; } - }; - - _currentAssigner.GetInputAndAssign(assigner, keyboard); - } - else - { - if (_currentAssigner != null) - { - _currentAssigner.Cancel(); - _currentAssigner = null; - button.IsChecked = false; } - } + }; + + _currentAssigner.GetInputAndAssign(assigner, keyboard); } else { - _currentAssigner?.Cancel(); - _currentAssigner = null; + if (_currentAssigner != null) + { + _currentAssigner.Cancel(); + _currentAssigner = null; + button.IsChecked = false; + } } } + else + { + _currentAssigner?.Cancel(); + _currentAssigner = null; + } } private void MouseClick(object sender, PointerPressedEventArgs e) @@ -189,15 +192,6 @@ namespace Ryujinx.Ava.UI.Views.Input PointerPressed -= MouseClick; } - private IButtonAssigner CreateButtonAssigner() - { - IButtonAssigner assigner; - - assigner = new KeyboardKeyAssigner((IKeyboard)(DataContext as KeyboardInputViewModel).ParentModel.SelectedGamepad); - - return assigner; - } - protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) { base.OnDetachedFromVisualTree(e); diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml index 31dda8873..03b7cfbe4 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml @@ -273,8 +273,8 @@ - - + + diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs index 88b9bb980..1acee3af5 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs @@ -184,8 +184,10 @@ namespace Ryujinx.Ava.UI.Views.Main if (sender is not MenuItem { Tag: string resolution }) return; - (int height, int width) = resolution.Split(' ') - .Into(parts => (int.Parse(parts[0]), int.Parse(parts[1]))); + (int width, int height) = resolution.Split(' ', 2) + .Into(parts => + (int.Parse(parts[0]), int.Parse(parts[1])) + ); await Dispatcher.UIThread.InvokeAsync(() => { @@ -200,7 +202,7 @@ namespace Ryujinx.Ava.UI.Views.Main public async void CheckForUpdates(object sender, RoutedEventArgs e) { if (Updater.CanUpdate(true)) - await Updater.BeginParse(Window, true); + await Window.BeginUpdateAsync(true); } public async void OpenXCITrimmerWindow(object sender, RoutedEventArgs e) => await XCITrimmerWindow.Show(ViewModel); diff --git a/src/Ryujinx/UI/Views/User/UserProfileImageSelectorView.axaml.cs b/src/Ryujinx/UI/Views/User/UserProfileImageSelectorView.axaml.cs index b4f23b5b8..dba762972 100644 --- a/src/Ryujinx/UI/Views/User/UserProfileImageSelectorView.axaml.cs +++ b/src/Ryujinx/UI/Views/User/UserProfileImageSelectorView.axaml.cs @@ -63,8 +63,7 @@ namespace Ryujinx.Ava.UI.Views.User private async void Import_OnClick(object sender, RoutedEventArgs e) { - var window = this.GetVisualRoot() as Window; - var result = await window.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions + var result = await ((Window)this.GetVisualRoot()!).StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions { AllowMultiple = false, FileTypeFilter = new List diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs index 8a6be3c81..24a1b62a2 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs @@ -28,6 +28,7 @@ using Ryujinx.UI.Common.Configuration; using Ryujinx.UI.Common.Helper; using System; using System.Collections.Generic; +using System.Linq; using System.Reactive.Linq; using System.Runtime.Versioning; using System.Threading; @@ -349,12 +350,12 @@ namespace Ryujinx.Ava.UI.Windows await Dispatcher.UIThread.InvokeAsync(async () => await UserErrorDialog.ShowUserErrorDialog(UserError.NoKeys)); } - if (ConfigurationState.Instance.CheckUpdatesOnStart && Updater.CanUpdate(false)) + if (ConfigurationState.Instance.CheckUpdatesOnStart && Updater.CanUpdate()) { - await Updater.BeginParse(this, false).ContinueWith(task => - { - Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}"); - }, TaskContinuationOptions.OnlyOnFaulted); + await this.BeginUpdateAsync() + .ContinueWith( + task => Logger.Error?.Print(LogClass.Application, $"Updater Error: {task.Exception}"), + TaskContinuationOptions.OnlyOnFaulted); } } @@ -392,30 +393,17 @@ namespace Ryujinx.Ava.UI.Windows ViewModel.WindowState = ConfigurationState.Instance.UI.WindowStartup.WindowMaximized.Value ? WindowState.Maximized : WindowState.Normal; - if (CheckScreenBounds(savedPoint)) + if (Screens.All.Any(screen => screen.Bounds.Contains(savedPoint))) { Position = savedPoint; } else { + Logger.Warning?.Print(LogClass.Application, "Failed to find valid start-up coordinates. Defaulting to primary monitor center."); WindowStartupLocation = WindowStartupLocation.CenterScreen; } } - private bool CheckScreenBounds(PixelPoint configPoint) - { - for (int i = 0; i < Screens.ScreenCount; i++) - { - if (Screens.All[i].Bounds.Contains(configPoint)) - { - return true; - } - } - - Logger.Warning?.Print(LogClass.Application, "Failed to find valid start-up coordinates. Defaulting to primary monitor center."); - return false; - } - private void SaveWindowSizePosition() { ConfigurationState.Instance.UI.WindowStartup.WindowMaximized.Value = WindowState == WindowState.Maximized; @@ -507,8 +495,7 @@ namespace Ryujinx.Ava.UI.Windows private void VolumeStatus_CheckedChanged(object sender, RoutedEventArgs e) { - var volumeSplitButton = sender as ToggleSplitButton; - if (ViewModel.IsGameRunning) + if (ViewModel.IsGameRunning && sender is ToggleSplitButton volumeSplitButton) { if (!volumeSplitButton.IsChecked) { diff --git a/src/Ryujinx/Updater.cs b/src/Ryujinx/Updater.cs index e8ef02052..7005fe528 100644 --- a/src/Ryujinx/Updater.cs +++ b/src/Ryujinx/Updater.cs @@ -32,6 +32,8 @@ namespace Ryujinx.Ava internal static class Updater { private const string GitHubApiUrl = "https://api.github.com"; + private const string LatestReleaseUrl = $"{GitHubApiUrl}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest"; + private static readonly GithubReleasesJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly string _homeDir = AppDomain.CurrentDomain.BaseDirectory; @@ -46,9 +48,9 @@ namespace Ryujinx.Ava private static bool _updateSuccessful; private static bool _running; - private static readonly string[] _windowsDependencyDirs = Array.Empty(); + private static readonly string[] _windowsDependencyDirs = []; - public static async Task BeginParse(Window mainWindow, bool showVersionUpToDate) + public static async Task BeginUpdateAsync(this Window mainWindow, bool showVersionUpToDate = false) { if (_running) { @@ -96,9 +98,8 @@ namespace Ryujinx.Ava try { using HttpClient jsonClient = ConstructHttpClient(); - - string buildInfoUrl = $"{GitHubApiUrl}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest"; - string fetchedJson = await jsonClient.GetStringAsync(buildInfoUrl); + + string fetchedJson = await jsonClient.GetStringAsync(LatestReleaseUrl); var fetched = JsonHelper.Deserialize(fetchedJson, _serializerContext.GithubReleasesJsonResponse); _buildVer = fetched.Name; @@ -159,7 +160,7 @@ namespace Ryujinx.Ava } catch { - Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from Github!"); + Logger.Error?.Print(LogClass.Application, $"Failed to convert the received {App.FullAppName} version from GitHub!"); await ContentDialogHelper.CreateWarningDialog( LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedGithubMessage], @@ -636,7 +637,7 @@ namespace Ryujinx.Ava taskDialog.Hide(); } - public static bool CanUpdate(bool showWarnings) + public static bool CanUpdate(bool showWarnings = false) { #if !DISABLE_UPDATER if (!NetworkInterface.GetIsNetworkAvailable()) From 5bf50836e17f721f0f062c7d5c0b048188eaf698 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 6 Nov 2024 18:24:30 -0600 Subject: [PATCH 12/15] i18n: missing comma in en_US locale --- src/Ryujinx/Assets/Locales/en_US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json index f0b10c945..faa53230d 100644 --- a/src/Ryujinx/Assets/Locales/en_US.json +++ b/src/Ryujinx/Assets/Locales/en_US.json @@ -451,7 +451,7 @@ "DialogUpdaterCancelUpdateMessage": "Update canceled!", "DialogUpdaterAlreadyOnLatestVersionMessage": "You are already using the latest version of Ryujinx!", "DialogUpdaterFailedToGetVersionMessage": "An error occurred while trying to retrieve release information from GitHub. This may happen if a new release is currently being compiled by GitHub Actions. Please try again in a few minutes.", - "DialogUpdaterConvertFailedGithubMessage": "Failed to convert the Ryujinx version received from GitHub." + "DialogUpdaterConvertFailedGithubMessage": "Failed to convert the Ryujinx version received from GitHub.", "DialogUpdaterDownloadingMessage": "Downloading Update...", "DialogUpdaterExtractionMessage": "Extracting Update...", "DialogUpdaterRenamingMessage": "Renaming Update...", From 708256ce9619f77c4d8a5c112f26a98f58843fdb Mon Sep 17 00:00:00 2001 From: Luke Warner <65521430+LukeWarnut@users.noreply.github.com> Date: Wed, 6 Nov 2024 20:22:40 -0500 Subject: [PATCH 13/15] Add just, a whole bunch of games to RPC assets. (#98) --- .../DiscordIntegrationModule.cs | 160 +++++++++++++----- 1 file changed, 117 insertions(+), 43 deletions(-) diff --git a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs index 01781bab6..7bfb1c95b 100644 --- a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs +++ b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs @@ -122,70 +122,144 @@ namespace Ryujinx.UI.Common private static readonly string[] _discordGameAssetKeys = [ - "01002da013484000", // The Legend of Zelda: Skyward Sword HD + "010055d009f78000", // Fire Emblem: Three Houses + "0100a12011cc8000", // Fire Emblem: Shadow Dragon + "0100a6301214e000", // Fire Emblem Engage + "0100f15003e64000", // Fire Emblem Warriors + "010071f0143ea000", // Fire Emblem Warriors: Three Hopes + + "01007e3006dda000", // Kirby Star Allies + "01004d300c5ae000", // Kirby and the Forgotten Land + "01006b601380e000", // Kirby's Return to Dream Land Deluxe + "01003fb00c5a8000", // Super Kirby Clash + "0100227010460000", // Kirby Fighters 2 + "0100a8e016236000", // Kirby's Dream Buffet + "01007ef00011e000", // The Legend of Zelda: Breath of the Wild + "01006bb00c6f0000", // The Legend of Zelda: Link's Awakening + "01002da013484000", // The Legend of Zelda: Skyward Sword HD "0100f2c0115b6000", // The Legend of Zelda: Tears of the Kingdom "01008cf01baac000", // The Legend of Zelda: Echoes of Wisdom - "01006bb00c6f0000", // The Legend of Zelda: Link's Awakening - - "0100000000010000", // SUPER MARIO ODYSSEY - "010015100b514000", // Super Mario Bros. Wonder - "0100152000022000", // Mario Kart 8 Deluxe - "01006fe013472000", // Mario Party Superstars - "0100965017338000", // Super Mario Party Jamboree - "010049900f546000", // Super Mario 3D All-Stars - "010028600ebda000", // Super Mario 3D World + Bowser's Fury - "0100ecd018ebe000", // Paper Mario: The Thousand-Year Door - "010019401051c000", // Mario Strikers League - "0100ea80032ea000", // Super Mario Bros. U Deluxe - "0100bc0018138000", // Super Mario RPG - "0100bde00862a000", // Mario Tennis Aces + "01000b900d8b0000", // Cadence of Hyrule + "0100ae00096ea000", // Hyrule Warriors: Definitive Edition + "01002b00111a2000", // Hyrule Warriors: Age of Calamity "010048701995e000", // Luigi's Mansion 2 HD "0100dca0064a6000", // Luigi's Mansion 3 - "01008f6008c5e000", // Pokémon Violet - "0100abf008968000", // Pokémon Sword - "01008db008c2c000", // Pokémon Shield - "0100000011d90000", // Pokémon Brilliant Diamond - "01001f5010dfa000", // Pokémon Legends: Arceus + "010093801237c000", // Metroid Dread + "010012101468c000", // Metroid Prime Remastered + + "0100000000010000", // SUPER MARIO ODYSSEY + "0100ea80032ea000", // Super Mario Bros. U Deluxe + "01009b90006dc000", // Super Mario Maker 2 + "010049900f546000", // Super Mario 3D All-Stars + "010049900F546001", // ^ 64 + "010049900F546002", // ^ Sunshine + "010049900F546003", // ^ Galaxy + "010028600ebda000", // Super Mario 3D World + Bowser's Fury + "010015100b514000", // Super Mario Bros. Wonder + "0100152000022000", // Mario Kart 8 Deluxe + "010036b0034e4000", // Super Mario Party + "01006fe013472000", // Mario Party Superstars + "0100965017338000", // Super Mario Party Jamboree + "010067300059a000", // Mario + Rabbids: Kingdom Battle + "0100317013770000", // Mario + Rabbids: Sparks of Hope + "0100a3900c3e2000", // Paper Mario: The Origami King + "0100ecd018ebe000", // Paper Mario: The Thousand-Year Door + "0100bc0018138000", // Super Mario RPG + "0100bde00862a000", // Mario Tennis Aces + "0100c9c00e25c000", // Mario Golf: Super Rush + "010019401051c000", // Mario Strikers: Battle League + "010003000e146000", // Mario & Sonic at the Olympic Games Tokyo 2020 + "0100b99019412000", // Mario vs. Donkey Kong "0100aa80194b0000", // Pikmin 1 "0100d680194b2000", // Pikmin 2 "0100f4c009322000", // Pikmin 3 Deluxe "0100b7c00933a000", // Pikmin 4 - + + "010003f003a34000", // Pokémon: Let's Go Pikachu! + "0100187003a36000", // Pokémon: Let's Go Eevee! + "0100abf008968000", // Pokémon Sword + "01008db008c2c000", // Pokémon Shield + "0100000011d90000", // Pokémon Brilliant Diamond + "010018e011d92000", // Pokémon Shining Pearl + "01001f5010dfa000", // Pokémon Legends: Arceus + "0100a3d008c5c000", // Pokémon Scarlet + "01008f6008c5e000", // Pokémon Violet + "0100b3f000be2000", // Pokkén Tournament DX + "0100f4300bf2c000", // New Pokémon Snap + + "01003bc0000a0000", // Splatoon 2 (US) + "0100f8f0000a2000", // Splatoon 2 (EU) + "01003c700009c000", // Splatoon 2 (JP) + "0100c2500fc20000", // Splatoon 3 + "0100ba0018500000", // Splatoon 3: Splatfest World Premiere + + "010040600c5ce000", // Tetris 99 + "0100277011f1a000", // Super Mario Bros. 35 + "0100ad9012510000", // PAC-MAN 99 + "0100ccf019c8c000", // F-ZERO 99 + "0100d870045b6000", // NES - Nintendo Switch Online + "01008d300c50c000", // SNES - Nintendo Switch Online + "0100c9a00ece6000", // N64 - Nintendo Switch Online + "0100e0601c632000", // N64 - Nintendo Switch Online 18+ + "0100c62011050000", // GB - Nintendo Switch Online + "010012f017576000", // GBA - Nintendo Switch Online + + "01000320000cc000", // 1-2 Switch + "0100300012f2a000", // Advance Wars 1+2: Re-Boot Camp + "01006f8002326000", // Animal Crossing: New Horizons + "0100620012d6e000", // Big Brain Academy: Brain vs. Brain + "010018300d006000", // BOXBOY! + BOXGIRL! + "0100c1f0051b6000", // Donkey Kong Country: Tropical Freeze + "0100ed000d390000", // Dr. Kawashima's Brain Training + "010067b017588000", // Endless Ocean Luminous + "0100d2f00d5c0000", // Nintendo Switch Sports + "01006b5012b32000", // Part Time UFO + "0100704000B3A000", // Snipperclips + "01006a800016e000", // Super Smash Bros. Ultimate + "0100a9400c9c2000", // Tokyo Mirage Sessions #FE Encore + + "010076f0049a2000", // Bayonetta + "01007960049a0000", // Bayonetta 2 + "01004a4010fea000", // Bayonetta 3 + "0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon + + "0100dcd01525a000", // Persona 3 Portable + "010062b01525c000", // Persona 4 Golden + "010075a016a3a000", // Persona 4 Arena Ultimax + "01005ca01580e000", // Persona 5 Royal + "0100801011c3e000", // Persona 5 Strikers + "010087701b092000", // Persona 5 Tactica + + "01009aa000faa000", // Sonic Mania "01004ad014bf0000", // Sonic Frontiers "01005ea01c0fc000", // SONIC X SHADOW GENERATIONS "01005ea01c0fc001", // ^ - - "01004d300c5ae000", // Kirby and the Forgotten Land - "01006b601380e000", // Kirby's Return to Dreamland Deluxe - "01007e3006dda000", // Kirby Star Allies - "0100c2500fc20000", // Splatoon 3 - "0100ba0018500000", // Splatoon 3: Splatfest World Premiere - "01000a10041ea000", // The Elder Scrolls V: Skyrim - "01007820196a6000", // Red Dead Redemption - "01008c8012920000", // Dying Light Platinum Edition - "0100744001588000", // Cars 3: Driven to Win - "0100c1f0051b6000", // Donkey Kong Country: Tropical Freeze - "01002b00111a2000", // Hyrule Warriors: Age of Calamity - "01006f8002326000", // Animal Crossing: New Horizons - "0100853015e86000", // No Man's Sky - "01008d100d43e000", // Saints Row IV - "0100de600beee000", // Saints Row: The Third - The Full Package - "0100d7a01b7a2000", // Star Wars: Bounty Hunter - "0100dbf01000a000", // Burnout Paradise Remastered - "0100e46006708000", // Terraria "010056e00853a000", // A Hat in Time - "01006a800016e000", // Super Smash Bros. Ultimate + "0100dbf01000a000", // Burnout Paradise Remastered + "0100744001588000", // Cars 3: Driven to Win + "0100b41013c82000", // Cruis'n Blast + "01008c8012920000", // Dying Light Platinum Edition + "01000a10041ea000", // The Elder Scrolls V: Skyrim + "0100770008dd8000", // Monster Hunter Generations Ultimate + "0100b04011742000", // Monster Hunter Rise + "0100853015e86000", // No Man's Sky "01007bb017812000", // Portal "0100abd01785c000", // Portal 2 "01008e200c5c2000", // Muse Dash + "01007820196a6000", // Red Dead Redemption + "01002f7013224000", // Rune Factory 5 + "01008d100d43e000", // Saints Row IV + "0100de600beee000", // Saints Row: The Third - The Full Package "01001180021fa000", // Shovel Knight: Specter of Torment - "010012101468c000", // Metroid Prime Remastered - "0100c9a00ece6000", // Nintendo 64 - Nintendo Switch Online + "0100d7a01b7a2000", // Star Wars: Bounty Hunter + "0100800015926000", // Suika Game + "0100e46006708000", // Terraria + "010080b00ad66000", // Undertale ]; } } From 6acd86c890cd03a4bcf4eacd6ef1412c7cba2935 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 6 Nov 2024 19:46:20 -0600 Subject: [PATCH 14/15] Fix canary updater & checking if current build is canary. --- src/Ryujinx.Common/ReleaseInformation.cs | 4 ++-- src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs | 2 +- src/Ryujinx/Updater.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Ryujinx.Common/ReleaseInformation.cs b/src/Ryujinx.Common/ReleaseInformation.cs index 888c57e81..523479d82 100644 --- a/src/Ryujinx.Common/ReleaseInformation.cs +++ b/src/Ryujinx.Common/ReleaseInformation.cs @@ -28,9 +28,9 @@ namespace Ryujinx.Common public static bool IsFlatHubBuild => IsValid && ReleaseChannelOwner.Equals(FlatHubChannel); - public static bool IsCanaryBuild => IsValid && ReleaseChannelOwner.Equals(CanaryChannel); + public static bool IsCanaryBuild => IsValid && ReleaseChannelName.Equals(CanaryChannel); - public static bool IsReleaseBuild => IsValid && ReleaseChannelOwner.Equals(ReleaseChannel); + public static bool IsReleaseBuild => IsValid && ReleaseChannelName.Equals(ReleaseChannel); public static string Version => IsValid ? BuildVersion : Assembly.GetEntryAssembly()!.GetCustomAttribute()?.InformationalVersion; } diff --git a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs index 068dee350..fd413d2f9 100644 --- a/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs +++ b/src/Ryujinx/UI/Views/Main/MainStatusBarView.axaml.cs @@ -33,7 +33,7 @@ namespace Ryujinx.Ava.UI.Views.Main LocaleManager.Instance.LocaleChanged += () => Dispatcher.UIThread.Post(() => { if (Window.ViewModel.EnableNonGameRunningControls) - Refresh_OnClick(null, null); + Window.LoadApplications(); }); } } diff --git a/src/Ryujinx/Updater.cs b/src/Ryujinx/Updater.cs index 7005fe528..7fc362cda 100644 --- a/src/Ryujinx/Updater.cs +++ b/src/Ryujinx/Updater.cs @@ -156,7 +156,7 @@ namespace Ryujinx.Ava try { - newVersion = Version.Parse(_buildVer); + newVersion = Version.Parse(ReleaseInformation.IsCanaryBuild ? _buildVer.Split(' ')[1] : _buildVer); } catch { From 640d7f9e779b51433406b4f65ca175bbbb960394 Mon Sep 17 00:00:00 2001 From: Evan Husted Date: Wed, 6 Nov 2024 19:55:58 -0600 Subject: [PATCH 15/15] Updater: kinda confused how this didn't work? --- .../Models/Github/GithubReleasesJsonResponse.cs | 2 ++ src/Ryujinx/Updater.cs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Ryujinx.UI.Common/Models/Github/GithubReleasesJsonResponse.cs b/src/Ryujinx.UI.Common/Models/Github/GithubReleasesJsonResponse.cs index 0250e1094..7bec1bcdc 100644 --- a/src/Ryujinx.UI.Common/Models/Github/GithubReleasesJsonResponse.cs +++ b/src/Ryujinx.UI.Common/Models/Github/GithubReleasesJsonResponse.cs @@ -5,6 +5,8 @@ namespace Ryujinx.UI.Common.Models.Github public class GithubReleasesJsonResponse { public string Name { get; set; } + + public string TagName { get; set; } public List Assets { get; set; } } } diff --git a/src/Ryujinx/Updater.cs b/src/Ryujinx/Updater.cs index 7fc362cda..a466ea832 100644 --- a/src/Ryujinx/Updater.cs +++ b/src/Ryujinx/Updater.cs @@ -101,7 +101,7 @@ namespace Ryujinx.Ava string fetchedJson = await jsonClient.GetStringAsync(LatestReleaseUrl); var fetched = JsonHelper.Deserialize(fetchedJson, _serializerContext.GithubReleasesJsonResponse); - _buildVer = fetched.Name; + _buildVer = fetched.TagName; foreach (var asset in fetched.Assets) { @@ -156,7 +156,7 @@ namespace Ryujinx.Ava try { - newVersion = Version.Parse(ReleaseInformation.IsCanaryBuild ? _buildVer.Split(' ')[1] : _buildVer); + newVersion = Version.Parse(_buildVer); } catch {