Compare commits

...

49 Commits

Author SHA1 Message Date
Evan Husted
42cbe24bb1 Actually fix Canary showing the wrong repo 2024-11-10 23:32:37 -06:00
Evan Husted
79ba9d1258 UI: RPC: Fix asset image hover string version pointing to the Canary repo in Canary 2024-11-10 23:26:15 -06:00
Evan Husted
826ffd4a04 misc: Move the LowPowerPtc event handler that changes Optimizations.LowPower into the ConfigurationState ctor 2024-11-10 22:31:26 -06:00
Evan Husted
7369079459 misc: chore: cleanup 2 accidental xml namespaces 2024-11-10 22:23:03 -06:00
Evan Husted
a506d81989 Split ConfigurationState into 3 parts:
Migration, Model, and everything else.
2024-11-10 22:16:45 -06:00
Evan Husted
15c20920b3 I thought this was a typo on my part; it wasn't 2024-11-10 22:04:55 -06:00
Evan Husted
285ee276b6 misc: Bake in value change logging into ReactiveObject to reduce logic duplication. 2024-11-10 22:03:12 -06:00
Evan Husted
617b81e209 UI: Conditionally enable install/uninstall file types buttons based on whether they're installed already 2024-11-10 20:33:49 -06:00
Evan Husted
eb6ce7bcb3 misc: chore: replace some new "" additions & some I missed 2024-11-10 20:09:02 -06:00
Evan Husted
69f75f2df1 misc: Fix small code formatting & styling issues 2024-11-10 19:58:02 -06:00
Evan Husted
10c8d73b60 UI: Ryujinx Canary title in NCA extractor 2024-11-10 19:10:02 -06:00
Evan Husted
e01a30016e RPC: Add Mario & Luigi Brothership image. 2024-11-10 17:01:47 -06:00
Evan Husted
e26625dfd5 UI: Disable XCI trimmer button when in-game 2024-11-10 16:17:36 -06:00
Evan Husted
9c82d98ec4 headless: Add Ignore Controller Applet as a configurable option 2024-11-10 15:48:07 -06:00
Evan Husted
4aae82bad1 misc: Small cleanups 2024-11-10 15:34:24 -06:00
Vladimir Sokolov
299be822c4 UI: fix: when switching players, it would show old config (#122)
When switching between players' gamepads while saving settings, then
returning to the previous player, the settings show the default settings
instead of the actual settings applied
2024-11-09 23:24:17 -06:00
Jacobwasbeast
b17e4f79fb Adds the ability to read a amiibo's nickname from the VirtualAmiiboFile (#217)
This feature adds a way to change the Amiibo's nickname inside Smash and
other places where it's used, so it’s not always "Ryujinx." However, I
did not add a GUI or create the Cabinet applet that would allow users to
change this. So you will have to go to system/amiibo and find your
amiibo id to change it.
2024-11-09 21:18:50 -06:00
Piplup
a7b58df3fe Appimage Round 2 (#73) 2024-11-09 19:30:19 -06:00
Jacobwasbeast
8c2d6192ba Add Dummy Applet to Replace NotImplementedException (#216)
Currently, in Ryujinx, if an app attempts to open an unimplemented
applet, it crashes. This change adds a dummy applet to send a dummy
response instead of crashing and logs the applet.
2024-11-09 19:28:12 -06:00
Evan Husted
2a23000fed Add Canary release badge & links 2024-11-08 19:54:36 -06:00
dependabot[bot]
ab7d0a2e6d nuget: bump Microsoft.IdentityModel.JsonWebTokens from 8.0.1 to 8.1.2 (#13) 2024-11-07 10:47:40 -06:00
WilliamWsyHK
bd2681b2f9 Add missing and update translations for zh-tw (#158)
Simply add back some missing translations and update outdated
translations for zh-tw.
2024-11-07 10:46:40 -06:00
Evan Husted
640d7f9e77 Updater: kinda confused how this didn't work? 2024-11-06 19:55:58 -06:00
Evan Husted
02e8278438 Merge remote-tracking branch 'origin/master' 2024-11-06 19:46:30 -06:00
Evan Husted
6acd86c890 Fix canary updater & checking if current build is canary. 2024-11-06 19:46:20 -06:00
Luke Warner
708256ce96 Add just, a whole bunch of games to RPC assets. (#98) 2024-11-06 19:22:40 -06:00
Evan Husted
5bf50836e1 i18n: missing comma in en_US locale 2024-11-06 18:24:30 -06:00
Evan Husted
730ba44043 misc: Canary-specific naming & other small changes I had that I need to push. 2024-11-06 18:23:27 -06:00
Kekschen
36c374cc7a fix: remove --deep (#188) 2024-11-06 18:18:59 -06:00
GabCoolGuy
75f714488e Add many missing locales to all languages (#160)
* Added many missing locales
2024-11-06 17:57:12 -06:00
TheToid
4831965404 Add ability to trim and untrim XCI files from the application context menu AND in Bulk (#105) 2024-11-06 17:37:30 -06:00
Luke Warner
47b8145809 Fix fullscreen when using 'Show Title Bar' (#150) 2024-11-06 17:36:30 -06:00
James Duarte
20cc21add6 fix minor grammatical issues in en_US.json (#183) 2024-11-06 17:36:02 -06:00
Evan Husted
683baec1af OOPSIE!!!!!!!!! 2024-11-06 17:04:20 -06:00
Evan Husted
f4957d2a09 Didn't realize you could compare tags and not just releases although that should have been obvious 2024-11-06 17:00:16 -06:00
Evan Husted
3e1182af22 Specify what is a canary tag 2024-11-06 16:55:17 -06:00
Evan Husted
6664ed1b11 Merge remote-tracking branch 'origin/master' 2024-11-06 16:48:33 -06:00
Evan Husted
0c88b9eff7 Canary & Release separation. 2024-11-06 16:48:20 -06:00
LotP1
8a064bcd7e Update README.md (#187) 2024-11-05 12:34:38 -06:00
Daniel Zauner
5ff962be37 fix index out of range check in GetCoefficientAtIndex (#164) 2024-11-03 13:58:27 -06:00
agnostk
d9c8b7d937 feat: add DebugMouse HID (#163) 2024-11-03 13:58:14 -06:00
Otozinclus
feeeafe8fe Update MacOS distribution .icns (#139) 2024-11-02 19:37:42 -05:00
Evan Husted
04f014c777 hotfix: Locale formatting 2024-11-01 16:17:08 -05:00
Evan Husted
4a677deb50 infra: Add build/release workflows to solution items, remove jitsupport dylib from linux & windows, pack native libraries into Ryujinx executable. 2024-11-01 16:04:32 -05:00
Evan Husted
1c07bf3dd0 misc: Abstract repeated logic in markup extensions & move Updater into the base of the Avalonia project. 2024-11-01 15:48:25 -05:00
Evan Husted
4c83794254 Avalonia: Move LocaleExtension & IconExtension into one namespace to simplify the usage sites in the markup. 2024-11-01 13:00:56 -05:00
Evan Husted
6911e288bc misc: Code cleanups. 2024-11-01 12:00:07 -05:00
Evan Husted
67ab54e2bb misc: Remove custom themes in config. 2024-11-01 11:58:58 -05:00
Evan Husted
139c195eb7 misc: Replace "" with string.Empty. 2024-11-01 11:57:23 -05:00
188 changed files with 7320 additions and 4387 deletions

View File

@@ -61,11 +61,11 @@ jobs:
if: matrix.platform.name != 'linux-arm64'
- name: Publish Ryujinx
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
- name: Publish Ryujinx.Headless.SDL2
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained true
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
- name: Set executable bit
@@ -74,36 +74,36 @@ jobs:
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
#- name: Build AppImage
# if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
# run: |
# PLATFORM_NAME="${{ matrix.platform.name }}"
- name: Build AppImage
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
run: |
PLATFORM_NAME="${{ matrix.platform.name }}"
# sudo apt install -y zsync desktop-file-utils appstream
sudo apt install -y zsync desktop-file-utils appstream
# mkdir -p tools
# export PATH="$PATH:$(readlink -f tools)"
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
# 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
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 OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
# shell: bash
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
shell: bash
- name: Upload Ryujinx artifact
uses: actions/upload-artifact@v4
@@ -112,12 +112,12 @@ jobs:
path: publish
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
#- name: Upload Ryujinx (AppImage) artifact
# uses: actions/upload-artifact@v4
# if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
# with:
# name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}-AppImage
# path: publish_appimage
- name: Upload Ryujinx (AppImage) artifact
uses: actions/upload-artifact@v4
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
with:
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}-AppImage
path: publish_appimage
- name: Upload Ryujinx.Headless.SDL2 artifact
uses: actions/upload-artifact@v4

257
.github/workflows/canary.yml vendored Normal file
View File

@@ -0,0 +1,257 @@
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_SOURCE_REPO: "Ryujinx"
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/Canary-${{ 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 }}
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 }}
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_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
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/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ 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_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
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 }}
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
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}

View File

@@ -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
@@ -93,6 +93,7 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_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
@@ -101,79 +102,79 @@ jobs:
- 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 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 true
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained -p:IncludeNativeLibrariesForSelfExtract=true
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained -p:IncludeNativeLibrariesForSelfExtract=true
- name: Packing Windows builds
if: matrix.platform.os == 'windows-latest'
run: |
pushd publish_ava
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
pushd publish
rm 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
7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
rm 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: 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 OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
pushd publish_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: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest'
run: |
pushd publish_ava
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
pushd publish
chmod +x Ryujinx.sh 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
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
chmod +x Ryujinx.sh 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*"
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
@@ -224,12 +225,13 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_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
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
- name: Publish macOS Ryujinx.Headless.SDL2
run: |
@@ -239,7 +241,7 @@ jobs:
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
artifacts: "publish/*.tar.gz, publish_headless/*.tar.gz"
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

View File

@@ -22,7 +22,7 @@
<PackageVersion Include="LibHac" Version="0.19.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.0.1" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.1.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />

View File

@@ -14,6 +14,15 @@
<img src="https://img.shields.io/github/v/release/GreemDev/Ryujinx"
alt="Latest Release">
</a>
<br>
<a href="https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml">
<img src="https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml/badge.svg"
alt="">
</a>
<a href="https://github.com/GreemDev/Ryujinx-Canary/releases/latest">
<img src="https://img.shields.io/github/v/release/GreemDev/Ryujinx-Canary?label=canary"
alt="Latest Canary Release">
</a>
</h1>
<p align="center">
@@ -61,9 +70,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 +83,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

View File

@@ -29,12 +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
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}"
@@ -87,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

Binary file not shown.

View File

@@ -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
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$APP_BUNDLE_DIRECTORY"
fi

View File

@@ -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"
echo "Done"

View File

@@ -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"
echo "Done"

View File

@@ -77,7 +77,7 @@ namespace ARMeilleure.Translation
{
continue;
}
for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++)
{
BasicBlock current = block.Predecessors[pBlkIndex];

View File

@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -848,17 +849,15 @@ namespace ARMeilleure.Translation.PTC
}
}
List<Thread> threads = new();
for (int i = 0; i < degreeOfParallelism; i++)
{
Thread thread = new(TranslateFuncs)
{
IsBackground = true,
};
threads.Add(thread);
}
List<Thread> threads = Enumerable.Range(0, degreeOfParallelism)
.Select(idx =>
new Thread(TranslateFuncs)
{
IsBackground = true,
Name = "Ptc.TranslateThread." + idx
}
).ToList();
Stopwatch sw = Stopwatch.StartNew();
@@ -885,6 +884,7 @@ namespace ARMeilleure.Translation.PTC
Thread preSaveThread = new(PreSave)
{
IsBackground = true,
Name = "Ptc.DiskWriter"
};
preSaveThread.Start();
}

View File

@@ -41,7 +41,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
public OpenALHardwareDeviceDriver()
{
_device = ALC.OpenDevice("");
_device = ALC.OpenDevice(string.Empty);
_context = ALC.CreateContext(_device, new ALContextAttributes());
_updateRequiredEvent = new ManualResetEvent(false);
_pauseEvent = new ManualResetEvent(true);

View File

@@ -81,7 +81,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static short GetCoefficientAtIndex(ReadOnlySpan<short> coefficients, int index)
{
if ((uint)index > (uint)coefficients.Length)
if ((uint)index >= (uint)coefficients.Length)
{
Logger.Error?.Print(LogClass.AudioRenderer, $"Out of bound read for coefficient at index {index}");

View File

@@ -119,7 +119,7 @@ namespace Ryujinx.Common.Configuration
private static string SetUpLogsDir()
{
string logDir = "";
string logDir = string.Empty;
if (Mode == LaunchMode.Portable)
{
@@ -148,7 +148,7 @@ namespace Ryujinx.Common.Configuration
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
logDir = "";
logDir = string.Empty;
}
if (string.IsNullOrEmpty(logDir))
@@ -179,7 +179,7 @@ namespace Ryujinx.Common.Configuration
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
logDir = "";
logDir = string.Empty;
}
if (string.IsNullOrEmpty(logDir))

View File

@@ -121,8 +121,8 @@ namespace Ryujinx.Common.GraphicsDriver
};
application.AppName.Set("Ryujinx.exe");
application.UserFriendlyName.Set("Ryujinx");
application.Launcher.Set("");
application.FileInFolder.Set("");
application.Launcher.Set(string.Empty);
application.FileInFolder.Set(string.Empty);
Check(NvAPI_DRS_CreateApplication(handle, profileHandle, ref application));
}

View File

@@ -72,5 +72,6 @@ namespace Ryujinx.Common.Logging
TamperMachine,
UI,
Vic,
XCIFileTrimmer
}
}

View File

@@ -38,7 +38,7 @@ namespace Ryujinx.Common.Logging
{
if (_enabledClasses[(int)logClass])
{
Updated?.Invoke(null, new LogEventArgs(Level, _time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, "", message)));
Updated?.Invoke(null, new LogEventArgs(Level, _time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, string.Empty, message)));
}
}

View File

@@ -30,10 +30,10 @@ namespace Ryujinx.Common.Logging.Targets
string ILogTarget.Name { get => _target.Name; }
public AsyncLogTargetWrapper(ILogTarget target)
: this(target, -1, AsyncLogTargetOverflowAction.Block)
: this(target, -1)
{ }
public AsyncLogTargetWrapper(ILogTarget target, int queueLimit, AsyncLogTargetOverflowAction overflowAction)
public AsyncLogTargetWrapper(ILogTarget target, int queueLimit = -1, AsyncLogTargetOverflowAction overflowAction = AsyncLogTargetOverflowAction.Block)
{
_target = target;
_messageQueue = new BlockingCollection<LogEventArgs>(queueLimit);

View File

@@ -47,7 +47,7 @@ namespace Ryujinx.Common.Logging.Targets
}
// Clean up old logs, should only keep 3
FileInfo[] files = logDir.GetFiles("*.log").OrderBy((info => info.CreationTime)).ToArray();
FileInfo[] files = logDir.GetFiles("*.log").OrderBy(info => info.CreationTime).ToArray();
for (int i = 0; i < files.Length - 2; i++)
{
try

View File

@@ -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;
}
}
}
}

View File

