mirror of
https://github.com/par274/sharpemu.git
synced 2026-08-08 18:55:41 +08:00
[AGC/Vulkan] Extend PS5 runtime and rendering compatibility (#216)
* [Core] Add POSIX native execution and PS5 SELF support Extend the native backend, guest TLS, fixed-address memory, and loader paths needed by PS5 titles on Windows, Linux, and macOS. Keep workstation GC so high-core-count hosts do not reserve over fixed guest image bases. * [HLE] Expand PS5 service and media compatibility Add the kernel, threading, save-data, networking, audio, video-codec, font, dialog, and service exports required by newer PS5 software. Preserve every SysAbi NID currently registered by main while adding the compatibility surface used by ASTRO BOT. * [AGC/Vulkan] Extend Gen5 shader and presentation support Expand PM4 handling, Gen5 shader translation, MRT and packed export support, guest image tracking, depth initialization, texture aliasing, and Vulkan presentation. Add the performance overlay and address-filtered diagnostics used to validate ASTRO BOT with original shaders. * [Core] Align static TLS reservation across hosts * [Pad] Align primary user ID with UserService * [Gpu] Preserve runtime scalar buffers across renderer seam * [AGC] Restore omitted command helper exports * [Vulkan] Reuse primary views for promoted MRT targets * [Vulkan] Preserve scratch storage bindings in compute dispatches
This commit is contained in:
@@ -40,6 +40,11 @@ public static class HostWindowInput
|
||||
{
|
||||
keyboard.KeyDown += (_, key, _) =>
|
||||
{
|
||||
if (key == Key.F1)
|
||||
{
|
||||
VideoOut.PerfOverlay.Toggle();
|
||||
}
|
||||
|
||||
lock (Gate)
|
||||
{
|
||||
Pressed.Add(key);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using SharpEmu.HLE;
|
||||
|
||||
namespace SharpEmu.Libs.Pad;
|
||||
|
||||
public static class ImeExports
|
||||
{
|
||||
private const int PrimaryUserId = 0x10000000;
|
||||
private const int ImeErrorInvalidAddress = unchecked((int)0x80BC0001);
|
||||
private const int ImeErrorInvalidUserId = unchecked((int)0x80BC0010);
|
||||
private const int ImeErrorNotOpened = unchecked((int)0x80BC0005);
|
||||
|
||||
private static bool _keyboardOpen;
|
||||
public static int ImeKeyboardOpen(CpuContext ctx)
|
||||
{
|
||||
var userId = unchecked((int)ctx[CpuRegister.Rdi]);
|
||||
var parameterAddress = ctx[CpuRegister.Rsi];
|
||||
if (parameterAddress == 0)
|
||||
{
|
||||
return SetReturn(ctx, ImeErrorInvalidAddress);
|
||||
}
|
||||
|
||||
if (userId != PrimaryUserId)
|
||||
{
|
||||
return SetReturn(ctx, ImeErrorInvalidUserId);
|
||||
}
|
||||
|
||||
_keyboardOpen = true;
|
||||
return SetReturn(ctx, 0);
|
||||
}
|
||||
public static int ImeUpdate(CpuContext ctx) =>
|
||||
SetReturn(ctx, _keyboardOpen ? 0 : ImeErrorNotOpened);
|
||||
|
||||
private static int SetReturn(CpuContext ctx, int result)
|
||||
{
|
||||
ctx[CpuRegister.Rax] = unchecked((ulong)result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using System.Buffers.Binary;
|
||||
using System.Diagnostics;
|
||||
using SharpEmu.HLE;
|
||||
|
||||
namespace SharpEmu.Libs.Pad;
|
||||
|
||||
public static class MouseExports
|
||||
{
|
||||
private const int PrimaryUserId = 0x10000000;
|
||||
private const int MouseDataSize = 0x28;
|
||||
private const int MouseErrorInvalidArgument = unchecked((int)0x80020002);
|
||||
private const int MouseErrorInvalidHandle = unchecked((int)0x80020003);
|
||||
private const int MouseErrorNotInitialized = unchecked((int)0x80020005);
|
||||
private const int MouseErrorAlreadyOpened = unchecked((int)0x80020008);
|
||||
|
||||
private static readonly bool[] OpenHandles = new bool[2];
|
||||
private static bool _initialized;
|
||||
public static int MouseInit(CpuContext ctx)
|
||||
{
|
||||
_initialized = true;
|
||||
Array.Clear(OpenHandles);
|
||||
return SetReturn(ctx, 0);
|
||||
}
|
||||
public static int MouseOpen(CpuContext ctx)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
return SetReturn(ctx, MouseErrorNotInitialized);
|
||||
}
|
||||
|
||||
var userId = unchecked((int)ctx[CpuRegister.Rdi]);
|
||||
var type = unchecked((int)ctx[CpuRegister.Rsi]);
|
||||
var index = unchecked((int)ctx[CpuRegister.Rdx]);
|
||||
if (userId != PrimaryUserId || type != 0 || index is < 0 or > 1)
|
||||
{
|
||||
return SetReturn(ctx, MouseErrorInvalidArgument);
|
||||
}
|
||||
|
||||
if (OpenHandles[index])
|
||||
{
|
||||
return SetReturn(ctx, MouseErrorAlreadyOpened);
|
||||
}
|
||||
|
||||
OpenHandles[index] = true;
|
||||
return SetReturn(ctx, index);
|
||||
}
|
||||
public static int MouseRead(CpuContext ctx)
|
||||
{
|
||||
var handle = unchecked((int)ctx[CpuRegister.Rdi]);
|
||||
var dataAddress = ctx[CpuRegister.Rsi];
|
||||
var count = unchecked((int)ctx[CpuRegister.Rdx]);
|
||||
if (dataAddress == 0 || count is < 1 or > 64)
|
||||
{
|
||||
return SetReturn(ctx, MouseErrorInvalidArgument);
|
||||
}
|
||||
|
||||
if (handle is < 0 or > 1 || !OpenHandles[handle])
|
||||
{
|
||||
return SetReturn(ctx, MouseErrorInvalidHandle);
|
||||
}
|
||||
|
||||
Span<byte> data = stackalloc byte[MouseDataSize];
|
||||
data.Clear();
|
||||
var ticks = Stopwatch.GetTimestamp();
|
||||
var timestamp =
|
||||
((ulong)(ticks / Stopwatch.Frequency) * 1_000_000UL) +
|
||||
((ulong)(ticks % Stopwatch.Frequency) * 1_000_000UL / (ulong)Stopwatch.Frequency);
|
||||
BinaryPrimitives.WriteUInt64LittleEndian(data, timestamp);
|
||||
data[0x08] = 0; // No host mouse is exposed to the guest yet.
|
||||
return ctx.Memory.TryWrite(dataAddress, data)
|
||||
? SetReturn(ctx, 1)
|
||||
: SetReturn(ctx, (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT);
|
||||
}
|
||||
|
||||
[SysAbiExport(
|
||||
Nid = "cAnT0Rw-IwU",
|
||||
ExportName = "sceMouseClose",
|
||||
Target = Generation.Gen4 | Generation.Gen5,
|
||||
LibraryName = "libSceMouse")]
|
||||
public static int MouseClose(CpuContext ctx)
|
||||
{
|
||||
var handle = unchecked((int)ctx[CpuRegister.Rdi]);
|
||||
if (handle is < 0 or > 1 || !OpenHandles[handle])
|
||||
{
|
||||
return SetReturn(ctx, MouseErrorInvalidHandle);
|
||||
}
|
||||
|
||||
OpenHandles[handle] = false;
|
||||
return SetReturn(ctx, 0);
|
||||
}
|
||||
|
||||
private static int SetReturn(CpuContext ctx, int result)
|
||||
{
|
||||
ctx[CpuRegister.Rax] = unchecked((ulong)result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,11 @@ public static class PadExports
|
||||
private const int OrbisPadErrorNotInitialized = unchecked((int)0x80920005);
|
||||
private const int OrbisPadErrorDeviceNotConnected = unchecked((int)0x80920007);
|
||||
private const int OrbisPadErrorDeviceNoHandle = unchecked((int)0x80920008);
|
||||
private const int PrimaryUserId = 1000;
|
||||
// Keep the pad session on the same retail user id returned by
|
||||
// libSceUserService. A mismatched emulator-local id makes games pass a
|
||||
// valid 0x10000000 user to scePadOpen and receive DEVICE_NOT_CONNECTED,
|
||||
// leaving every later keyboard/gamepad read on an invalid handle.
|
||||
private const int PrimaryUserId = 0x10000000;
|
||||
private const int StandardPortType = 0;
|
||||
private const int PrimaryPadHandle = 1;
|
||||
private const int ControllerInformationSize = 0x1C;
|
||||
|
||||
Reference in New Issue
Block a user