unstub: preserve notice screen skip flag (#559)

* fix(system-service): preserve notice screen skip flag

* test(bink): avoid frame timing flake on CI
This commit is contained in:
Kurt Himebauch
2026-07-23 05:32:49 -04:00
committed by GitHub
parent 8e5a0bfb19
commit eb252af7b3
3 changed files with 42 additions and 5 deletions
@@ -18,6 +18,7 @@ public static class SystemServiceExports
private const int TitleIdFieldSize = 0x10;
private static string? _mainAppTitleId;
private static int _noticeScreenSkipFlag;
public static void ConfigureApplicationInfo(string? titleId)
{
@@ -37,9 +38,11 @@ public static class SystemServiceExports
return ctx.SetReturn(OrbisSystemServiceErrorParameter);
}
// No system notice screen to skip in the emulator; report "do not skip".
// Keep the flag state even though the emulator does not display the
// system notice screen. Titles use this service as a normal preference
// store and expect a later get to observe the value they set.
Span<byte> flagBytes = stackalloc byte[1];
flagBytes[0] = 0;
flagBytes[0] = unchecked((byte)Volatile.Read(ref _noticeScreenSkipFlag));
return ctx.Memory.TryWrite(flagAddress, flagBytes)
? ctx.SetReturn(0)
: ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
@@ -61,8 +64,13 @@ public static class SystemServiceExports
ExportName = "sceSystemServiceSetNoticeScreenSkipFlag",
Target = Generation.Gen5,
LibraryName = "libSceSystemService")]
public static int SystemServiceSetNoticeScreenSkipFlag(CpuContext ctx) =>
ctx.SetReturn(0);
public static int SystemServiceSetNoticeScreenSkipFlag(CpuContext ctx)
{
// The native API takes the flag value in the first argument. Treat any
// non-zero value as true, matching the bool-like PS5 ABI.
Volatile.Write(ref _noticeScreenSkipFlag, ctx[CpuRegister.Rdi] != 0 ? 1 : 0);
return ctx.SetReturn(0);
}
[SysAbiExport(
Nid = "4veE0XiIugA",
@@ -231,4 +239,7 @@ public static class SystemServiceExports
Target = Generation.Gen4 | Generation.Gen5,
LibraryName = "libSceSystemService")]
public static int SystemServiceReportAbnormalTermination(CpuContext ctx) => ctx.SetReturn(0);
internal static void ResetForTests() =>
Volatile.Write(ref _noticeScreenSkipFlag, 0);
}