[VideoOut] Separate guest display mode from presentation buffer dimensions
This commit is contained in:
parent
f8c85b6168
commit
5c9b409e18
|
|
@ -1011,7 +1011,7 @@ internal static partial class Program
|
|||
|
||||
private static void PrintUsage()
|
||||
{
|
||||
Log.Info("Usage: SharpEmu.CLI [--strict] [--trace-imports[=N]] [--cpu-engine=<native>] [--console=<ps5>] [--console-language=<language>] [--log-level=<level>] [--log-file[=<path>]] [--window-mode=<windowed|borderless|exclusive>] [--resolution=<WIDTHxHEIGHT>] [--display=<N>] [--refresh-rate=<HZ>] [--scaling=<fit|cover|stretch|integer>] [--vsync=<on|off>] [--hdr=<auto|on|off>] [--overlay=<on|off>] [--overlay-mode=<full|minimal|titlebar>] [--overlay-corner=<topleft|topright|bottomright|bottomleft>] [--debug-server[=host:port]] <path-to-eboot.bin>");
|
||||
Log.Info("Usage: SharpEmu.CLI [--strict] [--trace-imports[=N]] [--cpu-engine=<native>] [--console=<ps5>] [--console-language=<language>] [--log-level=<level>] [--log-file[=<path>]] [--window-mode=<windowed|borderless|exclusive>] [--resolution=<WIDTHxHEIGHT>] [--guest-resolution=<1920x1080|3840x2160>] [--display=<N>] [--refresh-rate=<HZ>] [--scaling=<fit|cover|stretch|integer>] [--vsync=<on|off>] [--hdr=<auto|on|off>] [--overlay=<on|off>] [--overlay-mode=<full|minimal|titlebar>] [--overlay-corner=<topleft|topright|bottomright|bottomleft>] [--debug-server[=host:port]] <path-to-eboot.bin>");
|
||||
Log.Info(@"Example: SharpEmu.CLI --cpu-engine=native --trace-imports=64 --log-level=debug --log-file ""E:\Games\...\eboot.bin""");
|
||||
Log.Info("Debug server: --debug-server starts a live debug listener (default 127.0.0.1:5714); connect with SharpEmu.DebugClient.");
|
||||
}
|
||||
|
|
@ -1076,6 +1076,7 @@ internal static partial class Program
|
|||
var systemLanguage = 1;
|
||||
HostWindowMode? windowModeOverride = null;
|
||||
HostScalingMode? scalingModeOverride = null;
|
||||
GuestDisplayResolution? guestResolutionOverride = null;
|
||||
int? windowWidthOverride = null;
|
||||
int? windowHeightOverride = null;
|
||||
int? displayIndexOverride = null;
|
||||
|
|
@ -1135,6 +1136,18 @@ internal static partial class Program
|
|||
windowHeightOverride = windowHeight;
|
||||
continue;
|
||||
}
|
||||
if (TrySplitOption(argument, "--guest-resolution", out var guestResolutionText))
|
||||
{
|
||||
if (guestResolutionText is not ("1920x1080" or "3840x2160"))
|
||||
{
|
||||
ebootPath = string.Empty;
|
||||
runtimeOptions = default;
|
||||
return false;
|
||||
}
|
||||
guestResolutionOverride = guestResolutionText == "3840x2160"
|
||||
? GuestDisplayResolution.UltraHd : GuestDisplayResolution.Hd;
|
||||
continue;
|
||||
}
|
||||
if (TrySplitOption(argument, "--display", out var displayText))
|
||||
{
|
||||
if (!int.TryParse(displayText, out var displayIndex) || displayIndex < 0)
|
||||
|
|
@ -1392,6 +1405,7 @@ internal static partial class Program
|
|||
{
|
||||
WindowMode = windowModeOverride ?? configuredVideoOptions.WindowMode,
|
||||
ScalingMode = scalingModeOverride ?? configuredVideoOptions.ScalingMode,
|
||||
GuestResolution = guestResolutionOverride ?? configuredVideoOptions.GuestResolution,
|
||||
Width = windowWidthOverride ?? configuredVideoOptions.Width,
|
||||
Height = windowHeightOverride ?? configuredVideoOptions.Height,
|
||||
DisplayIndex = displayIndexOverride ?? configuredVideoOptions.DisplayIndex,
|
||||
|
|
@ -1432,6 +1446,8 @@ internal static partial class Program
|
|||
{
|
||||
WindowMode = windowMode,
|
||||
ScalingMode = scalingMode,
|
||||
GuestResolution = effective.GuestResolution == "3840x2160"
|
||||
? GuestDisplayResolution.UltraHd : GuestDisplayResolution.Hd,
|
||||
Width = hasResolution ? configuredWidth : defaults.Width,
|
||||
Height = hasResolution ? configuredHeight : defaults.Height,
|
||||
DisplayIndex = effective.DisplayIndex,
|
||||
|
|
|
|||
|
|
@ -70,6 +70,11 @@ public sealed class GuiSettings
|
|||
|
||||
public string Resolution { get; set; } = "1920x1080";
|
||||
|
||||
public string GuestResolution { get; set; } = "1920x1080";
|
||||
|
||||
internal static string NormalizeGuestResolution(string? value) =>
|
||||
string.Equals(value, "3840x2160", StringComparison.OrdinalIgnoreCase) ? "3840x2160" : "1920x1080";
|
||||
|
||||
public int DisplayIndex { get; set; }
|
||||
|
||||
public int RefreshRate { get; set; }
|
||||
|
|
@ -89,9 +94,6 @@ public sealed class GuiSettings
|
|||
|
||||
public string BinkPlaybackMode { get; set; } = "Guest";
|
||||
|
||||
/// <summary>Internal render resolution scale (1.0 = native, 0.5 = half).</summary>
|
||||
public double RenderResolutionScale { get; set; } = 1.0;
|
||||
|
||||
/// <summary>
|
||||
/// Discord application ID used for Rich Presence; the default is the
|
||||
/// SharpEmu application. Override to rebrand what Discord shows as
|
||||
|
|
@ -184,6 +186,7 @@ public sealed class GuiSettings
|
|||
"Ukrainian");
|
||||
settings.WindowMode = NormalizeChoice(settings.WindowMode, "Windowed", "Borderless", "Exclusive");
|
||||
settings.Resolution = NormalizeResolution(settings.Resolution);
|
||||
settings.GuestResolution = NormalizeGuestResolution(settings.GuestResolution);
|
||||
settings.ScalingMode = NormalizeChoice(settings.ScalingMode, "Fit", "Cover", "Stretch", "Integer");
|
||||
settings.HdrMode = NormalizeChoice(settings.HdrMode, "Auto", "On", "Off");
|
||||
settings.BinkPlaybackMode = NormalizeChoice(settings.BinkPlaybackMode, "Guest", "Host", "Skip");
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@
|
|||
"Options.WindowMode.Exclusive": "Exclusive",
|
||||
"Options.Resolution.Label": "Resolution",
|
||||
"Options.Resolution.Desc": "Initial window size or exclusive fullscreen resolution.",
|
||||
"Options.GuestResolution.Label": "Game display mode",
|
||||
"Options.GuestResolution.Desc": "Display resolution reported to the game. Defaults to 1080p. Games choose their internal rendering resolution; fixed-resolution games may ignore this setting.",
|
||||
"Options.Display.Label": "Display",
|
||||
"Options.Display.Desc": "Monitor used for centering and fullscreen.",
|
||||
"Options.RefreshRate.Label": "Refresh rate",
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public partial class MainWindow
|
|||
GameLogLevelBox.ItemsSource = _logLevelChoices;
|
||||
GameWindowModeBox.ItemsSource = _windowModeChoices;
|
||||
GameScalingModeBox.ItemsSource = _scalingModeChoices;
|
||||
GameGuestResolutionBox.ItemsSource = new[] { "1920x1080", "3840x2160" };
|
||||
GameHdrModeBox.ItemsSource = _hdrModeChoices;
|
||||
GameOverlayModeBox.ItemsSource = _overlayModeChoices;
|
||||
GameOverlayCornerBox.ItemsSource = _overlayCornerChoices;
|
||||
|
|
@ -115,6 +116,7 @@ public partial class MainWindow
|
|||
GameRefreshRateBox.SelectionChanged += (_, _) => PersistOpenGameSettings();
|
||||
GameScalingModeBox.SelectionChanged += (_, _) => PersistOpenGameSettings();
|
||||
GameVSyncToggle.IsCheckedChanged += (_, _) => PersistOpenGameSettings();
|
||||
GameGuestResolutionBox.SelectionChanged += (_, _) => PersistOpenGameSettings();
|
||||
GameHdrModeBox.SelectionChanged += (_, _) => PersistOpenGameSettings();
|
||||
GameOverlayEnabledToggle.IsCheckedChanged += (_, _) => PersistOpenGameSettings();
|
||||
GameOverlayModeBox.SelectionChanged += (_, _) => PersistOpenGameSettings();
|
||||
|
|
@ -216,6 +218,7 @@ public partial class MainWindow
|
|||
_scalingModeChoices,
|
||||
effective.ScalingMode,
|
||||
"Fit");
|
||||
GameGuestResolutionBox.SelectedItem = effective.GuestResolution;
|
||||
GameVSyncToggle.IsChecked = effective.VSync;
|
||||
GameOverlayEnabledToggle.IsChecked = effective.OverlayEnabled;
|
||||
GameOverlayModeBox.SelectedItem = FindChoice(_overlayModeChoices, effective.OverlayMode, "TitleBar");
|
||||
|
|
@ -277,6 +280,7 @@ public partial class MainWindow
|
|||
LogToFile = GameLogToFileToggle.IsChecked == true,
|
||||
WindowMode = SelectedComboText(GameWindowModeBox, "Windowed"),
|
||||
Resolution = SelectedComboText(GameResolutionBox, "1920x1080"),
|
||||
GuestResolution = SelectedComboText(GameGuestResolutionBox, "1920x1080"),
|
||||
DisplayIndex = GameDisplayBox.SelectedItem is HostDisplayOption display
|
||||
? display.Index
|
||||
: 0,
|
||||
|
|
|
|||
|
|
@ -856,6 +856,14 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
|
||||
<local:SettingRow x:Name="GameGuestResolutionRow"
|
||||
Classes="optionRow"
|
||||
Label="{Binding [Options.GuestResolution.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.GuestResolution.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="GameGuestResolutionBox"
|
||||
Classes="optionValue"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
<local:SettingRow x:Name="GameDisplayRow"
|
||||
Classes="optionRow"
|
||||
Label="{Binding [Options.Display.Label],
|
||||
|
|
@ -1490,6 +1498,12 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||
Classes="optionValue"
|
||||
VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
<local:SettingRow x:Name="GuestResolutionRow"
|
||||
Classes="optionRow"
|
||||
Label="{Binding [Options.GuestResolution.Label], Source={x:Static local:Localization.Instance}}"
|
||||
Description="{Binding [Options.GuestResolution.Desc], Source={x:Static local:Localization.Instance}}">
|
||||
<ComboBox x:Name="GuestResolutionBox" Classes="optionValue" VerticalAlignment="Center" />
|
||||
</local:SettingRow>
|
||||
<local:SettingRow x:Name="DisplayRow"
|
||||
Classes="optionRow"
|
||||
Label="{Binding [Options.Display.Label], Source={x:Static local:Localization.Instance}}"
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ public partial class MainWindow : Window
|
|||
WindowModeBox.SelectionChanged += (_, _) => _settings.WindowMode = SelectedComboText(WindowModeBox, "Windowed");
|
||||
DisplayBox.SelectionChanged += (_, _) => OnHostDisplayChanged();
|
||||
ResolutionBox.SelectionChanged += (_, _) => OnHostResolutionChanged();
|
||||
GuestResolutionBox.SelectionChanged += (_, _) => _settings.GuestResolution = SelectedComboText(GuestResolutionBox, "1920x1080");
|
||||
RefreshRateBox.SelectionChanged += (_, _) => OnHostRefreshRateChanged();
|
||||
ScalingModeBox.SelectionChanged += (_, _) => _settings.ScalingMode = SelectedComboText(ScalingModeBox, "Fit");
|
||||
VSyncToggle.IsCheckedChanged += (_, _) => _settings.VSync = VSyncToggle.IsChecked == true;
|
||||
|
|
@ -1249,6 +1250,7 @@ public partial class MainWindow : Window
|
|||
LogLevelBox.ItemsSource = _logLevelChoices;
|
||||
WindowModeBox.ItemsSource = _windowModeChoices;
|
||||
ScalingModeBox.ItemsSource = _scalingModeChoices;
|
||||
GuestResolutionBox.ItemsSource = new[] { "1920x1080", "3840x2160" };
|
||||
HdrModeBox.ItemsSource = _hdrModeChoices;
|
||||
BinkPlaybackBox.ItemsSource = _binkPlaybackChoices;
|
||||
OverlayModeBox.ItemsSource = _overlayModeChoices;
|
||||
|
|
@ -1324,6 +1326,7 @@ public partial class MainWindow : Window
|
|||
LoadHostDisplayOptions();
|
||||
ScalingModeBox.SelectedIndex = ChoiceIndex(_settings.ScalingMode, "Fit", "Cover", "Stretch", "Integer");
|
||||
VSyncToggle.IsChecked = _settings.VSync;
|
||||
GuestResolutionBox.SelectedItem = GuiSettings.NormalizeGuestResolution(_settings.GuestResolution);
|
||||
HdrModeBox.SelectedIndex = ChoiceIndex(_settings.HdrMode, "Auto", "On", "Off");
|
||||
OverlayEnabledToggle.IsChecked = _settings.OverlayEnabled;
|
||||
OverlayModeBox.SelectedIndex = ChoiceIndex(_settings.OverlayMode, "Full", "Minimal", "TitleBar");
|
||||
|
|
@ -2560,13 +2563,6 @@ public partial class MainWindow : Window
|
|||
});
|
||||
_appliedEnvironmentVariables.Add(BinkModeEnvironmentName);
|
||||
|
||||
Environment.SetEnvironmentVariable(
|
||||
"SHARPEMU_RENDER_SCALE",
|
||||
_settings.RenderResolutionScale.ToString(
|
||||
"0.###",
|
||||
System.Globalization.CultureInfo.InvariantCulture));
|
||||
_appliedEnvironmentVariables.Add("SHARPEMU_RENDER_SCALE");
|
||||
|
||||
foreach (var entry in customEnvironment)
|
||||
{
|
||||
if (!CustomEnvironmentVariables.TryParseEntry(entry, out var name, out var value))
|
||||
|
|
@ -2784,6 +2780,7 @@ public partial class MainWindow : Window
|
|||
|
||||
arguments.Add($"--window-mode={launch.Settings.WindowMode.ToLowerInvariant()}");
|
||||
arguments.Add($"--resolution={launch.Settings.Resolution}");
|
||||
arguments.Add($"--guest-resolution={launch.Settings.GuestResolution}");
|
||||
arguments.Add($"--display={launch.Settings.DisplayIndex}");
|
||||
arguments.Add($"--refresh-rate={launch.Settings.RefreshRate}");
|
||||
arguments.Add($"--scaling={launch.Settings.ScalingMode.ToLowerInvariant()}");
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ public sealed class PerGameSettings
|
|||
|
||||
public string? Resolution { get; set; }
|
||||
|
||||
public string? GuestResolution { get; set; }
|
||||
|
||||
public int? DisplayIndex { get; set; }
|
||||
|
||||
public int? RefreshRate { get; set; }
|
||||
|
|
@ -52,6 +54,7 @@ public sealed class PerGameSettings
|
|||
LogToFile is null &&
|
||||
WindowMode is null &&
|
||||
Resolution is null &&
|
||||
GuestResolution is null &&
|
||||
DisplayIndex is null &&
|
||||
RefreshRate is null &&
|
||||
ScalingMode is null &&
|
||||
|
|
@ -145,6 +148,11 @@ public sealed class PerGameSettings
|
|||
Resolution = null;
|
||||
}
|
||||
|
||||
if (string.Equals(GuestResolution, global.GuestResolution, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
GuestResolution = null;
|
||||
}
|
||||
|
||||
if (DisplayIndex == global.DisplayIndex)
|
||||
{
|
||||
DisplayIndex = null;
|
||||
|
|
@ -272,6 +280,7 @@ public sealed record EffectiveLaunchSettings(
|
|||
bool LogToFile,
|
||||
string WindowMode,
|
||||
string Resolution,
|
||||
string GuestResolution,
|
||||
int DisplayIndex,
|
||||
int RefreshRate,
|
||||
string ScalingMode,
|
||||
|
|
@ -289,6 +298,7 @@ public sealed record EffectiveLaunchSettings(
|
|||
perGame?.LogToFile ?? global.LogToFile,
|
||||
perGame?.WindowMode ?? global.WindowMode,
|
||||
perGame?.Resolution ?? global.Resolution,
|
||||
GuiSettings.NormalizeGuestResolution(perGame?.GuestResolution ?? global.GuestResolution),
|
||||
Math.Max(0, perGame?.DisplayIndex ?? global.DisplayIndex),
|
||||
Math.Clamp(perGame?.RefreshRate ?? global.RefreshRate, 0, 1000),
|
||||
perGame?.ScalingMode ?? global.ScalingMode,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,13 @@ public enum HostScalingMode
|
|||
Integer,
|
||||
}
|
||||
|
||||
// The display mode exposed to the guest, independent of host window and guest buffer sizes.
|
||||
public enum GuestDisplayResolution
|
||||
{
|
||||
Hd = 1,
|
||||
UltraHd = 2,
|
||||
}
|
||||
|
||||
public enum HostHdrMode
|
||||
{
|
||||
Auto,
|
||||
|
|
@ -55,6 +62,8 @@ public sealed record HostVideoOptions
|
|||
|
||||
public int Height { get; init; } = 1080;
|
||||
|
||||
public GuestDisplayResolution GuestResolution { get; init; } = GuestDisplayResolution.Hd;
|
||||
|
||||
public int DisplayIndex { get; init; }
|
||||
|
||||
public int RefreshRate { get; init; }
|
||||
|
|
@ -82,6 +91,7 @@ public sealed record HostVideoOptions
|
|||
{
|
||||
Width = Math.Clamp(Width, 640, 16384),
|
||||
Height = Math.Clamp(Height, 360, 16384),
|
||||
GuestResolution = Enum.IsDefined(GuestResolution) ? GuestResolution : GuestDisplayResolution.Hd,
|
||||
DisplayIndex = Math.Max(0, DisplayIndex),
|
||||
RefreshRate = Math.Clamp(RefreshRate, 0, 1000),
|
||||
HdrMode = Enum.IsDefined(HdrMode) ? HdrMode : HostHdrMode.Auto,
|
||||
|
|
|
|||
|
|
@ -519,18 +519,19 @@ public static partial class VideoOutExports
|
|||
}
|
||||
|
||||
Span<byte> status = stackalloc byte[VideoOutOutputStatusSize];
|
||||
WriteOutputStatus(status, port.OutputWidth, port.OutputHeight, port.RefreshRate,
|
||||
WriteOutputStatus(status, HostVideoHost.CurrentOptions.GuestResolution, port.RefreshRate,
|
||||
HostVideoHost.IsHdrOutputSupported);
|
||||
return ctx.Memory.TryWrite(statusAddress, status)
|
||||
? (int)OrbisGen2Result.ORBIS_GEN2_OK
|
||||
: (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
|
||||
}
|
||||
|
||||
internal static void WriteOutputStatus(Span<byte> status, uint width, uint height, uint refreshRate,
|
||||
internal static void WriteOutputStatus(Span<byte> status, GuestDisplayResolution resolution, uint refreshRate,
|
||||
bool hdrOutputSupported)
|
||||
{
|
||||
status.Clear();
|
||||
var resolutionClass = width >= 3840 || height >= 2160 ? 2 : 1;
|
||||
// Buffer registration describes a source image, not the connected display.
|
||||
var resolutionClass = (int)resolution;
|
||||
BinaryPrimitives.WriteInt32LittleEndian(status[0x00..0x04], resolutionClass);
|
||||
BinaryPrimitives.WriteInt32LittleEndian(status[0x04..0x08], hdrOutputSupported ? 2 : 1);
|
||||
// The status uses a refresh-rate code, not the frequency used for pacing.
|
||||
|
|
|
|||
|
|
@ -8,6 +8,33 @@ namespace SharpEmu.Libs.Tests.GUI;
|
|||
|
||||
public sealed class PerGameSettingsTests
|
||||
{
|
||||
[Fact]
|
||||
public void GuestResolutionDefaultsToHdAndCanBeOverriddenPerGame()
|
||||
{
|
||||
var global = new GuiSettings { Resolution = "3840x2160" };
|
||||
Assert.Equal("1920x1080", EffectiveLaunchSettings.Resolve(global, null).GuestResolution);
|
||||
var game = new PerGameSettings { GuestResolution = "3840x2160" };
|
||||
game.RemoveInheritedValues(global);
|
||||
Assert.False(game.IsEmpty);
|
||||
var restored = PerGameSettings.NormalizeFromJson(System.Text.Json.JsonSerializer.Serialize(game));
|
||||
Assert.Equal("3840x2160", EffectiveLaunchSettings.Resolve(global, restored).GuestResolution);
|
||||
global.GuestResolution = "3840x2160";
|
||||
game.RemoveInheritedValues(global);
|
||||
Assert.True(game.IsEmpty);
|
||||
Assert.Equal("3840x2160", EffectiveLaunchSettings.Resolve(global, game).GuestResolution);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData("invalid")]
|
||||
[InlineData("7680x4320")]
|
||||
public void InvalidGuestResolutionFallsBackToHd(string? value)
|
||||
{
|
||||
Assert.Equal("1920x1080", EffectiveLaunchSettings.Resolve(
|
||||
new GuiSettings(), new PerGameSettings { GuestResolution = value }).GuestResolution);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NewGameInheritsWritableApp0AndGlobalCrashCapture()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public sealed class HostVideoOptionsTests
|
|||
DisplayIndex = -2,
|
||||
RefreshRate = 5000,
|
||||
HdrMode = (HostHdrMode)99,
|
||||
GuestResolution = (GuestDisplayResolution)99,
|
||||
}.Normalize();
|
||||
|
||||
Assert.Equal(640, options.Width);
|
||||
|
|
@ -25,5 +26,18 @@ public sealed class HostVideoOptionsTests
|
|||
Assert.Equal(0, options.DisplayIndex);
|
||||
Assert.Equal(1000, options.RefreshRate);
|
||||
Assert.Equal(HostHdrMode.Auto, options.HdrMode);
|
||||
Assert.Equal(GuestDisplayResolution.Hd, options.GuestResolution);
|
||||
}
|
||||
[Theory]
|
||||
[InlineData(1920, 1080, GuestDisplayResolution.UltraHd)]
|
||||
[InlineData(3840, 2160, GuestDisplayResolution.Hd)]
|
||||
public void GuestModeIsIndependentOfWindowSize(int width, int height, GuestDisplayResolution mode)
|
||||
{
|
||||
var options = new HostVideoOptions { Width = width, Height = height, GuestResolution = mode }.Normalize();
|
||||
Assert.Equal(mode, options.GuestResolution);
|
||||
Assert.Equal(GuestDisplayResolution.Hd, HostVideoOptions.Default.GuestResolution);
|
||||
Span<byte> status = stackalloc byte[0x30];
|
||||
VideoOutExports.WriteOutputStatus(status, options.GuestResolution, 60, false);
|
||||
Assert.Equal((int)mode, System.Buffers.Binary.BinaryPrimitives.ReadInt32LittleEndian(status));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public sealed class VideoOutOutputSupportTests
|
|||
Assert.Equal(expectedHdr, supported);
|
||||
|
||||
var bytes = Enumerable.Repeat((byte)0xA5, 0x32).ToArray();
|
||||
VideoOutExports.WriteOutputStatus(bytes.AsSpan(1, 0x30), 3840, 2160, 120, supported);
|
||||
VideoOutExports.WriteOutputStatus(bytes.AsSpan(1, 0x30), GuestDisplayResolution.UltraHd, 120, supported);
|
||||
|
||||
Assert.Equal(0xA5, bytes[0]);
|
||||
Assert.Equal(0xA5, bytes[^1]);
|
||||
|
|
|
|||
Loading…
Reference in New Issue