mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-08-01 02:30:08 -06:00
Compare commits
43 Commits
Canary-1.3
...
experiment
Author | SHA1 | Date | |
---|---|---|---|
e9824c9053 | |||
d2037da65f | |||
8fe7d54f85 | |||
b8f9f3e16a | |||
7b1c8717ef | |||
6122fa204f | |||
217fd90568 | |||
95157c0cfd | |||
8a3ccaafe3 | |||
45b2e613cf | |||
932c480325 | |||
0e24435414 | |||
a5cf0482b4 | |||
14e794af84 | |||
29a02f4787 | |||
e2f9d84b64 | |||
0cc94fdf37 | |||
74a9b94227 | |||
d3208a4c44 | |||
5d136980a3 | |||
572ad1eac5 | |||
6bb2af0091 | |||
534a194ed9 | |||
331805791e | |||
6773406bb6 | |||
6226eadf55 | |||
b1cde5fd97 | |||
39944b2063 | |||
973c6ba5df | |||
6803c91da8 | |||
557c2a50b2 | |||
77a797f154 | |||
faf9e3cdd7 | |||
7bc80ed4fe | |||
a1d44ec496 | |||
bab3beb0ac | |||
aa9e74339b | |||
908273d848 | |||
b51ad11574 | |||
ea027d65a7 | |||
d03ae9c164 | |||
90e9492f6c | |||
512120db04 |
84
.github/workflows/canary.yml
vendored
84
.github/workflows/canary.yml
vendored
@ -105,46 +105,48 @@ jobs:
|
|||||||
|
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
# If anyone wants to look into why appimagetool randomly errors with exit code 8, that would be cool
|
||||||
|
|
||||||
- name: Build AppImage (Linux)
|
# - name: Build AppImage (Linux)
|
||||||
if: matrix.platform.os == 'ubuntu-latest'
|
# if: matrix.platform.os == 'ubuntu-latest'
|
||||||
run: |
|
# run: |
|
||||||
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
# BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
|
||||||
PLATFORM_NAME="${{ matrix.platform.name }}"
|
# 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
|
# mkdir -p tools
|
||||||
export PATH="$PATH:$(readlink -f tools)"
|
# export PATH="$PATH:$(readlink -f tools)"
|
||||||
|
#
|
||||||
# Setup appimagetool
|
# # Setup appimagetool
|
||||||
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
# wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||||
chmod +x tools/appimagetool
|
# chmod +x tools/appimagetool
|
||||||
chmod +x distribution/linux/appimage/build-appimage.sh
|
# chmod +x distribution/linux/appimage/build-appimage.sh
|
||||||
|
#
|
||||||
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
# # Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
|
||||||
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
# if [ "$PLATFORM_NAME" = "linux-x64" ]; then
|
||||||
ARCH_NAME=x64
|
# ARCH_NAME=x64
|
||||||
export ARCH=x86_64
|
# export ARCH=x86_64
|
||||||
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
# elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
|
||||||
ARCH_NAME=arm64
|
# ARCH_NAME=arm64
|
||||||
export ARCH=aarch64
|
# export ARCH=aarch64
|
||||||
else
|
# else
|
||||||
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
# echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
|
||||||
exit 1
|
# exit 1
|
||||||
fi
|
# fi
|
||||||
|
#
|
||||||
export UFLAG="gh-releases-zsync|${{ secrets.RC_OWNER }}${{ secrets.RC_CANARY_NAME }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
# export UFLAG="gh-releases-zsync|${{ secrets.RC_OWNER }}${{ secrets.RC_CANARY_NAME }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||||
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
# BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||||
|
#
|
||||||
pushd publish_appimage
|
# pushd publish_appimage
|
||||||
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
# mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
|
||||||
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
# mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
|
||||||
popd
|
# popd
|
||||||
|
#
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||||
shell: bash
|
# shell: bash
|
||||||
|
|
||||||
macos_release:
|
macos_release:
|
||||||
name: Release MacOS universal
|
name: Release MacOS universal
|
||||||
@ -243,3 +245,7 @@ jobs:
|
|||||||
- name: Send notification webhook
|
- name: Send notification webhook
|
||||||
run: |
|
run: |
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|FF4500|${{ secrets.CANARY_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|FF4500|${{ secrets.CANARY_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
|
||||||
|
|
||||||
|
- name: Notify update server of new builds
|
||||||
|
run: |
|
||||||
|
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=canary' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'
|
||||||
|
84
.github/workflows/release.yml
vendored
84
.github/workflows/release.yml
vendored
@ -96,46 +96,48 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- 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
|
|
||||||
|
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
# If anyone wants to look into why appimagetool randomly errors with exit code 8, that would be cool
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
|
||||||
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
|
||||||
|
#
|
||||||
|
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||||
|
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||||
|
# shell: bash
|
||||||
|
|
||||||
macos_release:
|
macos_release:
|
||||||
name: Release MacOS universal
|
name: Release MacOS universal
|
||||||
@ -228,3 +230,7 @@ jobs:
|
|||||||
- name: Send notification webhook
|
- name: Send notification webhook
|
||||||
run: |
|
run: |
|
||||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|32cd32|${{ secrets.STABLE_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
|
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|32cd32|${{ secrets.STABLE_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
|
||||||
|
|
||||||
|
- name: Notify update server of new builds
|
||||||
|
run: |
|
||||||
|
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=stable' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'
|
||||||
|
@ -40,8 +40,10 @@
|
|||||||
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
|
<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.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
<PackageVersion Include="Ryujinx.LibHac" Version="0.20.0" />
|
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.116" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||||
|
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.29" />
|
||||||
|
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.29" />
|
||||||
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="Sep" Version="0.6.0" />
|
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||||
@ -53,6 +55,7 @@
|
|||||||
<PackageVersion Include="SkiaSharp" Version="2.88.9" />
|
<PackageVersion Include="SkiaSharp" Version="2.88.9" />
|
||||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
|
||||||
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
||||||
|
<PackageVersion Include="Starscript.Net" Version="1.0.36" />
|
||||||
<PackageVersion Include="System.IO.Hashing" Version="9.0.2" />
|
<PackageVersion Include="System.IO.Hashing" Version="9.0.2" />
|
||||||
<PackageVersion Include="System.Management" Version="9.0.2" />
|
<PackageVersion Include="System.Management" Version="9.0.2" />
|
||||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
# Ryujinx
|
# Ryujinx
|
||||||
|
|
||||||
[](https://git.ryujinx.app/ryubing/ryujinx/-/releases)
|
[](https://update.ryujinx.app/latest/stable)
|
||||||
[](https://git.ryujinx.app/ryubing/canary/-/releases)
|
[](https://update.ryujinx.app/latest/canary)
|
||||||
<br>
|
<br>
|
||||||
<a href="https://discord.gg/PEuzjrFXUA">
|
<a href="https://discord.gg/PEuzjrFXUA">
|
||||||
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
|
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
|
||||||
|
@ -77,6 +77,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Gene
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
||||||
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
@ -84,10 +86,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
.github\workflows\canary.yml = .github\workflows\canary.yml
|
.github\workflows\canary.yml = .github\workflows\canary.yml
|
||||||
Directory.Packages.props = Directory.Packages.props
|
Directory.Packages.props = Directory.Packages.props
|
||||||
.github\workflows\release.yml = .github\workflows\release.yml
|
.github\workflows\release.yml = .github\workflows\release.yml
|
||||||
|
nuget.config = nuget.config
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
1934
assets/locales.json
1934
assets/locales.json
File diff suppressed because it is too large
Load Diff
@ -2257,6 +2257,7 @@
|
|||||||
010086F0064CE000,"Poi: Explorer Edition",nvdec,playable,2021-01-21 19:32:00
|
010086F0064CE000,"Poi: Explorer Edition",nvdec,playable,2021-01-21 19:32:00
|
||||||
0100EB6012FD2000,"Poison Control",,playable,2021-05-16 14:01:54
|
0100EB6012FD2000,"Poison Control",,playable,2021-05-16 14:01:54
|
||||||
010072400E04A000,"Pokémon Café ReMix",,playable,2021-08-17 20:00:04
|
010072400E04A000,"Pokémon Café ReMix",,playable,2021-08-17 20:00:04
|
||||||
|
010008c01e742000,"Pokémon Friends",crash;services,menus,2025-07-24 13:32:00
|
||||||
01003D200BAA2000,"Pokémon Mystery Dungeon™: Rescue Team DX",mac-bug,playable,2024-01-21 00:16:32
|
01003D200BAA2000,"Pokémon Mystery Dungeon™: Rescue Team DX",mac-bug,playable,2024-01-21 00:16:32
|
||||||
01008DB008C2C000,"Pokémon Shield + Pokémon Shield Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-12 07:20:22
|
01008DB008C2C000,"Pokémon Shield + Pokémon Shield Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-12 07:20:22
|
||||||
0100ABF008968000,"Pokémon Sword + Pokémon Sword Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-26 15:40:37
|
0100ABF008968000,"Pokémon Sword + Pokémon Sword Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-26 15:40:37
|
||||||
@ -2436,6 +2437,7 @@
|
|||||||
0100E9C010EA8000,"Rise of Insanity",,playable,2020-08-30 15:42:14
|
0100E9C010EA8000,"Rise of Insanity",,playable,2020-08-30 15:42:14
|
||||||
01006BA00E652000,"Rise: Race The Future",,playable,2021-02-27 13:29:06
|
01006BA00E652000,"Rise: Race The Future",,playable,2021-02-27 13:29:06
|
||||||
010020C012F48000,"Rising Hell",,playable,2022-10-31 13:54:02
|
010020C012F48000,"Rising Hell",,playable,2022-10-31 13:54:02
|
||||||
|
0100D1801A0F4000,"Risk of Rain Returns",,playable,2025-06-28 04:24:04
|
||||||
010076D00E4BA000,"Risk of Rain 2",online-broken,playable,2024-03-04 17:01:05
|
010076D00E4BA000,"Risk of Rain 2",online-broken,playable,2024-03-04 17:01:05
|
||||||
0100E8300A67A000,"RISK® Global Domination",nvdec;online-broken,playable,2022-08-01 18:53:28
|
0100E8300A67A000,"RISK® Global Domination",nvdec;online-broken,playable,2022-08-01 18:53:28
|
||||||
010042500FABA000,"Ritual: Crown of Horns",,playable,2021-01-26 16:01:47
|
010042500FABA000,"Ritual: Crown of Horns",,playable,2021-01-26 16:01:47
|
||||||
@ -2746,6 +2748,7 @@
|
|||||||
01005D701264A000,"SpyHack",,playable,2021-04-15 10:53:51
|
01005D701264A000,"SpyHack",,playable,2021-04-15 10:53:51
|
||||||
010077B00E046000,"Spyro™ Reignited Trilogy",nvdec;UE4,playable,2022-09-11 18:38:33
|
010077B00E046000,"Spyro™ Reignited Trilogy",nvdec;UE4,playable,2022-09-11 18:38:33
|
||||||
0100085012A0E000,"Squeakers",,playable,2020-12-13 12:13:05
|
0100085012A0E000,"Squeakers",,playable,2020-12-13 12:13:05
|
||||||
|
0100E1D01EB2E000,"Squeakross: Home Squeak Home",,playable,2025-06-16 02:02:00
|
||||||
010009300D31C000,"Squidgies Takeover",,playable,2020-07-20 22:28:08
|
010009300D31C000,"Squidgies Takeover",,playable,2020-07-20 22:28:08
|
||||||
0100FCD0102EC000,"Squidlit",,playable,2020-08-06 12:38:32
|
0100FCD0102EC000,"Squidlit",,playable,2020-08-06 12:38:32
|
||||||
0100EBF00E702000,"STAR OCEAN First Departure R",nvdec,playable,2021-07-05 19:29:16
|
0100EBF00E702000,"STAR OCEAN First Departure R",nvdec,playable,2021-07-05 19:29:16
|
||||||
@ -3016,6 +3019,7 @@
|
|||||||
01009B101044C000,"The Legend of Heroes: Trails of Cold Steel III Demo",demo;nvdec,playable,2021-04-23 01:07:32
|
01009B101044C000,"The Legend of Heroes: Trails of Cold Steel III Demo",demo;nvdec,playable,2021-04-23 01:07:32
|
||||||
0100D3C010DE8000,"The Legend of Heroes: Trails of Cold Steel IV",nvdec,playable,2021-04-23 14:01:05
|
0100D3C010DE8000,"The Legend of Heroes: Trails of Cold Steel IV",nvdec,playable,2021-04-23 14:01:05
|
||||||
01005E5013862000,"THE LEGEND OF HEROES: ZERO NO KISEKI KAI [英雄傳說 零之軌跡:改]",crash,nothing,2021-09-30 14:41:07
|
01005E5013862000,"THE LEGEND OF HEROES: ZERO NO KISEKI KAI [英雄傳說 零之軌跡:改]",crash,nothing,2021-09-30 14:41:07
|
||||||
|
01009C901ACEE000,"The Legend of Nayuta: Boundless Trails",,ingame,2025-06-12 15:47
|
||||||
01008CF01BAAC000,"The Legend of Zelda Echoes of Wisdom",nvdec;ASTC;intel-vendor-bug,playable,2024-10-01 14:11:01
|
01008CF01BAAC000,"The Legend of Zelda Echoes of Wisdom",nvdec;ASTC;intel-vendor-bug,playable,2024-10-01 14:11:01
|
||||||
0100509005AF2000,"The Legend of Zelda: Breath of the Wild Demo",demo,ingame,2022-12-24 05:02:58
|
0100509005AF2000,"The Legend of Zelda: Breath of the Wild Demo",demo,ingame,2022-12-24 05:02:58
|
||||||
01007EF00011E000,"The Legend of Zelda™: Breath of the Wild",gpu;amd-vendor-bug;mac-bug,ingame,2024-09-23 19:35:46
|
01007EF00011E000,"The Legend of Zelda™: Breath of the Wild",gpu;amd-vendor-bug;mac-bug,ingame,2024-09-23 19:35:46
|
||||||
|
|
17
nuget.config
17
nuget.config
@ -5,6 +5,21 @@
|
|||||||
<clear />
|
<clear />
|
||||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||||
<!-- Only needed when using pre-release versions of Ryujinx.LibHac. -->
|
<!-- Only needed when using pre-release versions of Ryujinx.LibHac. -->
|
||||||
<!--<add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" />-->
|
<add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" />
|
||||||
|
<add key="Ryujinx.UpdateClient" value="https://git.ryujinx.app/api/v4/projects/71/packages/nuget/index.json" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
|
<packageSourceMapping>
|
||||||
|
<!-- key value for <packageSource> should match key values from <packageSources> element -->
|
||||||
|
<!-- These are defined and .NET still yells about multiple package sources with no mappings. Not sure what to do, this is in the docs lol -->
|
||||||
|
<packageSource key="nuget.org">
|
||||||
|
<package pattern="*" />
|
||||||
|
</packageSource>
|
||||||
|
<packageSource key="Ryujinx.UpdateClient">
|
||||||
|
<package pattern="Ryujinx.UpdateClient" />
|
||||||
|
<package pattern="Ryujinx.Systems.Update.Common" />
|
||||||
|
</packageSource>
|
||||||
|
<packageSource key="LibHacAlpha">
|
||||||
|
<package pattern="Ryujinx.LibHac" />
|
||||||
|
</packageSource>
|
||||||
|
</packageSourceMapping>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -33,7 +33,7 @@ namespace Ryujinx.BuildValidationTasks
|
|||||||
LocalesJson json;
|
LocalesJson json;
|
||||||
|
|
||||||
if (isGitRunner && data.Contains("\r\n"))
|
if (isGitRunner && data.Contains("\r\n"))
|
||||||
throw new FormatException("locales.json is using CRLF line endings! It should be using LF line endings, build locally to fix...");
|
throw new FormatException("locales.json is using CRLF line endings! It should be using LF line endings, rebuild locally to fix...");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -86,7 +86,7 @@ namespace Ryujinx.BuildValidationTasks
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isGitRunner && encounteredIssue)
|
if (isGitRunner && encounteredIssue)
|
||||||
throw new JsonException("1 or more locales are invalid!");
|
throw new JsonException("1 or more locales are invalid! Rebuild locally to fix...");
|
||||||
|
|
||||||
string jsonString = JsonSerializer.Serialize(json, _jsonOptions);
|
string jsonString = JsonSerializer.Serialize(json, _jsonOptions);
|
||||||
|
|
||||||
@ -102,6 +102,7 @@ namespace Ryujinx.BuildValidationTasks
|
|||||||
|
|
||||||
struct LocalesJson
|
struct LocalesJson
|
||||||
{
|
{
|
||||||
|
public Dictionary<string, string> Info { get; set; }
|
||||||
public List<string> Languages { get; set; }
|
public List<string> Languages { get; set; }
|
||||||
public List<LocalesEntry> Locales { get; set; }
|
public List<LocalesEntry> Locales { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,18 @@
|
|||||||
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
|
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
|
||||||
Command="dotnet Ryujinx.BuildValidationTasks.dll "$(ProjectDir)..\..\\""
|
Command="dotnet Ryujinx.BuildValidationTasks.dll "$(ProjectDir)..\..\\""
|
||||||
ConsoleToMsBuild="true"
|
ConsoleToMsBuild="true"
|
||||||
Condition="'$(RuntimeIdentifier)' == ''"
|
Condition="'$(RuntimeIdentifier)' == ''"
|
||||||
/>
|
IgnoreExitCode="true">
|
||||||
|
<Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
|
||||||
|
<Output TaskParameter="ExitCode" PropertyName="BuildExitCode"/>
|
||||||
|
</Exec>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(OutputOfExec.IndexOf(Unhandled exception))' != '-1'">
|
||||||
|
<ErrorOutput>$(OutputOfExec.Substring($(OutputOfExec.IndexOf("Unhandled exception"))))</ErrorOutput>
|
||||||
|
<ErrorOutput>$(ErrorOutput.Substring(0, $(ErrorOutput.IndexOf(';'))))</ErrorOutput>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Error Text="$(ErrorOutput)" Condition=" '$(BuildExitCode)' != '0'"/>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -93,6 +93,7 @@ namespace Ryujinx.Common
|
|||||||
//The Pokémon Franchise
|
//The Pokémon Franchise
|
||||||
"0100f4300bf2c000", // New Pokémon Snap
|
"0100f4300bf2c000", // New Pokémon Snap
|
||||||
"0100000011d90000", // Pokémon Brilliant Diamond
|
"0100000011d90000", // Pokémon Brilliant Diamond
|
||||||
|
"010008c01e742000", // Pokémon Friends
|
||||||
"01001f5010dfa000", // Pokémon Legends: Arceus
|
"01001f5010dfa000", // Pokémon Legends: Arceus
|
||||||
"01003d200baa2000", // Pokémon Mystery Dungeon - Rescue Team DX
|
"01003d200baa2000", // Pokémon Mystery Dungeon - Rescue Team DX
|
||||||
"0100a3d008c5c000", // Pokémon Scarlet
|
"0100a3d008c5c000", // Pokémon Scarlet
|
||||||
@ -195,6 +196,7 @@ namespace Ryujinx.Common
|
|||||||
"01008d100d43e000", // Saints Row IV
|
"01008d100d43e000", // Saints Row IV
|
||||||
"0100de600beee000", // Saints Row: The Third - The Full Package
|
"0100de600beee000", // Saints Row: The Third - The Full Package
|
||||||
"01001180021fa000", // Shovel Knight: Specter of Torment
|
"01001180021fa000", // Shovel Knight: Specter of Torment
|
||||||
|
"0100e1D01eb2e000", // Squeakross: Home Squeak Home
|
||||||
"0100e65002bb8000", // Stardew Valley
|
"0100e65002bb8000", // Stardew Valley
|
||||||
"0100d7a01b7a2000", // Star Wars: Bounty Hunter
|
"0100d7a01b7a2000", // Star Wars: Bounty Hunter
|
||||||
"0100800015926000", // Suika Game
|
"0100800015926000", // Suika Game
|
||||||
|
@ -21,6 +21,21 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
|
|||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CommandCmif(3)] // 20.0.0+
|
||||||
|
// CreateLibraryAppletEx(u32, u32, u64) -> object<nn::am::service::ILibraryAppletAccessor>
|
||||||
|
public ResultCode CreateLibraryAppletEx(ServiceCtx context)
|
||||||
|
{
|
||||||
|
AppletId appletId = (AppletId)context.RequestData.ReadInt32();
|
||||||
|
|
||||||
|
_ = context.RequestData.ReadInt32(); // libraryAppletMode
|
||||||
|
|
||||||
|
_ = context.RequestData.ReadUInt64(); // threadId
|
||||||
|
|
||||||
|
MakeObject(context, new ILibraryAppletAccessor(appletId, context.Device.System));
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
[CommandCmif(10)]
|
[CommandCmif(10)]
|
||||||
// CreateStorage(u64) -> object<nn::am::service::IStorage>
|
// CreateStorage(u64) -> object<nn::am::service::IStorage>
|
||||||
public ResultCode CreateStorage(ServiceCtx context)
|
public ResultCode CreateStorage(ServiceCtx context)
|
||||||
|
@ -885,7 +885,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
|||||||
// F_SETFL
|
// F_SETFL
|
||||||
else if (cmd == 0x4)
|
else if (cmd == 0x4)
|
||||||
{
|
{
|
||||||
socket.Blocking = (arg & 0x800) != 0;
|
socket.Blocking = (arg & 0x800) == 0;
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
namespace Ryujinx.Ava.Common.Models.Github
|
|
||||||
{
|
|
||||||
public class GithubReleaseAssetJsonResponse
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string State { get; set; }
|
|
||||||
public string BrowserDownloadUrl { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Common.Models.Github
|
|
||||||
{
|
|
||||||
public class GithubReleasesJsonResponse
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public string TagName { get; set; }
|
|
||||||
public List<GithubReleaseAssetJsonResponse> Assets { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Common.Models.Github
|
|
||||||
{
|
|
||||||
[JsonSerializable(typeof(GithubReleasesJsonResponse), GenerationMode = JsonSourceGenerationMode.Metadata)]
|
|
||||||
public partial class GithubReleasesJsonSerializerContext : JsonSerializerContext;
|
|
||||||
}
|
|
@ -65,12 +65,15 @@
|
|||||||
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
||||||
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" />
|
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" />
|
||||||
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'win-arm64'" />
|
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'win-arm64'" />
|
||||||
|
<PackageReference Include="Ryujinx.UpdateClient" />
|
||||||
|
<PackageReference Include="Ryujinx.Systems.Update.Common" />
|
||||||
<PackageReference Include="securifybv.ShellLink" />
|
<PackageReference Include="securifybv.ShellLink" />
|
||||||
<PackageReference Include="Sep" />
|
<PackageReference Include="Sep" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan" />
|
<PackageReference Include="Silk.NET.Vulkan" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
|
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
|
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
|
||||||
<PackageReference Include="SPB" />
|
<PackageReference Include="SPB" />
|
||||||
|
<PackageReference Include="Starscript.Net"/>
|
||||||
<PackageReference Include="SharpZipLib" />
|
<PackageReference Include="SharpZipLib" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
|
|
||||||
private readonly long _ticksPerFrame;
|
private readonly long _ticksPerFrame;
|
||||||
private readonly Stopwatch _chrono;
|
private readonly Stopwatch _chrono;
|
||||||
|
private readonly Stopwatch _playTimer;
|
||||||
private long _ticks;
|
private long _ticks;
|
||||||
|
|
||||||
private readonly AccountManager _accountManager;
|
private readonly AccountManager _accountManager;
|
||||||
@ -175,6 +176,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
|
|
||||||
_chrono = new Stopwatch();
|
_chrono = new Stopwatch();
|
||||||
_ticksPerFrame = Stopwatch.Frequency / TargetFps;
|
_ticksPerFrame = Stopwatch.Frequency / TargetFps;
|
||||||
|
_playTimer = new Stopwatch();
|
||||||
|
|
||||||
if (ApplicationPath.StartsWith("@SystemContent"))
|
if (ApplicationPath.StartsWith("@SystemContent"))
|
||||||
{
|
{
|
||||||
@ -565,6 +567,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
_isActive = false;
|
_isActive = false;
|
||||||
|
_playTimer.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Exit()
|
private void Exit()
|
||||||
@ -616,7 +619,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
private void Dispose()
|
private void Dispose()
|
||||||
{
|
{
|
||||||
if (Device.Processes != null)
|
if (Device.Processes != null)
|
||||||
MainWindowViewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText);
|
MainWindowViewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText, _playTimer.Elapsed);
|
||||||
|
|
||||||
ConfigurationState.Instance.System.IgnoreMissingServices.Event -= UpdateIgnoreMissingServicesState;
|
ConfigurationState.Instance.System.IgnoreMissingServices.Event -= UpdateIgnoreMissingServicesState;
|
||||||
ConfigurationState.Instance.Graphics.AspectRatio.Event -= UpdateAspectRatioState;
|
ConfigurationState.Instance.Graphics.AspectRatio.Event -= UpdateAspectRatioState;
|
||||||
@ -635,6 +638,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
_gpuCancellationTokenSource.Dispose();
|
_gpuCancellationTokenSource.Dispose();
|
||||||
|
|
||||||
_chrono.Stop();
|
_chrono.Stop();
|
||||||
|
_playTimer.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisposeGpu()
|
public void DisposeGpu()
|
||||||
@ -868,6 +872,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText,
|
ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText,
|
||||||
appMetadata => appMetadata.UpdatePreGame()
|
appMetadata => appMetadata.UpdatePreGame()
|
||||||
);
|
);
|
||||||
|
_playTimer.Start();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -877,6 +882,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
Device?.System.TogglePauseEmulation(false);
|
Device?.System.TogglePauseEmulation(false);
|
||||||
|
|
||||||
_viewModel.IsPaused = false;
|
_viewModel.IsPaused = false;
|
||||||
|
_playTimer.Start();
|
||||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI);
|
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI);
|
||||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed");
|
Logger.Info?.Print(LogClass.Emulation, "Emulation was resumed");
|
||||||
}
|
}
|
||||||
@ -886,6 +892,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
Device?.System.TogglePauseEmulation(true);
|
Device?.System.TogglePauseEmulation(true);
|
||||||
|
|
||||||
_viewModel.IsPaused = true;
|
_viewModel.IsPaused = true;
|
||||||
|
_playTimer.Stop();
|
||||||
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI, LocaleManager.Instance[LocaleKeys.Paused]);
|
_viewModel.Title = TitleHelper.ActiveApplicationTitle(Device?.Processes.ActiveApplication, Program.Version, !ConfigurationState.Instance.ShowOldUI, LocaleManager.Instance[LocaleKeys.Paused]);
|
||||||
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused");
|
Logger.Info?.Print(LogClass.Emulation, "Emulation was paused");
|
||||||
}
|
}
|
||||||
@ -1152,6 +1159,24 @@ namespace Ryujinx.Ava.Systems
|
|||||||
|
|
||||||
_dialogShown = true;
|
_dialogShown = true;
|
||||||
|
|
||||||
|
// The hard-coded hotkey mapped to exit is Escape, but it's also the same key
|
||||||
|
// that causes the dialog we launch to close (without doing anything). In release
|
||||||
|
// mode, a race is observed that between ShowExitPrompt() appearing on KeyDown
|
||||||
|
// and the ContentDialog we create seeing the key state before KeyUp. Merely waiting
|
||||||
|
// for the key to no longer be pressed appears to be insufficient.
|
||||||
|
// NB: Using _keyboardInterface.IsPressed(Key.Escape) does not currently work.
|
||||||
|
if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
while (GetAsyncKeyState(0x1B) != 0)
|
||||||
|
{
|
||||||
|
await Task.Delay(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Task.Delay(250);
|
||||||
|
}
|
||||||
|
|
||||||
shouldExit = await ContentDialogHelper.CreateStopEmulationDialog();
|
shouldExit = await ContentDialogHelper.CreateStopEmulationDialog();
|
||||||
|
|
||||||
_dialogShown = false;
|
_dialogShown = false;
|
||||||
|
@ -14,6 +14,7 @@ using LibHac.Tools.FsSystem.NcaUtils;
|
|||||||
using Ryujinx.Ava.Common.Models;
|
using Ryujinx.Ava.Common.Models;
|
||||||
using Ryujinx.Ava.Systems.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
using Ryujinx.Ava.Systems.Configuration.System;
|
using Ryujinx.Ava.Systems.Configuration.System;
|
||||||
|
using Ryujinx.Ava.Systems.Starscript;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
@ -25,6 +26,7 @@ using Ryujinx.HLE.HOS.SystemState;
|
|||||||
using Ryujinx.HLE.Loaders.Npdm;
|
using Ryujinx.HLE.Loaders.Npdm;
|
||||||
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
||||||
using Ryujinx.HLE.Utilities;
|
using Ryujinx.HLE.Utilities;
|
||||||
|
using Starscript;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -41,7 +43,7 @@ using TimeSpan = System.TimeSpan;
|
|||||||
|
|
||||||
namespace Ryujinx.Ava.Systems.AppLibrary
|
namespace Ryujinx.Ava.Systems.AppLibrary
|
||||||
{
|
{
|
||||||
public class ApplicationLibrary
|
public class ApplicationLibrary : IStarscriptObject
|
||||||
{
|
{
|
||||||
public Language DesiredLanguage { get; set; }
|
public Language DesiredLanguage { get; set; }
|
||||||
public event EventHandler<ApplicationCountUpdatedEventArgs> ApplicationCountUpdated;
|
public event EventHandler<ApplicationCountUpdatedEventArgs> ApplicationCountUpdated;
|
||||||
@ -1611,5 +1613,14 @@ namespace Ryujinx.Ava.Systems.AppLibrary
|
|||||||
ApplicationData newApplication = newApplications.First(it => it.IdBase == appIdBase);
|
ApplicationData newApplication = newApplications.First(it => it.IdBase == appIdBase);
|
||||||
_applications.AddOrUpdate(newApplication);
|
_applications.AddOrUpdate(newApplication);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ValueMap _starscriptMap;
|
||||||
|
|
||||||
|
public ValueMap ToStarscript()
|
||||||
|
{
|
||||||
|
_starscriptMap ??= StarscriptHelper.Wrap(this);
|
||||||
|
|
||||||
|
return _starscriptMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,19 +33,11 @@ namespace Ryujinx.Ava.Systems.AppLibrary
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates <see cref="LastPlayed"/> and <see cref="TimePlayed"/>. Call this after a game ends.
|
/// Updates <see cref="LastPlayed"/> and <see cref="TimePlayed"/>. Call this after a game ends.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdatePostGame()
|
/// <param name="playTime">The active gameplay time this past session.</param>
|
||||||
|
public void UpdatePostGame(TimeSpan playTime)
|
||||||
{
|
{
|
||||||
DateTime? prevLastPlayed = LastPlayed;
|
|
||||||
UpdatePreGame();
|
UpdatePreGame();
|
||||||
|
TimePlayed += playTime;
|
||||||
if (!prevLastPlayed.HasValue)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeSpan diff = DateTime.UtcNow - prevLastPlayed.Value;
|
|
||||||
double newTotalSeconds = TimePlayed.Add(diff).TotalSeconds;
|
|
||||||
TimePlayed = TimeSpan.FromSeconds(Math.Round(newTotalSeconds, MidpointRounding.AwayFromZero));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
src/Ryujinx/Systems/Starscript/RyujinxStarscript.cs
Normal file
29
src/Ryujinx/Systems/Starscript/RyujinxStarscript.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
|
using Ryujinx.Common;
|
||||||
|
using Starscript;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.Systems.Starscript
|
||||||
|
{
|
||||||
|
public static class RyujinxStarscript
|
||||||
|
{
|
||||||
|
public static readonly StarscriptHypervisor Hypervisor = StarscriptHypervisor.Create().WithStandardLibrary(true);
|
||||||
|
|
||||||
|
static RyujinxStarscript()
|
||||||
|
{
|
||||||
|
Hypervisor.Set("ryujinx.releaseChannel",
|
||||||
|
ReleaseInformation.IsCanaryBuild
|
||||||
|
? "Canary"
|
||||||
|
: ReleaseInformation.IsReleaseBuild
|
||||||
|
? "Stable"
|
||||||
|
: "Custom");
|
||||||
|
Hypervisor.Set("ryujinx.version", Program.Version);
|
||||||
|
Hypervisor.Set("appLibrary", RyujinxApp.MainWindow.ApplicationLibrary);
|
||||||
|
Hypervisor.Set("currentApplication", () =>
|
||||||
|
RyujinxApp.MainWindow.ApplicationLibrary.FindApplication(
|
||||||
|
RyujinxApp.MainWindow.ViewModel.AppHost?.ApplicationId ?? 0,
|
||||||
|
out ApplicationData appData)
|
||||||
|
? StarscriptHelper.Wrap(appData)
|
||||||
|
: Value.Null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
68
src/Ryujinx/Systems/Starscript/StarscriptHelper.cs
Normal file
68
src/Ryujinx/Systems/Starscript/StarscriptHelper.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using Gommon;
|
||||||
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
|
using Starscript;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.Systems.Starscript
|
||||||
|
{
|
||||||
|
public static class StarscriptHelper
|
||||||
|
{
|
||||||
|
public static ValueMap Wrap(ApplicationLibrary appLib)
|
||||||
|
{
|
||||||
|
ValueMap lMap = new();
|
||||||
|
lMap.Set("appCount", () => appLib.Applications.Count);
|
||||||
|
lMap.Set("dlcCount", () => appLib.DownloadableContents.Count);
|
||||||
|
lMap.Set("updateCount", () => appLib.TitleUpdates.Count);
|
||||||
|
lMap.Set("has", ctx =>
|
||||||
|
{
|
||||||
|
ulong titleId;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
titleId = ctx.Constrain(Constraint.ExactlyOneArgument).NextString(1).ToULong();
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
throw ctx.Error(
|
||||||
|
$"Invalid input to {ctx.FormattedName}; input must be a hexadecimal number in a string.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return appLib.FindApplication(titleId, out _);
|
||||||
|
});
|
||||||
|
lMap.Set("get", ctx =>
|
||||||
|
{
|
||||||
|
ulong titleId;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
titleId = ctx.Constrain(Constraint.ExactlyOneArgument).NextString(1).ToULong();
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
throw ctx.Error(
|
||||||
|
$"Invalid input to {ctx.FormattedName}; input must be a hexadecimal number in a string.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return appLib.FindApplication(titleId,
|
||||||
|
out ApplicationData applicationData)
|
||||||
|
? Wrap(applicationData)
|
||||||
|
: null;
|
||||||
|
});
|
||||||
|
return lMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValueMap Wrap(ApplicationData appData)
|
||||||
|
{
|
||||||
|
ValueMap aMap = new();
|
||||||
|
aMap.Set("name", appData.Name);
|
||||||
|
aMap.Set("version", appData.Version);
|
||||||
|
aMap.Set("developer", appData.Developer);
|
||||||
|
aMap.Set("fileExtension", appData.FileExtension);
|
||||||
|
aMap.Set("fileSize", appData.FileSizeString);
|
||||||
|
aMap.Set("hasLdnGames", appData.HasLdnGames);
|
||||||
|
aMap.Set("timePlayed", appData.TimePlayedString);
|
||||||
|
aMap.Set("isFavorite", appData.Favorite);
|
||||||
|
return aMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
src/Ryujinx/Systems/Starscript/StarscriptTextBox.axaml
Normal file
21
src/Ryujinx/Systems/Starscript/StarscriptTextBox.axaml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:local="using:Ryujinx.Ava.Systems.Starscript"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Ryujinx.Ava.Systems.Starscript.StarscriptTextBox"
|
||||||
|
x:DataType="local:StarscriptTextBoxViewModel">
|
||||||
|
<StackPanel Spacing="10">
|
||||||
|
<TextBlock Text="{Binding ErrorMessage}" IsVisible="{Binding HasError}"/>
|
||||||
|
<TextBlock Text="{Binding CurrentScriptResult}" IsVisible="{Binding !HasError}"/>
|
||||||
|
<AutoCompleteBox Name="InputBox"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
FilterMode="Custom"
|
||||||
|
MinimumPrefixLength="0"
|
||||||
|
MaxDropDownHeight="400">
|
||||||
|
</AutoCompleteBox>
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
||||||
|
|
87
src/Ryujinx/Systems/Starscript/StarscriptTextBox.axaml.cs
Normal file
87
src/Ryujinx/Systems/Starscript/StarscriptTextBox.axaml.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Styling;
|
||||||
|
using FluentAvalonia.UI.Controls;
|
||||||
|
using Humanizer;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
using Ryujinx.Ava.UI.Controls;
|
||||||
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
|
using Starscript;
|
||||||
|
using Starscript.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.Systems.Starscript
|
||||||
|
{
|
||||||
|
public partial class StarscriptTextBox : RyujinxControl<StarscriptTextBoxViewModel>
|
||||||
|
{
|
||||||
|
public IReadOnlyList<string> CurrentSuggestions => ViewModel.CurrentSuggestions;
|
||||||
|
|
||||||
|
public ParserResult CurrentScriptSource => ViewModel.CurrentScriptSource;
|
||||||
|
public Exception Exception => ViewModel.Exception;
|
||||||
|
public Script CurrentScript => ViewModel.CurrentScript;
|
||||||
|
public StringSegment CurrentScriptResult => ViewModel.CurrentScriptResult;
|
||||||
|
|
||||||
|
public StarscriptTextBox()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
InputBox.AsyncPopulator = GetSuggestionsAsync;
|
||||||
|
InputBox.MinimumPopulateDelay = 0.Seconds();
|
||||||
|
InputBox.TextFilter = (_, _) => true;
|
||||||
|
InputBox.TextSelector = (text, suggestion) =>
|
||||||
|
{
|
||||||
|
if (text is not null && suggestion is null)
|
||||||
|
return text;
|
||||||
|
if (text is null && suggestion is not null)
|
||||||
|
return suggestion;
|
||||||
|
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
|
||||||
|
if (text is null && suggestion is null)
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
var sb = new StringBuilder(text.Length + suggestion.Length + 1);
|
||||||
|
sb.Append(text);
|
||||||
|
|
||||||
|
for (int i = 0; i < suggestion.Length - 1; i++)
|
||||||
|
{
|
||||||
|
if (text.EndsWith(suggestion[..(suggestion.Length - i - 1)]))
|
||||||
|
{
|
||||||
|
suggestion = suggestion[(suggestion.Length - i - 1)..];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Append(suggestion);
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
};
|
||||||
|
|
||||||
|
Style textStyle = new(x => x.OfType<AutoCompleteBox>().Descendant().OfType<TextBlock>());
|
||||||
|
textStyle.Setters.Add(new Setter(MarginProperty, new Thickness(0, 0)));
|
||||||
|
|
||||||
|
Styles.Add(textStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<IEnumerable<object>> GetSuggestionsAsync(string input, CancellationToken token)
|
||||||
|
=> Task.FromResult(ViewModel.GetSuggestions(input, token));
|
||||||
|
|
||||||
|
public static StarscriptTextBox Create(StarscriptHypervisor hv)
|
||||||
|
=> new() { ViewModel = new StarscriptTextBoxViewModel(hv) };
|
||||||
|
|
||||||
|
public static async Task Show()
|
||||||
|
{
|
||||||
|
ContentDialog contentDialog = new()
|
||||||
|
{
|
||||||
|
PrimaryButtonText = string.Empty,
|
||||||
|
SecondaryButtonText = string.Empty,
|
||||||
|
CloseButtonText = LocaleManager.Instance[LocaleKeys.UserProfilesClose],
|
||||||
|
Content = new StarscriptTextBox { ViewModel = new() }
|
||||||
|
};
|
||||||
|
|
||||||
|
await ContentDialogHelper.ShowAsync(contentDialog.ApplyStyles());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
126
src/Ryujinx/Systems/Starscript/StarscriptTextBoxViewModel.cs
Normal file
126
src/Ryujinx/Systems/Starscript/StarscriptTextBoxViewModel.cs
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using Starscript;
|
||||||
|
using Starscript.Internal;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.Systems.Starscript
|
||||||
|
{
|
||||||
|
public partial class StarscriptTextBoxViewModel : BaseModel
|
||||||
|
{
|
||||||
|
private readonly StarscriptHypervisor _hv;
|
||||||
|
|
||||||
|
public StarscriptTextBoxViewModel(StarscriptHypervisor hv = null)
|
||||||
|
{
|
||||||
|
_hv = hv ?? RyujinxStarscript.Hypervisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<string> CurrentSuggestions { get; } = [];
|
||||||
|
|
||||||
|
[ObservableProperty] private bool _hasError;
|
||||||
|
[ObservableProperty] private StringSegment _currentScriptResult;
|
||||||
|
[ObservableProperty] private string _errorMessage;
|
||||||
|
private Exception _exception;
|
||||||
|
private ParserResult _currentScriptSource;
|
||||||
|
private Script _currentScript;
|
||||||
|
|
||||||
|
public Exception Exception
|
||||||
|
{
|
||||||
|
get => _exception;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ErrorMessage = (_exception = value) switch
|
||||||
|
{
|
||||||
|
ParseException pe => pe.Error.ToString(),
|
||||||
|
StarscriptException se => se.Message,
|
||||||
|
_ => string.Empty
|
||||||
|
};
|
||||||
|
|
||||||
|
HasError = value is not null;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParserResult CurrentScriptSource
|
||||||
|
{
|
||||||
|
get => _currentScriptSource;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_currentScriptSource = value;
|
||||||
|
|
||||||
|
if (value is null)
|
||||||
|
{
|
||||||
|
CurrentScript = null;
|
||||||
|
CurrentScriptResult = null;
|
||||||
|
Exception = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentScript = Compiler.SingleCompile(value);
|
||||||
|
Exception = null;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Script CurrentScript
|
||||||
|
{
|
||||||
|
get => _currentScript;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CurrentScriptResult = value?.Execute(_hv)!;
|
||||||
|
_currentScript = value;
|
||||||
|
Exception = null;
|
||||||
|
}
|
||||||
|
catch (StarscriptException se)
|
||||||
|
{
|
||||||
|
_currentScript = null;
|
||||||
|
CurrentScriptResult = null;
|
||||||
|
Exception = se;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReExecuteScript()
|
||||||
|
{
|
||||||
|
if (_currentScript is null) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CurrentScriptResult = _currentScript.Execute(_hv)!;
|
||||||
|
}
|
||||||
|
catch (StarscriptException se)
|
||||||
|
{
|
||||||
|
CurrentScriptResult = null;
|
||||||
|
Exception = se;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<object> GetSuggestions(string input, CancellationToken token)
|
||||||
|
{
|
||||||
|
CurrentSuggestions.Clear();
|
||||||
|
|
||||||
|
CurrentScriptSource = _hv.ParseAndGetCompletions(input, input.Length, CompletionCallback, token);
|
||||||
|
|
||||||
|
if (CurrentScriptSource.HasErrors)
|
||||||
|
{
|
||||||
|
Exception = new ParseException(CurrentScriptSource.Errors.First());
|
||||||
|
}
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(CurrentSuggestions));
|
||||||
|
|
||||||
|
return CurrentSuggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CompletionCallback(string result, bool isFunction) => CurrentSuggestions.Add(isFunction ? $"{result}(" : result);
|
||||||
|
}
|
||||||
|
}
|
@ -4,42 +4,26 @@ using Ryujinx.Ava.UI.Helpers;
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Systems.Update.Client;
|
||||||
|
using Ryujinx.Systems.Update.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Json;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Systems
|
namespace Ryujinx.Ava.Systems
|
||||||
{
|
{
|
||||||
internal static partial class Updater
|
internal static partial class Updater
|
||||||
{
|
{
|
||||||
private static string CreateUpdateQueryUrl()
|
private static VersionResponse _versionResponse;
|
||||||
{
|
|
||||||
#pragma warning disable CS8524
|
|
||||||
var os = RunningPlatform.CurrentOS switch
|
|
||||||
#pragma warning restore CS8524
|
|
||||||
{
|
|
||||||
OperatingSystemType.MacOS => "mac",
|
|
||||||
OperatingSystemType.Linux => "linux",
|
|
||||||
OperatingSystemType.Windows => "win"
|
|
||||||
};
|
|
||||||
|
|
||||||
var arch = RunningPlatform.Architecture switch
|
private static UpdateClient CreateUpdateClient()
|
||||||
{
|
=> UpdateClient.Builder()
|
||||||
Architecture.Arm64 => "arm",
|
.WithServerEndpoint("https://update.ryujinx.app") // This is the default, and doesn't need to be provided; it's here for transparency.
|
||||||
Architecture.X64 => "amd64",
|
.WithLogger((format, args, caller) =>
|
||||||
_ => null
|
Logger.Info?.Print(
|
||||||
};
|
LogClass.Application,
|
||||||
|
args.Length is 0 ? format : format.Format(args),
|
||||||
if (arch is null)
|
caller: caller)
|
||||||
return null;
|
);
|
||||||
|
|
||||||
var rc = ReleaseInformation.IsCanaryBuild ? "canary" : "stable";
|
|
||||||
|
|
||||||
return $"https://update.ryujinx.app/latest/query?os={os}&arch={arch}&rc={rc}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<Optional<(Version Current, Version Incoming)>> CheckVersionAsync(bool showVersionUpToDate = false)
|
public static async Task<Optional<(Version Current, Version Incoming)>> CheckVersionAsync(bool showVersionUpToDate = false)
|
||||||
{
|
{
|
||||||
@ -57,39 +41,31 @@ namespace Ryujinx.Ava.Systems
|
|||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CreateUpdateQueryUrl() is not {} updateUrl)
|
using UpdateClient updateClient = CreateUpdateClient();
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, "Could not determine URL for updates.");
|
|
||||||
|
|
||||||
_running = false;
|
|
||||||
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, $"Checking for updates from {updateUrl}.");
|
|
||||||
|
|
||||||
// Get latest version number from update.ryujinx.app API
|
|
||||||
using HttpClient jsonClient = ConstructHttpClient();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UpdaterResponse response =
|
_versionResponse = await updateClient.QueryLatestAsync(ReleaseInformation.IsCanaryBuild
|
||||||
await jsonClient.GetFromJsonAsync(updateUrl, UpdaterResponseJsonContext.Default.UpdaterResponse);
|
? ReleaseChannel.Canary
|
||||||
|
: ReleaseChannel.Stable);
|
||||||
_buildVer = response.Tag;
|
|
||||||
_buildUrl = response.DownloadUrl;
|
|
||||||
_changelogUrlFormat = response.ReleaseUrlFormat;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application, $"An error occurred when parsing JSON response from API ({e.GetType().AsFullNamePrettyString()}): {e.Message}");
|
Logger.Error?.Print(LogClass.Application, $"An error occurred when requesting for updates ({e.GetType().AsFullNamePrettyString()}): {e.Message}");
|
||||||
|
|
||||||
_running = false;
|
_running = false;
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_versionResponse == null)
|
||||||
|
{
|
||||||
|
// logging is done via the UpdateClient library
|
||||||
|
_running = false;
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
// If build URL not found, assume no new update is available.
|
// If build URL not found, assume no new update is available.
|
||||||
if (_buildUrl is null or "")
|
if (_versionResponse.ArtifactUrl is null or "")
|
||||||
{
|
{
|
||||||
if (showVersionUpToDate)
|
if (showVersionUpToDate)
|
||||||
{
|
{
|
||||||
@ -99,7 +75,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
|
|
||||||
if (userResult is UserResult.Ok)
|
if (userResult is UserResult.Ok)
|
||||||
{
|
{
|
||||||
OpenHelper.OpenUrl(_changelogUrlFormat.Format(currentVersion));
|
OpenHelper.OpenUrl(_versionResponse.ReleaseUrlFormat.Format(currentVersion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +87,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!Version.TryParse(_buildVer, out Version newVersion))
|
if (!Version.TryParse(_versionResponse.Version, out Version newVersion))
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application,
|
Logger.Error?.Print(LogClass.Application,
|
||||||
$"Failed to convert the received {RyujinxApp.FullAppName} version from the update server!");
|
$"Failed to convert the received {RyujinxApp.FullAppName} version from the update server!");
|
||||||
@ -127,17 +103,5 @@ namespace Ryujinx.Ava.Systems
|
|||||||
|
|
||||||
return (currentVersion, newVersion);
|
return (currentVersion, newVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonSerializable(typeof(UpdaterResponse))]
|
|
||||||
partial class UpdaterResponseJsonContext : JsonSerializerContext;
|
|
||||||
|
|
||||||
public class UpdaterResponse
|
|
||||||
{
|
|
||||||
[JsonPropertyName("tag")] public string Tag { get; set; }
|
|
||||||
[JsonPropertyName("download_url")] public string DownloadUrl { get; set; }
|
|
||||||
[JsonPropertyName("web_url")] public string ReleaseUrl { get; set; }
|
|
||||||
|
|
||||||
[JsonIgnore] public string ReleaseUrlFormat => ReleaseUrl.Replace(Tag, "{0}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,11 @@ using ICSharpCode.SharpZipLib.GZip;
|
|||||||
using ICSharpCode.SharpZipLib.Tar;
|
using ICSharpCode.SharpZipLib.Tar;
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Common.Models.Github;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@ -35,17 +33,13 @@ namespace Ryujinx.Ava.Systems
|
|||||||
private static readonly string _updateDir = Path.Combine(Path.GetTempPath(), "Ryujinx", "update");
|
private static readonly string _updateDir = Path.Combine(Path.GetTempPath(), "Ryujinx", "update");
|
||||||
private static readonly string _updatePublishDir = Path.Combine(_updateDir, "publish");
|
private static readonly string _updatePublishDir = Path.Combine(_updateDir, "publish");
|
||||||
private const int ConnectionCount = 4;
|
private const int ConnectionCount = 4;
|
||||||
|
|
||||||
private static string _buildVer;
|
|
||||||
private static string _buildUrl;
|
|
||||||
private static long _buildSize;
|
private static long _buildSize;
|
||||||
private static bool _updateSuccessful;
|
private static bool _updateSuccessful;
|
||||||
private static bool _running;
|
private static bool _running;
|
||||||
|
|
||||||
private static readonly string[] _windowsDependencyDirs = [];
|
private static readonly string[] _windowsDependencyDirs = [];
|
||||||
|
|
||||||
private static string _changelogUrlFormat = null;
|
|
||||||
|
|
||||||
public static async Task BeginUpdateAsync(bool showVersionUpToDate = false)
|
public static async Task BeginUpdateAsync(bool showVersionUpToDate = false)
|
||||||
{
|
{
|
||||||
if (_running)
|
if (_running)
|
||||||
@ -72,7 +66,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
|
|
||||||
if (userResult is UserResult.Ok)
|
if (userResult is UserResult.Ok)
|
||||||
{
|
{
|
||||||
OpenHelper.OpenUrl(_changelogUrlFormat.Format(currentVersion));
|
OpenHelper.OpenUrl(_versionResponse.ReleaseUrlFormat.Format(currentVersion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +86,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
// GitLab instance is located in Ukraine. Connection times will vary across the world.
|
// GitLab instance is located in Ukraine. Connection times will vary across the world.
|
||||||
buildSizeClient.Timeout = TimeSpan.FromSeconds(10);
|
buildSizeClient.Timeout = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
HttpResponseMessage message = await buildSizeClient.GetAsync(new Uri(_buildUrl), HttpCompletionOption.ResponseHeadersRead);
|
HttpResponseMessage message = await buildSizeClient.GetAsync(new Uri(_versionResponse.ArtifactUrl), HttpCompletionOption.ResponseHeadersRead);
|
||||||
|
|
||||||
_buildSize = message.Content.Headers.ContentRange.Length.Value;
|
_buildSize = message.Content.Headers.ContentRange.Length.Value;
|
||||||
}
|
}
|
||||||
@ -122,7 +116,7 @@ namespace Ryujinx.Ava.Systems
|
|||||||
switch (shouldUpdate)
|
switch (shouldUpdate)
|
||||||
{
|
{
|
||||||
case UserResult.Yes:
|
case UserResult.Yes:
|
||||||
await UpdateRyujinx(_buildUrl);
|
await UpdateRyujinx(_versionResponse.ArtifactUrl);
|
||||||
break;
|
break;
|
||||||
// Secondary button maps to no, which in this case is the show changelog button.
|
// Secondary button maps to no, which in this case is the show changelog button.
|
||||||
case UserResult.No:
|
case UserResult.No:
|
||||||
|
29
src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml
Normal file → Executable file
29
src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml
Normal file → Executable file
@ -41,32 +41,34 @@
|
|||||||
Command="{Binding OpenApplicationCompatibility}"
|
Command="{Binding OpenApplicationCompatibility}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuShowCompatEntry}"
|
Header="{ext:Locale GameListContextMenuShowCompatEntry}"
|
||||||
Icon="{ext:Icon mdi-gamepad}"
|
Icon="{ext:Icon fa-solid fa-database}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuShowCompatEntryToolTip}"/>
|
ToolTip.Tip="{ext:Locale GameListContextMenuShowCompatEntryToolTip}"/>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenApplicationData}"
|
Command="{Binding OpenApplicationData}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuShowGameData}"
|
Header="{ext:Locale GameListContextMenuShowGameData}"
|
||||||
Icon="{ext:Icon mdi-chart-line}"
|
Icon="{ext:Icon fa-solid fa-chart-line}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuShowGameDataToolTip}"/>
|
ToolTip.Tip="{ext:Locale GameListContextMenuShowGameDataToolTip}"/>
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenUserSaveDirectory}"
|
Command="{Binding OpenUserSaveDirectory}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuOpenUserSaveDirectory}"
|
Header="{ext:Locale GameListContextMenuOpenUserSaveDirectory}"
|
||||||
Icon="{ext:Icon mdi-folder-account}"
|
Icon="{ext:Icon fa-solid fa-sd-card}"
|
||||||
IsEnabled="{Binding OpenUserSaveDirectoryEnabled}"
|
IsEnabled="{Binding OpenUserSaveDirectoryEnabled}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenDeviceSaveDirectory}"
|
Command="{Binding OpenDeviceSaveDirectory}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuOpenDeviceSaveDirectory}"
|
Header="{ext:Locale GameListContextMenuOpenDeviceSaveDirectory}"
|
||||||
|
Icon="{ext:Icon fa-solid fa-hard-drive}"
|
||||||
IsEnabled="{Binding OpenDeviceSaveDirectoryEnabled}"
|
IsEnabled="{Binding OpenDeviceSaveDirectoryEnabled}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuOpenDeviceSaveDirectoryToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuOpenDeviceSaveDirectoryToolTip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenBcatSaveDirectory}"
|
Command="{Binding OpenBcatSaveDirectory}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuOpenBcatSaveDirectory}"
|
Header="{ext:Locale GameListContextMenuOpenBcatSaveDirectory}"
|
||||||
|
Icon="{ext:Icon fa-solid fa-box-archive}"
|
||||||
IsEnabled="{Binding OpenBcatSaveDirectoryEnabled}"
|
IsEnabled="{Binding OpenBcatSaveDirectoryEnabled}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuOpenBcatSaveDirectoryToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuOpenBcatSaveDirectoryToolTip}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
@ -92,20 +94,20 @@
|
|||||||
Command="{Binding OpenModManager}"
|
Command="{Binding OpenModManager}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuManageMod}"
|
Header="{ext:Locale GameListContextMenuManageMod}"
|
||||||
Icon="{ext:Icon mdi-view-module}"
|
Icon="{ext:Icon fa-solid fa-sliders}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuManageModToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuManageModToolTip}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenModsDirectory}"
|
Command="{Binding OpenModsDirectory}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuOpenModsDirectory}"
|
Header="{ext:Locale GameListContextMenuOpenModsDirectory}"
|
||||||
Icon="{ext:Icon mdi-folder-file}"
|
Icon="{ext:Icon fa-solid fa-folder}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenSdModsDirectory}"
|
Command="{Binding OpenSdModsDirectory}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuOpenSdModsDirectory}"
|
Header="{ext:Locale GameListContextMenuOpenSdModsDirectory}"
|
||||||
Icon="{ext:Icon mdi-folder-file}"
|
Icon="{ext:Icon fa-solid fa-folder}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@ -113,40 +115,41 @@
|
|||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuTrimXCI}"
|
Header="{ext:Locale GameListContextMenuTrimXCI}"
|
||||||
IsEnabled="{Binding TrimXCIEnabled}"
|
IsEnabled="{Binding TrimXCIEnabled}"
|
||||||
|
Icon="{ext:Icon fa-solid fa-scissors}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuTrimXCIToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuTrimXCIToolTip}" />
|
||||||
<MenuItem Header="{ext:Locale GameListContextMenuCacheManagement}" Icon="{ext:Icon mdi-cached}">
|
<MenuItem Header="{ext:Locale GameListContextMenuCacheManagement}" Icon="{ext:Icon fa-solid fa-memory}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding PurgePtcCache}"
|
Command="{Binding PurgePtcCache}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuCacheManagementPurgePptc}"
|
Header="{ext:Locale GameListContextMenuCacheManagementPurgePptc}"
|
||||||
Icon="{ext:Icon mdi-refresh}"
|
Icon="{ext:Icon fa-solid fa-arrow-rotate-right}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding NukePtcCache}"
|
Command="{Binding NukePtcCache}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuCacheManagementNukePptc}"
|
Header="{ext:Locale GameListContextMenuCacheManagementNukePptc}"
|
||||||
Icon="{ext:Icon mdi-delete-alert}"
|
Icon="{ext:Icon fa-solid fa-trash-can}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementNukePptcToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementNukePptcToolTip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding PurgeShaderCache}"
|
Command="{Binding PurgeShaderCache}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
|
Header="{ext:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
|
||||||
Icon="{ext:Icon mdi-delete-alert}"
|
Icon="{ext:Icon fa-solid fa-trash-can}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenPtcDirectory}"
|
Command="{Binding OpenPtcDirectory}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
|
Header="{ext:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
|
||||||
Icon="{ext:Icon mdi-folder-arrow-up-down}"
|
Icon="{ext:Icon fa-solid fa-folder}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenShaderCacheDirectory}"
|
Command="{Binding OpenShaderCacheDirectory}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Header="{ext:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
|
Header="{ext:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
|
||||||
Icon="{ext:Icon mdi-folder-arrow-up-down}"
|
Icon="{ext:Icon fa-solid fa-folder}"
|
||||||
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
|
ToolTip.Tip="{ext:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="{ext:Locale GameListContextMenuExtractData}">
|
<MenuItem Header="{ext:Locale GameListContextMenuExtractData}" Icon="{ext:Icon fa-solid fa-file-export}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding ExtractApplicationExeFs}"
|
Command="{Binding ExtractApplicationExeFs}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
|
@ -110,5 +110,8 @@ namespace Ryujinx.Ava.UI.Helpers
|
|||||||
|
|
||||||
[LibraryImport("user32.dll", SetLastError = true)]
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
public static partial nint SetWindowLongPtrW(nint hWnd, int nIndex, nint value);
|
public static partial nint SetWindowLongPtrW(nint hWnd, int nIndex, nint value);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
|
public static partial ushort GetAsyncKeyState(int nVirtKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,10 +310,15 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
|
|
||||||
private void TotalTimePlayed_Recalculated(Optional<TimeSpan> ts)
|
private void TotalTimePlayed_Recalculated(Optional<TimeSpan> ts)
|
||||||
{
|
{
|
||||||
ShowTotalTimePlayed = ts.HasValue;
|
|
||||||
|
|
||||||
if (ts.HasValue)
|
if (ts.HasValue)
|
||||||
LocaleManager.Instance.SetDynamicValues(LocaleKeys.GameListLabelTotalTimePlayed, ValueFormatUtils.FormatTimeSpan(ts.Value));
|
{
|
||||||
|
var formattedPlayTime = ValueFormatUtils.FormatTimeSpan(ts.Value);
|
||||||
|
LocaleManager.Instance.SetDynamicValues(LocaleKeys.GameListLabelTotalTimePlayed, formattedPlayTime);
|
||||||
|
ShowTotalTimePlayed = formattedPlayTime != string.Empty;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowTotalTimePlayed = ts.HasValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ShowTotalTimePlayed
|
public bool ShowTotalTimePlayed
|
||||||
@ -334,7 +339,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
_listSelectedApplication = value;
|
_listSelectedApplication = value;
|
||||||
|
|
||||||
if (_listSelectedApplication != null && ListAppContextMenu == null)
|
if (_listSelectedApplication != null && ListAppContextMenu == null)
|
||||||
|
|
||||||
ListAppContextMenu = new ApplicationContextMenu();
|
ListAppContextMenu = new ApplicationContextMenu();
|
||||||
else if (_listSelectedApplication == null && ListAppContextMenu != null)
|
else if (_listSelectedApplication == null && ListAppContextMenu != null)
|
||||||
ListAppContextMenu = null!;
|
ListAppContextMenu = null!;
|
||||||
@ -1688,8 +1692,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||||||
RendererHostControl.Focus();
|
RendererHostControl.Focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
public static void UpdateGameMetadata(string titleId)
|
public static void UpdateGameMetadata(string titleId, TimeSpan playTime)
|
||||||
=> ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata => appMetadata.UpdatePostGame());
|
=> ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata => appMetadata.UpdatePostGame(playTime));
|
||||||
|
|
||||||
public void RefreshFirmwareStatus()
|
public void RefreshFirmwareStatus()
|
||||||
{
|
{
|
||||||
|
47
src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml
Normal file → Executable file
47
src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml
Normal file → Executable file
@ -37,7 +37,7 @@
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenFolder}"
|
Command="{Binding OpenFolder}"
|
||||||
Header="{ext:Locale MenuBarFileOpenUnpacked}"
|
Header="{ext:Locale MenuBarFileOpenUnpacked}"
|
||||||
Icon="{ext:Icon fa-solid fa-folder}"
|
Icon="{ext:Icon fa-solid fa-folder-open}"
|
||||||
IsEnabled="{Binding EnableNonGameRunningControls}"
|
IsEnabled="{Binding EnableNonGameRunningControls}"
|
||||||
ToolTip.Tip="{ext:Locale LoadApplicationFolderTooltip}" />
|
ToolTip.Tip="{ext:Locale LoadApplicationFolderTooltip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@ -52,7 +52,7 @@
|
|||||||
Icon="{ext:Icon fa-solid fa-code-compare}"
|
Icon="{ext:Icon fa-solid fa-code-compare}"
|
||||||
IsEnabled="{Binding EnableNonGameRunningControls}"
|
IsEnabled="{Binding EnableNonGameRunningControls}"
|
||||||
ToolTip.Tip="{ext:Locale LoadTitleUpdatesFromFolderTooltip}" />
|
ToolTip.Tip="{ext:Locale LoadTitleUpdatesFromFolderTooltip}" />
|
||||||
<MenuItem Header="{ext:Locale MenuBarFileOpenApplet}" IsEnabled="{Binding IsAppletMenuActive}" Icon="{ext:Icon mdi-launch}">
|
<MenuItem Header="{ext:Locale MenuBarFileOpenApplet}" IsEnabled="{Binding IsAppletMenuActive}" Icon="{ext:Icon fa-solid fa-microchip}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="MiiAppletMenuItem"
|
Name="MiiAppletMenuItem"
|
||||||
Header="{ext:Locale MenuBarFileOpenAppletOpenMiiApplet}"
|
Header="{ext:Locale MenuBarFileOpenAppletOpenMiiApplet}"
|
||||||
@ -63,20 +63,23 @@
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenRyujinxFolder}"
|
Command="{Binding OpenRyujinxFolder}"
|
||||||
Header="{ext:Locale MenuBarFileOpenEmuFolder}"
|
Header="{ext:Locale MenuBarFileOpenEmuFolder}"
|
||||||
|
Icon="{ext:Icon fa-solid fa-folder-closed}"
|
||||||
ToolTip.Tip="{ext:Locale OpenRyujinxFolderTooltip}" />
|
ToolTip.Tip="{ext:Locale OpenRyujinxFolderTooltip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenScreenshotsFolder}"
|
Command="{Binding OpenScreenshotsFolder}"
|
||||||
Header="{ext:Locale MenuBarFileOpenScreenshotsFolder}"
|
Header="{ext:Locale MenuBarFileOpenScreenshotsFolder}"
|
||||||
|
Icon="{ext:Icon fa-solid fa-desktop}"
|
||||||
ToolTip.Tip="{ext:Locale OpenScreenshotFolderTooltip}"/>
|
ToolTip.Tip="{ext:Locale OpenScreenshotFolderTooltip}"/>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenLogsFolder}"
|
Command="{Binding OpenLogsFolder}"
|
||||||
Header="{ext:Locale MenuBarFileOpenLogsFolder}"
|
Header="{ext:Locale MenuBarFileOpenLogsFolder}"
|
||||||
|
Icon="{ext:Icon fa-solid fa-file-lines}"
|
||||||
ToolTip.Tip="{ext:Locale OpenRyujinxLogsTooltip}" />
|
ToolTip.Tip="{ext:Locale OpenRyujinxLogsTooltip}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="CloseRyujinxMenuItem"
|
Name="CloseRyujinxMenuItem"
|
||||||
Header="{ext:Locale MenuBarFileExit}"
|
Header="{ext:Locale MenuBarFileExit}"
|
||||||
Icon="{ext:Icon fa-solid fa-xmark}"
|
Icon="{ext:Icon fa-solid fa-power-off}"
|
||||||
ToolTip.Tip="{ext:Locale ExitTooltip}" />
|
ToolTip.Tip="{ext:Locale ExitTooltip}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarOptions}">
|
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarOptions}">
|
||||||
@ -133,7 +136,7 @@
|
|||||||
Name="ChangeLanguageMenuItem"
|
Name="ChangeLanguageMenuItem"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
Header="{ext:Locale MenuBarOptionsChangeLanguage}"
|
Header="{ext:Locale MenuBarOptionsChangeLanguage}"
|
||||||
Icon="{ext:Icon fa-solid fa-language}"
|
Icon="{ext:Icon fa-solid fa-globe}"
|
||||||
Classes="withCheckbox">
|
Classes="withCheckbox">
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@ -153,7 +156,7 @@
|
|||||||
Command="{Binding ManageProfiles}"
|
Command="{Binding ManageProfiles}"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
Header="{ext:Locale MenuBarOptionsManageUserProfiles}"
|
Header="{ext:Locale MenuBarOptionsManageUserProfiles}"
|
||||||
Icon="{ext:Icon mdi-account}"
|
Icon="{ext:Icon fa-solid fa-user}"
|
||||||
IsEnabled="{Binding EnableNonGameRunningControls}"
|
IsEnabled="{Binding EnableNonGameRunningControls}"
|
||||||
ToolTip.Tip="{ext:Locale OpenProfileManagerTooltip}"
|
ToolTip.Tip="{ext:Locale OpenProfileManagerTooltip}"
|
||||||
Classes="withCheckbox">
|
Classes="withCheckbox">
|
||||||
@ -185,33 +188,33 @@
|
|||||||
InputGesture="Escape"
|
InputGesture="Escape"
|
||||||
IsEnabled="{Binding IsGameRunning}"
|
IsEnabled="{Binding IsGameRunning}"
|
||||||
ToolTip.Tip="{ext:Locale StopEmulationTooltip}" />
|
ToolTip.Tip="{ext:Locale StopEmulationTooltip}" />
|
||||||
<MenuItem Command="{Binding SimulateWakeUpMessage}" Header="{ext:Locale MenuBarOptionsSimulateWakeUpMessage}" />
|
<MenuItem Command="{Binding SimulateWakeUpMessage}" Header="{ext:Locale MenuBarOptionsSimulateWakeUpMessage}" Icon="{ext:Icon fa-solid fa-sun}" />
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenAmiiboWindow}"
|
Command="{Binding OpenAmiiboWindow}"
|
||||||
AttachedToVisualTree="ScanAmiiboMenuItem_AttachedToVisualTree"
|
AttachedToVisualTree="ScanAmiiboMenuItem_AttachedToVisualTree"
|
||||||
Header="{ext:Locale MenuBarActionsScanAmiibo}"
|
Header="{ext:Locale MenuBarActionsScanAmiibo}"
|
||||||
Icon="{ext:Icon mdi-cube-scan}"
|
Icon="{ext:Icon fa-solid fa-cube}"
|
||||||
InputGesture="Ctrl + A"
|
InputGesture="Ctrl + A"
|
||||||
IsEnabled="{Binding IsAmiiboRequested}" />
|
IsEnabled="{Binding IsAmiiboRequested}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding OpenBinFile}"
|
Command="{Binding OpenBinFile}"
|
||||||
AttachedToVisualTree="ScanBinAmiiboMenuItem_AttachedToVisualTree"
|
AttachedToVisualTree="ScanBinAmiiboMenuItem_AttachedToVisualTree"
|
||||||
Header="{ext:Locale MenuBarActionsScanAmiiboBin}"
|
Header="{ext:Locale MenuBarActionsScanAmiiboBin}"
|
||||||
Icon="{ext:Icon mdi-cube-scan}"
|
Icon="{ext:Icon fa-solid fa-cube}"
|
||||||
IsVisible="{Binding CanScanAmiiboBinaries}"
|
IsVisible="{Binding CanScanAmiiboBinaries}"
|
||||||
InputGesture="Ctrl + B"
|
InputGesture="Ctrl + B"
|
||||||
IsEnabled="{Binding IsAmiiboBinRequested}" />
|
IsEnabled="{Binding IsAmiiboBinRequested}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding TakeScreenshot}"
|
Command="{Binding TakeScreenshot}"
|
||||||
Header="{ext:Locale MenuBarFileToolsTakeScreenshot}"
|
Header="{ext:Locale MenuBarFileToolsTakeScreenshot}"
|
||||||
Icon="{ext:Icon mdi-monitor-screenshot}"
|
Icon="{ext:Icon fa-solid fa-camera}"
|
||||||
InputGesture="{Binding ScreenshotKey}"
|
InputGesture="{Binding ScreenshotKey}"
|
||||||
IsEnabled="{Binding IsGameRunning}" />
|
IsEnabled="{Binding IsGameRunning}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{Binding HideUi}"
|
Command="{Binding HideUi}"
|
||||||
Header="{ext:Locale MenuBarFileToolsHideUi}"
|
Header="{ext:Locale MenuBarFileToolsHideUi}"
|
||||||
Icon="{ext:Icon mdi-eye-off}"
|
Icon="{ext:Icon fa-solid fa-eye-slash}"
|
||||||
InputGesture="{Binding ShowUiKey}"
|
InputGesture="{Binding ShowUiKey}"
|
||||||
IsEnabled="{Binding IsGameRunning}" />
|
IsEnabled="{Binding IsGameRunning}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@ -222,12 +225,12 @@
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarActions}" IsVisible="{Binding EnableNonGameRunningControls}">
|
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarActions}" IsVisible="{Binding EnableNonGameRunningControls}">
|
||||||
<MenuItem Header="{ext:Locale MenuBarActionsInstallKeys}" Icon="{ext:Icon fa-solid fa-key}">
|
<MenuItem Header="{ext:Locale MenuBarActionsInstallKeys}" Icon="{ext:Icon fa-solid fa-key}">
|
||||||
<MenuItem Command="{Binding InstallKeysFromFile}" Header="{ext:Locale MenuBarFileActionsInstallKeysFromFile}" Icon="{ext:Icon mdi-file-cog}" />
|
<MenuItem Command="{Binding InstallKeysFromFile}" Header="{ext:Locale MenuBarFileActionsInstallKeysFromFile}" Icon="{ext:Icon fa-solid fa-file-code}" />
|
||||||
<MenuItem Command="{Binding InstallKeysFromFolder}" Header="{ext:Locale MenuBarFileActionsInstallKeysFromFolder}" Icon="{ext:Icon mdi-folder-cog}" />
|
<MenuItem Command="{Binding InstallKeysFromFolder}" Header="{ext:Locale MenuBarFileActionsInstallKeysFromFolder}" Icon="{ext:Icon fa-solid fa-folder-closed}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="{ext:Locale MenuBarActionsInstallFirmware}" Icon="{ext:Icon fa-solid fa-download}">
|
<MenuItem Header="{ext:Locale MenuBarActionsInstallFirmware}" Icon="{ext:Icon fa-solid fa-floppy-disk}">
|
||||||
<MenuItem Command="{Binding InstallFirmwareFromFile}" Header="{ext:Locale MenuBarActionsInstallFirmwareFromFile}" Icon="{ext:Icon mdi-file-cog}" />
|
<MenuItem Command="{Binding InstallFirmwareFromFile}" Header="{ext:Locale MenuBarActionsInstallFirmwareFromFile}" Icon="{ext:Icon fa-solid fa-file-code}" />
|
||||||
<MenuItem Command="{Binding InstallFirmwareFromFolder}" Header="{ext:Locale MenuBarActionsInstallFirmwareFromDirectory}" Icon="{ext:Icon mdi-folder-cog}" />
|
<MenuItem Command="{Binding InstallFirmwareFromFolder}" Header="{ext:Locale MenuBarActionsInstallFirmwareFromDirectory}" Icon="{ext:Icon fa-solid fa-folder-closed}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="{ext:Locale MenuBarActionsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}">
|
<MenuItem Header="{ext:Locale MenuBarActionsManageFileTypes}" IsVisible="{Binding ManageFileTypesVisible}">
|
||||||
<MenuItem Name="InstallFileTypesMenuItem" Header="{ext:Locale MenuBarActionsInstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered, Converter={x:Static BoolConverters.Not}}" />
|
<MenuItem Name="InstallFileTypesMenuItem" Header="{ext:Locale MenuBarActionsInstallFileTypes}" IsEnabled="{Binding AreMimeTypesRegistered, Converter={x:Static BoolConverters.Not}}" />
|
||||||
@ -250,34 +253,38 @@
|
|||||||
Header="{ext:Locale MenuBarHelpAbout}"
|
Header="{ext:Locale MenuBarHelpAbout}"
|
||||||
Icon="{ext:Icon fa-solid fa-circle-info}"
|
Icon="{ext:Icon fa-solid fa-circle-info}"
|
||||||
ToolTip.Tip="{ext:Locale OpenAboutTooltip}" />
|
ToolTip.Tip="{ext:Locale OpenAboutTooltip}" />
|
||||||
|
<MenuItem
|
||||||
|
Name="StarscriptDebugMenuItem"
|
||||||
|
Header="Debug Starscript"
|
||||||
|
Icon="{ext:Icon fa-solid fa-star}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="UpdateMenuItem"
|
Name="UpdateMenuItem"
|
||||||
IsEnabled="{Binding CanUpdate}"
|
IsEnabled="{Binding CanUpdate}"
|
||||||
Header="{ext:Locale MenuBarHelpCheckForUpdates}"
|
Header="{ext:Locale MenuBarHelpCheckForUpdates}"
|
||||||
Icon="{ext:Icon mdi-update}"
|
Icon="{ext:Icon fa-solid fa-rotate}"
|
||||||
ToolTip.Tip="{ext:Locale CheckUpdatesTooltip}" />
|
ToolTip.Tip="{ext:Locale CheckUpdatesTooltip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="CompatibilityListMenuItem"
|
Name="CompatibilityListMenuItem"
|
||||||
Header="{ext:Locale CompatibilityListOpen}"
|
Header="{ext:Locale CompatibilityListOpen}"
|
||||||
Icon="{ext:Icon mdi-gamepad}"/>
|
Icon="{ext:Icon fa-solid fa-database}"/>
|
||||||
<Separator />
|
<Separator />
|
||||||
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarHelpFaqAndGuides}" Icon="{ext:Icon fa-solid fa-question}" >
|
<MenuItem VerticalAlignment="Center" Header="{ext:Locale MenuBarHelpFaqAndGuides}" Icon="{ext:Icon fa-solid fa-question}" >
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="FaqMenuItem"
|
Name="FaqMenuItem"
|
||||||
Header="{ext:Locale MenuBarHelpFaq}"
|
Header="{ext:Locale MenuBarHelpFaq}"
|
||||||
Icon="{ext:Icon fa-github}"
|
Icon="{ext:Icon fa-brands fa-gitlab}"
|
||||||
CommandParameter="https://git.ryujinx.app/ryubing/ryujinx/-/wikis/FAQ-&-Troubleshooting"
|
CommandParameter="https://git.ryujinx.app/ryubing/ryujinx/-/wikis/FAQ-&-Troubleshooting"
|
||||||
ToolTip.Tip="{ext:Locale MenuBarHelpFaqTooltip}" />
|
ToolTip.Tip="{ext:Locale MenuBarHelpFaqTooltip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="SetupGuideMenuItem"
|
Name="SetupGuideMenuItem"
|
||||||
Header="{ext:Locale MenuBarHelpSetup}"
|
Header="{ext:Locale MenuBarHelpSetup}"
|
||||||
Icon="{ext:Icon fa-github}"
|
Icon="{ext:Icon fa-brands fa-gitlab}"
|
||||||
CommandParameter="https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Setup-&-Configuration-Guide"
|
CommandParameter="https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Setup-&-Configuration-Guide"
|
||||||
ToolTip.Tip="{ext:Locale MenuBarHelpSetupTooltip}" />
|
ToolTip.Tip="{ext:Locale MenuBarHelpSetupTooltip}" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="LdnGuideMenuItem"
|
Name="LdnGuideMenuItem"
|
||||||
Header="{ext:Locale MenuBarHelpMultiplayer}"
|
Header="{ext:Locale MenuBarHelpMultiplayer}"
|
||||||
Icon="{ext:Icon fa-github}"
|
Icon="{ext:Icon fa-brands fa-gitlab}"
|
||||||
CommandParameter="https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Multiplayer-(LDN-Local-Wireless)-Guide"
|
CommandParameter="https://git.ryujinx.app/ryubing/ryujinx/-/wikis/Multiplayer-(LDN-Local-Wireless)-Guide"
|
||||||
ToolTip.Tip="{ext:Locale MenuBarHelpMultiplayerTooltip}" />
|
ToolTip.Tip="{ext:Locale MenuBarHelpMultiplayerTooltip}" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
@ -8,6 +8,7 @@ using LibHac.Ns;
|
|||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Systems.AppLibrary;
|
using Ryujinx.Ava.Systems.AppLibrary;
|
||||||
using Ryujinx.Ava.Systems.Configuration;
|
using Ryujinx.Ava.Systems.Configuration;
|
||||||
|
using Ryujinx.Ava.Systems.Starscript;
|
||||||
using Ryujinx.Ava.UI.Controls;
|
using Ryujinx.Ava.UI.Controls;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
@ -51,6 +52,8 @@ namespace Ryujinx.Ava.UI.Views.Main
|
|||||||
CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityListWindow.Show());
|
CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityListWindow.Show());
|
||||||
|
|
||||||
UpdateMenuItem.Command = MainWindowViewModel.UpdateCommand;
|
UpdateMenuItem.Command = MainWindowViewModel.UpdateCommand;
|
||||||
|
|
||||||
|
StarscriptDebugMenuItem.Command = Commands.Create(StarscriptTextBox.Show);
|
||||||
|
|
||||||
FaqMenuItem.Command =
|
FaqMenuItem.Command =
|
||||||
SetupGuideMenuItem.Command =
|
SetupGuideMenuItem.Command =
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
MinWidth="200"
|
MinWidth="200"
|
||||||
Height="6"
|
Height="6"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
Margin="0, 0, 5, 0"
|
||||||
Foreground="{DynamicResource SystemAccentColorLight2}"
|
Foreground="{DynamicResource SystemAccentColorLight2}"
|
||||||
IsVisible="{Binding StatusBarVisible}"
|
IsVisible="{Binding StatusBarVisible}"
|
||||||
Maximum="{Binding StatusBarProgressMaximum}"
|
Maximum="{Binding StatusBarProgressMaximum}"
|
||||||
|
@ -213,13 +213,13 @@ namespace Ryujinx.Ava.UI.Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Application_Opened(object sender, ApplicationOpenedEventArgs args)
|
public async void Application_Opened(object sender, ApplicationOpenedEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Application != null)
|
if (args.Application != null)
|
||||||
{
|
{
|
||||||
ViewModel.SelectedIcon = args.Application.Icon;
|
ViewModel.SelectedIcon = args.Application.Icon;
|
||||||
|
|
||||||
ViewModel.LoadApplication(args.Application).Wait();
|
await ViewModel.LoadApplication(args.Application);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
|
Reference in New Issue
Block a user