diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9b11f0778..b678e5f8e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,36 +74,36 @@ jobs: chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest' - #- name: Build AppImage - # if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest' - # run: | - # PLATFORM_NAME="${{ matrix.platform.name }}" + - name: Build AppImage + if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest' + run: | + PLATFORM_NAME="${{ matrix.platform.name }}" - # sudo apt install -y zsync desktop-file-utils appstream + sudo apt install -y zsync desktop-file-utils appstream - # mkdir -p tools - # export PATH="$PATH:$(readlink -f tools)" + mkdir -p tools + export PATH="$PATH:$(readlink -f tools)" - # # Setup appimagetool - # wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" - # chmod +x tools/appimagetool - # chmod +x distribution/linux/appimage/build-appimage.sh + # Setup appimagetool + wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" + chmod +x tools/appimagetool + chmod +x distribution/linux/appimage/build-appimage.sh # Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name) - # if [ "$PLATFORM_NAME" = "linux-x64" ]; then - # ARCH_NAME=x64 - # export ARCH=x86_64 - # elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then - # ARCH_NAME=arm64 - # export ARCH=aarch64 - # else - # echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME"" - # exit 1 - # fi + if [ "$PLATFORM_NAME" = "linux-x64" ]; then + ARCH_NAME=x64 + export ARCH=x86_64 + elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then + ARCH_NAME=arm64 + export ARCH=aarch64 + else + echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME"" + exit 1 + fi - # export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync" - # BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh - # shell: bash + export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync" + BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh + shell: bash - name: Upload Ryujinx artifact uses: actions/upload-artifact@v4 @@ -112,12 +112,12 @@ jobs: path: publish if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13' - #- name: Upload Ryujinx (AppImage) artifact - # uses: actions/upload-artifact@v4 - # if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest' - # with: - # name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}-AppImage - # path: publish_appimage + - name: Upload Ryujinx (AppImage) artifact + uses: actions/upload-artifact@v4 + if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest' + with: + name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}-AppImage + path: publish_appimage - name: Upload Ryujinx.Headless.SDL2 artifact uses: actions/upload-artifact@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c3c1e2a28..7a78718be 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -101,83 +101,79 @@ jobs: - name: Publish run: | - dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained -p:IncludeNativeLibrariesForSelfExtract=true - dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained -p:IncludeNativeLibrariesForSelfExtract=true + dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained -p:IncludeNativeLibrariesForSelfExtract=true + dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained -p:IncludeNativeLibrariesForSelfExtract=true - name: Packing Windows builds if: matrix.platform.os == 'windows-latest' run: | - pushd publish_ava - rm publish/libarmeilleure-jitsupport.dylib - 7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish + pushd publish + rm libarmeilleure-jitsupport.dylib + 7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish popd pushd publish_sdl2_headless - rm publish/libarmeilleure-jitsupport.dylib - 7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish + rm libarmeilleure-jitsupport.dylib + 7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish popd shell: bash + + - name: Build AppImage (Linux) + if: matrix.platform.os == 'ubuntu-latest' + run: | + BUILD_VERSION="${{ steps.version_info.outputs.build_version }}" + PLATFORM_NAME="${{ matrix.platform.name }}" + + sudo apt install -y zsync desktop-file-utils appstream + + mkdir -p tools + export PATH="$PATH:$(readlink -f tools)" + + # Setup appimagetool + wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" + chmod +x tools/appimagetool + chmod +x distribution/linux/appimage/build-appimage.sh + + # Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name) + if [ "$PLATFORM_NAME" = "linux-x64" ]; then + ARCH_NAME=x64 + export ARCH=x86_64 + elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then + ARCH_NAME=arm64 + export ARCH=aarch64 + else + echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME"" + exit 1 + fi + + export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync" + BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh + + pushd publish_appimage + mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage + mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync + popd + shell: bash - name: Packing Linux builds if: matrix.platform.os == 'ubuntu-latest' run: | - pushd publish_ava - rm publish/libarmeilleure-jitsupport.dylib - chmod +x publish/Ryujinx.sh publish/Ryujinx - tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish + pushd publish + chmod +x Ryujinx.sh Ryujinx + tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish popd pushd publish_sdl2_headless - rm publish/libarmeilleure-jitsupport.dylib - chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2 - tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish + chmod +x Ryujinx.sh Ryujinx.Headless.SDL2 + tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish popd shell: bash - - #- name: Build AppImage (Linux) - # if: matrix.platform.os == 'ubuntu-latest' - # run: | - # BUILD_VERSION="${{ steps.version_info.outputs.build_version }}" - # PLATFORM_NAME="${{ matrix.platform.name }}" - - # sudo apt install -y zsync desktop-file-utils appstream - - # mkdir -p tools - # export PATH="$PATH:$(readlink -f tools)" - - # Setup appimagetool - # wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" - # chmod +x tools/appimagetool - # chmod +x distribution/linux/appimage/build-appimage.sh - - # Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name) - # if [ "$PLATFORM_NAME" = "linux-x64" ]; then - # ARCH_NAME=x64 - # export ARCH=x86_64 - # elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then - # ARCH_NAME=arm64 - # export ARCH=aarch64 - # else - # echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME"" - # exit 1 - # fi - - # export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync" - # BUILDDIR=publish_ava OUTDIR=publish_ava_appimage distribution/linux/appimage/build-appimage.sh - - # Add to release output - # pushd publish_ava_appimage - # mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage - # mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync - # popd - # shell: bash - name: Pushing new release uses: ncipollo/release-action@v1 with: name: ${{ steps.version_info.outputs.build_version }} - artifacts: "release_output/*.tar.gz,release_output/*.zip" - #artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*" + artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*" tag: ${{ steps.version_info.outputs.build_version }} body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}" omitBodyDuringUpdate: true @@ -233,7 +229,7 @@ jobs: - name: Publish macOS Ryujinx run: | - ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release + ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release - name: Publish macOS Ryujinx.Headless.SDL2 run: | @@ -243,7 +239,7 @@ jobs: uses: ncipollo/release-action@v1 with: name: ${{ steps.version_info.outputs.build_version }} - artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz" + artifacts: "publish/*.tar.gz, publish_headless/*.tar.gz" tag: ${{ steps.version_info.outputs.build_version }} body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}" omitBodyDuringUpdate: true diff --git a/README.md b/README.md index d2ce7ca01..7fa78c4b0 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,15 @@ Latest Release +
+ + + + + Latest Canary Release +