@@ -1,11 +1,13 @@
using Ryujinx.Common.Logging;
using System;
using System.Globalization;
using System.Threading;
namespace Ryujinx.Common
{
public class ReactiveObject<T>
{
private readonly ReaderWriterLockSlim _readerWriterLock = new();
private readonly ReaderWriterLockSlim _rwLock = new();
private bool _isInitialized;
private T _value;
@@ -15,15 +17,15 @@ namespace Ryujinx.Common
{
get
{
_readerWriterLock.EnterReadLock();
_rwLock.EnterReadLock();
T value = _value;
_readerWriterLock.ExitReadLock();
_rwLock.ExitReadLock();
return value;
}
set
{
_readerWriterLock.EnterWriteLock();
_rwLock.EnterWriteLock();
T oldValue = _value;
@@ -32,7 +34,7 @@ namespace Ryujinx.Common
_isInitialized = true;
_value = value;
_readerWriterLock.ExitWriteLock();
_rwLock.ExitWriteLock();
if (!oldIsInitialized || oldValue == null || !oldValue.Equals(_value))
{
@@ -40,12 +42,22 @@ namespace Ryujinx.Common
}
}
}
public void LogChangesToValue(string valueName, LogClass logClass = LogClass.Configuration)
=> Event += (_, e) => ReactiveObjectHelper.LogValueChange(logClass, e, valueName);
public static implicit operator T(ReactiveObject<T> obj) => obj.Value;
}
public static class ReactiveObjectHelper
{
public static void LogValueChange<T>(LogClass logClass, ReactiveEventArgs<T> eventArgs, string valueName)
{
string message = string.Create(CultureInfo.InvariantCulture, $"{valueName} set to: {eventArgs.NewValue}");
Logger.Info?.Print(logClass, message);
}
public static void Toggle(this ReactiveObject<bool> rBoolean) => rBoolean.Value = !rBoolean.Value;
}

View File

@@ -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%%";
@@ -13,6 +15,7 @@ namespace Ryujinx.Common
private const string ConfigFileName = "%%RYUJINX_CONFIG_FILE_NAME%%";
public const string ReleaseChannelOwner = "%%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER%%";
public const string ReleaseChannelSourceRepo = "%%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO%%";
public const string ReleaseChannelRepo = "%%RYUJINX_TARGET_RELEASE_CHANNEL_REPO%%";
public static string ConfigName => !ConfigFileName.StartsWith("%%") ? ConfigFileName : "Config.json";
@@ -21,10 +24,15 @@ namespace Ryujinx.Common
!BuildGitHash.StartsWith("%%") &&
!ReleaseChannelName.StartsWith("%%") &&
!ReleaseChannelOwner.StartsWith("%%") &&
!ReleaseChannelSourceRepo.StartsWith("%%") &&
!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 && ReleaseChannelName.Equals(CanaryChannel);
public static bool IsReleaseBuild => IsValid && ReleaseChannelName.Equals(ReleaseChannel);
public static string Version => IsValid ? BuildVersion : Assembly.GetEntryAssembly()!.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
}

View File

@@ -10,6 +10,7 @@
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" />
<PackageReference Include="MsgPack.Cli" />
<PackageReference Include="System.Management" />
<PackageReference Include="Humanizer" />
<PackageReference Include="Gommon" />
</ItemGroup>

View File

@@ -17,29 +17,19 @@ namespace Ryujinx.Common.Utilities
/// It is REQUIRED for you to save returned options statically or as a part of static serializer context
/// in order to avoid performance issues. You can safely modify returned options for your case before storing.
/// </remarks>
public static JsonSerializerOptions GetDefaultSerializerOptions(bool indented = true)
{
JsonSerializerOptions options = new()
public static JsonSerializerOptions GetDefaultSerializerOptions(bool indented = true) =>
new()
{
DictionaryKeyPolicy = _snakeCasePolicy,
PropertyNamingPolicy = _snakeCasePolicy,
WriteIndented = indented,
AllowTrailingCommas = true,
ReadCommentHandling = JsonCommentHandling.Skip,
ReadCommentHandling = JsonCommentHandling.Skip
};
return options;
}
public static string Serialize<T>(T value, JsonTypeInfo<T> typeInfo) => JsonSerializer.Serialize(value, typeInfo);
public static string Serialize<T>(T value, JsonTypeInfo<T> typeInfo)
{
return JsonSerializer.Serialize(value, typeInfo);
}
public static T Deserialize<T>(string value, JsonTypeInfo<T> typeInfo)
{
return JsonSerializer.Deserialize(value, typeInfo);
}
public static T Deserialize<T>(string value, JsonTypeInfo<T> typeInfo) => JsonSerializer.Deserialize(value, typeInfo);
public static void SerializeToFile<T>(string filePath, T value, JsonTypeInfo<T> typeInfo)
{
@@ -53,10 +43,7 @@ namespace Ryujinx.Common.Utilities
return JsonSerializer.Deserialize(file, typeInfo);
}
public static void SerializeToStream<T>(Stream stream, T value, JsonTypeInfo<T> typeInfo)
{
JsonSerializer.Serialize(stream, value, typeInfo);
}
public static void SerializeToStream<T>(Stream stream, T value, JsonTypeInfo<T> typeInfo) => JsonSerializer.Serialize(stream, value, typeInfo);
private class SnakeCaseNamingPolicy : JsonNamingPolicy
{

View File

@@ -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";
/// <summary>
/// Cartridge Sizes (ByteIdentifier, SizeInGB)
/// </summary>
private static readonly Dictionary<byte, long> _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<byte>(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;
}
}
}

View File

@@ -432,7 +432,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
bool colorIsVector = isGather || !isShadow;
texCall += ")" + (colorIsVector ? GetMaskMultiDest(texOp.Index) : "");
texCall += ")" + (colorIsVector ? GetMaskMultiDest(texOp.Index) : string.Empty);
return texCall;
}

View File

@@ -830,12 +830,12 @@ namespace Ryujinx.Graphics.Shader.Translation
if (use.Node != null)
{
Console.Write($"{indentation} {separator}- ({(use.Inverted ? "INV " : "")}{use.Index})");
Console.Write($"{indentation} {separator}- ({(use.Inverted ? "INV " : string.Empty)}{use.Index})");
PrintTreeNode(use.Node, indentation + (last ? " " : " | "));
}
else
{
Console.WriteLine($"{indentation} {separator}- ({(use.Inverted ? "INV " : "")}{use.Index}) NULL");
Console.WriteLine($"{indentation} {separator}- ({(use.Inverted ? "INV " : string.Empty)}{use.Index}) NULL");
}
}
}
@@ -852,12 +852,12 @@ namespace Ryujinx.Graphics.Shader.Translation
if (use.Node != null)
{
Console.Write($"{indentation} {separator}- ({(use.Inverted ? "INV " : "")}{use.Index})");
Console.Write($"{indentation} {separator}- ({(use.Inverted ? "INV " : string.Empty)}{use.Index})");
PrintTreeNode(use.Node, indentation + (last ? " " : " | "));
}
else
{
Console.WriteLine($"{indentation} {separator}- ({(use.Inverted ? "INV " : "")}{use.Index}) NULL");
Console.WriteLine($"{indentation} {separator}- ({(use.Inverted ? "INV " : string.Empty)}{use.Index}) NULL");
}
}
}

View File

@@ -104,25 +104,27 @@ namespace Ryujinx.Graphics.Vulkan
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
public VulkanRenderer(Vk api, Func<Instance, Vk, SurfaceKHR> surfaceFunc, Func<string[]> requiredExtensionsFunc, string preferredGpuId)
public VulkanRenderer(Vk api, Func<Instance, Vk, SurfaceKHR> getSurface, Func<string[]> requiredExtensionsFunc, string preferredGpuId)
{
_getSurface = surfaceFunc;
_getSurface = getSurface;
_getRequiredExtensions = requiredExtensionsFunc;
_preferredGpuId = preferredGpuId;
Api = api;
Shaders = new HashSet<ShaderCollection>();
Textures = new HashSet<ITexture>();
Samplers = new HashSet<SamplerHolder>();
Shaders = [];
Textures = [];
Samplers = [];
if (OperatingSystem.IsMacOS())
{
// Any device running on MacOS is using MoltenVK, even Intel and AMD vendors.
if (IsMoltenVk = OperatingSystem.IsMacOS())
MVKInitialization.Initialize();
// Any device running on MacOS is using MoltenVK, even Intel and AMD vendors.
IsMoltenVk = true;
}
}
public static VulkanRenderer Create(
string preferredGpuId,
Func<Instance, Vk, SurfaceKHR> getSurface,
Func<string[]> getRequiredExtensions
) => new(Vk.GetApi(), getSurface, getRequiredExtensions, preferredGpuId);
private unsafe void LoadFeatures(uint maxQueueCount, uint queueFamilyIndex)
{
FormatCapabilities = new FormatCapabilities(Api, _physicalDevice.PhysicalDevice);

View File

@@ -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");
@@ -22,7 +23,7 @@ namespace Ryujinx.HLE.Generators
{
if (className.Modifiers.Any(SyntaxKind.AbstractKeyword) || className.Modifiers.Any(SyntaxKind.PrivateKeyword) || !className.AttributeLists.Any(x => x.Attributes.Any(y => y.ToString().StartsWith("Service"))))
continue;
var name = GetFullName(className, context).Replace("global::", "");
var name = GetFullName(className, context).Replace("global::", string.Empty);
if (!name.StartsWith("Ryujinx.HLE.HOS.Services"))
continue;
var constructors = className.ChildNodes().Where(x => x.IsKind(SyntaxKind.ConstructorDeclaration)).Select(y => y as ConstructorDeclarationSyntax).ToArray();
@@ -58,6 +59,7 @@ namespace Ryujinx.HLE.Generators
generator.LeaveScope();
generator.LeaveScope();
generator.AppendLine("#nullable disable");
context.AddSource($"IUserInterface.g.cs", generator.ToString());
}

View File

@@ -523,7 +523,7 @@ namespace Ryujinx.HLE.FileSystem
{
// Clean up the name and get the NcaId
string[] pathComponents = entry.FullName.Replace(".cnmt", "").Split('/');
string[] pathComponents = entry.FullName.Replace(".cnmt", string.Empty).Split('/');
string ncaId = pathComponents[^1];

View File

@@ -132,7 +132,7 @@ namespace Ryujinx.HLE.FileSystem
if (systemPath.StartsWith(baseSystemPath))
{
string rawPath = systemPath.Replace(baseSystemPath, "");
string rawPath = systemPath.Replace(baseSystemPath, string.Empty);
int firstSeparatorOffset = rawPath.IndexOf(Path.DirectorySeparatorChar);
if (firstSeparatorOffset == -1)

View File

@@ -1,4 +1,6 @@
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Applets.Browser;
using Ryujinx.HLE.HOS.Applets.Dummy;
using Ryujinx.HLE.HOS.Applets.Error;
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
using System;
@@ -26,9 +28,13 @@ namespace Ryujinx.HLE.HOS.Applets
return new BrowserApplet(system);
case AppletId.LibAppletOff:
return new BrowserApplet(system);
case AppletId.MiiEdit:
Logger.Warning?.Print(LogClass.Application, $"Please use the MiiEdit inside File/Open Applet");
return new DummyApplet(system);
}
throw new NotImplementedException($"{applet} applet is not implemented.");
Logger.Warning?.Print(LogClass.Application, $"Applet {applet} not implemented!");
return new DummyApplet(system);
}
}
}

View File

@@ -0,0 +1,43 @@
using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory;
using Ryujinx.HLE.HOS.Applets;
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Applets.Dummy
{
internal class DummyApplet : IApplet
{
private readonly Horizon _system;
private AppletSession _normalSession;
public event EventHandler AppletStateChanged;
public DummyApplet(Horizon system)
{
_system = system;
}
public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
{
_normalSession = normalSession;
_normalSession.Push(BuildResponse());
AppletStateChanged?.Invoke(this, null);
_system.ReturnFocus();
return ResultCode.Success;
}
private static T ReadStruct<T>(byte[] data) where T : struct
{
return MemoryMarshal.Read<T>(data.AsSpan());
}
private static byte[] BuildResponse()
{
using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using BinaryWriter writer = new(stream);
writer.Write((ulong)ResultCode.Success);
return stream.ToArray();
}
public ResultCode GetResult()
{
return ResultCode.Success;
}
}
}

View File

@@ -107,7 +107,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
private static string CleanText(string value)
{
return CleanTextRegex().Replace(value, "").Replace("\0", "");
return CleanTextRegex().Replace(value, string.Empty).Replace("\0", string.Empty);
}
private string GetMessageText(uint module, uint description, string key)
@@ -129,17 +129,15 @@ namespace Ryujinx.HLE.HOS.Applets.Error
return CleanText(reader.ReadToEnd());
}
else
{
return "";
}
return string.Empty;
}
private string[] GetButtonsText(uint module, uint description, string key)
{
string buttonsText = GetMessageText(module, description, key);
return (buttonsText == "") ? null : buttonsText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
return (buttonsText == string.Empty) ? null : buttonsText.Split(["\r\n", "\r", "\n"], StringSplitOptions.None);
}
private void ParseErrorCommonArg()
@@ -156,7 +154,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
string message = GetMessageText(module, description, "DlgMsg");
if (message == "")
if (message == string.Empty)
{
message = "An error has occured.\n\nPlease try again later.";
}
@@ -190,7 +188,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
// TODO: Handle the LanguageCode to return the translated "OK" and "Details".
if (detailsText.Trim() != "")
if (detailsText.Trim() != string.Empty)
{
buttons.Add("Details");
}

View File

@@ -51,7 +51,7 @@ namespace Ryujinx.HLE.HOS.Applets
private byte[] _transferMemory;
private string _textValue = "";
private string _textValue = string.Empty;
private int _cursorBegin = 0;
private Encoding _encoding = Encoding.Unicode;
private KeyboardResult _lastResult = KeyboardResult.NotSet;

View File

