Compare commits

..

18 Commits

Author SHA1 Message Date
Evan Husted
2f93a0f706 infra: Conditionally compile Metal & OpenGL depending on if the target RuntimeIdentifier is mac 2025-01-18 10:38:29 -06:00
Evan Husted
80f44d9547 misc: chore: small cleanup 2025-01-18 10:33:57 -06:00
Evan Husted
b08e5db6d8 Headless: Dispose of inputmanager in a catch-all try 2025-01-18 10:30:19 -06:00
Evan Husted
6a291d4116 Headless: Use main UI logo for window icon instead of separate bmp 2025-01-18 10:26:12 -06:00
Evan Husted
6fc827fe67 headless: collapse headless window definition into a "Windows" folder, change GetWindowFlags to an abstract property. 2025-01-18 10:15:24 -06:00
Daniel Nylander
6cd4866d76 Updated sv_SE in locales.json (#513) 2025-01-17 18:04:18 -06:00
WilliamWsyHK
4d7ca5c0f0 Update Chinese translations (#375) 2025-01-17 17:35:34 -06:00
GabCoolGuy
a375faecc1 UI: Fix UpdateWaitWindow.axaml windows being too big on windows (#314) 2025-01-17 14:14:19 -06:00
Evan Husted
1728b0f20c WWE 2K18 is not playable. 2025-01-17 11:37:08 -06:00
LotP1
5aa071c59b remove notice for unusual core counts (#531) 2025-01-17 05:50:42 -06:00
Daenorth
1018c9db8b Update Norwegian Translation (#503)
Norwegian translation updated with the Compatibility list addition
2025-01-16 10:02:33 -06:00
Evan Husted
01ccd18726 UI: Meant to use that method in another place [ci-skip] 2025-01-16 09:52:35 -06:00
Evan Husted
abfbc6f4bc UI: Prevent desynced RPC when toggling it off/on while in-game 2025-01-16 09:52:01 -06:00
Francesco Saltori
6a4bc02d7a Update Italian translation (#489) 2025-01-16 06:38:36 -06:00
Hack茶ん
814c0526d2 Korean translations for compat list (#502) 2025-01-16 04:57:32 -06:00
Evan Husted
a5a4ef38e6 HLE: Stub IHidServer SetGestureOutputRanges (#524)
Lets "Donkey Kong Country Returns HD" get into main gameplay.
2025-01-16 02:39:39 -06:00
Evan Husted
c17e3bfcdf genuinely dont know how that was still there, i thought i got rid of UI.Common 2025-01-15 03:01:17 -06:00
Evan Husted
017f46f318 HLE: misc: throw a more descriptive error when the loaded processes doesn't contain _latestPid (likely missing FW) 2025-01-15 03:01:17 -06:00
36 changed files with 473 additions and 699 deletions

View File

@@ -3348,7 +3348,7 @@
01001C400482C000,"Wunderling DX",audio;crash,ingame,2022-09-10 13:20:12
01003B401148E000,"Wurroom",,playable,2020-10-07 22:46:21
010081700EDF4000,"WWE 2K Battlegrounds",nvdec;online-broken;UE4,playable,2022-10-07 12:44:40
010009800203E000,"WWE 2K18",nvdec,playable,2023-10-21 17:22:01
010009800203E000,"WWE 2K18",nvdec;online-broken,ingame,2025-01-17 11:36:56
0100DF100B97C000,"X-Morph: Defense",,playable,2020-06-22 11:05:31
0100D0B00FB74000,"XCOM® 2 Collection",gpu;crash,ingame,2022-10-04 09:38:30
0100CC9015360000,"XEL",gpu,ingame,2022-10-03 10:19:39
@@ -3421,4 +3421,4 @@
0100936018EB4000,"牧場物語 Welcomeワンダフルライフ",crash,ingame,2023-04-25 19:43:52
0100F4401940A000,"超探偵事件簿 レインコード (Master Detective Archives: Rain Code)",crash,ingame,2024-02-12 20:58:31
010064801A01C000,"超次元ゲイム ネプテューヌ GameMaker R:Evolution",crash,nothing,2023-10-30 22:37:40
0100F3400332C000,"ブレイド2",deadlock;amd-vendor-bug,ingame,2024-03-28 14:31:41
0100F3400332C000,"ブレイド2",deadlock;amd-vendor-bug,ingame,2024-03-28 14:31:41
1 title_id game_name labels status last_updated
3348 01001C400482C000 Wunderling DX audio;crash ingame 2022-09-10 13:20:12
3349 01003B401148E000 Wurroom playable 2020-10-07 22:46:21
3350 010081700EDF4000 WWE 2K Battlegrounds nvdec;online-broken;UE4 playable 2022-10-07 12:44:40
3351 010009800203E000 WWE 2K18 nvdec nvdec;online-broken playable ingame 2023-10-21 17:22:01 2025-01-17 11:36:56
3352 0100DF100B97C000 X-Morph: Defense playable 2020-06-22 11:05:31
3353 0100D0B00FB74000 XCOM® 2 Collection gpu;crash ingame 2022-10-04 09:38:30
3354 0100CC9015360000 XEL gpu ingame 2022-10-03 10:19:39
3421 0100936018EB4000 牧場物語 Welcome!ワンダフルライフ crash ingame 2023-04-25 19:43:52
3422 0100F4401940A000 超探偵事件簿 レインコード (Master Detective Archives: Rain Code) crash ingame 2024-02-12 20:58:31
3423 010064801A01C000 超次元ゲイム ネプテューヌ GameMaker R:Evolution crash nothing 2023-10-30 22:37:40
3424 0100F3400332C000 ゼノブレイド2 deadlock;amd-vendor-bug ingame 2024-03-28 14:31:41

View File

@@ -0,0 +1,10 @@
using System;
namespace Ryujinx.Common
{
public class RyujinxException : Exception
{
public RyujinxException(string message) : base(message)
{ }
}
}

View File

@@ -176,9 +176,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
AllowedCpuCoresMask = GetMaskFromMinMax(lowestCpuCore, highestCpuCore);
AllowedThreadPriosMask = GetMaskFromMinMax(lowestThreadPrio, highestThreadPrio);
if (isApplication && lowestCpuCore == 0 && highestCpuCore != 2)
Ryujinx.Common.Logging.Logger.Error?.Print(Ryujinx.Common.Logging.LogClass.Application, $"Application requested cores with index range {lowestCpuCore} to {highestCpuCore}! Report this to @LotP on the Ryujinx/Ryubing discord server (discord.gg/ryujinx)!");
else if (isApplication)
if (isApplication)
Ryujinx.Common.Logging.Logger.Info?.Print(Ryujinx.Common.Logging.LogClass.Application, $"Application requested cores with index range {lowestCpuCore} to {highestCpuCore}");
break;

View File

@@ -702,6 +702,18 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ResultCode.Success;
}
[CommandCmif(92)]
// SetGestureOutputRanges(pid, ushort Unknown0)
public ResultCode SetGestureOutputRanges(ServiceCtx context)
{
ulong pid = context.Request.HandleDesc.PId;
ushort unknown0 = context.RequestData.ReadUInt16();
Logger.Stub?.PrintStub(LogClass.ServiceHid, new { pid, unknown0 });
return ResultCode.Success;
}
[CommandCmif(100)]
// SetSupportedNpadStyleSet(pid, nn::applet::AppletResourceUserId, nn::hid::NpadStyleTag)

View File

@@ -26,7 +26,17 @@ namespace Ryujinx.HLE.Loaders.Processes
private ulong _latestPid;
public ProcessResult ActiveApplication => _processesByPid[_latestPid];
public ProcessResult ActiveApplication
{
get
{
if (!_processesByPid.TryGetValue(_latestPid, out ProcessResult value))
throw new RyujinxException(
$"The HLE Process map did not have a process with ID {_latestPid}. Are you missing firmware?");
return value;
}
}
public ProcessLoader(Switch device)
{

View File

@@ -253,23 +253,11 @@ namespace Ryujinx.Input.SDL2
return IGamepad.GetStateSnapshot(this);
}
private static bool hotButtonMinus = false;
private static bool hotExit = false;
public bool SpecialExit()
{
if (hotButtonMinus)
{
hotButtonMinus = false;
return hotExit;
}
return hotExit = false;
}
public GamepadStateSnapshot GetMappedStateSnapshot()
{
GamepadStateSnapshot rawState = GetStateSnapshot();
GamepadStateSnapshot result = default;
lock (_userMappingLock)
{
if (_buttonsUserMapping.Count == 0)
@@ -282,28 +270,6 @@ namespace Ryujinx.Input.SDL2
if (!entry.IsValid)
continue;
if (GamepadButtonInputId.Minus == entry.To)
{
if (rawState.IsPressed(entry.From) && !hotButtonMinus)
{
hotButtonMinus = true;
}
else if (!result.IsPressed(entry.From) && hotButtonMinus)
{
hotButtonMinus = false;
}
}
if (GamepadButtonInputId.Plus == entry.To)
{
if (rawState.IsPressed(entry.To) && hotButtonMinus)
{
hotExit = true;
}
}
// Do not touch state of button already pressed
if (!result.IsPressed(entry.To))
{
@@ -410,7 +376,5 @@ namespace Ryujinx.Input.SDL2
return SDL_GameControllerGetButton(_gamepadHandle, _buttonsDriverMapping[(int)inputId]) == 1;
}
}
}

View File

@@ -329,11 +329,6 @@ namespace Ryujinx.Input.SDL2
return result;
}
public bool SpecialExit()
{
return false;
}
public GamepadStateSnapshot GetStateSnapshot()
{
throw new NotSupportedException();

View File

@@ -25,10 +25,6 @@ namespace Ryujinx.Input.SDL2
{
_driver = driver;
}
public bool SpecialExit()
{
return false;
}
public Vector2 GetPosition()
{

View File

@@ -3,7 +3,6 @@ using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Configuration.Hid.Controller.Motion;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.HOS.Services.Hid;
using System;
using System.Collections.Concurrent;
@@ -274,21 +273,15 @@ namespace Ryujinx.Input.HLE
}
}
public bool Update()
public void Update()
{
// _gamepad may be altered by other threads
var gamepad = _gamepad;
if (gamepad != null && GamepadDriver != null)
{
State = gamepad.GetMappedStateSnapshot();
if (gamepad.SpecialExit())
{
return true;
}
if (_config is StandardControllerInputConfig controllerConfig && controllerConfig.Motion.EnableMotion)
{
if (controllerConfig.Motion.MotionBackend == MotionInputBackendType.GamepadDriver)
@@ -341,7 +334,6 @@ namespace Ryujinx.Input.HLE
State = default;
_leftMotionInput = null;
}
return false;
}
public GamepadInput GetHLEInputState()

View File

@@ -200,10 +200,8 @@ namespace Ryujinx.Input.HLE
ReloadConfiguration(inputConfig, enableKeyboard, enableMouse);
}
public bool Update(float aspectRatio = 1)
public void Update(float aspectRatio = 1)
{
bool specialExit = false;
lock (_lock)
{
List<GamepadInput> hleInputStates = new();
@@ -227,10 +225,9 @@ namespace Ryujinx.Input.HLE
DriverConfigurationUpdate(ref controller, inputConfig);
controller.UpdateUserConfiguration(inputConfig);
specialExit = controller.Update(); //hotkey press check
controller.Update();
controller.UpdateRumble(_device.Hid.Npads.GetRumbleQueue(playerIndex));
inputState = controller.GetHLEInputState();
inputState.Buttons |= _device.Hid.UpdateStickButtons(inputState.LStick, inputState.RStick);
@@ -318,8 +315,6 @@ namespace Ryujinx.Input.HLE
_device.TamperMachine.UpdateInput(hleInputStates);
}
return specialExit;
}
internal InputConfig GetPlayerInputConfigByIndex(int index)

View File

@@ -79,12 +79,6 @@ namespace Ryujinx.Input
/// <returns>A remapped snaphost of the state of the gamepad.</returns>
GamepadStateSnapshot GetMappedStateSnapshot();
/// <summary>
/// Gets the state if the minus and plus buttons were pressed on the gamepad.
/// </summary>
/// <returns>returns true if the buttons were pressed.</returns>
bool SpecialExit();
/// <summary>
/// Get a snaphost of the state of the gamepad.
/// </summary>

View File

@@ -1,36 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<None Remove="Resources\Controller_JoyConLeft.svg" />
<None Remove="Resources\Controller_JoyConPair.svg" />
<None Remove="Resources\Controller_JoyConRight.svg" />
<None Remove="Resources\Controller_ProCon.svg" />
<None Remove="Resources\Icon_NCA.png" />
<None Remove="Resources\Icon_NRO.png" />
<None Remove="Resources\Icon_NSO.png" />
<None Remove="Resources\Icon_NSP.png" />
<None Remove="Resources\Icon_XCI.png" />
<None Remove="Resources\Logo_Amiibo.png" />
<None Remove="Resources\Logo_Discord.png" />
<None Remove="Resources\Logo_GitHub.png" />
<None Remove="Resources\Logo_Ryujinx.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="DiscordRichPresence" />
<PackageReference Include="DynamicData" />
<PackageReference Include="securifybv.ShellLink" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
<ProjectReference Include="..\Ryujinx.HLE\Ryujinx.HLE.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj" />
</ItemGroup>
</Project>

View File

@@ -18,7 +18,6 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.Renderer;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Views.Main;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Utilities.AppLibrary;
@@ -71,7 +70,6 @@ namespace Ryujinx.Ava
private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping.
private const int TargetFps = 60;
private const float VolumeDelta = 0.05f;
static bool SpecialExit = false;
private static readonly Cursor _invisibleCursor = new(StandardCursorType.None);
private readonly nint _invisibleCursorWin;
@@ -98,7 +96,6 @@ namespace Ryujinx.Ava
private bool _isCursorInRenderer = true;
private bool _ignoreCursorState = false;
private enum CursorStates
{
CursorIsHidden,
@@ -506,13 +503,8 @@ namespace Ryujinx.Ava
_viewModel.Volume = ConfigurationState.Instance.System.AudioVolume.Value;
MainLoop();
Exit();
}
public bool IsSpecialExit()
{
return SpecialExit;
Exit();
}
private void UpdateIgnoreMissingServicesState(object sender, ReactiveEventArgs<bool> args)
@@ -597,7 +589,6 @@ namespace Ryujinx.Ava
_isStopped = true;
Stop();
}
public void DisposeContext()
@@ -1144,7 +1135,6 @@ namespace Ryujinx.Ava
string dockedMode = ConfigurationState.Instance.System.EnableDockedMode ? LocaleManager.Instance[LocaleKeys.Docked] : LocaleManager.Instance[LocaleKeys.Handheld];
string vSyncMode = Device.VSyncMode.ToString();
UpdateShaderCount();
if (GraphicsConfig.ResScale != 1)
@@ -1210,17 +1200,7 @@ namespace Ryujinx.Ava
return false;
}
if (NpadManager.Update(ConfigurationState.Instance.Graphics.AspectRatio.Value.ToFloat()))
{
if (ConfigurationState.Instance.Hid.SpecialExitEmulator.Value == 1)
{
SpecialExit = true; // close App
}
if (ConfigurationState.Instance.Hid.SpecialExitEmulator.Value > 0)
{
_isActive = false; //close game
}
}
NpadManager.Update(ConfigurationState.Instance.Graphics.AspectRatio.Value.ToFloat());
if (_viewModel.IsActive)
{
@@ -1355,8 +1335,6 @@ namespace Ryujinx.Ava
Device.Hid.DebugPad.Update();
return true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
using DiscordRPC;
using Gommon;
using Humanizer;
using Humanizer.Localisation;
using Ryujinx.Ava.Utilities.AppLibrary;
@@ -45,16 +46,7 @@ namespace Ryujinx.Ava
};
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
TitleIDs.CurrentApplication.Event += (_, e) =>
{
if (e.NewValue)
SwitchToPlayingState(
ApplicationLibrary.LoadAndSaveMetaData(e.NewValue),
Switch.Shared.Processes.ActiveApplication
);
else
SwitchToMainState();
};
TitleIDs.CurrentApplication.Event += (_, e) => Use(e.NewValue);
}
private static void Update(object sender, ReactiveEventArgs<bool> evnt)
@@ -75,11 +67,23 @@ namespace Ryujinx.Ava
_discordClient = new DiscordRpcClient(ApplicationId);
_discordClient.Initialize();
_discordClient.SetPresence(_discordPresenceMain);
Use(TitleIDs.CurrentApplication);
}
}
}
public static void Use(Optional<string> titleId)
{
if (titleId.TryGet(out string tid))
SwitchToPlayingState(
ApplicationLibrary.LoadAndSaveMetaData(tid),
Switch.Shared.Processes.ActiveApplication
);
else
SwitchToMainState();
}
private static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResult procRes)
{
_discordClient?.SetPresence(new RichPresence

View File

@@ -228,8 +228,6 @@ namespace Ryujinx.Headless
_inputConfiguration ??= [];
_enableKeyboard = option.EnableKeyboard;
_enableMouse = option.EnableMouse;
LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1);
LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2);
@@ -301,7 +299,10 @@ namespace Ryujinx.Headless
_userChannelPersistence.ShouldRestart = false;
}
_inputManager.Dispose();
try
{
_inputManager.Dispose();
} catch {}
return;
@@ -338,23 +339,23 @@ namespace Ryujinx.Headless
{
string label = state switch
{
LoadState => $"PTC : {current}/{total}",
ShaderCacheState => $"Shaders : {current}/{total}",
_ => throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}"),
LoadState => "PTC",
ShaderCacheState => "Shaders",
_ => throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}")
};
Logger.Info?.Print(LogClass.Application, label);
Logger.Info?.Print(LogClass.Application, $"{label} : {current}/{total}");
}
private static WindowBase CreateWindow(Options options)
{
return options.GraphicsBackend switch
{
GraphicsBackend.Vulkan => new VulkanWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet, options.SpecialExit),
GraphicsBackend.Vulkan => new VulkanWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet),
GraphicsBackend.Metal => OperatingSystem.IsMacOS() ?
new MetalWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableKeyboard, options.HideCursorMode, options.IgnoreControllerApplet, options.SpecialExit) :
new MetalWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableKeyboard, options.HideCursorMode, options.IgnoreControllerApplet) :
throw new Exception("Attempted to use Metal renderer on non-macOS platform!"),
_ => new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet, options.SpecialExit)
_ => new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode, options.IgnoreControllerApplet)
};
}