diff --git a/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs b/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs index 3c34d5c78..da4d2e51b 100644 --- a/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs +++ b/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs @@ -1,4 +1,6 @@ +using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Applets.Browser; +using Ryujinx.HLE.HOS.Applets.Dummy; using Ryujinx.HLE.HOS.Applets.Error; using Ryujinx.HLE.HOS.Services.Am.AppletAE; using System; @@ -26,9 +28,13 @@ namespace Ryujinx.HLE.HOS.Applets return new BrowserApplet(system); case AppletId.LibAppletOff: return new BrowserApplet(system); + case AppletId.MiiEdit: + Logger.Warning?.Print(LogClass.Application, $"Please use the MiiEdit inside File/Open Applet"); + return new DummyApplet(system); } - throw new NotImplementedException($"{applet} applet is not implemented."); + Logger.Warning?.Print(LogClass.Application, $"Applet {applet} not implemented!"); + return new DummyApplet(system); } } } diff --git a/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs new file mode 100644 index 000000000..75df7a373 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs @@ -0,0 +1,43 @@ +using Ryujinx.Common.Logging; +using Ryujinx.Common.Memory; +using Ryujinx.HLE.HOS.Applets; +using Ryujinx.HLE.HOS.Services.Am.AppletAE; +using System; +using System.IO; +using System.Runtime.InteropServices; +namespace Ryujinx.HLE.HOS.Applets.Dummy +{ + internal class DummyApplet : IApplet + { + private readonly Horizon _system; + private AppletSession _normalSession; + public event EventHandler AppletStateChanged; + public DummyApplet(Horizon system) + { + _system = system; + } + public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession) + { + _normalSession = normalSession; + _normalSession.Push(BuildResponse()); + AppletStateChanged?.Invoke(this, null); + _system.ReturnFocus(); + return ResultCode.Success; + } + private static T ReadStruct(byte[] data) where T : struct + { + return MemoryMarshal.Read(data.AsSpan()); + } + private static byte[] BuildResponse() + { + using MemoryStream stream = MemoryStreamManager.Shared.GetStream(); + using BinaryWriter writer = new(stream); + writer.Write((ulong)ResultCode.Success); + return stream.ToArray(); + } + public ResultCode GetResult() + { + return ResultCode.Success; + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/VirtualAmiiboFile.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/VirtualAmiiboFile.cs index 65d380979..e1db98e5f 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/VirtualAmiiboFile.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/Types/VirtualAmiiboFile.cs @@ -8,6 +8,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager public uint FileVersion { get; set; } public byte[] TagUuid { get; set; } public string AmiiboId { get; set; } + public string NickName { get; set; } public DateTime FirstWriteDate { get; set; } public DateTime LastWriteDate { get; set; } public ushort WriteCounter { get; set; } diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs index ba4a81e0e..7ce749d1a 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs @@ -64,16 +64,17 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp }; } - public static RegisterInfo GetRegisterInfo(ITickSource tickSource, string amiiboId, string nickname) + public static RegisterInfo GetRegisterInfo(ITickSource tickSource, string amiiboId, string userName) { VirtualAmiiboFile amiiboFile = LoadAmiiboFile(amiiboId); - + string nickname = amiiboFile.NickName ?? "Ryujinx"; UtilityImpl utilityImpl = new(tickSource); CharInfo charInfo = new(); charInfo.SetFromStoreData(StoreData.BuildDefault(utilityImpl, 0)); - charInfo.Nickname = Nickname.FromString(nickname); + // This is the player's name + charInfo.Nickname = Nickname.FromString(userName); RegisterInfo registerInfo = new() { @@ -85,7 +86,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp Reserved1 = new Array64(), Reserved2 = new Array58(), }; - "Ryujinx"u8.CopyTo(registerInfo.Nickname.AsSpan()); + // This is the amiibo's name + byte[] nicknameBytes = System.Text.Encoding.UTF8.GetBytes(nickname); + nicknameBytes.CopyTo(registerInfo.Nickname.AsSpan()); return registerInfo; } diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json index 3ed614cc8..15a9c6157 100644 --- a/src/Ryujinx/Assets/Locales/en_US.json +++ b/src/Ryujinx/Assets/Locales/en_US.json @@ -413,6 +413,7 @@ "AvatarSetBackgroundColor": "Set Background Color", "AvatarClose": "Close", "ControllerSettingsLoadProfileToolTip": "Load Profile", + "ControllerSettingsViewProfileToolTip": "View Profile", "ControllerSettingsAddProfileToolTip": "Add Profile", "ControllerSettingsRemoveProfileToolTip": "Remove Profile", "ControllerSettingsSaveProfileToolTip": "Save Profile", diff --git a/src/Ryujinx/Program.cs b/src/Ryujinx/Program.cs index a52b75453..06013ac77 100644 --- a/src/Ryujinx/Program.cs +++ b/src/Ryujinx/Program.cs @@ -30,6 +30,7 @@ namespace Ryujinx.Ava { internal partial class Program { + // public static double WindowScaleFactor { get; set; } public static double DesktopScaleFactor { get; set; } = 1.0; public static string Version { get; private set; } diff --git a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs index 67a3642a9..bd8c1e3a7 100644 --- a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs +++ b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs @@ -226,6 +226,24 @@ namespace Ryujinx.Ava.UI.Helpers (int)Symbol.Help, primaryButtonResult); + internal static async Task CreateConfirmationDialogExtended( + string primaryText, + string secondaryText, + string acceptButtonText, + string noacceptButtonText, + string cancelButtonText, + string title, + UserResult primaryButtonResult = UserResult.Yes) + => await ShowTextDialog( + string.IsNullOrWhiteSpace(title) ? LocaleManager.Instance[LocaleKeys.DialogConfirmationTitle] : title, + primaryText, + secondaryText, + acceptButtonText, + noacceptButtonText, + cancelButtonText, + (int)Symbol.Help, + primaryButtonResult); + internal static async Task CreateLocalizedConfirmationDialog(string primaryText, string secondaryText) => await CreateConfirmationDialog( primaryText, diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs index c133f25fa..54f278cec 100644 --- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs @@ -44,6 +44,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input private readonly MainWindow _mainWindow; private PlayerIndex _playerId; + private PlayerIndex _playerIdChoose; private int _controller; private string _controllerImage; private int _device; @@ -83,6 +84,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input } } + public PlayerIndex PlayerIdChoose + { + get => _playerIdChoose; + set { } + } + public PlayerIndex PlayerId { get => _playerId; @@ -90,6 +97,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input { if (IsModified) { + + _playerIdChoose = value; return; } @@ -99,7 +108,9 @@ namespace Ryujinx.Ava.UI.ViewModels.Input if (!Enum.IsDefined(typeof(PlayerIndex), _playerId)) { _playerId = PlayerIndex.Player1; + } + _isLoaded = false; LoadConfiguration(); LoadDevice(); diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs index b76648da7..c900ea532 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs @@ -4,11 +4,14 @@ using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.LogicalTree; +using DiscordRPC; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels.Input; using Ryujinx.Common.Configuration.Hid.Controller; +using Ryujinx.Common.Logging; using Ryujinx.Input; using Ryujinx.Input.Assigner; +using System; using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId; namespace Ryujinx.Ava.UI.Views.Input @@ -27,6 +30,16 @@ namespace Ryujinx.Ava.UI.Views.Input { button.IsCheckedChanged += Button_IsCheckedChanged; } + + if (visual is CheckBox check) + { + check.IsCheckedChanged += CheckBox_IsCheckedChanged; + } + + if (visual is Slider slider) + { + slider.PropertyChanged += Slider_IsCheckedChanged; + } } } @@ -40,9 +53,51 @@ namespace Ryujinx.Ava.UI.Views.Input } } + private float _changeSlider = -1.0f; + + private void Slider_IsCheckedChanged(object sender, AvaloniaPropertyChangedEventArgs e) + { + if (sender is Slider check) + { + if ((bool)check.IsPointerOver && _changeSlider == -1.0f) + { + _changeSlider = (float)check.Value; + + } + else if (!(bool)check.IsPointerOver) + { + _changeSlider = -1.0f; + } + + if (_changeSlider != -1.0f && _changeSlider != (float)check.Value) + { + + var viewModel = (DataContext as ControllerInputViewModel); + viewModel.ParentModel.IsModified = true; + _changeSlider = (float)check.Value; + } + } + } + + private void CheckBox_IsCheckedChanged(object sender, RoutedEventArgs e) + { + if (sender is CheckBox check) + { + if ((bool)check.IsPointerOver) + { + + var viewModel = (DataContext as ControllerInputViewModel); + viewModel.ParentModel.IsModified = true; + _currentAssigner?.Cancel(); + _currentAssigner = null; + } + } + } + + private void Button_IsCheckedChanged(object sender, RoutedEventArgs e) { - if (sender is ToggleButton button) + if (sender is ToggleButton button ) { if ((bool)button.IsChecked) { @@ -149,7 +204,7 @@ namespace Ryujinx.Ava.UI.Views.Input } else { - if (_currentAssigner != null) + if (_currentAssigner != null ) { _currentAssigner.Cancel(); _currentAssigner = null; diff --git a/src/Ryujinx/UI/Views/Input/InputView.axaml b/src/Ryujinx/UI/Views/Input/InputView.axaml index 851c9c626..b5bfa666d 100644 --- a/src/Ryujinx/UI/Views/Input/InputView.axaml +++ b/src/Ryujinx/UI/Views/Input/InputView.axaml @@ -108,7 +108,7 @@ ToolTip.Tip="{ext:Locale ControllerSettingsLoadProfileToolTip}" Command="{Binding LoadProfile}"> diff --git a/src/Ryujinx/UI/Views/Input/InputView.axaml.cs b/src/Ryujinx/UI/Views/Input/InputView.axaml.cs index 356381a8a..5fda7ef6a 100644 --- a/src/Ryujinx/UI/Views/Input/InputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/InputView.axaml.cs @@ -25,17 +25,27 @@ namespace Ryujinx.Ava.UI.Views.Input private async void PlayerIndexBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e) { + if (PlayerIndexBox != null) + { + if (PlayerIndexBox.SelectedIndex != (int)ViewModel.PlayerId) + { + PlayerIndexBox.SelectedIndex = (int)ViewModel.PlayerId; + } + } + if (ViewModel.IsModified && !_dialogOpen) { _dialogOpen = true; - var result = await ContentDialogHelper.CreateConfirmationDialog( + var result = await ContentDialogHelper.CreateConfirmationDialogExtended( LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmMessage], LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmSubMessage], LocaleManager.Instance[LocaleKeys.InputDialogYes], LocaleManager.Instance[LocaleKeys.InputDialogNo], + LocaleManager.Instance[LocaleKeys.Cancel], LocaleManager.Instance[LocaleKeys.RyujinxConfirm]); + if (result == UserResult.Yes) { ViewModel.Save(); @@ -43,14 +53,30 @@ namespace Ryujinx.Ava.UI.Views.Input _dialogOpen = false; + if (result == UserResult.Cancel) + { + + return; + } + ViewModel.IsModified = false; - if (e.AddedItems.Count > 0) + if (result != UserResult.Cancel) { - var player = (PlayerModel)e.AddedItems[0]; - ViewModel.PlayerId = player.Id; + ViewModel.PlayerId = ViewModel.PlayerIdChoose; + } + + if (result == UserResult.Cancel) + { + if (e.AddedItems.Count > 0) + { + ViewModel.IsModified = true; + var player = (PlayerModel)e.AddedItems[0]; + ViewModel.PlayerId = player.Id; + } } } + } public void Dispose()