Settings option for suspending application on start

This commit is contained in:
svc64 2023-12-20 20:52:46 +02:00
parent eea36e8a37
commit 1bf244173d
14 changed files with 81 additions and 9 deletions

View file

@ -679,7 +679,8 @@ namespace Ryujinx.UI
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value, ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value,
ConfigurationState.Instance.Multiplayer.Mode, ConfigurationState.Instance.Multiplayer.Mode,
ConfigurationState.Instance.Debug.EnableGdbStub, ConfigurationState.Instance.Debug.EnableGdbStub,
ConfigurationState.Instance.Debug.GdbStubPort); ConfigurationState.Instance.Debug.GdbStubPort,
ConfigurationState.Instance.Debug.DebuggerSuspendOnStart);
_emulationContext = new HLE.Switch(configuration); _emulationContext = new HLE.Switch(configuration);
} }

View file

@ -118,6 +118,7 @@ namespace Ryujinx.UI.Windows
[GUI] ToggleButton _configureController8; [GUI] ToggleButton _configureController8;
[GUI] ToggleButton _configureControllerH; [GUI] ToggleButton _configureControllerH;
[GUI] ToggleButton _gdbStubToggle; [GUI] ToggleButton _gdbStubToggle;
[GUI] ToggleButton _suspendOnStartToggle;
[GUI] Adjustment _gdbStubPortSpinAdjustment; [GUI] Adjustment _gdbStubPortSpinAdjustment;
#pragma warning restore CS0649, IDE0044 #pragma warning restore CS0649, IDE0044
@ -322,6 +323,11 @@ namespace Ryujinx.UI.Windows
_gdbStubToggle.Click(); _gdbStubToggle.Click();
} }
if (ConfigurationState.Instance.Debug.DebuggerSuspendOnStart)
{
_suspendOnStartToggle.Click();
}
// Custom EntryCompletion Columns. If added to glade, need to override more signals // Custom EntryCompletion Columns. If added to glade, need to override more signals
ListStore tzList = new(typeof(string), typeof(string), typeof(string)); ListStore tzList = new(typeof(string), typeof(string), typeof(string));
_systemTimeZoneCompletion.Model = tzList; _systemTimeZoneCompletion.Model = tzList;
@ -668,6 +674,7 @@ namespace Ryujinx.UI.Windows
ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value = (int)_scalingFilterLevel.Value; ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value = (int)_scalingFilterLevel.Value;
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value = _multiLanSelect.ActiveId; ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value = _multiLanSelect.ActiveId;
ConfigurationState.Instance.Debug.EnableGdbStub.Value = _gdbStubToggle.Active; ConfigurationState.Instance.Debug.EnableGdbStub.Value = _gdbStubToggle.Active;
ConfigurationState.Instance.Debug.DebuggerSuspendOnStart.Value = _suspendOnStartToggle.Active;
ConfigurationState.Instance.Debug.GdbStubPort.Value = (ushort)_gdbStubPortSpinAdjustment.Value; ConfigurationState.Instance.Debug.GdbStubPort.Value = (ushort)_gdbStubPortSpinAdjustment.Value;
_previousVolumeLevel = ConfigurationState.Instance.System.AudioVolume.Value; _previousVolumeLevel = ConfigurationState.Instance.System.AudioVolume.Value;

View file

@ -3252,6 +3252,24 @@
<property name="position">9</property> <property name="position">9</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton" id="_suspendOnStartToggle">
<property name="label" translatable="yes">Suspend application on start</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="tooltip-text" translatable="yes">Suspends the application before executing the first instruction, allowing for debugging from the earliest point.</property>
<property name="halign">start</property>
<property name="margin-top">5</property>
<property name="margin-bottom">5</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>

View file