View File

@@ -150,10 +150,7 @@ namespace Ryujinx.Headless
if (NeedsOverride(nameof(IgnoreControllerApplet)))
IgnoreControllerApplet = configurationState.IgnoreApplet;
if (NeedsOverride(nameof(SpecialExit)))
SpecialExit = configurationState.Hid.SpecialExitEmulator;
return;
bool NeedsOverride(string argKey) => originalArgs.None(arg => arg.TrimStart('-').EqualsIgnoreCase(OptionName(argKey)));
@@ -277,9 +274,6 @@ namespace Ryujinx.Headless
[Option("enable-mouse", Required = false, Default = false, HelpText = "Enable or disable mouse support.")]
public bool EnableMouse { get; set; }
[Option("enable-press-hotkeys-to-exit", Required = false, Default = 0, HelpText = "press the minus and plus buttons to: 0 -disable, 1 - exit app, 2 - exit game.")]
public int SpecialExit { get; set; }
[Option("hide-cursor", Required = false, Default = HideCursorMode.OnIdle, HelpText = "Change when the cursor gets hidden.")]
public HideCursorMode HideCursorMode { get; set; }
@@ -420,7 +414,6 @@ namespace Ryujinx.Headless
[Option("ignore-controller-applet", Required = false, Default = false, HelpText = "Enable ignoring the controller applet when your game loses connection to your controller.")]
public bool IgnoreControllerApplet { get; set; }
// Values
[Value(0, MetaName = "input", HelpText = "Input to load.", Required = true)]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -23,11 +23,10 @@ namespace Ryujinx.Headless
AspectRatio aspectRatio,
bool enableMouse,
HideCursorMode hideCursorMode,
bool ignoreControllerApplet,
int specialExitEmulator)
: base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet, specialExitEmulator) { }
bool ignoreControllerApplet)
: base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet) { }
public override SDL_WindowFlags GetWindowFlags() => SDL_WindowFlags.SDL_WINDOW_METAL;
public override SDL_WindowFlags WindowFlags => SDL_WindowFlags.SDL_WINDOW_METAL;
protected override void InitializeWindowRenderer()
{

View File

@@ -118,14 +118,13 @@ namespace Ryujinx.Headless
AspectRatio aspectRatio,
bool enableMouse,
HideCursorMode hideCursorMode,
bool ignoreControllerApplet,
int specialExitEmulator)
: base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet, specialExitEmulator)
bool ignoreControllerApplet)
: base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet)
{
_glLogLevel = glLogLevel;
}
public override SDL_WindowFlags GetWindowFlags() => SDL_WindowFlags.SDL_WINDOW_OPENGL;
public override SDL_WindowFlags WindowFlags => SDL_WindowFlags.SDL_WINDOW_OPENGL;
protected override void InitializeWindowRenderer()
{

View File

@@ -18,14 +18,13 @@ namespace Ryujinx.Headless
AspectRatio aspectRatio,
bool enableMouse,
HideCursorMode hideCursorMode,
bool ignoreControllerApplet,
int specialExitEmulator)
: base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet, specialExitEmulator)
bool ignoreControllerApplet)
: base(inputManager, glLogLevel, aspectRatio, enableMouse, hideCursorMode, ignoreControllerApplet)
{
_glLogLevel = glLogLevel;
}
public override SDL_WindowFlags GetWindowFlags() => SDL_WindowFlags.SDL_WINDOW_VULKAN;
public override SDL_WindowFlags WindowFlags => SDL_WindowFlags.SDL_WINDOW_VULKAN;
protected override void InitializeWindowRenderer() { }