@@ -305,7 +305,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
{
SKRect bounds = SKRect.Empty;
if (text == "")
if (text == string.Empty)
{
paint.MeasureText(" ", ref bounds);
}
@@ -321,7 +321,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
{
SKRect bounds = SKRect.Empty;
if (text == "")
if (text == string.Empty)
{
paint.MeasureText(" ", ref bounds);
}

View File

@@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
/// </summary>
internal class SoftwareKeyboardUIState
{
public string InputText = "";
public string InputText = string.Empty;
public int CursorBegin = 0;
public int CursorEnd = 0;
public bool AcceptPressed = false;

View File

@@ -2463,7 +2463,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler
return ParseIntegerLiteral("unsigned short");
case 'i':
_position++;
return ParseIntegerLiteral("");
return ParseIntegerLiteral(string.Empty);
case 'j':
_position++;
return ParseIntegerLiteral("u");

View File

@@ -238,7 +238,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
else
{
info.SubName = "";
info.SubName = string.Empty;
}
info.ImageName = GetGuessedNsoNameFromIndex(imageIndex);

View File

@@ -116,18 +116,13 @@ namespace Ryujinx.HLE.HOS
private readonly Dictionary<ulong, ModCache> _appMods; // key is ApplicationId
private PatchCache _patches;
private static readonly EnumerationOptions _dirEnumOptions;
static ModLoader()
private static readonly EnumerationOptions _dirEnumOptions = new()
{
_dirEnumOptions = new EnumerationOptions
{
MatchCasing = MatchCasing.CaseInsensitive,
MatchType = MatchType.Simple,
RecurseSubdirectories = false,
ReturnSpecialDirectories = false,
};
}
MatchCasing = MatchCasing.CaseInsensitive,
MatchType = MatchType.Simple,
RecurseSubdirectories = false,
ReturnSpecialDirectories = false,
};
public ModLoader()
{
@@ -169,7 +164,7 @@ namespace Ryujinx.HLE.HOS
foreach (var modDir in dir.EnumerateDirectories())
{
types.Clear();
Mod<DirectoryInfo> mod = new("", null, true);
Mod<DirectoryInfo> mod = new(string.Empty, null, true);
if (StrEquals(RomfsDir, modDir.Name))
{

View File

@@ -64,7 +64,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
if (userId.IsNull)
{
userId = new UserId(Guid.NewGuid().ToString().Replace("-", ""));
userId = new UserId(Guid.NewGuid().ToString().Replace("-", string.Empty));
}
UserProfile profile = new(userId, name, image);

View File

@@ -5,6 +5,7 @@ using Ryujinx.HLE.Exceptions;
using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse;
@@ -28,6 +29,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
public DebugPadDevice DebugPad;
public TouchDevice Touchscreen;
public MouseDevice Mouse;
public DebugMouseDevice DebugMouse;
public KeyboardDevice Keyboard;
public NpadDevices Npads;
@@ -44,6 +46,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
CheckTypeSizeOrThrow<RingLifo<DebugPadState>>(0x2c8);
CheckTypeSizeOrThrow<RingLifo<TouchScreenState>>(0x2C38);
CheckTypeSizeOrThrow<RingLifo<MouseState>>(0x350);
CheckTypeSizeOrThrow<RingLifo<DebugMouseState>>(0x350);
CheckTypeSizeOrThrow<RingLifo<KeyboardState>>(0x3D8);
CheckTypeSizeOrThrow<Array10<NpadState>>(0x32000);
CheckTypeSizeOrThrow<SharedMemory>(Horizon.HidSize);
@@ -64,6 +67,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
DebugPad = new DebugPadDevice(_device, true);
Touchscreen = new TouchDevice(_device, true);
Mouse = new MouseDevice(_device, false);
DebugMouse = new DebugMouseDevice(_device, false);
Keyboard = new KeyboardDevice(_device, false);
Npads = new NpadDevices(_device, true);
}

View File

@@ -0,0 +1,29 @@
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse;
namespace Ryujinx.HLE.HOS.Services.Hid
{
public class DebugMouseDevice : BaseDevice
{
public DebugMouseDevice(Switch device, bool active) : base(device, active) { }
public void Update()
{
ref RingLifo<DebugMouseState> lifo = ref _device.Hid.SharedMemory.DebugMouse;
ref DebugMouseState previousEntry = ref lifo.GetCurrentEntryRef();
DebugMouseState newState = new()
{
SamplingNumber = previousEntry.SamplingNumber + 1,
};
if (Active)
{
// TODO: This is a debug device only present in dev environment, do we want to support it?
}
lifo.Write(ref newState);
}
}
}

View File

@@ -130,6 +130,26 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success;
}
[CommandCmif(26)]
// ActivateDebugMouse(nn::applet::AppletResourceUserId)
public ResultCode ActivateDebugMouse(ServiceCtx context)
{
long appletResourceUserId = context.RequestData.ReadInt64();
context.Device.Hid.DebugMouse.Active = true;
// Initialize entries to avoid issues with some games.
for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
{
context.Device.Hid.DebugMouse.Update();
}
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
return ResultCode.Success;
}
[CommandCmif(31)]
// ActivateKeyboard(nn::applet::AppletResourceUserId)

View File

@@ -0,0 +1,12 @@
using System;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse
{
[Flags]
enum DebugMouseAttribute : uint
{
None = 0,
Transferable = 1 << 0,
IsConnected = 1 << 1,
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse
{
[Flags]
enum DebugMouseButton : uint
{
None = 0,
Left = 1 << 0,
Right = 1 << 1,
Middle = 1 << 2,
Forward = 1 << 3,
Back = 1 << 4,
}
}

View File

@@ -0,0 +1,19 @@
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct DebugMouseState : ISampledDataStruct
{
public ulong SamplingNumber;
public int X;
public int Y;
public int DeltaX;
public int DeltaY;
public int WheelDeltaX;
public int WheelDeltaY;
public DebugMouseButton Buttons;
public DebugMouseAttribute Attributes;
}
}

View File

@@ -1,5 +1,6 @@
using Ryujinx.Common.Memory;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugMouse;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.DebugPad;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Keyboard;
using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Mouse;
@@ -44,6 +45,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory
/// </summary>
[FieldOffset(0x9A00)]
public Array10<NpadState> Npads;
/// <summary>
/// Debug mouse.
/// </summary>
[FieldOffset(0x3DC00)]
public RingLifo<DebugMouseState> DebugMouse;
public static SharedMemory Create()
{

View File

@@ -1,3 +1,4 @@
using Gommon;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory;
using Ryujinx.Common.Utilities;
@@ -143,7 +144,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm
if (decompressedLdnData.Length != header.DecompressLength)
{
Logger.Error?.PrintMsg(LogClass.ServiceLdn, $"Decompress error: length does not match. ({decompressedLdnData.Length} != {header.DecompressLength})");
Logger.Error?.PrintMsg(LogClass.ServiceLdn, $"Decompress error data: '{string.Join("", decompressedLdnData.Select(x => (int)x).ToArray())}'");
Logger.Error?.PrintMsg(LogClass.ServiceLdn, $"Decompress error data: '{decompressedLdnData.Select(x => (int)x).JoinToString(string.Empty)}'");
return;
}

View File

@@ -8,6 +8,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager
public uint FileVersion { get; set; }
public byte[] TagUuid { get; set; }
public string AmiiboId { get; set; }
public string NickName { get; set; }
public DateTime FirstWriteDate { get; set; }
public DateTime LastWriteDate { get; set; }
public ushort WriteCounter { get; set; }

View File

@@ -64,16 +64,17 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
};
}
public static RegisterInfo GetRegisterInfo(ITickSource tickSource, string amiiboId, string nickname)
public static RegisterInfo GetRegisterInfo(ITickSource tickSource, string amiiboId, string userName)
{
VirtualAmiiboFile amiiboFile = LoadAmiiboFile(amiiboId);
string nickname = amiiboFile.NickName ?? "Ryujinx";
UtilityImpl utilityImpl = new(tickSource);
CharInfo charInfo = new();
charInfo.SetFromStoreData(StoreData.BuildDefault(utilityImpl, 0));
charInfo.Nickname = Nickname.FromString(nickname);
// This is the player's name
charInfo.Nickname = Nickname.FromString(userName);
RegisterInfo registerInfo = new()
{
@@ -85,7 +86,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
Reserved1 = new Array64<byte>(),
Reserved2 = new Array58<byte>(),
};
"Ryujinx"u8.CopyTo(registerInfo.Nickname.AsSpan());
// This is the amiibo's name
byte[] nicknameBytes = System.Text.Encoding.UTF8.GetBytes(nickname);
nicknameBytes.CopyTo(registerInfo.Nickname.AsSpan());
return registerInfo;
}

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.HLE.HOS.Services.Ngct
ulong bufferSize = context.Request.PtrBuff[0].Size;
bool isMatch = false;
string text = "";
string text = string.Empty;
if (bufferSize != 0)
{
@@ -57,8 +57,8 @@ namespace Ryujinx.HLE.HOS.Services.Ngct
ulong bufferFilteredPosition = context.Request.RecvListBuff[0].Position;
string text = "";
string textFiltered = "";
string text = string.Empty;
string textFiltered = string.Empty;
if (bufferSize != 0)
{

File diff suppressed because it is too large Load Diff

View File

@@ -36,7 +36,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager
// TODO: Load Environment from the savedata.
address = address.Replace("%", IManager.NsdSettings.Environment);
resolvedAddress = "";
resolvedAddress = string.Empty;
if (IManager.NsdSettings == null)
{

View File

@@ -63,7 +63,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
if (size < 0)
{
return "";
return string.Empty;
}
ReadOnlySpan<byte> data = ReadInPlace((size + 1) * 2);

View File

@@ -166,7 +166,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
private ResultCode OpenDisplayImpl(ServiceCtx context, string name)
{
if (name == "")
if (name == string.Empty)
{
return ResultCode.InvalidValue;
}

View File

@@ -102,7 +102,7 @@ namespace Ryujinx.HLE.Loaders.Executables
Match fsSdkMatch = FsSdkRegex().Match(rawTextBuffer);
if (fsSdkMatch.Success)
{
stringBuilder.AppendLine($" FS SDK Version: {fsSdkMatch.Value.Replace("sdk_version: ", "")}");
stringBuilder.AppendLine($" FS SDK Version: {fsSdkMatch.Value.Replace("sdk_version: ", string.Empty)}");
}
MatchCollection sdkMwMatches = SdkMwRegex().Matches(rawTextBuffer);

View File

@@ -89,7 +89,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
Logger.Warning?.Print(LogClass.Ptc, "Detected unsupported ExeFs modifications. PTC disabled.");
}
string programName = "";
string programName = string.Empty;
if (!isHomebrew && programId > 0x010000000000FFFF)
{

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.HLE.Loaders.Processes
var nacpData = new BlitStruct<ApplicationControlProperty>(1);
ulong programId = metaLoader.GetProgramId();
device.Configuration.VirtualFileSystem.ModLoader.CollectMods(new[] { programId });
device.Configuration.VirtualFileSystem.ModLoader.CollectMods([programId]);
if (programId != 0)
{

View File

@@ -145,7 +145,7 @@ namespace Ryujinx.HLE.Loaders.Processes
IFileSystem dummyExeFs = null;
Stream romfsStream = null;
string programName = "";
string programName = string.Empty;
ulong programId = 0000000000000000;
// Load executable.

View File

@@ -255,7 +255,7 @@ namespace Ryujinx.HLE.Loaders.Processes
{
NsoExecutable nso => Convert.ToHexString(nso.BuildId.ItemsRo.ToArray()),
NroExecutable nro => Convert.ToHexString(nro.Header.BuildId),
_ => "",
_ => string.Empty
}).ToUpper());
ulong[] nsoBase = new ulong[executables.Length];

View File

@@ -117,8 +117,9 @@ namespace Ryujinx.Headless.SDL2.OpenGL
GraphicsDebugLevel glLogLevel,
AspectRatio aspectRatio,
bool enableMouse,
HideCursorMode hideCursorMode)
: base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode)
HideCursorMode hideCursorMode,
bool ignoreControllerApplet)
: base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet)
{
_glLogLevel = glLogLevel;
}

View File

@@ -225,6 +225,9 @@ namespace Ryujinx.Headless.SDL2
[Option("ignore-missing-services", Required = false, Default = false, HelpText = "Enable ignoring missing services.")]
public bool IgnoreMissingServices { get; set; }
[Option("ignore-controller-applet", Required = false, Default = false, HelpText = "Enable ignoring the controller applet when your game loses connection to your controller.")]
public bool IgnoreControllerApplet { get; set; }
// Values

View File

@@ -444,8 +444,7 @@ namespace Ryujinx.Headless.SDL2
{
Logger.AddTarget(new AsyncLogTargetWrapper(
new FileLogTarget("file", logFile),
1000,
AsyncLogTargetOverflowAction.Block
1000
));
}
else
@@ -506,8 +505,8 @@ namespace Ryujinx.Headless.SDL2
private static WindowBase CreateWindow(Options options)
{
return options.GraphicsBackend == GraphicsBackend.Vulkan
? new VulkanWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode)
: new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode);
? new VulkanWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet)
: new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet);
}
private static IRenderer CreateRenderer(Options options, WindowBase window)

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
@@ -17,7 +17,7 @@
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$([MSBuild]::IsOSPlatform('OSX'))">
<Exec Command="codesign --entitlements '$(ProjectDir)..\..\distribution\macos\entitlements.xml' -f --deep -s $(SigningCertificate) '$(TargetDir)$(TargetName)'" />
<Exec Command="codesign --entitlements '$(ProjectDir)..\..\distribution\macos\entitlements.xml' -f -s $(SigningCertificate) '$(TargetDir)$(TargetName)'" />
</Target>
<ItemGroup>

View File

@@ -17,8 +17,9 @@ namespace Ryujinx.Headless.SDL2.Vulkan
GraphicsDebugLevel glLogLevel,
AspectRatio aspectRatio,
bool enableMouse,
HideCursorMode hideCursorMode)
: base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode)
HideCursorMode hideCursorMode,
bool ignoreControllerApplet)
: base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet)
{
_glLogLevel = glLogLevel;
}

View File

