mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-14 23:16:17 +08:00
Avplayer implements (#21)
This commit is contained in:
@@ -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<ulong> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -103,6 +103,7 @@ public static class KernelMemoryCompatExports
|
|||||||
private static readonly Dictionary<ulong, DirectAllocation> _directAllocations = new();
|
private static readonly Dictionary<ulong, DirectAllocation> _directAllocations = new();
|
||||||
private static readonly Dictionary<ulong, LibcHeapAllocation> _libcAllocations = new();
|
private static readonly Dictionary<ulong, LibcHeapAllocation> _libcAllocations = new();
|
||||||
private static readonly Dictionary<ulong, MappedRegion> _mappedRegions = new();
|
private static readonly Dictionary<ulong, MappedRegion> _mappedRegions = new();
|
||||||
|
private static readonly Dictionary<ulong, string> _mappedRegionNames = new();
|
||||||
private static readonly Dictionary<ulong, ulong> _tlsModuleBlocks = new();
|
private static readonly Dictionary<ulong, ulong> _tlsModuleBlocks = new();
|
||||||
private static readonly Dictionary<string, string> _guestMounts = new(StringComparer.OrdinalIgnoreCase);
|
private static readonly Dictionary<string, string> _guestMounts = new(StringComparer.OrdinalIgnoreCase);
|
||||||
private static readonly HashSet<string> _tracedStatResults = new(StringComparer.Ordinal);
|
private static readonly HashSet<string> _tracedStatResults = new(StringComparer.Ordinal);
|
||||||
@@ -231,6 +232,25 @@ public static class KernelMemoryCompatExports
|
|||||||
return true;
|
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(
|
[SysAbiExport(
|
||||||
Nid = "8zTFvBIAIN8",
|
Nid = "8zTFvBIAIN8",
|
||||||
ExportName = "memset",
|
ExportName = "memset",
|
||||||
@@ -2435,6 +2455,36 @@ public static class KernelMemoryCompatExports
|
|||||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
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(
|
[SysAbiExport(
|
||||||
Nid = "L-Q3LEjIbgA",
|
Nid = "L-Q3LEjIbgA",
|
||||||
ExportName = "sceKernelMapDirectMemory",
|
ExportName = "sceKernelMapDirectMemory",
|
||||||
@@ -2614,6 +2664,16 @@ public static class KernelMemoryCompatExports
|
|||||||
return KernelMapNamedFlexibleMemory(ctx);
|
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(
|
[SysAbiExport(
|
||||||
Nid = "2SKEx6bSq-4",
|
Nid = "2SKEx6bSq-4",
|
||||||
ExportName = "sceKernelBatchMap",
|
ExportName = "sceKernelBatchMap",
|
||||||
@@ -2667,6 +2727,44 @@ public static class KernelMemoryCompatExports
|
|||||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
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(
|
[SysAbiExport(
|
||||||
Nid = "rVjRvHJ0X6c",
|
Nid = "rVjRvHJ0X6c",
|
||||||
ExportName = "sceKernelVirtualQuery",
|
ExportName = "sceKernelVirtualQuery",
|
||||||
@@ -2724,11 +2822,16 @@ public static class KernelMemoryCompatExports
|
|||||||
BinaryPrimitives.WriteInt32LittleEndian(payload[28..32], memoryType);
|
BinaryPrimitives.WriteInt32LittleEndian(payload[28..32], memoryType);
|
||||||
payload[32] = unchecked((byte)stateFlags);
|
payload[32] = unchecked((byte)stateFlags);
|
||||||
|
|
||||||
var name = region.IsDirect
|
string name;
|
||||||
? "direct"
|
lock (_memoryGate)
|
||||||
: region.IsFlexible
|
{
|
||||||
? "flexible"
|
name = _mappedRegionNames.GetValueOrDefault(region.Address)
|
||||||
: string.Empty;
|
?? (region.IsDirect
|
||||||
|
? "direct"
|
||||||
|
: region.IsFlexible
|
||||||
|
? "flexible"
|
||||||
|
: string.Empty);
|
||||||
|
}
|
||||||
if (!string.IsNullOrEmpty(name))
|
if (!string.IsNullOrEmpty(name))
|
||||||
{
|
{
|
||||||
var nameBytes = Encoding.ASCII.GetBytes(name);
|
var nameBytes = Encoding.ASCII.GetBytes(name);
|
||||||
|
|||||||
@@ -717,6 +717,35 @@ public static class KernelPthreadExtendedCompatExports
|
|||||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
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(
|
[SysAbiExport(
|
||||||
Nid = "DzES9hQF4f4",
|
Nid = "DzES9hQF4f4",
|
||||||
ExportName = "scePthreadAttrSetschedparam",
|
ExportName = "scePthreadAttrSetschedparam",
|
||||||
|
|||||||
@@ -752,6 +752,7 @@ public static class KernelRuntimeCompatExports
|
|||||||
_nextReservedVirtualBase = Math.Max(_nextReservedVirtualBase, mappedAddress + length);
|
_nextReservedVirtualBase = Math.Max(_nextReservedVirtualBase, mappedAddress + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KernelMemoryCompatExports.RegisterReservedVirtualRange(mappedAddress, length);
|
||||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user