View File

@@ -1,6 +1,7 @@
using Humanizer;
using LibHac.Tools.Fs;
using Ryujinx.Ava;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Logging;
@@ -88,7 +89,6 @@ namespace Ryujinx.Headless
private readonly AspectRatio _aspectRatio;
private readonly bool _enableMouse;
private readonly int _specialExitEmulator;
private readonly bool _ignoreControllerApplet;
public WindowBase(
@@ -97,8 +97,7 @@ namespace Ryujinx.Headless
AspectRatio aspectRatio,
bool enableMouse,
HideCursorMode hideCursorMode,
bool ignoreControllerApplet,
int specialExitEmulator)
bool ignoreControllerApplet)
{
MouseDriver = new SDL2MouseDriver(hideCursorMode);
_inputManager = inputManager;
@@ -114,7 +113,6 @@ namespace Ryujinx.Headless
_gpuDoneEvent = new ManualResetEvent(false);
_aspectRatio = aspectRatio;
_enableMouse = enableMouse;
_specialExitEmulator = specialExitEmulator;
_ignoreControllerApplet = ignoreControllerApplet;
HostUITheme = new HeadlessHostUiTheme();
@@ -140,7 +138,7 @@ namespace Ryujinx.Headless
private void SetWindowIcon()
{
Stream iconStream = typeof(Program).Assembly.GetManifestResourceStream("HeadlessLogo");
Stream iconStream = EmbeddedResources.GetStream("Ryujinx/Assets/UIImages/Logo_Ryujinx.png");
byte[] iconBytes = new byte[iconStream!.Length];
if (iconStream.Read(iconBytes, 0, iconBytes.Length) != iconBytes.Length)
@@ -194,7 +192,7 @@ namespace Ryujinx.Headless
FullscreenFlag = SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
}
WindowHandle = SDL_CreateWindow($"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}", SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), Width, Height, DefaultFlags | FullscreenFlag | GetWindowFlags());
WindowHandle = SDL_CreateWindow($"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}", SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), Width, Height, DefaultFlags | FullscreenFlag | WindowFlags);
if (WindowHandle == nint.Zero)
{
@@ -249,7 +247,7 @@ namespace Ryujinx.Headless
protected abstract void SwapBuffers();
public abstract SDL_WindowFlags GetWindowFlags();
public abstract SDL_WindowFlags WindowFlags { get; }
private string GetGpuDriverName()
{

View File

@@ -30,11 +30,6 @@ namespace Ryujinx.Ava.Input
public readonly Key From = from;
}
public bool SpecialExit()
{
return false;
}
public AvaloniaKeyboard(AvaloniaKeyboardDriver driver, string id, string name)
{
_buttonsUserMapping = [];

View File

@@ -13,11 +13,6 @@ namespace Ryujinx.Ava.Input
public string Id => "0";
public string Name => "AvaloniaMouse";
public bool SpecialExit()
{
return false;
}
public bool IsConnected => true;
public GamepadFeaturesFlag Features => throw new NotImplementedException();
public bool[] Buttons => _driver.PressedButtons;

View File

@@ -21,6 +21,7 @@ using Ryujinx.Graphics.Vulkan.MoltenVK;
using Ryujinx.Headless;
using Ryujinx.SDL2.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
@@ -243,16 +244,33 @@ namespace Ryujinx.Ava
: $"Launch Mode: {AppDataManager.Mode}");
}
internal static void ProcessUnhandledException(object sender, Exception ex, bool isTerminating)
internal static void ProcessUnhandledException(object sender, Exception initialException, bool isTerminating)
{
Logger.Log log = Logger.Error ?? Logger.Notice;
string message = $"Unhandled exception caught: {ex}";
// ReSharper disable once ConstantConditionalAccessQualifier
if (sender?.GetType()?.AsPrettyString() is { } senderName)
log.Print(LogClass.Application, message, senderName);
List<Exception> exceptions = [];
if (initialException is AggregateException ae)
{
exceptions.AddRange(ae.InnerExceptions);
}
else
log.PrintMsg(LogClass.Application, message);
{
exceptions.Add(initialException);
}
foreach (var e in exceptions)
{
string message = $"Unhandled exception caught: {e}";
// ReSharper disable once ConstantConditionalAccessQualifier
if (sender?.GetType()?.AsPrettyString() is { } senderName)
log.Print(LogClass.Application, message, senderName);
else
log.PrintMsg(LogClass.Application, message);
}
if (isTerminating)
Exit();

View File

@@ -72,8 +72,8 @@
<ItemGroup>
<ProjectReference Include="..\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Metal\Ryujinx.Graphics.Metal.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" Condition="'$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
<ProjectReference Include="..\Ryujinx.Graphics.Metal\Ryujinx.Graphics.Metal.csproj" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
<ProjectReference Include="..\Ryujinx.Input\Ryujinx.Input.csproj" />
<ProjectReference Include="..\Ryujinx.Input.SDL2\Ryujinx.Input.SDL2.csproj" />
<ProjectReference Include="..\Ryujinx.Audio.Backends.OpenAL\Ryujinx.Audio.Backends.OpenAL.csproj" />
@@ -166,7 +166,6 @@
<EmbeddedResource Include="Assets\UIImages\Logo_GitHub_Light.png" />
<EmbeddedResource Include="Assets\UIImages\Logo_Ryujinx.png" />
<EmbeddedResource Include="Assets\UIImages\Logo_Ryujinx_AntiAlias.png" />
<EmbeddedResource Include="Headless\Ryujinx.bmp" LogicalName="HeadlessLogo" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="Assets\locales.json" />

View File

@@ -7,6 +7,7 @@
Title="Ryujinx - Waiting"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterOwner"
CanResize="False"
mc:Ignorable="d"
Focusable="True">
<Grid

View File

@@ -1049,7 +1049,6 @@ namespace Ryujinx.Ava.UI.ViewModels
private void InitializeGame()
{
RendererHostControl.WindowCreated += RendererHost_Created;
AppHost.StatusUpdatedEvent += Update_StatusBar;
@@ -1059,13 +1058,7 @@ namespace Ryujinx.Ava.UI.ViewModels
AppHost?.Start();
if (AppHost?.IsSpecialExit() == true)
{
Window.ForceExit();
}
AppHost?.DisposeContext();
}
private async Task HandleRelaunch()

View File

@@ -128,7 +128,6 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableDockedMode { get; set; }
public bool EnableKeyboard { get; set; }
public bool EnableMouse { get; set; }
public int EnableSpecialExit { get; set; }
public VSyncMode VSyncMode
{
get => _vSyncMode;
@@ -260,8 +259,6 @@ namespace Ryujinx.Ava.UI.ViewModels
public int OpenglDebugLevel { get; set; }
public int MemoryMode { get; set; }
public int BaseStyleIndex { get; set; }
public int GraphicsBackendIndex
{
get => _graphicsBackendIndex;
@@ -514,13 +511,6 @@ namespace Ryujinx.Ava.UI.ViewModels
EnableDockedMode = config.System.EnableDockedMode;
EnableKeyboard = config.Hid.EnableKeyboard;
EnableMouse = config.Hid.EnableMouse;
EnableSpecialExit = config.Hid.SpecialExitEmulator.Value switch
{
0 => 0, // "Hotkey 'Exit' is Disabled"
1 => 1, // "Close app. by hotkey"
2 => 2, // "Close game by hotkey"
_ => 0
};
// Keyboard Hotkeys
KeyboardHotkey = new HotkeyConfig(config.Hid.Hotkeys.Value);
@@ -628,13 +618,6 @@ namespace Ryujinx.Ava.UI.ViewModels
config.System.EnableDockedMode.Value = EnableDockedMode;
config.Hid.EnableKeyboard.Value = EnableKeyboard;
config.Hid.EnableMouse.Value = EnableMouse;
config.Hid.SpecialExitEmulator.Value = EnableSpecialExit switch
{
0 => 0, // "Hotkey 'Exit' is Disabled",
1 => 1, // "Close app. by hotkey",
2 => 2, // "Close game by hotkey",
_ => 0
};
// Keyboard Hotkeys
config.Hid.Hotkeys.Value = KeyboardHotkey.GetConfig();

View File

@@ -1,4 +1,4 @@
<UserControl
<UserControl
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsInputView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -58,20 +58,6 @@
<TextBlock
Text="{ext:Locale SettingsTabInputDirectMouseAccess}" />
</CheckBox>
<ComboBox SelectedIndex="{Binding EnableSpecialExit}"
ToolTip.Tip="{ext:Locale SpecialExitTooltip}"
HorizontalContentAlignment="Left"
MinWidth="160">
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabInputDisableExitHotKey}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabInputHotkeyIsCloseApp}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabInputHotkeyIsCloseGame}" />
</ComboBoxItem>
</ComboBox>
</StackPanel>
</StackPanel>
</Grid>