@@ -1,3 +1,4 @@
using Humanizer;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Logging;
@@ -85,13 +86,15 @@ namespace Ryujinx.Headless.SDL2
private readonly AspectRatio _aspectRatio;
private readonly bool _enableMouse;
private readonly bool _ignoreControllerApplet;
public WindowBase(
InputManager inputManager,
GraphicsDebugLevel glLogLevel,
AspectRatio aspectRatio,
bool enableMouse,
HideCursorMode hideCursorMode)
HideCursorMode hideCursorMode,
bool ignoreControllerApplet)
{
MouseDriver = new SDL2MouseDriver(hideCursorMode);
_inputManager = inputManager;
@@ -107,6 +110,7 @@ namespace Ryujinx.Headless.SDL2
_gpuDoneEvent = new ManualResetEvent(false);
_aspectRatio = aspectRatio;
_enableMouse = enableMouse;
_ignoreControllerApplet = ignoreControllerApplet;
HostUITheme = new HeadlessHostUiTheme();
SDL2Driver.Instance.Initialize();
@@ -483,12 +487,14 @@ namespace Ryujinx.Headless.SDL2
public bool DisplayMessageDialog(ControllerAppletUIArgs args)
{
if (_ignoreControllerApplet) return false;
string playerCount = args.PlayerCountMin == args.PlayerCountMax ? $"exactly {args.PlayerCountMin}" : $"{args.PlayerCountMin}-{args.PlayerCountMax}";
string message = $"Application requests {playerCount} player(s) with:\n\n"
string message = $"Application requests {playerCount} {"player".ToQuantity(args.PlayerCountMin + args.PlayerCountMax, ShowQuantityAs.None)} with:\n\n"
+ $"TYPES: {args.SupportedStyles}\n\n"
+ $"PLAYERS: {string.Join(", ", args.SupportedPlayers)}\n\n"
+ (args.IsDocked ? "Docked mode set. Handheld is also invalid.\n\n" : "")
+ (args.IsDocked ? "Docked mode set. Handheld is also invalid.\n\n" : string.Empty)
+ "Please reconfigure Input now and then press OK.";
return DisplayMessageDialog("Controller Applet", message);

View File

@@ -1235,14 +1235,14 @@ namespace Ryujinx.Horizon.Common
{ 0x412, "NotFound" },
{ 0x612, "NotEnoughBuffer" },
{ 0xCA12, "Cancelled" },
{ 0x7FE12, "" },
{ 0xFA212, "" },
{ 0x7FE12, string.Empty },
{ 0xFA212, string.Empty },
{ 0xFA612, "InvalidTaskId" },
{ 0xFB612, "InvalidSize" },
{ 0xFCA12, "TaskCancelled" },
{ 0xFCC12, "TaskNotCompleted" },
{ 0xFCE12, "TaskQueueNotAvailable" },
{ 0x106A12, "" },
{ 0x106A12, string.Empty },
{ 0x106C12, "OutOfRpcTask" },
{ 0x109612, "InvalidCategory" },
{ 0x214, "OutOfKeyResource" },

View File

@@ -221,7 +221,7 @@ namespace Ryujinx.Horizon.Sdk.Ngc.Detail
if (includeMultiWord)
{
int lastMultiWordIndex = 0;
string multiWord = "";
string multiWord = string.Empty;
while (_multiWordMap.Has(nodePlainIndex))
{

View File

@@ -162,7 +162,7 @@ namespace Ryujinx.UI.App.Common
NsoReader reader = new();
reader.Initialize(nsoFile.Release().AsStorage().AsFile(OpenMode.Read)).ThrowIfFailure();
return BitConverter.ToString(reader.Header.ModuleId.ItemsRo.ToArray()).Replace("-", "").ToUpper()[..16];
return BitConverter.ToString(reader.Header.ModuleId.ItemsRo.ToArray()).Replace("-", string.Empty).ToUpper()[..16];
}
}
}

View File

@@ -298,16 +298,6 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary>
public string LanguageCode { get; set; }
/// <summary>
/// Enable or disable custom themes in the GUI
/// </summary>
public bool EnableCustomTheme { get; set; }
/// <summary>
/// Path to custom GUI theme
/// </summary>
public string CustomThemePath { get; set; }
/// <summary>
/// Chooses the base style // Not Used
/// </summary>

View File

@@ -0,0 +1,715 @@
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.Logging;
using Ryujinx.HLE;
using Ryujinx.UI.Common.Configuration.System;
using Ryujinx.UI.Common.Configuration.UI;
using System;
using System.Collections.Generic;
namespace Ryujinx.UI.Common.Configuration
{
public partial class ConfigurationState
{
public void Load(ConfigurationFileFormat configurationFileFormat, string configurationFilePath)
{
bool configurationFileUpdated = false;
if (configurationFileFormat.Version is < 0 or > ConfigurationFileFormat.CurrentVersion)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Unsupported configuration version {configurationFileFormat.Version}, loading default.");
LoadDefault();
}
if (configurationFileFormat.Version < 2)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 2.");
configurationFileFormat.SystemRegion = Region.USA;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 3)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 3.");
configurationFileFormat.SystemTimeZone = "UTC";
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 4)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 4.");
configurationFileFormat.MaxAnisotropy = -1;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 5)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 5.");
configurationFileFormat.SystemTimeOffset = 0;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 8)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 8.");
configurationFileFormat.EnablePtc = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 9)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 9.");
configurationFileFormat.ColumnSort = new ColumnSort
{
SortColumnId = 0,
SortAscending = false,
};
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVsync = Key.F1,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 10)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 10.");
configurationFileFormat.AudioBackend = AudioBackend.OpenAl;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 11)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 11.");
configurationFileFormat.ResScale = 1;
configurationFileFormat.ResScaleCustom = 1.0f;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 12)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 12.");
configurationFileFormat.LoggingGraphicsDebugLevel = GraphicsDebugLevel.None;
configurationFileUpdated = true;
}
// configurationFileFormat.Version == 13 -> LDN1
if (configurationFileFormat.Version < 14)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 14.");
configurationFileFormat.CheckUpdatesOnStart = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 16)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 16.");
configurationFileFormat.EnableShaderCache = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 17)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 17.");
configurationFileFormat.StartFullscreen = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 18)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 18.");
configurationFileFormat.AspectRatio = AspectRatio.Fixed16x9;
configurationFileUpdated = true;
}
// configurationFileFormat.Version == 19 -> LDN2
if (configurationFileFormat.Version < 20)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 20.");
configurationFileFormat.ShowConfirmExit = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 21)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 21.");
// Initialize network config.
configurationFileFormat.MultiplayerMode = MultiplayerMode.Disabled;
configurationFileFormat.MultiplayerLanInterfaceId = "0";
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 22)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 22.");
configurationFileFormat.HideCursor = HideCursorMode.Never;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 24)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 24.");
configurationFileFormat.InputConfig = new List<InputConfig>
{
new StandardKeyboardInputConfig
{
Version = InputConfig.CurrentVersion,
Backend = InputBackendType.WindowKeyboard,
Id = "0",
PlayerIndex = PlayerIndex.Player1,
ControllerType = ControllerType.ProController,
LeftJoycon = new LeftJoyconCommonConfig<Key>
{
DpadUp = Key.Up,
DpadDown = Key.Down,
DpadLeft = Key.Left,
DpadRight = Key.Right,
ButtonMinus = Key.Minus,
ButtonL = Key.E,
ButtonZl = Key.Q,
ButtonSl = Key.Unbound,
ButtonSr = Key.Unbound,
},
LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
{
StickUp = Key.W,
StickDown = Key.S,
StickLeft = Key.A,
StickRight = Key.D,
StickButton = Key.F,
},
RightJoycon = new RightJoyconCommonConfig<Key>
{
ButtonA = Key.Z,
ButtonB = Key.X,
ButtonX = Key.C,
ButtonY = Key.V,
ButtonPlus = Key.Plus,
ButtonR = Key.U,
ButtonZr = Key.O,
ButtonSl = Key.Unbound,
ButtonSr = Key.Unbound,
},
RightJoyconStick = new JoyconConfigKeyboardStick<Key>
{
StickUp = Key.I,
StickDown = Key.K,
StickLeft = Key.J,
StickRight = Key.L,
StickButton = Key.H,
},
},
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 25)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 25.");
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 26)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 26.");
configurationFileFormat.MemoryManagerMode = MemoryManagerMode.HostMappedUnsafe;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 27)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 27.");
configurationFileFormat.EnableMouse = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 28)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 28.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVsync = Key.F1,
Screenshot = Key.F8,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 29)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 29.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVsync = Key.F1,
Screenshot = Key.F8,
ShowUI = Key.F4,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 30)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 30.");
foreach (InputConfig config in configurationFileFormat.InputConfig)
{
if (config is StandardControllerInputConfig controllerConfig)
{
controllerConfig.Rumble = new RumbleConfigController
{
EnableRumble = false,
StrongRumble = 1f,
WeakRumble = 1f,
};
}
}
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 31)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 31.");
configurationFileFormat.BackendThreading = BackendThreading.Auto;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 32)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 32.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = Key.F5,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 33)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 33.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
ToggleMute = Key.F2,
};
configurationFileFormat.AudioVolume = 1;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 34)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 34.");
configurationFileFormat.EnableInternetAccess = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 35)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 35.");
foreach (InputConfig config in configurationFileFormat.InputConfig)
{
if (config is StandardControllerInputConfig controllerConfig)
{
controllerConfig.RangeLeft = 1.0f;
controllerConfig.RangeRight = 1.0f;
}
}
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 36)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 36.");
configurationFileFormat.LoggingEnableTrace = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 37)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 37.");
configurationFileFormat.ShowConsole = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 38)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 38.");
configurationFileFormat.BaseStyle = "Dark";
configurationFileFormat.GameListViewMode = 0;
configurationFileFormat.ShowNames = true;
configurationFileFormat.GridSize = 2;
configurationFileFormat.LanguageCode = "en_US";
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 39)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 39.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
ResScaleUp = Key.Unbound,
ResScaleDown = Key.Unbound,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 40)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 40.");
configurationFileFormat.GraphicsBackend = GraphicsBackend.OpenGl;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 41)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 41.");
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
VolumeUp = Key.Unbound,
VolumeDown = Key.Unbound,
};
}
if (configurationFileFormat.Version < 42)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 42.");
configurationFileFormat.EnableMacroHLE = true;
}
if (configurationFileFormat.Version < 43)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 43.");
configurationFileFormat.UseHypervisor = true;
}
if (configurationFileFormat.Version < 44)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 44.");
configurationFileFormat.AntiAliasing = AntiAliasing.None;
configurationFileFormat.ScalingFilter = ScalingFilter.Bilinear;
configurationFileFormat.ScalingFilterLevel = 80;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 45)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 45.");
configurationFileFormat.ShownFileTypes = new ShownFileTypes
{
NSP = true,
PFS0 = true,
XCI = true,
NCA = true,
NRO = true,
NSO = true,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 46)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 46.");
configurationFileFormat.MultiplayerLanInterfaceId = "0";
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 47)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 47.");
configurationFileFormat.WindowStartup = new WindowStartup
{
WindowPositionX = 0,
WindowPositionY = 0,
WindowSizeHeight = 760,
WindowSizeWidth = 1280,
WindowMaximized = false,
};
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 48)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 48.");
configurationFileFormat.EnableColorSpacePassthrough = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 49)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 49.");
if (OperatingSystem.IsMacOS())
{
AppDataManager.FixMacOSConfigurationFolders();
}
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 50)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 50.");
configurationFileFormat.EnableHardwareAcceleration = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 51)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 51.");
configurationFileFormat.RememberWindowState = true;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 52)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 52.");
configurationFileFormat.AutoloadDirs = [];
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 53)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 53.");
configurationFileFormat.EnableLowPowerPtc = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 54)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 54.");
configurationFileFormat.DramSize = MemoryConfiguration.MemoryConfiguration4GiB;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 55)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 55.");
configurationFileFormat.IgnoreApplet = false;
configurationFileUpdated = true;
}
if (configurationFileFormat.Version < 56)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 56.");
configurationFileFormat.ShowTitleBar = !OperatingSystem.IsWindows();
configurationFileUpdated = true;
}
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.ResScale.Value = configurationFileFormat.ResScale;
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
Graphics.MaxAnisotropy.Value = configurationFileFormat.MaxAnisotropy;
Graphics.AspectRatio.Value = configurationFileFormat.AspectRatio;
Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath;
Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading;
Graphics.GraphicsBackend.Value = configurationFileFormat.GraphicsBackend;
Graphics.PreferredGpu.Value = configurationFileFormat.PreferredGpu;
Graphics.AntiAliasing.Value = configurationFileFormat.AntiAliasing;
Graphics.ScalingFilter.Value = configurationFileFormat.ScalingFilter;
Graphics.ScalingFilterLevel.Value = configurationFileFormat.ScalingFilterLevel;
Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug;
Logger.EnableStub.Value = configurationFileFormat.LoggingEnableStub;
Logger.EnableInfo.Value = configurationFileFormat.LoggingEnableInfo;
Logger.EnableWarn.Value = configurationFileFormat.LoggingEnableWarn;
Logger.EnableError.Value = configurationFileFormat.LoggingEnableError;
Logger.EnableTrace.Value = configurationFileFormat.LoggingEnableTrace;
Logger.EnableGuest.Value = configurationFileFormat.LoggingEnableGuest;
Logger.EnableFsAccessLog.Value = configurationFileFormat.LoggingEnableFsAccessLog;
Logger.FilteredClasses.Value = configurationFileFormat.LoggingFilteredClasses;
Logger.GraphicsDebugLevel.Value = configurationFileFormat.LoggingGraphicsDebugLevel;
System.Language.Value = configurationFileFormat.SystemLanguage;
System.Region.Value = configurationFileFormat.SystemRegion;
System.TimeZone.Value = configurationFileFormat.SystemTimeZone;
System.SystemTimeOffset.Value = configurationFileFormat.SystemTimeOffset;
System.EnableDockedMode.Value = configurationFileFormat.DockedMode;
EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart;
ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit;
IgnoreApplet.Value = configurationFileFormat.IgnoreApplet;
RememberWindowState.Value = configurationFileFormat.RememberWindowState;
ShowTitleBar.Value = configurationFileFormat.ShowTitleBar;
EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration;
HideCursor.Value = configurationFileFormat.HideCursor;
Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
Graphics.EnableTextureRecompression.Value = configurationFileFormat.EnableTextureRecompression;
Graphics.EnableMacroHLE.Value = configurationFileFormat.EnableMacroHLE;
Graphics.EnableColorSpacePassthrough.Value = configurationFileFormat.EnableColorSpacePassthrough;
System.EnablePtc.Value = configurationFileFormat.EnablePtc;
System.EnableLowPowerPtc.Value = configurationFileFormat.EnableLowPowerPtc;
System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess;
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
System.AudioBackend.Value = configurationFileFormat.AudioBackend;
System.AudioVolume.Value = configurationFileFormat.AudioVolume;
System.MemoryManagerMode.Value = configurationFileFormat.MemoryManagerMode;
System.DramSize.Value = configurationFileFormat.DramSize;
System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices;
System.UseHypervisor.Value = configurationFileFormat.UseHypervisor;
UI.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn;
UI.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn;
UI.GuiColumns.AppColumn.Value = configurationFileFormat.GuiColumns.AppColumn;
UI.GuiColumns.DevColumn.Value = configurationFileFormat.GuiColumns.DevColumn;
UI.GuiColumns.VersionColumn.Value = configurationFileFormat.GuiColumns.VersionColumn;
UI.GuiColumns.TimePlayedColumn.Value = configurationFileFormat.GuiColumns.TimePlayedColumn;
UI.GuiColumns.LastPlayedColumn.Value = configurationFileFormat.GuiColumns.LastPlayedColumn;
UI.GuiColumns.FileExtColumn.Value = configurationFileFormat.GuiColumns.FileExtColumn;
UI.GuiColumns.FileSizeColumn.Value = configurationFileFormat.GuiColumns.FileSizeColumn;
UI.GuiColumns.PathColumn.Value = configurationFileFormat.GuiColumns.PathColumn;
UI.ColumnSort.SortColumnId.Value = configurationFileFormat.ColumnSort.SortColumnId;
UI.ColumnSort.SortAscending.Value = configurationFileFormat.ColumnSort.SortAscending;
UI.GameDirs.Value = configurationFileFormat.GameDirs;
UI.AutoloadDirs.Value = configurationFileFormat.AutoloadDirs ?? [];
UI.ShownFileTypes.NSP.Value = configurationFileFormat.ShownFileTypes.NSP;
UI.ShownFileTypes.PFS0.Value = configurationFileFormat.ShownFileTypes.PFS0;
UI.ShownFileTypes.XCI.Value = configurationFileFormat.ShownFileTypes.XCI;
UI.ShownFileTypes.NCA.Value = configurationFileFormat.ShownFileTypes.NCA;
UI.ShownFileTypes.NRO.Value = configurationFileFormat.ShownFileTypes.NRO;
UI.ShownFileTypes.NSO.Value = configurationFileFormat.ShownFileTypes.NSO;
UI.LanguageCode.Value = configurationFileFormat.LanguageCode;
UI.BaseStyle.Value = configurationFileFormat.BaseStyle;
UI.GameListViewMode.Value = configurationFileFormat.GameListViewMode;
UI.ShowNames.Value = configurationFileFormat.ShowNames;
UI.IsAscendingOrder.Value = configurationFileFormat.IsAscendingOrder;
UI.GridSize.Value = configurationFileFormat.GridSize;
UI.ApplicationSort.Value = configurationFileFormat.ApplicationSort;
UI.StartFullscreen.Value = configurationFileFormat.StartFullscreen;
UI.ShowConsole.Value = configurationFileFormat.ShowConsole;
UI.WindowStartup.WindowSizeWidth.Value = configurationFileFormat.WindowStartup.WindowSizeWidth;
UI.WindowStartup.WindowSizeHeight.Value = configurationFileFormat.WindowStartup.WindowSizeHeight;
UI.WindowStartup.WindowPositionX.Value = configurationFileFormat.WindowStartup.WindowPositionX;
UI.WindowStartup.WindowPositionY.Value = configurationFileFormat.WindowStartup.WindowPositionY;
UI.WindowStartup.WindowMaximized.Value = configurationFileFormat.WindowStartup.WindowMaximized;
Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard;
Hid.EnableMouse.Value = configurationFileFormat.EnableMouse;
Hid.Hotkeys.Value = configurationFileFormat.Hotkeys;
Hid.InputConfig.Value = configurationFileFormat.InputConfig ?? [];
Multiplayer.LanInterfaceId.Value = configurationFileFormat.MultiplayerLanInterfaceId;
Multiplayer.Mode.Value = configurationFileFormat.MultiplayerMode;
if (configurationFileUpdated)
{
ToFileFormat().SaveConfig(configurationFilePath);
Ryujinx.Common.Logging.Logger.Notice.Print(LogClass.Application, $"Configuration file updated to version {ConfigurationFileFormat.CurrentVersion}");
}
}
}
}

View File