@ -21,6 +21,7 @@ namespace Ryujinx.HLE.Debugger
internal Switch Device { get; private set; } internal Switch Device { get; private set; }
public ushort GdbStubPort { get; private set; } public ushort GdbStubPort { get; private set; }
public bool SuspendOnStart { get; private set; }
private TcpListener ListenerSocket; private TcpListener ListenerSocket;
private Socket ClientSocket = null; private Socket ClientSocket = null;
@ -34,10 +35,11 @@ namespace Ryujinx.HLE.Debugger
private ulong? cThread; private ulong? cThread;
private ulong? gThread; private ulong? gThread;
public Debugger(Switch device, ushort port) public Debugger(Switch device, ushort port, bool suspendOnStart)
{ {
Device = device; Device = device;
GdbStubPort = port; GdbStubPort = port;
SuspendOnStart = suspendOnStart;
ARMeilleure.Optimizations.EnableDebugging = true; ARMeilleure.Optimizations.EnableDebugging = true;

View file

@ -179,6 +179,11 @@ namespace Ryujinx.HLE
/// </summary> /// </summary>
public ushort GdbStubPort { get; internal set; } public ushort GdbStubPort { get; internal set; }
/// <summary>
/// Suspend execution when starting an application
/// </summary>
public bool DebuggerSuspendOnStart { get; internal set; }
public HLEConfiguration(VirtualFileSystem virtualFileSystem, public HLEConfiguration(VirtualFileSystem virtualFileSystem,
LibHacHorizonManager libHacHorizonManager, LibHacHorizonManager libHacHorizonManager,
ContentManager contentManager, ContentManager contentManager,
@ -206,7 +211,8 @@ namespace Ryujinx.HLE
string multiplayerLanInterfaceId, string multiplayerLanInterfaceId,
MultiplayerMode multiplayerMode, MultiplayerMode multiplayerMode,
bool enableGdbStub, bool enableGdbStub,
ushort gdbStubPort) ushort gdbStubPort,
bool debuggerSuspendOnStart)
{ {
VirtualFileSystem = virtualFileSystem; VirtualFileSystem = virtualFileSystem;
LibHacHorizonManager = libHacHorizonManager; LibHacHorizonManager = libHacHorizonManager;
@ -236,6 +242,7 @@ namespace Ryujinx.HLE
MultiplayerMode = multiplayerMode; MultiplayerMode = multiplayerMode;
EnableGdbStub = enableGdbStub; EnableGdbStub = enableGdbStub;
GdbStubPort = gdbStubPort; GdbStubPort = gdbStubPort;
DebuggerSuspendOnStart = debuggerSuspendOnStart;
} }
} }
} }

View file

@ -54,7 +54,7 @@ namespace Ryujinx.HLE
AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver); AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(Configuration.AudioDeviceDriver);
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags); Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
Gpu = new GpuContext(Configuration.GpuRenderer); Gpu = new GpuContext(Configuration.GpuRenderer);
Debugger = Configuration.EnableGdbStub ? new Debugger.Debugger(this, Configuration.GdbStubPort) : null; Debugger = Configuration.EnableGdbStub ? new Debugger.Debugger(this, Configuration.GdbStubPort, Configuration.DebuggerSuspendOnStart) : null;
System = new HOS.Horizon(this); System = new HOS.Horizon(this);
Statistics = new PerformanceStatistics(); Statistics = new PerformanceStatistics();
Hid = new Hid(this, System.HidStorage); Hid = new Hid(this, System.HidStorage);

View file

@ -233,6 +233,9 @@ namespace Ryujinx.Headless.SDL2
[Option("gdb-stub-port", Required = false, Default = 55555, HelpText = "Specifies which TCP port the GDB stub listens on.")] [Option("gdb-stub-port", Required = false, Default = 55555, HelpText = "Specifies which TCP port the GDB stub listens on.")]
public ushort GdbStubPort { get; set; } public ushort GdbStubPort { get; set; }
[Option("suspend-on-start", Required = false, Default = false, HelpText = "Suspend execution when starting an application.")]
public bool DebuggerSuspendOnStart { get; set; }
// Values // Values
[Value(0, MetaName = "input", HelpText = "Input to load.", Required = true)] [Value(0, MetaName = "input", HelpText = "Input to load.", Required = true)]

View file

@ -573,7 +573,8 @@ namespace Ryujinx.Headless.SDL2
options.MultiplayerLanInterfaceId, options.MultiplayerLanInterfaceId,
Common.Configuration.Multiplayer.MultiplayerMode.Disabled, Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
options.EnableGdbStub, options.EnableGdbStub,
options.GdbStubPort); options.GdbStubPort,
options.DebuggerSuspendOnStart);
return new Switch(configuration); return new Switch(configuration);
} }

View file

@ -396,6 +396,11 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary> /// </summary>
public ushort GdbStubPort { get; set; } public ushort GdbStubPort { get; set; }
/// <summary>
/// Which TCP port should the GDB stub listen on
/// </summary>
public ushort DebuggerSuspendOnStart { get; set; }
/// <summary> /// <summary>
/// Loads a configuration file from disk /// Loads a configuration file from disk
/// </summary> /// </summary>

View file

