Merge branch 'master' into more-launch-checks

This commit is contained in:
Max 2026-04-27 11:33:35 -04:00
commit 61a52d86d9
29 changed files with 238 additions and 229 deletions

View file

@ -10,6 +10,10 @@ gpu:
- changed-files:
- any-glob-to-any-file: ['src/Ryujinx.Graphics.*/**', 'src/Spv.Generator/**', 'src/Ryujinx.ShaderTools/**']
input:
- changed-files:
- any-glob-to-any-file: ['src/Ryujinx.Input*/**', 'src/Ryujinx/UI/Views/Input/**']
'graphics-backend:opengl':
- changed-files:
- any-glob-to-any-file: 'src/Ryujinx.Graphics.OpenGL/**'
@ -18,17 +22,17 @@ gpu:
- changed-files:
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**']
'graphics-backend:metal':
- changed-files:
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Metal/**', 'src/Ryujinx.Graphics.Metal.SharpMetalExtensions/**']
gui:
- changed-files:
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**']
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.LocaleGenerator/**']
horizon:
'horizon/hle':
- changed-files:
- any-glob-to-any-file: ['src/Ryujinx.HLE/**', 'src/Ryujinx.Horizon/**']
- any-glob-to-any-file: ['src/Ryujinx.HLE/**', 'src/Ryujinx.HLE.Generators/**', 'src/Ryujinx.Horizon/**']
i18n:
- changed-files:
- any-glob-to-any-file: ['assets/**/*.json', 'src/Ryujinx.UI.LocaleGenerator/**']
kernel:
- changed-files:
@ -44,4 +48,4 @@ documentation:
ldn:
- changed-files:
- any-glob-to-any-file: 'src/Ryujinx.HLE/HOS/Services/Ldn/**'
- any-glob-to-any-file: ['src/Ryujinx.HLE/HOS/Services/Ldn/**', 'src/Ryujinx/UI/Windows/LdnGamesListWindow.*', 'src/Ryujinx/UI/ViewModels/LdnGamesListViewModel.cs']

View file

@ -46,13 +46,17 @@ jobs:
with:
token: ${{ secrets.SETUP_GLI_TOKEN }}
- name: Install 7zip
run: |
sudo apt update && sudo apt install -y 7zip
- name: Overwrite csc problem matcher
run: echo "::add-matcher::.forgejo/csc.json"
- name: Get version info
id: version_info
run: |
echo "result=$(gli get-next-version -c Stable -R)" >> $FORGEJO_OUTPUT
echo "result=$(gli get-next-version -c Canary -R)" >> $FORGEJO_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ forgejo.sha }}")" >> $FORGEJO_OUTPUT
shell: bash
@ -83,14 +87,24 @@ jobs:
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.result }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained
if: forgejo.event_name == 'pull_request'
- name: Set executable bit
- name: Packing Windows builds
if: contains(matrix.platform.name, 'win')
run: |
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'linux')
7z a artifact/ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }}.7z publish
shell: bash
- name: Upload Ryujinx Windows artifact
uses: actions/upload-artifact@v4
with:
name: ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }}
path: artifact
if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'win')
- name: Build AppImage
if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'linux')
run: |
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
PLATFORM_NAME="${{ matrix.platform.name }}"
sudo apt update && sudo apt install -y zsync desktop-file-utils appstream libfuse2t64
@ -118,14 +132,7 @@ jobs:
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
shell: bash
- name: Upload Ryujinx artifact
uses: actions/upload-artifact@v4
with:
name: ryujinx-${{ matrix.configuration }}-${{ steps.version_info.outputs.result }}+${{ steps.version_info.outputs.git_short_hash }}-${{ matrix.platform.zip_os_name }}
path: publish
if: forgejo.event_name == 'pull_request'
- name: Upload Ryujinx (AppImage) artifact
- name: Upload Ryujinx AppImage artifact
uses: actions/upload-artifact@v4
if: forgejo.event_name == 'pull_request' && contains(matrix.platform.name, 'linux')
with:

View file

@ -84,6 +84,7 @@ jobs:
pushd publish
rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.7z ../publish
popd
shell: bash
@ -94,6 +95,7 @@ jobs:
rm libarmeilleure-jitsupport.dylib
chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
tar -cJvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.xz ../publish
popd
shell: bash
@ -136,6 +138,7 @@ jobs:
uses: actions/create-release@v1
with:
name: "Canary ${{ steps.version_info.outputs.build_version }}"
body: "**Full Changelog:** [`${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}`](https://git.ryujinx.app/projects/Ryubing/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})"
repository: "Ryubing/Canary"
token: ${{ secrets.RELEASER_TOKEN }}
tag_name: ${{ steps.version_info.outputs.build_version }}
@ -198,6 +201,7 @@ jobs:
uses: actions/create-release@v1
with:
name: "Canary ${{ steps.version_info.outputs.build_version }}"
body: "**Full Changelog:** [`${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}`](https://git.ryujinx.app/projects/Ryubing/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})"
repository: "Ryubing/Canary"
token: ${{ secrets.RELEASER_TOKEN }}
tag_name: ${{ steps.version_info.outputs.build_version }}
@ -246,4 +250,4 @@ jobs:
- name: Advance to the next version
run: |
gli increment-version -T ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }} -c Canary
gli increment-version -T ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }} -c Canary

View file

@ -18,7 +18,7 @@ jobs:
ref: master
- name: Update labels based on changes
uses: actions/labeler@v5
uses: actions/labeler@v6
with:
repo-token: ${{ secrets.LABELER_TOKEN }}
configuration-path: .forgejo/labeler.yml

View file

@ -81,6 +81,7 @@ jobs:
pushd publish
rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.7z ../publish
popd
shell: bash
@ -91,6 +92,7 @@ jobs:
rm libarmeilleure-jitsupport.dylib
chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
tar -cJvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.xz ../publish
popd
shell: bash
@ -203,8 +205,8 @@ jobs:
files: |-
publish_ava/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz
create_gitlab_release:
name: Create GitLab Release
post_ci:
name: Post-CI Steps
runs-on: ubuntu-24.04
needs:
- macos_release

View file

@ -8,6 +8,7 @@
<PackageVersion Include="Avalonia.Desktop" Version="11.3.12" />
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.12" />
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.12" />
<PackageVersion Include="SharpCompress" Version="0.47.4" />
<PackageVersion Include="Svg.Controls.Avalonia" Version="11.3.9.4" />
<PackageVersion Include="Svg.Controls.Skia.Avalonia" Version="11.3.9.4" />
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
@ -16,7 +17,7 @@
<PackageVersion Include="Projektanker.Icons.Avalonia" Version="9.6.2" />
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.6.2" />
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.6.2" />
<PackageVersion Include="ppy.SDL3-CS" Version="2025.920.0" />
<PackageVersion Include="Ryujinx.SDL3-CS" Version="2026.426.0" />
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageVersion Include="Concentus" Version="2.2.2" />
@ -42,13 +43,12 @@
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.129" />
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.44" />
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.44" />
<PackageVersion Include="Ryujinx.UpdateClient" Version="2.0.6" />
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="2.0.6" />
<PackageVersion Include="Gommon" Version="2.8.0.1" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="Sep" Version="0.11.1" />
<PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.22.0" />

View file

@ -31,7 +31,7 @@
<br>
This is not a Ryujinx revival project. This is not a Phoenix project.
<br>
Guides and documentation can be found on the <a href="https://git.greemdev.net/projects/Ryubing/wiki/Home">Wiki tab</a>.
Guides and documentation can be found on the <a href="https://git.ryujinx.app/projects/Ryubing/wiki/Home">Wiki tab</a>.
</p>
<p align="center">

View file

@ -86,11 +86,11 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.github\workflows\build.yml = .github\workflows\build.yml
.github\workflows\canary.yml = .github\workflows\canary.yml
.forgejo\workflows\build.yml = .forgejo\workflows\build.yml
.forgejo\workflows\canary.yml = .forgejo\workflows\canary.yml
Directory.Packages.props = Directory.Packages.props
Directory.Build.props = Directory.Build.props
.github\workflows\release.yml = .github\workflows\release.yml
.forgejo\workflows\release.yml = .forgejo\workflows\release.yml
nuget.config = nuget.config
EndProjectSection
EndProject
@ -573,6 +573,16 @@ Global
{D58FA894-27D5-4EAA-9042-AD422AD82931}.Release|x86.Build.0 = Release|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Debug|x64.ActiveCfg = Debug|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Debug|x64.Build.0 = Debug|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Debug|x86.ActiveCfg = Debug|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Debug|x86.Build.0 = Debug|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Release|Any CPU.Build.0 = Release|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Release|x64.ActiveCfg = Release|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Release|x64.Build.0 = Release|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Release|x86.ActiveCfg = Release|Any CPU
{AC26EFF0-8593-4184-9A09-98E37EFFB32E}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -22,7 +22,7 @@
"tr_TR": "",
"uk_UA": "",
"zh_CN": "启动 RenderDoc 帧捕获",
"zh_TW": ""
"zh_TW": "啟動 RenderDoc 畫格擷取"
}
},
{
@ -47,7 +47,7 @@
"tr_TR": "",
"uk_UA": "",
"zh_CN": "结束 RenderDoc 帧捕获",
"zh_TW": ""
"zh_TW": "停止 RenderDoc 畫格擷取"
}
},
{
@ -72,7 +72,7 @@
"tr_TR": "",
"uk_UA": "",
"zh_CN": "丢弃 RenderDoc 帧捕获",
"zh_TW": ""
"zh_TW": "捨棄 RenderDoc 畫格擷取"
}
},
{
@ -97,7 +97,7 @@
"tr_TR": "",
"uk_UA": "",
"zh_CN": "结束当前正在进行的 RenderDoc 帧捕获,并立即丢弃其结果。",
"zh_TW": ""
"zh_TW": "停止正在執行的 RenderDoc 畫格擷取,且立即捨棄其結果。"
}
}
]

View file

@ -582,8 +582,8 @@
"de_DE": "",
"el_GR": "",
"en_US": "Restart Emulation",
"es_ES": "",
"fr_FR": "",
"es_ES": "Reiniciar Emulación",
"fr_FR": "Redémarrer l'Émulation",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
@ -597,7 +597,7 @@
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
"zh_TW": "重新啟動模擬"
}
},
{
@ -11332,8 +11332,8 @@
"de_DE": "Speichern",
"el_GR": "",
"en_US": "Save",
"es_ES": "",
"fr_FR": "",
"es_ES": "Guardar",
"fr_FR": "Sauvegarder",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
@ -11347,7 +11347,7 @@
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
"zh_TW": "儲存"
}
},
{
@ -15351,28 +15351,28 @@
}
},
{
"ID": "AboutGitLabUrlTooltipMessage",
"ID": "AboutForgejoUrlTooltipMessage",
"Translations": {
"ar_SA": "انقر لفتح صفحة ريوجينكس في غيت هاب في متصفحك الافتراضي.",
"de_DE": "Klicke hier, um die Ryujinx GitLab Seite im Standardbrowser zu öffnen.",
"el_GR": "Κάντε κλικ για να ανοίξετε τη σελίδα Ryujinx GitLab στο προεπιλεγμένο πρόγραμμα περιήγησης.",
"en_US": "Click to open the Ryujinx GitLab page in your default browser.",
"es_ES": "Haz clic para abrir el GitLab de Ryujinx en tu navegador predeterminado.",
"fr_FR": "Cliquez pour ouvrir la page GitLab de Ryujinx dans votre navigateur par défaut.",
"de_DE": "Klicke hier, um die Ryujinx Forgejo Seite im Standardbrowser zu öffnen.",
"el_GR": "Κάντε κλικ για να ανοίξετε τη σελίδα Ryujinx Forgejo στο προεπιλεγμένο πρόγραμμα περιήγησης.",
"en_US": "Click to open the Ryujinx Forgejo page in your default browser.",
"es_ES": "Haz clic para abrir el Forgejo de Ryujinx en tu navegador predeterminado.",
"fr_FR": "Cliquez pour ouvrir la page Forgejo de Ryujinx dans votre navigateur par défaut.",
"he_IL": "לחץ כדי לפתוח את דף הגיטהב של ריוג'ינקס בדפדפן ברירת המחדל שלך.",
"it_IT": "Clicca per aprire la pagina GitLab di Ryujinx nel tuo browser predefinito.",
"ja_JP": "クリックするとデフォルトのブラウザで Ryujinx の GitLab ページを開きます.",
"ko_KR": "클릭하면 기본 브라우저에서 Ryujinx GitLab 페이지가 열립니다.",
"no_NO": "Klikk for å åpne Ryujinx GitLab siden i din standardnettleser.",
"pl_PL": "Kliknij, aby otworzyć stronę GitLab Ryujinx w domyślnej przeglądarce.",
"pt_BR": "Clique para abrir a página do GitLab do Ryujinx no seu navegador padrão.",
"ru_RU": "Нажмите, чтобы открыть страницу Ryujinx на GitLab",
"sv_SE": "Klicka för att öppna Ryujinx GitLab-sida i din webbläsare.",
"th_TH": "คลิกเพื่อเปิดหน้า GitLab ของ Ryujinx บนเบราว์เซอร์เริ่มต้นของคุณ",
"tr_TR": "Ryujinx'in GitLab sayfasını varsayılan tarayıcınızda açmak için tıklayın.",
"uk_UA": "Натисніть, щоб відкрити сторінку GitLab Ryujinx у браузері.",
"zh_CN": "在浏览器中打开 Ryujinx 的 GitLab 代码库。",
"zh_TW": "在預設瀏覽器中開啟 Ryujinx 的 GitLab 網頁。"
"it_IT": "Clicca per aprire la pagina Forgejo di Ryujinx nel tuo browser predefinito.",
"ja_JP": "クリックするとデフォルトのブラウザで Ryujinx の Forgejo ページを開きます.",
"ko_KR": "클릭하면 기본 브라우저에서 Ryujinx Forgejo 페이지가 열립니다.",
"no_NO": "Klikk for å åpne Ryujinx Forgejo siden i din standardnettleser.",
"pl_PL": "Kliknij, aby otworzyć stronę Forgejo Ryujinx w domyślnej przeglądarce.",
"pt_BR": "Clique para abrir a página do Forgejo do Ryujinx no seu navegador padrão.",
"ru_RU": "Нажмите, чтобы открыть страницу Ryujinx на Forgejo",
"sv_SE": "Klicka för att öppna Ryujinx Forgejo-sida i din webbläsare.",
"th_TH": "คลิกเพื่อเปิดหน้า Forgejo ของ Ryujinx บนเบราว์เซอร์เริ่มต้นของคุณ",
"tr_TR": "Ryujinx'in Forgejo sayfasını varsayılan tarayıcınızda açmak için tıklayın.",
"uk_UA": "Натисніть, щоб відкрити сторінку Forgejo Ryujinx у браузері.",
"zh_CN": "在浏览器中打开 Ryujinx 的 Forgejo 代码库。",
"zh_TW": "在預設瀏覽器中開啟 Ryujinx 的 Forgejo 網頁。"
}
},
{
@ -15431,23 +15431,23 @@
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Ryujinx is an emulator for the Nintendo Switch™ 1.\nGet all the latest news in our Discord.\nDevelopers interested in contributing can find out more on our GitLab or Discord.",
"es_ES": "Ryujinx es un emulador para Nintendo Switch™ 1.\nObtén todas las novedades en nuestro Discord.\nLos desarrolladores interesados en contribuir pueden obtener más información en nuestro GitLab o Discord.",
"fr_FR": "Ryujinx est un émulateur pour la Nintendo Switch™ 1.\nObtenez les dernières nouvelles sur notre Discord.\nLes développeurs souhaitant contribuer peuvent en savoir plus sur notre GitLab ou Discord.",
"en_US": "Ryujinx is an emulator for the Nintendo Switch™ 1.\nGet all the latest news in our Discord.\nDevelopers interested in contributing can find out more on our Forgejo or Discord.",
"es_ES": "Ryujinx es un emulador para Nintendo Switch™ 1.\nObtén todas las novedades en nuestro Discord.\nLos desarrolladores interesados en contribuir pueden obtener más información en nuestro Forgejo o Discord.",
"fr_FR": "Ryujinx est un émulateur pour la Nintendo Switch™ 1.\nObtenez les dernières nouvelles sur notre Discord.\nLes développeurs souhaitant contribuer peuvent en savoir plus sur notre Forgejo ou Discord.",
"he_IL": "",
"it_IT": "Ryujinx è un emulatore della console Nintendo Switch™ 1.\nRimani aggiornato sulle ultime novità nel nostro server Discord.\nGli sviluppatori interessati a contribuire possono trovare maggiori informazioni su Discord o sulla nostra pagina GitLab.",
"it_IT": "Ryujinx è un emulatore della console Nintendo Switch™ 1.\nRimani aggiornato sulle ultime novità nel nostro server Discord.\nGli sviluppatori interessati a contribuire possono trovare maggiori informazioni su Discord o sulla nostra pagina Forgejo.",
"ja_JP": "",
"ko_KR": "Ryujinx는 Nintendo Switch™ 1용 에뮬레이터입니다.\n모든 최신 소식을 Discord에서 확인하세요.\n기여에 관심이 있는 개발자는 GitLab 또는 Discord에서 자세한 내용을 확인할 수 있습니다.",
"no_NO": "Ryujinx er en emulator for Nintendo Switch™ 1\nVennligst støtt oss på Patreon.\nFå alle de siste nyhetene på vår Twitter eller Discord.\nUtviklere som er interessert i å bidra kan finne ut mer på GitLab eller Discord.",
"ko_KR": "Ryujinx는 Nintendo Switch™ 1용 에뮬레이터입니다.\n모든 최신 소식을 Discord에서 확인하세요.\n기여에 관심이 있는 개발자는 Forgejo 또는 Discord에서 자세한 내용을 확인할 수 있습니다.",
"no_NO": "Ryujinx er en emulator for Nintendo Switch™ 1\nVennligst støtt oss på Patreon.\nFå alle de siste nyhetene på vår Twitter eller Discord.\nUtviklere som er interessert i å bidra kan finne ut mer på Forgejo eller Discord.",
"pl_PL": "",
"pt_BR": "Ryujinx é um emulador de Nintendo Switch™ 1.\nReceba todas as últimas notícias em nosso Discord.\nDesenvolvedores interessados em contribuir podem descobrir mais em nosso GitLab ou Discord.",
"ru_RU": "Ryujinx - это эмулятор для Nintendo Switch™ 1.\nПолучайте все последние новости разработки в нашем Discord.\nРазработчики, заинтересованные в участии, могут узнать больше на нашем GitLab или Discord.",
"sv_SE": "Ryujinx är en emulator för Nintendo Switch™ 1.\nFå de senaste nyheterna via vår Discord.\nUtvecklare som är intresserade att bidra kan hitta mer info på vår GitLab eller Discord.",
"th_TH": "Ryujinx เป็นโปรแกรมจำลองสำหรับเครื่อง Nintendo Switch™ 1\nติดตามข่าวสารล่าสุดได้ที่ Discord ของเรา\nนักพัฒนาที่สนใจร่วมพัฒนา สามารถดูข้อมูลเพิ่มเติมได้ทาง GitLab หรือ Discord",
"pt_BR": "Ryujinx é um emulador de Nintendo Switch™ 1.\nReceba todas as últimas notícias em nosso Discord.\nDesenvolvedores interessados em contribuir podem descobrir mais em nosso Forgejo ou Discord.",
"ru_RU": "Ryujinx - это эмулятор для Nintendo Switch™ 1.\nПолучайте все последние новости разработки в нашем Discord.\nРазработчики, заинтересованные в участии, могут узнать больше на нашем Forgejo или Discord.",
"sv_SE": "Ryujinx är en emulator för Nintendo Switch™ 1.\nFå de senaste nyheterna via vår Discord.\nUtvecklare som är intresserade att bidra kan hitta mer info på vår Forgejo eller Discord.",
"th_TH": "Ryujinx เป็นโปรแกรมจำลองสำหรับเครื่อง Nintendo Switch™ 1\nติดตามข่าวสารล่าสุดได้ที่ Discord ของเรา\nนักพัฒนาที่สนใจร่วมพัฒนา สามารถดูข้อมูลเพิ่มเติมได้ทาง Forgejo หรือ Discord",
"tr_TR": "",
"uk_UA": "Ryujinx — це емулятор для Nintendo Switch™ 1.\nОстанні новини можна отримати в нашому Discord.\nРозробники, що бажають долучитись до розробки та зробити свій внесок, можуть отримати більше інформації на нашому GitLab або в Discord.",
"zh_CN": "Ryujinx 是一个 Nintendo Switch™ 1 模拟器。\n有兴趣做出贡献的开发者可以在我们的 GitLab 或 Discord 上了解更多信息。\n",
"zh_TW": "Ryujinx 是一款 Nintendo Switch™ 1 模擬器。\n關注我們的 Discord 取得所有最新消息。\n對於有興趣貢獻的開發者可以在我們的 GitLab 或 Discord 上了解更多資訊。"
"uk_UA": "Ryujinx — це емулятор для Nintendo Switch™ 1.\nОстанні новини можна отримати в нашому Discord.\nРозробники, що бажають долучитись до розробки та зробити свій внесок, можуть отримати більше інформації на нашому Forgejo або в Discord.",
"zh_CN": "Ryujinx 是一个 Nintendo Switch™ 1 模拟器。\n有兴趣做出贡献的开发者可以在我们的 Forgejo 或 Discord 上了解更多信息。\n",
"zh_TW": "Ryujinx 是一款 Nintendo Switch™ 1 模擬器。\n關注我們的 Discord 取得所有最新消息。\n對於有興趣貢獻的開發者可以在我們的 Forgejo 或 Discord 上了解更多資訊。"
}
},
{
@ -24901,4 +24901,4 @@
}
}
]
}
}

View file

@ -16,15 +16,6 @@ namespace Ryujinx.Common.Helper
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool ShowWindow(nint hWnd, int nCmdShow);
[SupportedOSPlatform("windows")]
[LibraryImport("user32")]
private static partial nint GetForegroundWindow();
[SupportedOSPlatform("windows")]
[LibraryImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool SetForegroundWindow(nint hWnd);
public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows();
public static void SetConsoleWindowState(bool show)
@ -53,10 +44,6 @@ namespace Ryujinx.Common.Helper
return;
}
SetForegroundWindow(hWnd);
hWnd = GetForegroundWindow();
ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
}
}

View file

@ -29,8 +29,8 @@ namespace Ryujinx.Common
public static string GetChangelogUrl(Version currentVersion, Version newVersion) =>
IsCanaryBuild
? $"https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-{currentVersion}...Canary-{newVersion}"
: $"https://git.ryujinx.app/ryubing/ryujinx/-/releases/{newVersion}";
? $"https://git.ryujinx.app/projects/Ryubing/compare/Canary-{currentVersion}...Canary-{newVersion}"
: $"https://git.ryujinx.app/projects/Ryubing/releases/tag/{newVersion}";
}

View file

@ -8,12 +8,12 @@ namespace Ryujinx.Common
public const string AmiiboTagsUrl = "https://raw.githubusercontent.com/Ryubing/Nfc/refs/heads/main/tags.json";
public const string FaqWikiUrl = "https://git.ryujinx.app/ryubing/ryujinx/-/wikis/FAQ-&-Troubleshooting";
public const string FaqWikiUrl = "https://git.ryujinx.app/projects/Ryubing/wiki/FAQ-%26-Troubleshooting";
public const string SetupGuideWikiUrl =
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Setup-&-Configuration-Guide";
"https://git.ryujinx.app/projects/Ryubing/wiki/Setup-%26-Configuration-Guide";
public const string MultiplayerWikiUrl =
"https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Multiplayer-(LDN-Local-Wireless)-Guide";
"https://git.ryujinx.app/projects/Ryubing/wiki/Multiplayer-(LDN-Local-Wireless)-Guide";
}
}

View file

@ -118,8 +118,11 @@ namespace Ryujinx.HLE.HOS.Services.Caps
}
// NOTE: The saved JPEG file doesn't have the limitation in the extra EXIF data.
using SKBitmap bitmap = new(new SKImageInfo(1280, 720, SKColorType.Rgba8888));
Marshal.Copy(screenshotData, 0, bitmap.GetPixels(), screenshotData.Length);
using SKBitmap bitmap = new(new SKImageInfo(1280, 720, SKColorType.Rgba8888, SKAlphaType.Premul));
int dataLen = screenshotData.Length > bitmap.ByteCount ? bitmap.ByteCount : screenshotData.Length;
Marshal.Copy(screenshotData, 0, bitmap.GetPixels(), dataLen);
using SKData data = bitmap.Encode(SKEncodedImageFormat.Jpeg, 80);
using FileStream file = File.OpenWrite(filePath);
data.SaveTo(file);

View file

@ -151,7 +151,9 @@ namespace Ryujinx.Input.SDL3
result |= GamepadFeaturesFlag.Led;
}
SDL_UnlockProperties(propID);
SDL_DestroyProperties(propID);
// NOTE: Do not call SDL_DestroyProperties here. These properties are owned
// internally by SDL and are freed when SDL_CloseGamepad is called (in Dispose).
return result;
}

View file

@ -331,28 +331,18 @@ namespace Ryujinx.Input.SDL3
public IEnumerable<IGamepad> GetGamepads()
{
lock (_gamepadsIds)
string[] ids;
lock (_lock)
{
foreach (var gamepad in _gamepadsIds)
{
yield return GetGamepad(gamepad.Value);
}
ids = _gamepadsIds.Values
.Concat(_joyConsIds.Values)
.Concat(_linkedJoyConsIds.Values)
.ToArray();
}
lock (_joyConsIds)
foreach (string id in ids)
{
foreach (var gamepad in _joyConsIds)
{
yield return GetGamepad(gamepad.Value);
}
}
lock (_linkedJoyConsIds)
{
foreach (var gamepad in _linkedJoyConsIds)
{
yield return GetGamepad(gamepad.Value);
}
yield return GetGamepad(id);
}
}
}

View file

@ -563,7 +563,7 @@ namespace Ryujinx.Input.HLE
float low = Math.Min(1f, (float)((rightVibrationValue.AmplitudeLow * 0.85 + rightVibrationValue.AmplitudeHigh * 0.15) * controllerConfig.Rumble.StrongRumble));
float high = Math.Min(1f, (float)((leftVibrationValue.AmplitudeLow * 0.15 + leftVibrationValue.AmplitudeHigh * 0.85) * controllerConfig.Rumble.WeakRumble));
_gamepad.Rumble(low, high, uint.MaxValue);
_gamepad?.Rumble(low, high, uint.MaxValue);
Logger.Debug?.Print(LogClass.Hid, $"Effect for {controllerConfig.PlayerIndex} " +
$"L.low.amp={leftVibrationValue.AmplitudeLow}, " +

View file

@ -10,7 +10,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.SDL3-CS" />
<PackageReference Include="Ryujinx.SDL3-CS" />
</ItemGroup>
</Project>

View file

@ -61,6 +61,14 @@ namespace Ryujinx.SDL3.Common
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1");
SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1");
// When hid_nintendo is loaded, it creates separate evdev devices for the gamepad
// and IMU which SDL3's evdev backend combines via UNIQ matching. Using HIDAPI
// instead conflicts with the kernel driver and breaks motion and hotplug.
if (OperatingSystem.IsLinux() && Directory.Exists("/sys/module/hid_nintendo"))
{
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "0");
}
// NOTE: As of SDL3 2.24.0, joycons are combined by default but the motion source only come from one of them.
// We disable this behavior for now.
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, "0");

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

View file

@ -24,9 +24,11 @@ using Ryujinx.Headless;
using Ryujinx.SDL3.Common;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
namespace Ryujinx.Ava
@ -52,6 +54,22 @@ namespace Ryujinx.Ava
if (OperatingSystem.IsWindows())
{
#if !DEBUG
// this fixes the "hide console" option by forcing the emulator to launch in an old-school cmd
if (!Console.Title.Contains("conhost.exe"))
{
StringBuilder sb = new();
foreach (string arg in args)
{
sb.Append(arg.Contains(' ') ? $" \"{arg}\"" : $" {arg}");
}
Process.Start("conhost.exe", $"{Environment.ProcessPath} {sb}");
return 0;
}
#endif
if (!OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041))
{
Logger.Error?.PrintMsg(LogClass.Application, "Ryujinx is not intended to be run on an outdated version of Windows. Exiting...");

View file

@ -46,6 +46,7 @@
<PackageReference Include="Avalonia.Diagnostics" Condition="'$(Configuration)'=='Debug'" />
<PackageReference Include="Avalonia.Controls.DataGrid" />
<PackageReference Include="Avalonia.Markup.Xaml.Loader" />
<PackageReference Include="SharpCompress" />
<PackageReference Include="Svg.Controls.Avalonia" />
<PackageReference Include="Svg.Controls.Skia.Avalonia" />
<PackageReference Include="DynamicData" />
@ -68,7 +69,6 @@
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
<PackageReference Include="SPB" />
<PackageReference Include="SharpZipLib" />
</ItemGroup>
<ItemGroup>
@ -169,9 +169,8 @@
<EmbeddedResource Include="Assets\UIImages\Logo_Amiibo.png" />
<EmbeddedResource Include="Assets\UIImages\Logo_Discord_Dark.png" />
<EmbeddedResource Include="Assets\UIImages\Logo_Discord_Light.png" />
<EmbeddedResource Include="Assets\UIImages\Logo_GitLab_Dark.png" />
<EmbeddedResource Include="Assets\UIImages\Logo_GitLab_Light.png" />
<EmbeddedResource Include="Assets\UIImages\Logo_Ryujinx.png" />
<EmbeddedResource Include="Assets\UIImages\Logo_Forgejo.png" />
<EmbeddedResource Include="Assets\UIImages\Logo_Ryujinx_AntiAlias.png" />
</ItemGroup>
<ItemGroup>

View file

@ -91,7 +91,7 @@ namespace Ryujinx.Ava.Systems
}
// If build URL not found, assume no new update is available.
if (_versionResponse.ArtifactUrl is null or "")
if (string.IsNullOrEmpty(_versionResponse.ArtifactUrl))
{
if (showVersionUpToDate)
{
@ -123,6 +123,8 @@ namespace Ryujinx.Ava.Systems
return default;
}
_connectionCount = (int)_versionResponse.MaxConcurrency;
return (currentVersion, newVersion);
}
}

View file

@ -1,19 +1,20 @@
using Avalonia.Threading;
using FluentAvalonia.UI.Controls;
using Gommon;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using ICSharpCode.SharpZipLib.Zip;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Utilities;
using Ryujinx.Common;
using Ryujinx.Common.Helper;
using Ryujinx.Common.Logging;
using SharpCompress.Archives;
using SharpCompress.Compressors.Xz;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Formats.Tar;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
@ -21,7 +22,6 @@ using System.Net.NetworkInformation;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@ -32,8 +32,8 @@ namespace Ryujinx.Ava.Systems
private static readonly string _homeDir = AppDomain.CurrentDomain.BaseDirectory;
private static readonly string _updateDir = Path.Combine(Path.GetTempPath(), "Ryujinx", "update");
private static readonly string _updatePublishDir = Path.Combine(_updateDir, "publish");
private const int ConnectionCount = 4;
private static int _connectionCount = 1;
private static long _buildSize;
private static bool _updateSuccessful;
private static bool _running;
@ -73,27 +73,6 @@ namespace Ryujinx.Ava.Systems
return;
}
// Fetch build size information to learn chunk sizes.
using HttpClient buildSizeClient = ConstructHttpClient();
try
{
buildSizeClient.DefaultRequestHeaders.Add("Range", "bytes=0-0");
// GitLab instance is located in Ukraine. Connection times will vary across the world.
buildSizeClient.Timeout = TimeSpan.FromSeconds(10);
HttpResponseMessage message = await buildSizeClient.GetAsync(new Uri(_versionResponse.ArtifactUrl), HttpCompletionOption.ResponseHeadersRead);
_buildSize = message.Content.Headers.ContentRange.Length.Value;
}
catch (Exception ex)
{
Logger.Warning?.Print(LogClass.Application, ex.Message);
Logger.Warning?.Print(LogClass.Application, "Couldn't determine build size for update, using single-threaded updater");
_buildSize = -1;
}
await Dispatcher.UIThread.InvokeAsync(async () =>
{
string newVersionString = ReleaseInformation.IsCanaryBuild
@ -143,6 +122,14 @@ namespace Ryujinx.Ava.Systems
Directory.CreateDirectory(_updateDir);
// If we get a .zip url switch it to the preferred .7z file instead
// The update server still returns the .zip url by default for legacy support
downloadUrl = downloadUrl.Replace(".zip", ".7z");
// If we get a .tar.gz url switch it to the preferred .tar.xz file instead
// The update server still returns the .tar.gz url by default for legacy support
downloadUrl = downloadUrl.Replace(".tar.gz", ".tar.xz");
string updateFile = Path.Combine(_updateDir, "update.bin");
TaskDialog taskDialog = new()
@ -153,6 +140,27 @@ namespace Ryujinx.Ava.Systems
ShowProgressBar = true,
XamlRoot = RyujinxApp.MainWindow,
};
// Fetch build size information to learn chunk sizes.
using HttpClient buildSizeClient = ConstructHttpClient();
try
{
buildSizeClient.DefaultRequestHeaders.Add("Range", "bytes=0-0");
// Forgejo instance is located in Ukraine. Connection times will vary across the world.
buildSizeClient.Timeout = TimeSpan.FromSeconds(10);
HttpResponseMessage message = await buildSizeClient.GetAsync(new Uri(_versionResponse.ArtifactUrl), HttpCompletionOption.ResponseHeadersRead);
_buildSize = message.Content.Headers.ContentRange.Length.Value;
}
catch (Exception ex)
{
Logger.Warning?.Print(LogClass.Application, ex.Message);
Logger.Warning?.Print(LogClass.Application, "Couldn't determine build size for update, using single-threaded updater");
_buildSize = -1;
}
taskDialog.Opened += (s, e) =>
{
@ -234,22 +242,22 @@ namespace Ryujinx.Ava.Systems
private static void DoUpdateWithMultipleThreads(TaskDialog taskDialog, string downloadUrl, string updateFile)
{
// Multi-Threaded Updater
long chunkSize = _buildSize / ConnectionCount;
long remainderChunk = _buildSize % ConnectionCount;
long chunkSize = _buildSize / _connectionCount;
long remainderChunk = _buildSize % _connectionCount;
int completedRequests = 0;
int totalProgressPercentage = 0;
int[] progressPercentage = new int[ConnectionCount];
int[] progressPercentage = new int[_connectionCount];
List<byte[]> list = new(ConnectionCount);
List<WebClient> webClients = new(ConnectionCount);
List<byte[]> list = new(_connectionCount);
List<WebClient> webClients = new(_connectionCount);
for (int i = 0; i < ConnectionCount; i++)
for (int i = 0; i < _connectionCount; i++)
{
list.Add([]);
}
for (int i = 0; i < ConnectionCount; i++)
for (int i = 0; i < _connectionCount; i++)
{
#pragma warning disable SYSLIB0014
// TODO: WebClient is obsolete and need to be replaced with a more complex logic using HttpClient.
@ -258,7 +266,7 @@ namespace Ryujinx.Ava.Systems
webClients.Add(client);
if (i == ConnectionCount - 1)
if (i == _connectionCount - 1)
{
client.Headers.Add("Range", $"bytes={chunkSize * i}-{(chunkSize * (i + 1) - 1) + remainderChunk}");
}
@ -275,7 +283,7 @@ namespace Ryujinx.Ava.Systems
Interlocked.Exchange(ref progressPercentage[index], args.ProgressPercentage);
Interlocked.Add(ref totalProgressPercentage, args.ProgressPercentage);
taskDialog.SetProgressBarState(totalProgressPercentage / ConnectionCount, TaskDialogProgressState.Normal);
taskDialog.SetProgressBarState(totalProgressPercentage / _connectionCount, TaskDialogProgressState.Normal);
};
client.DownloadDataCompleted += (_, args) =>
@ -294,10 +302,10 @@ namespace Ryujinx.Ava.Systems
list[index] = args.Result;
Interlocked.Increment(ref completedRequests);
if (Equals(completedRequests, ConnectionCount))
if (Equals(completedRequests, _connectionCount))
{
byte[] mergedFileBytes = new byte[_buildSize];
for (int connectionIndex = 0, destinationOffset = 0; connectionIndex < ConnectionCount; connectionIndex++)
for (int connectionIndex = 0, destinationOffset = 0; connectionIndex < _connectionCount; connectionIndex++)
{
Array.Copy(list[connectionIndex], 0, mergedFileBytes, destinationOffset, list[connectionIndex].Length);
destinationOffset += list[connectionIndex].Length;
@ -402,73 +410,33 @@ namespace Ryujinx.Ava.Systems
[SupportedOSPlatform("linux")]
[SupportedOSPlatform("macos")]
private static void ExtractTarGzipFile(TaskDialog taskDialog, string archivePath, string outputDirectoryPath)
private static void ExtractTarGzipFile(string archivePath, string outputDirectoryPath)
{
using FileStream inStream = File.OpenRead(archivePath);
using GZipInputStream gzipStream = new(inStream);
using TarInputStream tarStream = new(gzipStream, Encoding.ASCII);
TarEntry tarEntry;
while ((tarEntry = tarStream.GetNextEntry()) is not null)
{
if (tarEntry.IsDirectory)
{
continue;
}
string outPath = Path.Combine(outputDirectoryPath, tarEntry.Name);
Directory.CreateDirectory(Path.GetDirectoryName(outPath));
using FileStream outStream = File.OpenWrite(outPath);
tarStream.CopyEntryContents(outStream);
File.SetUnixFileMode(outPath, (UnixFileMode)tarEntry.TarHeader.Mode);
File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc));
Dispatcher.UIThread.Post(() =>
{
if (tarEntry is null)
{
return;
}
taskDialog.SetProgressBarState(GetPercentage(tarEntry.Size, inStream.Length), TaskDialogProgressState.Normal);
});
}
using GZipStream gzipStream = new(inStream, CompressionMode.Decompress);
TarFile.ExtractToDirectory(gzipStream, outputDirectoryPath, true);
}
[SupportedOSPlatform("linux")]
[SupportedOSPlatform("macos")]
private static void ExtractTarXzipFile(string archivePath, string outputDirectoryPath)
{
using FileStream inStream = File.OpenRead(archivePath);
using XZStream gzipStream = new(inStream);
TarFile.ExtractToDirectory(gzipStream, outputDirectoryPath, true);
}
private static void ExtractZipFile(TaskDialog taskDialog, string archivePath, string outputDirectoryPath)
private static void ExtractZipFile(string archivePath, string outputDirectoryPath)
{
using Stream inStream = File.OpenRead(archivePath);
using ZipFile zipFile = new(inStream);
double count = 0;
foreach (ZipEntry zipEntry in zipFile)
{
count++;
if (zipEntry.IsDirectory)
{
continue;
}
string outPath = Path.Combine(outputDirectoryPath, zipEntry.Name);
Directory.CreateDirectory(Path.GetDirectoryName(outPath));
using Stream zipStream = zipFile.GetInputStream(zipEntry);
using FileStream outStream = File.OpenWrite(outPath);
zipStream.CopyTo(outStream);
File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc));
Dispatcher.UIThread.Post(() =>
{
taskDialog.SetProgressBarState(GetPercentage(count, zipFile.Count), TaskDialogProgressState.Normal);
});
}
ZipFile.ExtractToDirectory(archivePath, outputDirectoryPath);
}
private static void Extract7ZipFile(string archivePath, string outputDirectoryPath)
{
IArchive archive = ArchiveFactory.OpenArchive(archivePath);
archive.WriteToDirectory(outputDirectoryPath);
}
private static void InstallUpdate(TaskDialog taskDialog, string updateFile)
@ -479,16 +447,20 @@ namespace Ryujinx.Ava.Systems
if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
{
ExtractTarGzipFile(taskDialog, updateFile, _updateDir);
ExtractTarXzipFile(updateFile, _updateDir);
}
else if (OperatingSystem.IsWindows())
{
ExtractZipFile(taskDialog, updateFile, _updateDir);
Extract7ZipFile(updateFile, _updateDir);
}
else
{
throw new NotSupportedException();
}
// The new decompression implementations don't have a way to show progress
// so the progressbar is just set to 100% after the decompression is done
taskDialog.SetProgressBarState(100, TaskDialogProgressState.Normal);
// Delete downloaded zip
File.Delete(updateFile);

View file

@ -11,7 +11,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{
public partial class AboutWindowViewModel : BaseModel, IDisposable
{
[ObservableProperty] public partial Bitmap GitLabLogo { get; set; }
[ObservableProperty] public partial Bitmap ForgejoLogo { get; set; }
[ObservableProperty] public partial Bitmap DiscordLogo { get; set; }
@ -37,6 +37,7 @@ namespace Ryujinx.Ava.UI.ViewModels
}
private const string LogoPathFormat = "resm:Ryujinx.Assets.UIImages.Logo_{0}_{1}.png?assembly=Ryujinx";
private const string UnthemedLogoPathFormat = "resm:Ryujinx.Assets.UIImages.Logo_{0}.png?assembly=Ryujinx";
private void UpdateLogoTheme(string theme)
{
@ -46,7 +47,7 @@ namespace Ryujinx.Ava.UI.ViewModels
string themeName = isDarkTheme ? "Dark" : "Light";
DiscordLogo = LoadBitmap(LogoPathFormat.Format("Discord", themeName));
GitLabLogo = LoadBitmap(LogoPathFormat.Format("GitLab", themeName));
ForgejoLogo = LoadBitmap(UnthemedLogoPathFormat.Format("Forgejo"));
}
private static Bitmap LoadBitmap(string uri) => new(Avalonia.Platform.AssetLoader.Open(new Uri(uri)));
@ -55,7 +56,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{
RyujinxApp.ThemeChanged -= Ryujinx_ThemeChanged;
GitLabLogo.Dispose();
ForgejoLogo.Dispose();
DiscordLogo.Dispose();
GC.SuppressFinalize(this);

View file

@ -122,8 +122,8 @@
Click="Button_OnClick"
CornerRadius="15"
Tag="https://src.ryujinx.app"
ToolTip.Tip="{ext:Locale AboutGitLabUrlTooltipMessage}">
<Image Source="{Binding GitLabLogo}" />
ToolTip.Tip="{ext:Locale AboutForgejoUrlTooltipMessage}">
<Image Source="{Binding ForgejoLogo}" />
</Button>
<Button
MinWidth="30"

View file

@ -295,17 +295,17 @@
<MenuItem
Name="SetupGuideMenuItem"
Header="{ext:Locale MenuBarHelpSetup}"
Icon="{ext:Icon fa-brands fa-gitlab}"
Icon="{ext:Icon fa-solid fa-circle-info}"
CommandParameter="{x:Static common:SharedConstants.SetupGuideWikiUrl}" />
<MenuItem
Name="LdnGuideMenuItem"
Header="{ext:Locale MenuBarHelpMultiplayer}"
Icon="{ext:Icon fa-brands fa-gitlab}"
Icon="{ext:Icon fa-solid fa-circle-info}"
CommandParameter="{x:Static common:SharedConstants.MultiplayerWikiUrl}" />
<MenuItem
Name="FaqMenuItem"
Header="{ext:Locale MenuBarHelpFaq}"
Icon="{ext:Icon fa-brands fa-gitlab}"
Icon="{ext:Icon fa-solid fa-circle-info}"
CommandParameter="{x:Static common:SharedConstants.FaqWikiUrl}" />
</MenuItem>
<Separator />