@@ -0,0 +1,677 @@
using ARMeilleure;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.Logging;
using Ryujinx.HLE;
using Ryujinx.UI.Common.Configuration.System;
using Ryujinx.UI.Common.Helper;
using System.Collections.Generic;
namespace Ryujinx.UI.Common.Configuration
{
public partial class ConfigurationState
{
/// <summary>
/// UI configuration section
/// </summary>
public class UISection
{
public class Columns
{
public ReactiveObject<bool> FavColumn { get; private set; }
public ReactiveObject<bool> IconColumn { get; private set; }
public ReactiveObject<bool> AppColumn { get; private set; }
public ReactiveObject<bool> DevColumn { get; private set; }
public ReactiveObject<bool> VersionColumn { get; private set; }
public ReactiveObject<bool> TimePlayedColumn { get; private set; }
public ReactiveObject<bool> LastPlayedColumn { get; private set; }
public ReactiveObject<bool> FileExtColumn { get; private set; }
public ReactiveObject<bool> FileSizeColumn { get; private set; }
public ReactiveObject<bool> PathColumn { get; private set; }
public Columns()
{
FavColumn = new ReactiveObject<bool>();
IconColumn = new ReactiveObject<bool>();
AppColumn = new ReactiveObject<bool>();
DevColumn = new ReactiveObject<bool>();
VersionColumn = new ReactiveObject<bool>();
TimePlayedColumn = new ReactiveObject<bool>();
LastPlayedColumn = new ReactiveObject<bool>();
FileExtColumn = new ReactiveObject<bool>();
FileSizeColumn = new ReactiveObject<bool>();
PathColumn = new ReactiveObject<bool>();
}
}
public class ColumnSortSettings
{
public ReactiveObject<int> SortColumnId { get; private set; }
public ReactiveObject<bool> SortAscending { get; private set; }
public ColumnSortSettings()
{
SortColumnId = new ReactiveObject<int>();
SortAscending = new ReactiveObject<bool>();
}
}
/// <summary>
/// Used to toggle which file types are shown in the UI
/// </summary>
public class ShownFileTypeSettings
{
public ReactiveObject<bool> NSP { get; private set; }
public ReactiveObject<bool> PFS0 { get; private set; }
public ReactiveObject<bool> XCI { get; private set; }
public ReactiveObject<bool> NCA { get; private set; }
public ReactiveObject<bool> NRO { get; private set; }
public ReactiveObject<bool> NSO { get; private set; }
public ShownFileTypeSettings()
{
NSP = new ReactiveObject<bool>();
PFS0 = new ReactiveObject<bool>();
XCI = new ReactiveObject<bool>();
NCA = new ReactiveObject<bool>();
NRO = new ReactiveObject<bool>();
NSO = new ReactiveObject<bool>();
}
}
// <summary>
/// Determines main window start-up position, size and state
///<summary>
public class WindowStartupSettings
{
public ReactiveObject<int> WindowSizeWidth { get; private set; }
public ReactiveObject<int> WindowSizeHeight { get; private set; }
public ReactiveObject<int> WindowPositionX { get; private set; }
public ReactiveObject<int> WindowPositionY { get; private set; }
public ReactiveObject<bool> WindowMaximized { get; private set; }
public WindowStartupSettings()
{
WindowSizeWidth = new ReactiveObject<int>();
WindowSizeHeight = new ReactiveObject<int>();
WindowPositionX = new ReactiveObject<int>();
WindowPositionY = new ReactiveObject<int>();
WindowMaximized = new ReactiveObject<bool>();
}
}
/// <summary>
/// Used to toggle columns in the GUI
/// </summary>
public Columns GuiColumns { get; private set; }
/// <summary>
/// Used to configure column sort settings in the GUI
/// </summary>
public ColumnSortSettings ColumnSort { get; private set; }
/// <summary>
/// A list of directories containing games to be used to load games into the games list
/// </summary>
public ReactiveObject<List<string>> GameDirs { get; private set; }
/// <summary>
/// A list of directories containing DLC/updates the user wants to autoload during library refreshes
/// </summary>
public ReactiveObject<List<string>> AutoloadDirs { get; private set; }
/// <summary>
/// A list of file types to be hidden in the games List
/// </summary>
public ShownFileTypeSettings ShownFileTypes { get; private set; }
/// <summary>
/// Determines main window start-up position, size and state
/// </summary>
public WindowStartupSettings WindowStartup { get; private set; }
/// <summary>
/// Language Code for the UI
/// </summary>
public ReactiveObject<string> LanguageCode { get; private set; }
/// <summary>
/// Selects the base style
/// </summary>
public ReactiveObject<string> BaseStyle { get; private set; }
/// <summary>
/// Start games in fullscreen mode
/// </summary>
public ReactiveObject<bool> StartFullscreen { get; private set; }
/// <summary>
/// Hide / Show Console Window
/// </summary>
public ReactiveObject<bool> ShowConsole { get; private set; }
/// <summary>
/// View Mode of the Game list
/// </summary>
public ReactiveObject<int> GameListViewMode { get; private set; }
/// <summary>
/// Show application name in Grid Mode
/// </summary>
public ReactiveObject<bool> ShowNames { get; private set; }
/// <summary>
/// Sets App Icon Size in Grid Mode
/// </summary>
public ReactiveObject<int> GridSize { get; private set; }
/// <summary>
/// Sorts Apps in Grid Mode
/// </summary>
public ReactiveObject<int> ApplicationSort { get; private set; }
/// <summary>
/// Sets if Grid is ordered in Ascending Order
/// </summary>
public ReactiveObject<bool> IsAscendingOrder { get; private set; }
public UISection()
{
GuiColumns = new Columns();
ColumnSort = new ColumnSortSettings();
GameDirs = new ReactiveObject<List<string>>();
AutoloadDirs = new ReactiveObject<List<string>>();
ShownFileTypes = new ShownFileTypeSettings();
WindowStartup = new WindowStartupSettings();
BaseStyle = new ReactiveObject<string>();
StartFullscreen = new ReactiveObject<bool>();
GameListViewMode = new ReactiveObject<int>();
ShowNames = new ReactiveObject<bool>();
GridSize = new ReactiveObject<int>();
ApplicationSort = new ReactiveObject<int>();
IsAscendingOrder = new ReactiveObject<bool>();
LanguageCode = new ReactiveObject<string>();
ShowConsole = new ReactiveObject<bool>();
ShowConsole.Event += static (_, e) => ConsoleHelper.SetConsoleWindowState(e.NewValue);
}
}
/// <summary>
/// Logger configuration section
/// </summary>
public class LoggerSection
{
/// <summary>
/// Enables printing debug log messages
/// </summary>
public ReactiveObject<bool> EnableDebug { get; private set; }
/// <summary>
/// Enables printing stub log messages
/// </summary>
public ReactiveObject<bool> EnableStub { get; private set; }
/// <summary>
/// Enables printing info log messages
/// </summary>
public ReactiveObject<bool> EnableInfo { get; private set; }
/// <summary>
/// Enables printing warning log messages
/// </summary>
public ReactiveObject<bool> EnableWarn { get; private set; }
/// <summary>
/// Enables printing error log messages
/// </summary>
public ReactiveObject<bool> EnableError { get; private set; }
/// <summary>
/// Enables printing trace log messages
/// </summary>
public ReactiveObject<bool> EnableTrace { get; private set; }
/// <summary>
/// Enables printing guest log messages
/// </summary>
public ReactiveObject<bool> EnableGuest { get; private set; }
/// <summary>
/// Enables printing FS access log messages
/// </summary>
public ReactiveObject<bool> EnableFsAccessLog { get; private set; }
/// <summary>
/// Controls which log messages are written to the log targets
/// </summary>
public ReactiveObject<LogClass[]> FilteredClasses { get; private set; }
/// <summary>
/// Enables or disables logging to a file on disk
/// </summary>
public ReactiveObject<bool> EnableFileLog { get; private set; }
/// <summary>
/// Controls which OpenGL log messages are recorded in the log
/// </summary>
public ReactiveObject<GraphicsDebugLevel> GraphicsDebugLevel { get; private set; }
public LoggerSection()
{
EnableDebug = new ReactiveObject<bool>();
EnableDebug.LogChangesToValue(nameof(EnableDebug));
EnableStub = new ReactiveObject<bool>();
EnableInfo = new ReactiveObject<bool>();
EnableWarn = new ReactiveObject<bool>();
EnableError = new ReactiveObject<bool>();
EnableTrace = new ReactiveObject<bool>();
EnableGuest = new ReactiveObject<bool>();
EnableFsAccessLog = new ReactiveObject<bool>();
FilteredClasses = new ReactiveObject<LogClass[]>();
EnableFileLog = new ReactiveObject<bool>();
EnableFileLog.LogChangesToValue(nameof(EnableFileLog));
GraphicsDebugLevel = new ReactiveObject<GraphicsDebugLevel>();
}
}
/// <summary>
/// System configuration section
/// </summary>
public class SystemSection
{
/// <summary>
/// Change System Language
/// </summary>
public ReactiveObject<Language> Language { get; private set; }
/// <summary>
/// Change System Region
/// </summary>
public ReactiveObject<Region> Region { get; private set; }
/// <summary>
/// Change System TimeZone
/// </summary>
public ReactiveObject<string> TimeZone { get; private set; }
/// <summary>
/// System Time Offset in Seconds
/// </summary>
public ReactiveObject<long> SystemTimeOffset { get; private set; }
/// <summary>
/// Enables or disables Docked Mode
/// </summary>
public ReactiveObject<bool> EnableDockedMode { get; private set; }
/// <summary>
/// Enables or disables persistent profiled translation cache
/// </summary>
public ReactiveObject<bool> EnablePtc { get; private set; }
/// <summary>
/// Enables or disables low-power persistent profiled translation cache loading
/// </summary>
public ReactiveObject<bool> EnableLowPowerPtc { get; private set; }
/// <summary>
/// Enables or disables guest Internet access
/// </summary>
public ReactiveObject<bool> EnableInternetAccess { get; private set; }
/// <summary>
/// Enables integrity checks on Game content files
/// </summary>
public ReactiveObject<bool> EnableFsIntegrityChecks { get; private set; }
/// <summary>
/// Enables FS access log output to the console. Possible modes are 0-3
/// </summary>
public ReactiveObject<int> FsGlobalAccessLogMode { get; private set; }
/// <summary>
/// The selected audio backend
/// </summary>
public ReactiveObject<AudioBackend> AudioBackend { get; private set; }
/// <summary>
/// The audio backend volume
/// </summary>
public ReactiveObject<float> AudioVolume { get; private set; }
/// <summary>
/// The selected memory manager mode
/// </summary>
public ReactiveObject<MemoryManagerMode> MemoryManagerMode { get; private set; }
/// <summary>
/// Defines the amount of RAM available on the emulated system, and how it is distributed
/// </summary>
public ReactiveObject<MemoryConfiguration> DramSize { get; private set; }
/// <summary>
/// Enable or disable ignoring missing services
/// </summary>
public ReactiveObject<bool> IgnoreMissingServices { get; private set; }
/// <summary>
/// Uses Hypervisor over JIT if available
/// </summary>
public ReactiveObject<bool> UseHypervisor { get; private set; }
public SystemSection()
{
Language = new ReactiveObject<Language>();
Language.LogChangesToValue(nameof(Language));
Region = new ReactiveObject<Region>();
Region.LogChangesToValue(nameof(Region));
TimeZone = new ReactiveObject<string>();
TimeZone.LogChangesToValue(nameof(TimeZone));
SystemTimeOffset = new ReactiveObject<long>();
SystemTimeOffset.LogChangesToValue(nameof(SystemTimeOffset));
EnableDockedMode = new ReactiveObject<bool>();
EnableDockedMode.LogChangesToValue(nameof(EnableDockedMode));
EnablePtc = new ReactiveObject<bool>();
EnablePtc.LogChangesToValue(nameof(EnablePtc));
EnableLowPowerPtc = new ReactiveObject<bool>();
EnableLowPowerPtc.LogChangesToValue(nameof(EnableLowPowerPtc));
EnableLowPowerPtc.Event += (_, evnt)
=> Optimizations.LowPower = evnt.NewValue;
EnableInternetAccess = new ReactiveObject<bool>();
EnableInternetAccess.LogChangesToValue(nameof(EnableInternetAccess));
EnableFsIntegrityChecks = new ReactiveObject<bool>();
EnableFsIntegrityChecks.LogChangesToValue(nameof(EnableFsIntegrityChecks));
FsGlobalAccessLogMode = new ReactiveObject<int>();
FsGlobalAccessLogMode.LogChangesToValue(nameof(FsGlobalAccessLogMode));
AudioBackend = new ReactiveObject<AudioBackend>();
AudioBackend.LogChangesToValue(nameof(AudioBackend));
MemoryManagerMode = new ReactiveObject<MemoryManagerMode>();
MemoryManagerMode.LogChangesToValue(nameof(MemoryManagerMode));
DramSize = new ReactiveObject<MemoryConfiguration>();
DramSize.LogChangesToValue(nameof(DramSize));
IgnoreMissingServices = new ReactiveObject<bool>();
IgnoreMissingServices.LogChangesToValue(nameof(IgnoreMissingServices));
AudioVolume = new ReactiveObject<float>();
AudioVolume.LogChangesToValue(nameof(AudioVolume));
UseHypervisor = new ReactiveObject<bool>();
UseHypervisor.LogChangesToValue(nameof(UseHypervisor));
}
}
/// <summary>
/// Hid configuration section
/// </summary>
public class HidSection
{
/// <summary>
/// Enable or disable keyboard support (Independent from controllers binding)
/// </summary>
public ReactiveObject<bool> EnableKeyboard { get; private set; }
/// <summary>
/// Enable or disable mouse support (Independent from controllers binding)
/// </summary>
public ReactiveObject<bool> EnableMouse { get; private set; }
/// <summary>
/// Hotkey Keyboard Bindings
/// </summary>
public ReactiveObject<KeyboardHotkeys> Hotkeys { get; private set; }
/// <summary>
/// Input device configuration.
/// NOTE: This ReactiveObject won't issue an event when the List has elements added or removed.
/// TODO: Implement a ReactiveList class.
/// </summary>
public ReactiveObject<List<InputConfig>> InputConfig { get; private set; }
public HidSection()
{
EnableKeyboard = new ReactiveObject<bool>();
EnableMouse = new ReactiveObject<bool>();
Hotkeys = new ReactiveObject<KeyboardHotkeys>();
InputConfig = new ReactiveObject<List<InputConfig>>();
}
}
/// <summary>
/// Graphics configuration section
/// </summary>
public class GraphicsSection
{
/// <summary>
/// Whether or not backend threading is enabled. The "Auto" setting will determine whether threading should be enabled at runtime.
/// </summary>
public ReactiveObject<BackendThreading> BackendThreading { get; private set; }
/// <summary>
/// Max Anisotropy. Values range from 0 - 16. Set to -1 to let the game decide.
/// </summary>
public ReactiveObject<float> MaxAnisotropy { get; private set; }
/// <summary>
/// Aspect Ratio applied to the renderer window.
/// </summary>
public ReactiveObject<AspectRatio> AspectRatio { get; private set; }
/// <summary>
/// Resolution Scale. An integer scale applied to applicable render targets. Values 1-4, or -1 to use a custom floating point scale instead.
/// </summary>
public ReactiveObject<int> ResScale { get; private set; }
/// <summary>
/// Custom Resolution Scale. A custom floating point scale applied to applicable render targets. Only active when Resolution Scale is -1.
/// </summary>
public ReactiveObject<float> ResScaleCustom { get; private set; }
/// <summary>
/// Dumps shaders in this local directory
/// </summary>
public ReactiveObject<string> ShadersDumpPath { get; private set; }
/// <summary>
/// Enables or disables Vertical Sync
/// </summary>
public ReactiveObject<bool> EnableVsync { get; private set; }
/// <summary>
/// Enables or disables Shader cache
/// </summary>
public ReactiveObject<bool> EnableShaderCache { get; private set; }
/// <summary>
/// Enables or disables texture recompression
/// </summary>
public ReactiveObject<bool> EnableTextureRecompression { get; private set; }
/// <summary>
/// Enables or disables Macro high-level emulation
/// </summary>
public ReactiveObject<bool> EnableMacroHLE { get; private set; }
/// <summary>
/// Enables or disables color space passthrough, if available.
/// </summary>
public ReactiveObject<bool> EnableColorSpacePassthrough { get; private set; }
/// <summary>
/// Graphics backend
/// </summary>
public ReactiveObject<GraphicsBackend> GraphicsBackend { get; private set; }
/// <summary>
/// Applies anti-aliasing to the renderer.
/// </summary>
public ReactiveObject<AntiAliasing> AntiAliasing { get; private set; }
/// <summary>
/// Sets the framebuffer upscaling type.
/// </summary>
public ReactiveObject<ScalingFilter> ScalingFilter { get; private set; }
/// <summary>
/// Sets the framebuffer upscaling level.
/// </summary>
public ReactiveObject<int> ScalingFilterLevel { get; private set; }
/// <summary>
/// Preferred GPU
/// </summary>
public ReactiveObject<string> PreferredGpu { get; private set; }
public GraphicsSection()
{
BackendThreading = new ReactiveObject<BackendThreading>();
BackendThreading.LogChangesToValue(nameof(BackendThreading));
ResScale = new ReactiveObject<int>();
ResScale.LogChangesToValue(nameof(ResScale));
ResScaleCustom = new ReactiveObject<float>();
ResScaleCustom.LogChangesToValue(nameof(ResScaleCustom));
MaxAnisotropy = new ReactiveObject<float>();
MaxAnisotropy.LogChangesToValue(nameof(MaxAnisotropy));
AspectRatio = new ReactiveObject<AspectRatio>();
AspectRatio.LogChangesToValue(nameof(AspectRatio));
ShadersDumpPath = new ReactiveObject<string>();
EnableVsync = new ReactiveObject<bool>();
EnableVsync.LogChangesToValue(nameof(EnableVsync));
EnableShaderCache = new ReactiveObject<bool>();
EnableShaderCache.LogChangesToValue(nameof(EnableShaderCache));
EnableTextureRecompression = new ReactiveObject<bool>();
EnableTextureRecompression.LogChangesToValue(nameof(EnableTextureRecompression));
GraphicsBackend = new ReactiveObject<GraphicsBackend>();
GraphicsBackend.LogChangesToValue(nameof(GraphicsBackend));
PreferredGpu = new ReactiveObject<string>();
PreferredGpu.LogChangesToValue(nameof(PreferredGpu));
EnableMacroHLE = new ReactiveObject<bool>();
EnableMacroHLE.LogChangesToValue(nameof(EnableMacroHLE));
EnableColorSpacePassthrough = new ReactiveObject<bool>();
EnableColorSpacePassthrough.LogChangesToValue(nameof(EnableColorSpacePassthrough));
AntiAliasing = new ReactiveObject<AntiAliasing>();
AntiAliasing.LogChangesToValue(nameof(AntiAliasing));
ScalingFilter = new ReactiveObject<ScalingFilter>();
ScalingFilter.LogChangesToValue(nameof(ScalingFilter));
ScalingFilterLevel = new ReactiveObject<int>();
ScalingFilterLevel.LogChangesToValue(nameof(ScalingFilterLevel));
}
}
/// <summary>
/// Multiplayer configuration section
/// </summary>
public class MultiplayerSection
{
/// <summary>
/// GUID for the network interface used by LAN (or 0 for default)
/// </summary>
public ReactiveObject<string> LanInterfaceId { get; private set; }
/// <summary>
/// Multiplayer Mode
/// </summary>
public ReactiveObject<MultiplayerMode> Mode { get; private set; }
public MultiplayerSection()
{
LanInterfaceId = new ReactiveObject<string>();
Mode = new ReactiveObject<MultiplayerMode>();
Mode.LogChangesToValue(nameof(MultiplayerMode));
}
}
/// <summary>
/// The default configuration instance
/// </summary>
public static ConfigurationState Instance { get; private set; }
/// <summary>
/// The UI section
/// </summary>
public UISection UI { get; private set; }
/// <summary>
/// The Logger section
/// </summary>
public LoggerSection Logger { get; private set; }
/// <summary>
/// The System section
/// </summary>
public SystemSection System { get; private set; }
/// <summary>
/// The Graphics section
/// </summary>
public GraphicsSection Graphics { get; private set; }
/// <summary>
/// The Hid section
/// </summary>
public HidSection Hid { get; private set; }
/// <summary>
/// The Multiplayer section
/// </summary>
public MultiplayerSection Multiplayer { get; private set; }
/// <summary>
/// Enables or disables Discord Rich Presence
/// </summary>
public ReactiveObject<bool> EnableDiscordIntegration { get; private set; }
/// <summary>
/// Checks for updates when Ryujinx starts when enabled
/// </summary>
public ReactiveObject<bool> CheckUpdatesOnStart { get; private set; }
/// <summary>
/// Show "Confirm Exit" Dialog
/// </summary>
public ReactiveObject<bool> ShowConfirmExit { get; private set; }
/// <summary>
/// Ignore Applet
/// </summary>
public ReactiveObject<bool> IgnoreApplet { get; private set; }
/// <summary>
/// Enables or disables save window size, position and state on close.
/// </summary>
public ReactiveObject<bool> RememberWindowState { get; private set; }
/// <summary>
/// Enables or disables the redesigned title bar
/// </summary>
public ReactiveObject<bool> ShowTitleBar { get; private set; }
/// <summary>
/// Enables hardware-accelerated rendering for Avalonia
/// </summary>
public ReactiveObject<bool> EnableHardwareAcceleration { get; private set; }
/// <summary>
/// Hide Cursor on Idle
/// </summary>
public ReactiveObject<HideCursorMode> HideCursor { get; private set; }
private ConfigurationState()
{
UI = new UISection();
Logger = new LoggerSection();
System = new SystemSection();
Graphics = new GraphicsSection();
Hid = new HidSection();
Multiplayer = new MultiplayerSection();
EnableDiscordIntegration = new ReactiveObject<bool>();
CheckUpdatesOnStart = new ReactiveObject<bool>();
ShowConfirmExit = new ReactiveObject<bool>();
IgnoreApplet = new ReactiveObject<bool>();
IgnoreApplet.LogChangesToValue(nameof(IgnoreApplet));
RememberWindowState = new ReactiveObject<bool>();
ShowTitleBar = new ReactiveObject<bool>();
EnableHardwareAcceleration = new ReactiveObject<bool>();
HideCursor = new ReactiveObject<HideCursorMode>();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,3 @@
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Logging.Targets;
@@ -11,103 +10,69 @@ namespace Ryujinx.UI.Common.Configuration
{
public static void Initialize()
{
ConfigurationState.Instance.Logger.EnableDebug.Event += ReloadEnableDebug;
ConfigurationState.Instance.Logger.EnableStub.Event += ReloadEnableStub;
ConfigurationState.Instance.Logger.EnableInfo.Event += ReloadEnableInfo;
ConfigurationState.Instance.Logger.EnableWarn.Event += ReloadEnableWarning;
ConfigurationState.Instance.Logger.EnableError.Event += ReloadEnableError;
ConfigurationState.Instance.Logger.EnableTrace.Event += ReloadEnableTrace;
ConfigurationState.Instance.Logger.EnableGuest.Event += ReloadEnableGuest;
ConfigurationState.Instance.Logger.EnableFsAccessLog.Event += ReloadEnableFsAccessLog;
ConfigurationState.Instance.Logger.FilteredClasses.Event += ReloadFilteredClasses;
ConfigurationState.Instance.Logger.EnableFileLog.Event += ReloadFileLogger;
}
private static void ReloadEnableDebug(object sender, ReactiveEventArgs<bool> e)
{
Logger.SetEnable(LogLevel.Debug, e.NewValue);
}
private static void ReloadEnableStub(object sender, ReactiveEventArgs<bool> e)
{
Logger.SetEnable(LogLevel.Stub, e.NewValue);
}
private static void ReloadEnableInfo(object sender, ReactiveEventArgs<bool> e)
{
Logger.SetEnable(LogLevel.Info, e.NewValue);
}
private static void ReloadEnableWarning(object sender, ReactiveEventArgs<bool> e)
{
Logger.SetEnable(LogLevel.Warning, e.NewValue);
}
private static void ReloadEnableError(object sender, ReactiveEventArgs<bool> e)
{
Logger.SetEnable(LogLevel.Error, e.NewValue);
}
private static void ReloadEnableTrace(object sender, ReactiveEventArgs<bool> e)
{
Logger.SetEnable(LogLevel.Trace, e.NewValue);
}
private static void ReloadEnableGuest(object sender, ReactiveEventArgs<bool> e)
{
Logger.SetEnable(LogLevel.Guest, e.NewValue);
}
private static void ReloadEnableFsAccessLog(object sender, ReactiveEventArgs<bool> e)
{
Logger.SetEnable(LogLevel.AccessLog, e.NewValue);
}
private static void ReloadFilteredClasses(object sender, ReactiveEventArgs<LogClass[]> e)
{
bool noFilter = e.NewValue.Length == 0;
foreach (var logClass in Enum.GetValues<LogClass>())
ConfigurationState.Instance.Logger.EnableDebug.Event +=
(_, e) => Logger.SetEnable(LogLevel.Debug, e.NewValue);
ConfigurationState.Instance.Logger.EnableStub.Event +=
(_, e) => Logger.SetEnable(LogLevel.Stub, e.NewValue);
ConfigurationState.Instance.Logger.EnableInfo.Event +=
(_, e) => Logger.SetEnable(LogLevel.Info, e.NewValue);
ConfigurationState.Instance.Logger.EnableWarn.Event +=
(_, e) => Logger.SetEnable(LogLevel.Warning, e.NewValue);
ConfigurationState.Instance.Logger.EnableError.Event +=
(_, e) => Logger.SetEnable(LogLevel.Error, e.NewValue);
ConfigurationState.Instance.Logger.EnableTrace.Event +=
(_, e) => Logger.SetEnable(LogLevel.Error, e.NewValue);
ConfigurationState.Instance.Logger.EnableGuest.Event +=
(_, e) => Logger.SetEnable(LogLevel.Guest, e.NewValue);
ConfigurationState.Instance.Logger.EnableFsAccessLog.Event +=
(_, e) => Logger.SetEnable(LogLevel.AccessLog, e.NewValue);
ConfigurationState.Instance.Logger.FilteredClasses.Event += (_, e) =>
{
Logger.SetEnable(logClass, noFilter);
}
bool noFilter = e.NewValue.Length == 0;
foreach (var logClass in e.NewValue)
{
Logger.SetEnable(logClass, true);
}
}
private static void ReloadFileLogger(object sender, ReactiveEventArgs<bool> e)
{
if (e.NewValue)
{
string logDir = AppDataManager.LogsDirPath;
FileStream logFile = null;
if (!string.IsNullOrEmpty(logDir))
foreach (var logClass in Enum.GetValues<LogClass>())
{
logFile = FileLogTarget.PrepareLogFile(logDir);
Logger.SetEnable(logClass, noFilter);
}
if (logFile == null)
foreach (var logClass in e.NewValue)
{
Logger.SetEnable(logClass, true);
}
};
ConfigurationState.Instance.Logger.EnableFileLog.Event += (_, e) =>
{
if (e.NewValue)
{
string logDir = AppDataManager.LogsDirPath;
FileStream logFile = null;
if (!string.IsNullOrEmpty(logDir))
{
logFile = FileLogTarget.PrepareLogFile(logDir);
}
if (logFile == null)
{
Logger.Error?.Print(LogClass.Application,
"No writable log directory available. Make sure either the Logs directory, Application Data, or the Ryujinx directory is writable.");
Logger.RemoveTarget("file");
return;
}
Logger.AddTarget(new AsyncLogTargetWrapper(
new FileLogTarget("file", logFile),
1000
));
}
else
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the Logs directory, Application Data, or the Ryujinx directory is writable.");
Logger.RemoveTarget("file");
return;
}
Logger.AddTarget(new AsyncLogTargetWrapper(
new FileLogTarget("file", logFile),
1000,
AsyncLogTargetOverflowAction.Block
));
}
else
{
Logger.RemoveTarget("file");
}
};
}
}
}