@ -592,12 +592,19 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary> /// </summary>
public ReactiveObject<ushort> GdbStubPort { get; private set; } public ReactiveObject<ushort> GdbStubPort { get; private set; }
/// <summary>
/// Suspend execution when starting an application
/// </summary>
public ReactiveObject<bool> DebuggerSuspendOnStart { get; private set; }
public DebugSection() public DebugSection()
{ {
EnableGdbStub = new ReactiveObject<bool>(); EnableGdbStub = new ReactiveObject<bool>();
EnableGdbStub.Event += static (sender, e) => LogValueChange(e, nameof(EnableGdbStub)); EnableGdbStub.Event += static (sender, e) => LogValueChange(e, nameof(EnableGdbStub));
GdbStubPort = new ReactiveObject<ushort>(); GdbStubPort = new ReactiveObject<ushort>();
GdbStubPort.Event += static (sender, e) => LogValueChange(e, nameof(GdbStubPort)); GdbStubPort.Event += static (sender, e) => LogValueChange(e, nameof(GdbStubPort));
DebuggerSuspendOnStart = new ReactiveObject<bool>();
DebuggerSuspendOnStart.Event += static (sender, e) => LogValueChange(e, nameof(DebuggerSuspendOnStart));
} }
} }

View file

@ -871,7 +871,8 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value, ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value,
ConfigurationState.Instance.Multiplayer.Mode, ConfigurationState.Instance.Multiplayer.Mode,
ConfigurationState.Instance.Debug.EnableGdbStub.Value, ConfigurationState.Instance.Debug.EnableGdbStub.Value,
ConfigurationState.Instance.Debug.GdbStubPort.Value); ConfigurationState.Instance.Debug.GdbStubPort.Value,
ConfigurationState.Instance.Debug.DebuggerSuspendOnStart.Value);
Device = new Switch(configuration); Device = new Switch(configuration);
} }

View file

@ -783,7 +783,9 @@
"MultiplayerModeLdnMitm": "ldn_mitm", "MultiplayerModeLdnMitm": "ldn_mitm",
"SettingsTabDebug": "Debug", "SettingsTabDebug": "Debug",
"SettingsTabDebugTitle": "Debug (WARNING: For developer use only)", "SettingsTabDebugTitle": "Debug (WARNING: For developer use only)",
"SettingsTabDebugEnableGDBStub": "Enable GDB Stub", "EnableGDBStub": "Enable GDB Stub",
"GDBStubToggleTooltip": "Enables the GDB stub which makes it possible to debug the running application. For development use only!", "GDBStubToggleTooltip": "Enables the GDB stub which makes it possible to debug the running application. For development use only!",
"GDBStubPort": "GDB stub port:" "GDBStubPort": "GDB stub port:",
"DebuggerSuspendOnStart": "Suspend application on start",
"DebuggerSuspendOnStartTooltip": "Suspends the application before executing the first instruction, allowing for debugging from the earliest point."
} }

View file

@ -56,6 +56,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private int _multiplayerModeIndex; private int _multiplayerModeIndex;
private bool _enableGDBStub; private bool _enableGDBStub;
private ushort _gdbStubPort; private ushort _gdbStubPort;
private bool _debuggerSuspendOnStart;
public int ResolutionScale public int ResolutionScale
{ {
@ -281,6 +282,16 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
} }
public bool DebuggerSuspendOnStart
{
get => _debuggerSuspendOnStart;
set
{
_debuggerSuspendOnStart = value;
ConfigurationState.Instance.Debug.DebuggerSuspendOnStart.Value = _debuggerSuspendOnStart;
}
}
public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this() public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this()
{ {
_virtualFileSystem = virtualFileSystem; _virtualFileSystem = virtualFileSystem;

View file

@ -30,7 +30,7 @@
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Orientation="Vertical"> Orientation="Vertical">
<CheckBox IsChecked="{Binding EnableGdbStub}"> <CheckBox IsChecked="{Binding EnableGdbStub}">
<TextBlock Text="{locale:Locale SettingsTabDebugEnableGDBStub}" <TextBlock Text="{locale:Locale EnableGDBStub}"
ToolTip.Tip="{locale:Locale GDBStubToggleTooltip}" /> ToolTip.Tip="{locale:Locale GDBStubToggleTooltip}" />
</CheckBox> </CheckBox>
</StackPanel> </StackPanel>
@ -48,6 +48,13 @@
Minimum="1024" Minimum="1024"
Maximum="65535" /> Maximum="65535" />
</StackPanel> </StackPanel>
<StackPanel
Orientation="Horizontal">
<CheckBox IsChecked="{Binding DebuggerSuspendOnStart}">
<TextBlock Text="{locale:Locale DebuggerSuspendOnStart}"
ToolTip.Tip="{locale:Locale DebuggerSuspendOnStartTooltip}" />
</CheckBox>
</StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
</ScrollViewer> </ScrollViewer>