From 8bfbb9c7febd0978f3c817f8c1e93342b0d3d4d7 Mon Sep 17 00:00:00 2001 From: Berk Date: Sun, 5 Jul 2026 22:09:04 +0300 Subject: [PATCH] Avplayer implements (#21) --- src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs | 77 ++++++++++++ .../Kernel/KernelMemoryCompatExports.cs | 113 +++++++++++++++++- .../KernelPthreadExtendedCompatExports.cs | 29 +++++ .../Kernel/KernelRuntimeCompatExports.cs | 1 + 4 files changed, 215 insertions(+), 5 deletions(-) create mode 100644 src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs diff --git a/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs b/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs new file mode 100644 index 0000000..1cfc6fa --- /dev/null +++ b/src/SharpEmu.Libs/AvPlayer/AvPlayerExports.cs @@ -0,0 +1,77 @@ +// Copyright (C) 2026 SharpEmu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +using SharpEmu.HLE; +using SharpEmu.Libs.Kernel; + +namespace SharpEmu.Libs.AvPlayer; + +public static class AvPlayerExports +{ + private const int InvalidParameters = unchecked((int)0x806A0001); + private static readonly object StateGate = new(); + private static readonly HashSet Players = new(); + + [SysAbiExport( + Nid = "aS66RI0gGgo", + ExportName = "sceAvPlayerInit", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libSceAvPlayer")] + public static int AvPlayerInit(CpuContext ctx) + { + if (ctx[CpuRegister.Rdi] == 0 || + !KernelMemoryCompatExports.TryAllocateHleData(ctx, 0x40, 16, out var handle)) + { + ctx[CpuRegister.Rax] = 0; + return 0; + } + + lock (StateGate) + { + Players.Add(handle); + } + + ctx[CpuRegister.Rax] = handle; + return unchecked((int)handle); + } + + [SysAbiExport( + Nid = "HD1YKVU26-M", + ExportName = "sceAvPlayerPostInit", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libSceAvPlayer")] + public static int AvPlayerPostInit(CpuContext ctx) + { + var handle = ctx[CpuRegister.Rdi]; + var dataAddress = ctx[CpuRegister.Rsi]; + lock (StateGate) + { + return SetReturn( + ctx, + handle != 0 && dataAddress != 0 && Players.Contains(handle) + ? 0 + : InvalidParameters); + } + } + + [SysAbiExport( + Nid = "NkJwDzKmIlw", + ExportName = "sceAvPlayerClose", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libSceAvPlayer")] + public static int AvPlayerClose(CpuContext ctx) + { + lock (StateGate) + { + return SetReturn( + ctx, + Players.Remove(ctx[CpuRegister.Rdi]) ? 0 : InvalidParameters); + } + } + + private static int SetReturn(CpuContext ctx, int result) + { + ctx[CpuRegister.Rax] = unchecked((ulong)result); + return result; + } +} diff --git a/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs index 124af76..16769f5 100644 --- a/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs @@ -103,6 +103,7 @@ public static class KernelMemoryCompatExports private static readonly Dictionary _directAllocations = new(); private static readonly Dictionary _libcAllocations = new(); private static readonly Dictionary _mappedRegions = new(); + private static readonly Dictionary _mappedRegionNames = new(); private static readonly Dictionary _tlsModuleBlocks = new(); private static readonly Dictionary _guestMounts = new(StringComparer.OrdinalIgnoreCase); private static readonly HashSet _tracedStatResults = new(StringComparer.Ordinal); @@ -231,6 +232,25 @@ public static class KernelMemoryCompatExports return true; } + internal static void RegisterReservedVirtualRange(ulong address, ulong length) + { + if (address == 0 || length == 0) + { + return; + } + + lock (_memoryGate) + { + _mappedRegions[address] = new MappedRegion( + address, + length, + Protection: 0, + IsFlexible: false, + IsDirect: false, + DirectStart: 0); + } + } + [SysAbiExport( Nid = "8zTFvBIAIN8", ExportName = "memset", @@ -2435,6 +2455,36 @@ public static class KernelMemoryCompatExports return (int)OrbisGen2Result.ORBIS_GEN2_OK; } + [SysAbiExport( + Nid = "hwVSPCmp5tM", + ExportName = "sceKernelCheckedReleaseDirectMemory", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libKernel")] + public static int KernelCheckedReleaseDirectMemory(CpuContext ctx) + { + var start = ctx[CpuRegister.Rdi]; + var length = ctx[CpuRegister.Rsi]; + + if (length == 0) + { + return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT; + } + + lock (_memoryGate) + { + if (!_directAllocations.TryGetValue(start, out var allocation) || + allocation.Length != length) + { + return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND; + } + + _directAllocations.Remove(start); + _nextPhysicalAddress = GetDirectMemoryHighWaterMarkLocked(); + } + + return (int)OrbisGen2Result.ORBIS_GEN2_OK; + } + [SysAbiExport( Nid = "L-Q3LEjIbgA", ExportName = "sceKernelMapDirectMemory", @@ -2614,6 +2664,16 @@ public static class KernelMemoryCompatExports return KernelMapNamedFlexibleMemory(ctx); } + [SysAbiExport( + Nid = "4h6F1LLbTiw", + ExportName = "sceKernelMapFlexibleMemoryInternal", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libKernel")] + public static int KernelMapFlexibleMemoryInternal(CpuContext ctx) + { + return KernelMapNamedFlexibleMemory(ctx); + } + [SysAbiExport( Nid = "2SKEx6bSq-4", ExportName = "sceKernelBatchMap", @@ -2667,6 +2727,44 @@ public static class KernelMemoryCompatExports return (int)OrbisGen2Result.ORBIS_GEN2_OK; } + [SysAbiExport( + Nid = "DGMG3JshrZU", + ExportName = "sceKernelSetVirtualRangeName", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libKernel")] + public static int KernelSetVirtualRangeName(CpuContext ctx) + { + var address = ctx[CpuRegister.Rdi]; + var length = ctx[CpuRegister.Rsi]; + var nameAddress = ctx[CpuRegister.Rdx]; + if (nameAddress == 0) + { + return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; + } + + if (!TryReadCString(ctx, nameAddress, OrbisKernelMaximumNameLength, out var nameBytes)) + { + return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT; + } + + var name = Encoding.UTF8.GetString(nameBytes); + lock (_memoryGate) + { + if (!TryFindVirtualQueryRegionLocked(address, findNext: false, out var region) || + length > region.Length || + address < region.Address || + length > region.Address + region.Length - address) + { + return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND; + } + + _mappedRegionNames[region.Address] = name; + } + + ctx[CpuRegister.Rax] = 0; + return (int)OrbisGen2Result.ORBIS_GEN2_OK; + } + [SysAbiExport( Nid = "rVjRvHJ0X6c", ExportName = "sceKernelVirtualQuery", @@ -2724,11 +2822,16 @@ public static class KernelMemoryCompatExports BinaryPrimitives.WriteInt32LittleEndian(payload[28..32], memoryType); payload[32] = unchecked((byte)stateFlags); - var name = region.IsDirect - ? "direct" - : region.IsFlexible - ? "flexible" - : string.Empty; + string name; + lock (_memoryGate) + { + name = _mappedRegionNames.GetValueOrDefault(region.Address) + ?? (region.IsDirect + ? "direct" + : region.IsFlexible + ? "flexible" + : string.Empty); + } if (!string.IsNullOrEmpty(name)) { var nameBytes = Encoding.ASCII.GetBytes(name); diff --git a/src/SharpEmu.Libs/Kernel/KernelPthreadExtendedCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelPthreadExtendedCompatExports.cs index 9ccaaa5..a798599 100644 --- a/src/SharpEmu.Libs/Kernel/KernelPthreadExtendedCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelPthreadExtendedCompatExports.cs @@ -717,6 +717,35 @@ public static class KernelPthreadExtendedCompatExports return (int)OrbisGen2Result.ORBIS_GEN2_OK; } + [SysAbiExport( + Nid = "FXPWHNk8Of0", + ExportName = "scePthreadAttrGetschedparam", + Target = Generation.Gen4 | Generation.Gen5, + LibraryName = "libKernel")] + public static int PthreadAttrGetschedparam(CpuContext ctx) + { + var attrAddress = ctx[CpuRegister.Rdi]; + var schedParamAddress = ctx[CpuRegister.Rsi]; + if (attrAddress == 0 || schedParamAddress == 0) + { + return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT; + } + + PthreadAttrState state; + lock (_stateGate) + { + state = GetOrCreateAttrStateLocked(attrAddress); + } + + if (!TryWriteInt32(ctx, schedParamAddress, state.SchedPriority)) + { + return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; + } + + ctx[CpuRegister.Rax] = 0; + return (int)OrbisGen2Result.ORBIS_GEN2_OK; + } + [SysAbiExport( Nid = "DzES9hQF4f4", ExportName = "scePthreadAttrSetschedparam", diff --git a/src/SharpEmu.Libs/Kernel/KernelRuntimeCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelRuntimeCompatExports.cs index 167c6c8..d210bc0 100644 --- a/src/SharpEmu.Libs/Kernel/KernelRuntimeCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelRuntimeCompatExports.cs @@ -752,6 +752,7 @@ public static class KernelRuntimeCompatExports _nextReservedVirtualBase = Math.Max(_nextReservedVirtualBase, mappedAddress + length); } + KernelMemoryCompatExports.RegisterReservedVirtualRange(mappedAddress, length); return (int)OrbisGen2Result.ORBIS_GEN2_OK; }