View File

@@ -15,9 +15,13 @@ namespace Ryujinx.UI.Common
{
public static Timestamps StartedAt { get; set; }
private static readonly string _description = ReleaseInformation.IsValid
? $"v{ReleaseInformation.Version} {ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}@{ReleaseInformation.BuildGitHash}"
: "dev build";
private static string VersionString
=> (ReleaseInformation.IsCanaryBuild ? "Canary " : string.Empty) + $"v{ReleaseInformation.Version}";
private static readonly string _description =
ReleaseInformation.IsValid
? $"{VersionString} {ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelSourceRepo}@{ReleaseInformation.BuildGitHash}"
: "dev build";
private const string ApplicationId = "1293250299716173864";
@@ -122,70 +126,145 @@ 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
"01006d0017f7a000", // Mario & Luigi: Brothership
"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
];
}
}

View File

@@ -4,6 +4,7 @@ using Ryujinx.Common.Logging;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
@@ -23,6 +24,26 @@ namespace Ryujinx.UI.Common.Helper
public static partial void SHChangeNotify(uint wEventId, uint uFlags, nint dwItem1, nint dwItem2);
public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) && !ReleaseInformation.IsFlatHubBuild;
public static bool AreMimeTypesRegistered
{
get
{
if (OperatingSystem.IsLinux())
{
return AreMimeTypesRegisteredLinux();
}
if (OperatingSystem.IsWindows())
{
return AreMimeTypesRegisteredWindows();
}
// TODO: Add macOS support.
return false;
}
}
[SupportedOSPlatform("linux")]
private static bool AreMimeTypesRegisteredLinux() => File.Exists(Path.Combine(_mimeDbPath, "packages", "Ryujinx.xml"));
@@ -35,7 +56,7 @@ namespace Ryujinx.UI.Common.Helper
if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux()))
{
string mimeTypesFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "mime", "Ryujinx.xml");
string additionalArgs = !uninstall ? "--novendor" : "";
string additionalArgs = !uninstall ? "--novendor" : string.Empty;
using Process mimeProcess = new();
@@ -72,6 +93,10 @@ namespace Ryujinx.UI.Common.Helper
[SupportedOSPlatform("windows")]
private static bool AreMimeTypesRegisteredWindows()
{
return _fileExtensions.Aggregate(false,
(current, ext) => current | CheckRegistering(ext)
);
static bool CheckRegistering(string ext)
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(@$"Software\Classes\{ext}");
@@ -83,24 +108,24 @@ namespace Ryujinx.UI.Common.Helper
var openCmd = key.OpenSubKey(@"shell\open\command");
string keyValue = (string)openCmd.GetValue("");
string keyValue = (string)openCmd.GetValue(string.Empty);
return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName));
}
bool registered = false;
foreach (string ext in _fileExtensions)
{
registered |= CheckRegistering(ext);
}
return registered;
}
[SupportedOSPlatform("windows")]
private static bool InstallWindowsMimeTypes(bool uninstall = false)
{
bool registered = _fileExtensions.Aggregate(false,
(current, ext) => current | RegisterExtension(ext, uninstall)
);
// Notify Explorer the file association has been changed.
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, nint.Zero, nint.Zero);
return registered;
static bool RegisterExtension(string ext, bool uninstall = false)
{
string keyString = @$"Software\Classes\{ext}";
@@ -127,42 +152,13 @@ namespace Ryujinx.UI.Common.Helper
Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}");
using var openCmd = key.CreateSubKey(@"shell\open\command");
openCmd.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
openCmd.SetValue(string.Empty, $"\"{Environment.ProcessPath}\" \"%1\"");
Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}");
}
return true;
}
bool registered = false;
foreach (string ext in _fileExtensions)
{
registered |= RegisterExtension(ext, uninstall);
}
// Notify Explorer the file association has been changed.
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, nint.Zero, nint.Zero);
return registered;
}
public static bool AreMimeTypesRegistered()
{
if (OperatingSystem.IsLinux())
{
return AreMimeTypesRegisteredLinux();
}
if (OperatingSystem.IsWindows())
{
return AreMimeTypesRegisteredWindows();
}
// TODO: Add macOS support.
return false;
}
public static bool Install()

View File

@@ -53,7 +53,7 @@ namespace Ryujinx.UI.Common.Helper
{
var titleUpdateWindowData = new TitleUpdateMetadata
{
Selected = "",
Selected = string.Empty,
Paths = [],
};

View File

@@ -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<GithubReleaseAssetJsonResponse> Assets { get; set; }
}
}

View File

@@ -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;
return this.Path == obj.Path;
}
public override int GetHashCode()
{
return this.Path.GetHashCode();
}
}
}

View File

@@ -51,7 +51,6 @@
<ItemGroup>
<PackageReference Include="DiscordRichPresence" />
<PackageReference Include="DynamicData" />
<PackageReference Include="Humanizer" />
<PackageReference Include="securifybv.ShellLink" />
</ItemGroup>

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.UI.LocaleGenerator
context.RegisterSourceOutput(contents, (spc, content) =>
{
var lines = content.Split('\n').Where(x => x.Trim().StartsWith("\"")).Select(x => x.Split(':')[0].Trim().Replace("\"", ""));
var lines = content.Split('\n').Where(x => x.Trim().StartsWith("\"")).Select(x => x.Split(':')[0].Trim().Replace("\"", string.Empty));
StringBuilder enumSourceBuilder = new();
enumSourceBuilder.AppendLine("namespace Ryujinx.Ava.Common.Locale;");
enumSourceBuilder.AppendLine("internal enum LocaleKeys");

View File

@@ -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<IClassicDesktopStyleApplicationLifetime>()
@@ -58,11 +60,9 @@ namespace Ryujinx.Ava
if (Program.PreviewerDetached)
{
ApplyConfiguredTheme();
ApplyConfiguredTheme(ConfigurationState.Instance.UI.BaseStyle);
ConfigurationState.Instance.UI.BaseStyle.Event += ThemeChanged_Event;
ConfigurationState.Instance.UI.CustomThemePath.Event += ThemeChanged_Event;
ConfigurationState.Instance.UI.EnableCustomTheme.Event += CustomThemeChanged_Event;
}
}
@@ -88,17 +88,13 @@ namespace Ryujinx.Ava
}
});
}
private void CustomThemeChanged_Event(object _, ReactiveEventArgs<bool> __) => ApplyConfiguredTheme();
private void ThemeChanged_Event(object _, ReactiveEventArgs<string> __) => ApplyConfiguredTheme();
private void ThemeChanged_Event(object _, ReactiveEventArgs<string> rArgs) => ApplyConfiguredTheme(rArgs.NewValue);
public void ApplyConfiguredTheme()
public void ApplyConfiguredTheme(string baseStyle)
{
try
{
string baseStyle = ConfigurationState.Instance.UI.BaseStyle;
if (string.IsNullOrWhiteSpace(baseStyle))
{
ConfigurationState.Instance.UI.BaseStyle.Value = "Auto";

View File

@@ -604,61 +604,59 @@ namespace Ryujinx.Ava
SystemVersion firmwareVersion = ContentManager.GetCurrentFirmwareVersion();
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime)
{
if (!SetupValidator.CanStartApplication(ContentManager, ApplicationPath, out UserError userError))
{
{
if (SetupValidator.CanFixStartApplication(ContentManager, ApplicationPath, userError, out firmwareVersion))
{
if (SetupValidator.CanFixStartApplication(ContentManager, ApplicationPath, userError, out firmwareVersion))
if (userError is UserError.NoFirmware)
{
if (userError == UserError.NoFirmware)
{
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
LocaleManager.Instance[LocaleKeys.DialogFirmwareNoFirmwareInstalledMessage],
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstallEmbeddedMessage, firmwareVersion.VersionString),
LocaleManager.Instance[LocaleKeys.InputDialogYes],
LocaleManager.Instance[LocaleKeys.InputDialogNo],
"");
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
LocaleManager.Instance[LocaleKeys.DialogFirmwareNoFirmwareInstalledMessage],
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstallEmbeddedMessage, firmwareVersion.VersionString),
LocaleManager.Instance[LocaleKeys.InputDialogYes],
LocaleManager.Instance[LocaleKeys.InputDialogNo],
string.Empty);
if (result != UserResult.Yes)
{
await UserErrorDialog.ShowUserErrorDialog(userError);
Device.Dispose();
return false;
}
}
if (!SetupValidator.TryFixStartApplication(ContentManager, ApplicationPath, userError, out _))
if (result != UserResult.Yes)
{
await UserErrorDialog.ShowUserErrorDialog(userError);
Device.Dispose();
return false;
}
// Tell the user that we installed a firmware for them.
if (userError == UserError.NoFirmware)
{
firmwareVersion = ContentManager.GetCurrentFirmwareVersion();
_viewModel.RefreshFirmwareStatus();
await ContentDialogHelper.CreateInfoDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstalledMessage, firmwareVersion.VersionString),
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstallEmbeddedSuccessMessage, firmwareVersion.VersionString),
LocaleManager.Instance[LocaleKeys.InputDialogOk],
"",
LocaleManager.Instance[LocaleKeys.RyujinxInfo]);
}
}
else
if (!SetupValidator.TryFixStartApplication(ContentManager, ApplicationPath, userError, out _))
{
await UserErrorDialog.ShowUserErrorDialog(userError);
Device.Dispose();
return false;
}
// Tell the user that we installed a firmware for them.
if (userError is UserError.NoFirmware)
{
firmwareVersion = ContentManager.GetCurrentFirmwareVersion();
_viewModel.RefreshFirmwareStatus();
await ContentDialogHelper.CreateInfoDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstalledMessage, firmwareVersion.VersionString),
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogFirmwareInstallEmbeddedSuccessMessage, firmwareVersion.VersionString),
LocaleManager.Instance[LocaleKeys.InputDialogOk],
string.Empty,
LocaleManager.Instance[LocaleKeys.RyujinxInfo]);
}
}
else
{
await UserErrorDialog.ShowUserErrorDialog(userError);
Device.Dispose();
return false;
}
}
}
@@ -820,20 +818,12 @@ namespace Ryujinx.Ava
VirtualFileSystem.ReloadKeySet();
// Initialize Renderer.
IRenderer renderer;
if (ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.Vulkan)
{
renderer = new VulkanRenderer(
Vk.GetApi(),
IRenderer renderer = ConfigurationState.Instance.Graphics.GraphicsBackend.Value == GraphicsBackend.OpenGl
? new OpenGLRenderer()
: VulkanRenderer.Create(
ConfigurationState.Instance.Graphics.PreferredGpu,
(RendererHost.EmbeddedWindow as EmbeddedWindowVulkan)!.CreateSurface,
VulkanHelper.GetRequiredInstanceExtensions,
ConfigurationState.Instance.Graphics.PreferredGpu.Value);
}
else
{
renderer = new OpenGLRenderer();
}
VulkanHelper.GetRequiredInstanceExtensions);
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;