View File

@@ -136,6 +136,12 @@
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabSystemSystemLanguageBrazilianPortuguese}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabSystemSystemLanguageSwedish}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{ext:Locale SettingsTabSystemSystemLanguageNorwegian}" />
</ComboBoxItem>
</ComboBox>
</StackPanel>
<StackPanel

View File

@@ -45,7 +45,6 @@ namespace Ryujinx.Ava.UI.Windows
internal readonly AvaHostUIHandler UiHandler;
private bool _isLoading;
private bool _isExitWithoutConfirm = false;
private bool _applicationsLoadedOnce;
private UserChannelPersistence _userChannelPersistence;
@@ -572,11 +571,11 @@ namespace Ryujinx.Ava.UI.Windows
protected override void OnClosing(WindowClosingEventArgs e)
{
if (!ViewModel.IsClosing && ViewModel.AppHost != null && ConfigurationState.Instance.ShowConfirmExit && !_isExitWithoutConfirm)
if (!ViewModel.IsClosing && ViewModel.AppHost != null && ConfigurationState.Instance.ShowConfirmExit)
{
e.Cancel = true;
ConfirmExit();
ConfirmExit();
return;
}
@@ -617,12 +616,6 @@ namespace Ryujinx.Ava.UI.Windows
base.OnClosing(e);
}
public void ForceExit()
{
_isExitWithoutConfirm = true;
Close();
}
private void ConfirmExit()
{
Dispatcher.UIThread.InvokeAsync(async () =>

View File

@@ -17,7 +17,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// <summary>
/// The current version of the file format
/// </summary>
public const int CurrentVersion = 60;
public const int CurrentVersion = 59;
/// <summary>
/// Version of the configuration file format
@@ -366,12 +366,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// </summary>
public bool EnableMouse { get; set; }
/// <summary>
/// Allows you to choose one of several behaviors when pressing hotkeys:
/// 0 - Do nothing, 1 - Close the emulator application, 2 - Exit the game.
/// </summary>
public int SpecialExitEmulator { get; set; }
/// <summary>
/// Hotkey Keyboard Bindings
/// </summary>

View File

@@ -136,7 +136,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
Hid.EnableKeyboard.Value = cff.EnableKeyboard;
Hid.EnableMouse.Value = cff.EnableMouse;
Hid.SpecialExitEmulator.Value = cff.SpecialExitEmulator;
Hid.Hotkeys.Value = cff.Hotkeys;
Hid.InputConfig.Value = cff.InputConfig ?? [];
@@ -415,10 +414,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
// This was accidentally enabled by default when it was PRed. That is not what we want,
// so as a compromise users who want to use it will simply need to re-enable it once after updating.
cff.IgnoreApplet = false;
}),
(60, static cff =>
{
cff.SpecialExitEmulator = 0;
})
);
}

