mirror of
https://github.com/par274/sharpemu.git
synced 2026-08-01 15:39:47 +08:00
[AGC] Quake rendering progress: WAIT_REG_MEM, draw fixes, VideoOut, and HLE improvements (#68)
* [agc] WAIT_REG_MEM suspend/resume, draw packet fixes, new HLE exports, debug cleanup
Rebased onto upstream 79a7437 (par274/sharpemu, rewritten history).
- GpuWaitRegistry: DCBs suspended on unsatisfied WAIT_REG_MEM are re-polled
against guest memory on every submit; fixed 64-bit and standard packet parse
offsets, apply the mask, treat PM4 compare function 0 as "always".
- TryReadSubmittedDrawCount: accept the 5-dword ItDrawIndex2 form emitted by
DcbDrawIndex (count at +4); menu draws were silently discarded before.
- sceAgcDriverSubmitMultiDcbs: reversed ABI (rdi=address array, rsi=dword
sizes, rdx=count).
- VideoOut: vblank events, sceVideoOutGetFlipStatus, buffers registered via
sceVideoOutRegisterBuffers are valid flip targets.
- New HLE: libc stdio (fopen/fread/fseek/ftell/fclose/fgets), Dinkumware
_Getpctype ctype table, NpTrophy2 stubs, AMPR PAK sequential-read tracker,
MsgDialog lifecycle, NGS2 alt NIDs + dummy vtable for handle objects,
guarded memset intrinsic, abort()/strcasecmp null-arg recovery.
- Removed investigation-only code (INT3 breakpoints, qfont/mcpp dumps,
error-candidate printf traces, unconditional debug logs).
First rendered frame: Quake (PPSA01880) presents a 1920x1080 guest frame.
* Implemented a guarded native intrinsic (rep movsb) in DirectExecutionBackend to bypass HLE dispatch overhead, while preserving memory safety checks.
This commit is contained in:
@@ -18,6 +18,9 @@ public static class UserServiceExports
|
||||
private const string PrimaryUserName = "SharpEmu";
|
||||
private static int _loginEventDelivered;
|
||||
|
||||
private static readonly bool _traceUserService =
|
||||
string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_USER_SERVICE"), "1", StringComparison.Ordinal);
|
||||
|
||||
[SysAbiExport(
|
||||
Nid = "j3YMu1MVNNo",
|
||||
ExportName = "sceUserServiceInitialize",
|
||||
@@ -42,9 +45,11 @@ public static class UserServiceExports
|
||||
return ctx.SetReturn(OrbisUserServiceErrorInvalidArgument);
|
||||
}
|
||||
|
||||
return ctx.TryWriteInt32(userIdAddress, PrimaryUserId)
|
||||
? ctx.SetReturn(0)
|
||||
: ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
|
||||
var result = ctx.TryWriteInt32(userIdAddress, PrimaryUserId)
|
||||
? 0
|
||||
: (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
|
||||
TraceUserService($"get_initial_user out=0x{userIdAddress:X16} value={PrimaryUserId} result=0x{result:X8}");
|
||||
return ctx.SetReturn(result);
|
||||
}
|
||||
|
||||
[SysAbiExport(
|
||||
@@ -124,9 +129,12 @@ public static class UserServiceExports
|
||||
|
||||
Span<byte> output = stackalloc byte[nameBytes.Length + 1];
|
||||
nameBytes.CopyTo(output);
|
||||
return ctx.Memory.TryWrite(nameAddress, output)
|
||||
? ctx.SetReturn(0)
|
||||
: ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
|
||||
var result = ctx.Memory.TryWrite(nameAddress, output)
|
||||
? 0
|
||||
: (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
|
||||
TraceUserService(
|
||||
$"get_user_name user={userId} out=0x{nameAddress:X16} capacity=0x{capacity:X} value='{PrimaryUserName}' result=0x{result:X8}");
|
||||
return ctx.SetReturn(result);
|
||||
}
|
||||
|
||||
[SysAbiExport(
|
||||
@@ -152,4 +160,12 @@ public static class UserServiceExports
|
||||
? ctx.SetReturn(0)
|
||||
: ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
|
||||
}
|
||||
|
||||
private static void TraceUserService(string message)
|
||||
{
|
||||
if (_traceUserService)
|
||||
{
|
||||
Console.Error.WriteLine($"[LOADER][TRACE] user_service.{message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user