View File

@@ -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": "النظام",
@@ -402,6 +407,7 @@
"AvatarSetBackgroundColor": "تعيين لون الخلفية",
"AvatarClose": "إغلاق",
"ControllerSettingsLoadProfileToolTip": "تحميل الملف الشخصي",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "إضافة ملف شخصي",
"ControllerSettingsRemoveProfileToolTip": "إزالة الملف الشخصي",
"ControllerSettingsSaveProfileToolTip": "حفظ الملف الشخصي",
@@ -411,6 +417,7 @@
"GameListContextMenuToggleFavorite": "تعيين كمفضل",
"GameListContextMenuToggleFavoriteToolTip": "تبديل الحالة المفضلة للعبة",
"SettingsTabGeneralTheme": "السمة:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "داكن",
"SettingsTabGeneralThemeLight": "فاتح",
"ControllerSettingsConfigureGeneral": "ضبط",
@@ -431,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "حدث خطأ أثناء البحث عن بيانات الحفظ المحددة: {0}",
"FolderDialogExtractTitle": "اختر المجلد الذي تريد الاستخراج إليه",
"DialogNcaExtractionMessage": "استخراج قسم {0} من {1}...",
"DialogNcaExtractionTitle": "ريوجينكس - مستخرج قسم NCA",
"DialogNcaExtractionTitle": "مستخرج قسم NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "فشل الاستخراج. لم يكن NCA الرئيسي موجودا في الملف المحدد.",
"DialogNcaExtractionCheckLogErrorMessage": "فشل الاستخراج. اقرأ ملف التسجيل لمزيد من المعلومات.",
"DialogNcaExtractionSuccessMessage": "تم الاستخراج بنجاح.",
@@ -561,6 +568,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 +616,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 +669,8 @@
"OpenSetupGuideMessage": "فتح دليل الإعداد",
"NoUpdate": "لا يوجد تحديث",
"TitleUpdateVersionLabel": "الإصدار: {0}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
"RyujinxInfo": "ريوجينكس - معلومات",
"RyujinxConfirm": "ريوجينكس - تأكيد",
"FileDialogAllTypes": "كل الأنواع",
@@ -714,9 +728,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 +789,7 @@
"GraphicsScalingFilterBilinear": "Bilinear",
"GraphicsScalingFilterNearest": "Nearest",
"GraphicsScalingFilterFsr": "FSR",
"GraphicsScalingFilterArea": "Area",
"GraphicsScalingFilterLevelLabel": "المستوى",
"GraphicsScalingFilterLevelTooltip": "اضبط مستوى وضوح FSR 1.0. الأعلى هو أكثر وضوحا.",
"SmaaLow": "SMAA منخفض",

View File

@@ -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",
@@ -402,6 +407,7 @@
"AvatarSetBackgroundColor": "Hintergrundfarbe auswählen",
"AvatarClose": "Schließen",
"ControllerSettingsLoadProfileToolTip": "Lädt ein Profil",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "Fügt ein Profil hinzu",
"ControllerSettingsRemoveProfileToolTip": "Entfernt ein Profil",
"ControllerSettingsSaveProfileToolTip": "Speichert ein Profil",
@@ -411,6 +417,7 @@
"GameListContextMenuToggleFavorite": "Als Favoriten hinzufügen/entfernen",
"GameListContextMenuToggleFavoriteToolTip": "Aktiviert den Favoriten-Status des Spiels",
"SettingsTabGeneralTheme": "Design:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "Dunkel",
"SettingsTabGeneralThemeLight": "Hell",
"ControllerSettingsConfigureGeneral": "Konfigurieren",
@@ -431,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "Es ist ein Fehler beim Suchen der angegebenen Speicherdaten aufgetreten: {0}",
"FolderDialogExtractTitle": "Wähle den Ordner, in welchen die Dateien entpackt werden sollen",
"DialogNcaExtractionMessage": "Extrahiert {0} abschnitt von {1}...",
"DialogNcaExtractionTitle": "Ryujinx - NCA-Abschnitt-Extraktor",
"DialogNcaExtractionTitle": "NCA-Abschnitt-Extraktor",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Extraktion fehlgeschlagen. Der Hauptheader der NCA war in der ausgewählten Datei nicht vorhanden.",
"DialogNcaExtractionCheckLogErrorMessage": "Extraktion fehlgeschlagen. Überprüfe die Logs für weitere Informationen.",
"DialogNcaExtractionSuccessMessage": "Extraktion erfolgreich abgeschlossen.",
@@ -561,6 +568,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 +616,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 +669,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 +728,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 +789,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",

View File

@@ -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": "Σύστημα",
@@ -402,6 +407,7 @@
"AvatarSetBackgroundColor": "Ορισμός Χρώματος Φόντου",
"AvatarClose": "Κλείσιμο",
"ControllerSettingsLoadProfileToolTip": "Φόρτωση Προφίλ",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "Προσθήκη Προφίλ",
"ControllerSettingsRemoveProfileToolTip": "Κατάργηση Προφίλ",
"ControllerSettingsSaveProfileToolTip": "Αποθήκευση Προφίλ",
@@ -411,6 +417,7 @@
"GameListContextMenuToggleFavorite": "Εναλλαγή Αγαπημένου",
"GameListContextMenuToggleFavoriteToolTip": "Εναλλαγή της Κατάστασης Αγαπημένο του Παιχνιδιού",
"SettingsTabGeneralTheme": "Theme:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "Dark",
"SettingsTabGeneralThemeLight": "Light",
"ControllerSettingsConfigureGeneral": "Παραμέτρων",
@@ -431,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "Σφάλμα κατά την εύρεση των αποθηκευμένων δεδομένων: {0}",
"FolderDialogExtractTitle": "Επιλέξτε τον φάκελο στον οποίο θέλετε να εξαγάγετε",
"DialogNcaExtractionMessage": "Εξαγωγή ενότητας {0} από {1}...",
"DialogNcaExtractionTitle": "Ryujinx - NCA Εξαγωγέας Τμημάτων",
"DialogNcaExtractionTitle": "NCA Εξαγωγέας Τμημάτων",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Αποτυχία εξαγωγής. Η κύρια NCA δεν υπήρχε στο επιλεγμένο αρχείο.",
"DialogNcaExtractionCheckLogErrorMessage": "Αποτυχία εξαγωγής. Διαβάστε το αρχείο καταγραφής για περισσότερες πληροφορίες.",
"DialogNcaExtractionSuccessMessage": "Η εξαγωγή ολοκληρώθηκε με επιτυχία.",
@@ -561,6 +568,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 +616,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 +669,8 @@
"OpenSetupGuideMessage": "Ανοίξτε τον Οδηγό Εγκατάστασης.",
"NoUpdate": "Καμία Eνημέρωση",
"TitleUpdateVersionLabel": "Version {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
"RyujinxInfo": "Ryujinx - Πληροφορίες",
"RyujinxConfirm": "Ryujinx - Επιβεβαίωση",
"FileDialogAllTypes": "Όλοι οι τύποι",
@@ -714,9 +728,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 +789,7 @@
"GraphicsScalingFilterBilinear": "Bilinear",
"GraphicsScalingFilterNearest": "Nearest",
"GraphicsScalingFilterFsr": "FSR",
"GraphicsScalingFilterArea": "Area",
"GraphicsScalingFilterLevelLabel": "Επίπεδο",
"GraphicsScalingFilterLevelTooltip": "Set FSR 1.0 sharpening level. Higher is sharper.",
"SmaaLow": "Χαμηλό SMAA",

View File

@@ -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})",
@@ -407,6 +413,7 @@
"AvatarSetBackgroundColor": "Set Background Color",
"AvatarClose": "Close",
"ControllerSettingsLoadProfileToolTip": "Load Profile",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "Add Profile",
"ControllerSettingsRemoveProfileToolTip": "Remove Profile",
"ControllerSettingsSaveProfileToolTip": "Save Profile",
@@ -437,15 +444,15 @@
"DialogMessageFindSaveErrorMessage": "There was an error finding the specified savedata: {0}",
"FolderDialogExtractTitle": "Choose the folder to extract into",
"DialogNcaExtractionMessage": "Extracting {0} section from {1}...",
"DialogNcaExtractionTitle": "Ryujinx - NCA Section Extractor",
"DialogNcaExtractionTitle": "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...",
@@ -454,8 +461,8 @@
"DialogUpdaterRestartMessage": "Do you want to restart Ryujinx now?",
"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.",
"DialogUpdaterDirtyBuildMessage": "You cannot update a Dirty build of Ryujinx!",
"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",
@@ -468,6 +475,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 +678,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,17 +736,43 @@
"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}]",
"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",
@@ -740,6 +780,7 @@
"AutoloadUpdateRemovedMessage": "{0} missing update(s) removed",
"ModWindowHeading": "{0} Mod(s)",
"UserProfilesEditProfile": "Edit Selected",
"Continue": "Continue",
"Cancel": "Cancel",
"Save": "Save",
"Discard": "Discard",

View File

@@ -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",
@@ -402,6 +407,7 @@
"AvatarSetBackgroundColor": "Establecer color de fondo",
"AvatarClose": "Cerrar",
"ControllerSettingsLoadProfileToolTip": "Cargar perfil",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "Agregar perfil",
"ControllerSettingsRemoveProfileToolTip": "Eliminar perfil",
"ControllerSettingsSaveProfileToolTip": "Guardar perfil",
@@ -411,6 +417,7 @@
"GameListContextMenuToggleFavorite": "Marcar favorito",
"GameListContextMenuToggleFavoriteToolTip": "Marca o desmarca el juego como favorito",
"SettingsTabGeneralTheme": "Tema:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "Oscuro",
"SettingsTabGeneralThemeLight": "Claro",
"ControllerSettingsConfigureGeneral": "Configurar",
@@ -431,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "Hubo un error encontrando los datos de guardado especificados: {0}",
"FolderDialogExtractTitle": "Elige la carpeta en la que deseas extraer",
"DialogNcaExtractionMessage": "Extrayendo {0} sección de {1}...",
"DialogNcaExtractionTitle": "Ryujinx - Extractor de sección NCA",
"DialogNcaExtractionTitle": "Extractor de sección NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Fallo de extracción. El NCA principal no estaba presente en el archivo seleccionado.",
"DialogNcaExtractionCheckLogErrorMessage": "Fallo de extracción. Lee el registro para más información.",
"DialogNcaExtractionSuccessMessage": "Se completó la extracción con éxito.",
@@ -561,6 +568,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 +616,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 +669,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 +728,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 +788,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",

View File

@@ -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",
@@ -408,6 +408,7 @@
"AvatarClose": "Fermer",
"ControllerSettingsLoadProfileToolTip": "Charger un profil",
"ControllerSettingsAddProfileToolTip": "Ajouter un profil",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsRemoveProfileToolTip": "Supprimer un profil",
"ControllerSettingsSaveProfileToolTip": "Enregistrer un profil",
"MenuBarFileToolsTakeScreenshot": "Prendre une capture d'écran",
@@ -437,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "Une erreur s'est produite lors de la recherche de la sauvegarde spécifiée : {0}",
"FolderDialogExtractTitle": "Choisissez le dossier dans lequel extraire",
"DialogNcaExtractionMessage": "Extraction de la section {0} depuis {1}...",
"DialogNcaExtractionTitle": "Ryujinx - Extracteur de la section NCA",
"DialogNcaExtractionTitle": "Extracteur de la section NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Échec de l'extraction. Le NCA principal n'était pas présent dans le fichier sélectionné.",
"DialogNcaExtractionCheckLogErrorMessage": "Échec de l'extraction. Lisez le fichier journal pour plus d'informations.",
"DialogNcaExtractionSuccessMessage": "Extraction terminée avec succès.",
@@ -669,7 +670,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",

View File

@@ -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": "מערכת",
@@ -402,6 +407,7 @@
"AvatarSetBackgroundColor": "הגדר צבע רקע",
"AvatarClose": "סגור",
"ControllerSettingsLoadProfileToolTip": "טען פרופיל",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "הוסף פרופיל",
"ControllerSettingsRemoveProfileToolTip": "הסר פרופיל",
"ControllerSettingsSaveProfileToolTip": "שמור פרופיל",
@@ -411,6 +417,7 @@
"GameListContextMenuToggleFavorite": "למתג העדפה",
"GameListContextMenuToggleFavoriteToolTip": "למתג סטטוס העדפה של משחק",
"SettingsTabGeneralTheme": "ערכת נושא:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "כהה",
"SettingsTabGeneralThemeLight": "בהיר",
"ControllerSettingsConfigureGeneral": "הגדר",
@@ -431,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "אירעה שגיאה במציאת שמור המשחק שצויין: {0}",
"FolderDialogExtractTitle": "בחרו את התיקייה לחילוץ",
"DialogNcaExtractionMessage": "מלחץ {0} ממקטע {1}...",
"DialogNcaExtractionTitle": "ריוג'ינקס - מחלץ מקטע NCA",
"DialogNcaExtractionTitle": "מחלץ מקטע NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "כשל בחילוץ. ה-NCA הראשי לא היה קיים בקובץ שנבחר.",
"DialogNcaExtractionCheckLogErrorMessage": "כשל בחילוץ. קרא את קובץ הרישום למידע נוסף.",
"DialogNcaExtractionSuccessMessage": "החילוץ הושלם בהצלחה.",
@@ -561,6 +568,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 +616,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 +669,8 @@
"OpenSetupGuideMessage": "פתח מדריך התקנה",
"NoUpdate": "אין עדכון",
"TitleUpdateVersionLabel": "גרסה {0}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
"RyujinxInfo": "ריוג'ינקס - מידע",
"RyujinxConfirm": "ריוג'ינקס - אישור",
"FileDialogAllTypes": "כל הסוגים",
@@ -714,9 +728,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 +789,7 @@
"GraphicsScalingFilterBilinear": "Bilinear",
"GraphicsScalingFilterNearest": "Nearest",
"GraphicsScalingFilterFsr": "FSR",
"GraphicsScalingFilterArea": "Area",
"GraphicsScalingFilterLevelLabel": "רמה",
"GraphicsScalingFilterLevelTooltip": "Set FSR 1.0 sharpening level. Higher is sharper.",
"SmaaLow": "SMAA נמוך",