View File

@@ -420,13 +420,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// </summary>
public ReactiveObject<bool> EnableMouse { get; private set; }
/// <summary>
/// Allows you to choose one of several behaviors when pressing hotkeys:
/// 0 - Do nothing, 1 - Close the emulator application, 2 - Exit the game.
/// </summary>
public ReactiveObject<int> SpecialExitEmulator { get; private set; }
/// <summary>
/// Hotkey Keyboard Bindings
/// </summary>
@@ -443,7 +436,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
{
EnableKeyboard = new ReactiveObject<bool>();
EnableMouse = new ReactiveObject<bool>();
SpecialExitEmulator = new ReactiveObject<int>();
Hotkeys = new ReactiveObject<KeyboardHotkeys>();
InputConfig = new ReactiveObject<List<InputConfig>>();
}

View File

@@ -128,7 +128,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
ShowConsole = UI.ShowConsole,
EnableKeyboard = Hid.EnableKeyboard,
EnableMouse = Hid.EnableMouse,
SpecialExitEmulator = Hid.SpecialExitEmulator,
Hotkeys = Hid.Hotkeys,
KeyboardConfig = [],
ControllerConfig = [],
@@ -242,7 +241,6 @@ namespace Ryujinx.Ava.Utilities.Configuration
UI.WindowStartup.WindowMaximized.Value = false;
Hid.EnableKeyboard.Value = false;
Hid.EnableMouse.Value = false;
Hid.SpecialExitEmulator.Value = 0;
Hid.Hotkeys.Value = new KeyboardHotkeys
{
ToggleVSyncMode = Key.F1,