View File

@@ -407,6 +407,7 @@
"AvatarSetBackgroundColor": "Imposta colore di sfondo",
"AvatarClose": "Chiudi",
"ControllerSettingsLoadProfileToolTip": "Carica profilo",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "Aggiungi profilo",
"ControllerSettingsRemoveProfileToolTip": "Rimuovi profilo",
"ControllerSettingsSaveProfileToolTip": "Salva profilo",
@@ -437,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "C'è stato un errore durante la ricerca dei dati di salvataggio: {0}",
"FolderDialogExtractTitle": "Scegli una cartella in cui estrarre",
"DialogNcaExtractionMessage": "Estrazione della sezione {0} da {1}...",
"DialogNcaExtractionTitle": "Ryujinx - Estrazione sezione NCA",
"DialogNcaExtractionTitle": "Estrazione sezione NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "L'estrazione è fallita. L'NCA principale non era presente nel file selezionato.",
"DialogNcaExtractionCheckLogErrorMessage": "L'estrazione è fallita. Consulta il file di log per maggiori informazioni.",
"DialogNcaExtractionSuccessMessage": "Estrazione completata con successo.",
@@ -788,12 +789,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",

View File

@@ -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": "システム",
@@ -402,6 +407,7 @@
"AvatarSetBackgroundColor": "背景色を指定",
"AvatarClose": "閉じる",
"ControllerSettingsLoadProfileToolTip": "プロファイルをロード",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "プロファイルを追加",
"ControllerSettingsRemoveProfileToolTip": "プロファイルを削除",
"ControllerSettingsSaveProfileToolTip": "プロファイルをセーブ",
@@ -411,6 +417,7 @@
"GameListContextMenuToggleFavorite": "お気に入りを切り替え",
"GameListContextMenuToggleFavoriteToolTip": "ゲームをお気に入りに含めるかどうかを切り替えます",
"SettingsTabGeneralTheme": "テーマ:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "ダーク",
"SettingsTabGeneralThemeLight": "ライト",
"ControllerSettingsConfigureGeneral": "設定",
@@ -431,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "セーブデータ: {0} の検索中にエラーが発生しました",
"FolderDialogExtractTitle": "展開フォルダを選択",
"DialogNcaExtractionMessage": "{1} から {0} セクションを展開中...",
"DialogNcaExtractionTitle": "Ryujinx - NCA セクション展開",
"DialogNcaExtractionTitle": "NCA セクション展開",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "展開に失敗しました. 選択されたファイルにはメイン NCA が存在しません.",
"DialogNcaExtractionCheckLogErrorMessage": "展開に失敗しました. 詳細はログを確認してください.",
"DialogNcaExtractionSuccessMessage": "展開が正常終了しました",
@@ -561,6 +568,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 +616,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 +669,8 @@
"OpenSetupGuideMessage": "セットアップガイドを開く",
"NoUpdate": "アップデートなし",
"TitleUpdateVersionLabel": "バージョン {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
"RyujinxInfo": "Ryujinx - 情報",
"RyujinxConfirm": "Ryujinx - 確認",
"FileDialogAllTypes": "すべての種別",
@@ -714,9 +728,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 +788,7 @@
"GraphicsScalingFilterBilinear": "Bilinear",
"GraphicsScalingFilterNearest": "Nearest",
"GraphicsScalingFilterFsr": "FSR",
"GraphicsScalingFilterArea": "Area",
"GraphicsScalingFilterLevelLabel": "レベル",
"GraphicsScalingFilterLevelTooltip": "FSR 1.0のシャープ化レベルを設定します. 高い値ほどシャープになります.",
"SmaaLow": "SMAA Low",

View File

@@ -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": "시스템",
@@ -402,6 +407,7 @@
"AvatarSetBackgroundColor": "배경색 설정",
"AvatarClose": "닫기",
"ControllerSettingsLoadProfileToolTip": "프로필 불러오기",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "프로필 추가",
"ControllerSettingsRemoveProfileToolTip": "프로필 제거",
"ControllerSettingsSaveProfileToolTip": "프로필 저장",
@@ -411,6 +417,7 @@
"GameListContextMenuToggleFavorite": "즐겨찾기 전환",
"GameListContextMenuToggleFavoriteToolTip": "게임 즐겨찾기 상태 전환",
"SettingsTabGeneralTheme": "테마:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "어두운 테마",
"SettingsTabGeneralThemeLight": "밝은 테마",
"ControllerSettingsConfigureGeneral": "구성",
@@ -431,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "지정된 저장 데이터를 찾는 중에 오류 발생: {0}",
"FolderDialogExtractTitle": "추출할 폴더 선택",
"DialogNcaExtractionMessage": "{1}에서 {0} 섹션을 추출하는 중...",
"DialogNcaExtractionTitle": "Ryujinx - NCA 섹션 추출기",
"DialogNcaExtractionTitle": "NCA 섹션 추출기",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "추출 실패하였습니다. 선택한 파일에 기본 NCA가 없습니다.",
"DialogNcaExtractionCheckLogErrorMessage": "추출 실패하였습니다. 자세한 내용은 로그 파일을 읽으세요.",
"DialogNcaExtractionSuccessMessage": "추출이 성공적으로 완료되었습니다.",
@@ -561,6 +568,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 +616,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 +669,8 @@
"OpenSetupGuideMessage": "설정 가이드 열기",
"NoUpdate": "업데이트 없음",
"TitleUpdateVersionLabel": "버전 {0}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
"RyujinxInfo": "Ryujinx - 정보",
"RyujinxConfirm": "Ryujinx - 확인",
"FileDialogAllTypes": "모든 유형",
@@ -714,9 +728,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 +789,7 @@
"GraphicsScalingFilterBilinear": "Bilinear",
"GraphicsScalingFilterNearest": "Nearest",
"GraphicsScalingFilterFsr": "FSR",
"GraphicsScalingFilterArea": "Area",
"GraphicsScalingFilterLevelLabel": "수준",
"GraphicsScalingFilterLevelTooltip": "FSR 1.0의 샤프닝 레벨을 설정하세요. 높을수록 더 또렷해집니다.",
"SmaaLow": "SMAA 낮음",

View File

@@ -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",
@@ -402,6 +407,7 @@
"AvatarSetBackgroundColor": "Ustaw kolor tła",
"AvatarClose": "Zamknij",
"ControllerSettingsLoadProfileToolTip": "Wczytaj profil",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "Dodaj profil",
"ControllerSettingsRemoveProfileToolTip": "Usuń profil",
"ControllerSettingsSaveProfileToolTip": "Zapisz profil",
@@ -411,6 +417,7 @@
"GameListContextMenuToggleFavorite": "Przełącz na ulubione",
"GameListContextMenuToggleFavoriteToolTip": "Przełącz status Ulubionej Gry",
"SettingsTabGeneralTheme": "Motyw:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "Ciemny",
"SettingsTabGeneralThemeLight": "Jasny",
"ControllerSettingsConfigureGeneral": "Konfiguruj",
@@ -431,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "Wystąpił błąd podczas próby znalezienia określonych zapisanych danych: {0}",
"FolderDialogExtractTitle": "Wybierz folder, do którego chcesz rozpakować",
"DialogNcaExtractionMessage": "Wypakowywanie sekcji {0} z {1}...",
"DialogNcaExtractionTitle": "Ryujinx - Asystent wypakowania sekcji NCA",
"DialogNcaExtractionTitle": "Asystent wypakowania sekcji NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Niepowodzenie podczas wypakowywania. W wybranym pliku nie było głównego NCA.",
"DialogNcaExtractionCheckLogErrorMessage": "Niepowodzenie podczas wypakowywania. Przeczytaj plik dziennika, aby uzyskać więcej informacji.",
"DialogNcaExtractionSuccessMessage": "Wypakowywanie zakończone pomyślnie.",
@@ -561,6 +568,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 +616,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 +669,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 +728,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 +789,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",

View File

@@ -407,6 +407,7 @@
"AvatarSetBackgroundColor": "Definir cor de fundo",
"AvatarClose": "Fechar",
"ControllerSettingsLoadProfileToolTip": "Carregar perfil",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "Adicionar perfil",
"ControllerSettingsRemoveProfileToolTip": "Remover perfil",
"ControllerSettingsSaveProfileToolTip": "Salvar perfil",
@@ -437,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "Ocorreu um erro ao tentar encontrar o diretório de salvamento: {0}",
"FolderDialogExtractTitle": "Escolha o diretório onde os arquivos serão extraídos",
"DialogNcaExtractionMessage": "Extraindo seção {0} de {1}...",
"DialogNcaExtractionTitle": "Ryujinx - Extrator de seções NCA",
"DialogNcaExtractionTitle": "Extrator de seções NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Falha na extração. O NCA principal não foi encontrado no arquivo selecionado.",
"DialogNcaExtractionCheckLogErrorMessage": "Falha na extração. Leia o arquivo de log para mais informações.",
"DialogNcaExtractionSuccessMessage": "Extração concluída com êxito.",

View File

@@ -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": "Система",
@@ -402,6 +407,7 @@
"AvatarSetBackgroundColor": "Установить цвет фона",
"AvatarClose": "Закрыть",
"ControllerSettingsLoadProfileToolTip": "Загрузить профиль",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "Добавить профиль",
"ControllerSettingsRemoveProfileToolTip": "Удалить профиль",
"ControllerSettingsSaveProfileToolTip": "Сохранить профиль",
@@ -411,6 +417,7 @@
"GameListContextMenuToggleFavorite": "Добавить в избранное",
"GameListContextMenuToggleFavoriteToolTip": "Добавляет игру в избранное и помечает звездочкой",
"SettingsTabGeneralTheme": "Тема:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "Темная",
"SettingsTabGeneralThemeLight": "Светлая",
"ControllerSettingsConfigureGeneral": "Настройка",
@@ -431,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "Произошла ошибка при поиске указанных данных сохранения: {0}",
"FolderDialogExtractTitle": "Выберите папку для извлечения",
"DialogNcaExtractionMessage": "Извлечение {0} раздела из {1}...",
"DialogNcaExtractionTitle": "Ryujinx - Извлечение разделов NCA",
"DialogNcaExtractionTitle": "Извлечение разделов NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Ошибка извлечения. Основной NCA не присутствовал в выбранном файле.",
"DialogNcaExtractionCheckLogErrorMessage": "Ошибка извлечения. Прочтите файл журнала для получения дополнительной информации.",
"DialogNcaExtractionSuccessMessage": "Извлечение завершено успешно.",
@@ -561,6 +568,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 +616,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 +669,8 @@
"OpenSetupGuideMessage": "Открыть руководство по установке",
"NoUpdate": "Без обновлений",
"TitleUpdateVersionLabel": "Version {0} - {1}",
"TitleBundledUpdateVersionLabel": "Bundled: Version {0}",
"TitleBundledDlcLabel": "Bundled:",
"RyujinxInfo": "Ryujinx - Информация",
"RyujinxConfirm": "Ryujinx - Подтверждение",
"FileDialogAllTypes": "Все типы",
@@ -714,9 +728,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 +789,7 @@
"GraphicsScalingFilterBilinear": "Билинейная",
"GraphicsScalingFilterNearest": "Ступенчатая",
"GraphicsScalingFilterFsr": "FSR",
"GraphicsScalingFilterArea": "Area",
"GraphicsScalingFilterLevelLabel": "Уровень",
"GraphicsScalingFilterLevelTooltip": "Выбор режима работы FSR 1.0. Выше - четче.",
"SmaaLow": "SMAA Низкое",

View File

@@ -107,6 +107,7 @@
"SettingsTabGeneralHideCursorAlways": "ตลอดเวลา",
"SettingsTabGeneralGameDirectories": "ไดเรกทอรี่ของเกม",
"SettingsTabGeneralAutoloadDirectories": "โหลดไดเรกทอรี DLC/ไฟล์อัปเดต อัตโนมัติ",
"SettingsTabGeneralAutoloadNote": "DLC and Updates which refer to missing files will be unloaded automatically",
"SettingsTabGeneralAdd": "เพิ่ม",
"SettingsTabGeneralRemove": "เอาออก",
"SettingsTabSystem": "ระบบ",
@@ -406,6 +407,7 @@
"AvatarSetBackgroundColor": "ตั้งค่าสีพื้นหลัง",
"AvatarClose": "ปิด",
"ControllerSettingsLoadProfileToolTip": "โหลด โปรไฟล์",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "เพิ่ม โปรไฟล์",
"ControllerSettingsRemoveProfileToolTip": "ลบ โปรไฟล์",
"ControllerSettingsSaveProfileToolTip": "บันทึก โปรไฟล์",
@@ -436,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "มีข้อผิดพลาดในการค้นหาข้อมูลบันทึกที่ระบุไว้: {0}",
"FolderDialogExtractTitle": "เลือกโฟลเดอร์ที่จะแตกไฟล์เข้าไป",
"DialogNcaExtractionMessage": "กำลังแตกไฟล์ {0} จากส่วน {1}...",
"DialogNcaExtractionTitle": "Ryujinx - เครื่องมือแตกไฟล์ของ NCA",
"DialogNcaExtractionTitle": "เครื่องมือแตกไฟล์ของ NCA",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "เกิดความล้มเหลวในการแตกไฟล์เนื่องจากไม่พบ NCA หลักในไฟล์ที่เลือก",
"DialogNcaExtractionCheckLogErrorMessage": "เกิดความล้มเหลวในการแตกไฟล์ โปรดอ่านไฟล์บันทึกประวัติเพื่อดูข้อมูลเพิ่มเติม",
"DialogNcaExtractionSuccessMessage": "การแตกไฟล์เสร็จสมบูรณ์แล้ว",
@@ -734,8 +736,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": "ยกเลิก",

View File

@@ -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",
@@ -402,6 +407,7 @@
"AvatarSetBackgroundColor": "Arka Plan Rengi Ayarla",
"AvatarClose": "Kapat",
"ControllerSettingsLoadProfileToolTip": "Profil Yükle",
"ControllerSettingsViewProfileToolTip": "View Profile",
"ControllerSettingsAddProfileToolTip": "Profil Ekle",
"ControllerSettingsRemoveProfileToolTip": "Profili Kaldır",
"ControllerSettingsSaveProfileToolTip": "Profili Kaydet",
@@ -411,6 +417,7 @@
"GameListContextMenuToggleFavorite": "Favori Ayarla",
"GameListContextMenuToggleFavoriteToolTip": "Oyunu Favorilere Ekle/Çıkar",
"SettingsTabGeneralTheme": "Tema:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "Karanlık",
"SettingsTabGeneralThemeLight": "Aydınlık",
"ControllerSettingsConfigureGeneral": "Ayarla",
@@ -431,7 +438,7 @@
"DialogMessageFindSaveErrorMessage": "Belirtilen kayıt verisi bulunmaya çalışırken hata: {0}",
"FolderDialogExtractTitle": "İçine ayıklanacak klasörü seç",
"DialogNcaExtractionMessage": "{1} den {0} kısmı ayıklanıyor...",
"DialogNcaExtractionTitle": "Ryujinx - NCA Kısmı Ayıklayıcısı",
"DialogNcaExtractionTitle": "NCA Kısmı Ayıklayıcısı",
"DialogNcaExtractionMainNcaNotFoundErrorMessage": "Ayıklama hatası. Ana NCA seçilen dosyada bulunamadı.",
"DialogNcaExtractionCheckLogErrorMessage": "Ayıklama hatası. Ek bilgi için kayıt dosyasını okuyun.",
"DialogNcaExtractionSuccessMessage": "Ayıklama başarıyla tamamlandı.",
@@ -561,6 +568,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 +616,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 +669,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 +728,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 +789,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",

Some files were not shown because too many files have changed in this diff Show More