From 356ba6e082ace1ef8debe034c129d7280cc9021b Mon Sep 17 00:00:00 2001 From: microsoftv <6063922+microsoftv@users.noreply.github.com> Date: Tue, 29 Oct 2024 23:28:36 -0400 Subject: [PATCH] ngs2 latest --- src/core/libraries/ngs2/ngs2.cpp | 142 +++++++++++++++------ src/core/libraries/ngs2/ngs2.h | 77 +----------- src/core/libraries/ngs2/ngs2_impl.cpp | 163 ++++++++++++++++++++++-- src/core/libraries/ngs2/ngs2_impl.h | 171 +++++++++++++++++++++++++- 4 files changed, 427 insertions(+), 126 deletions(-) diff --git a/src/core/libraries/ngs2/ngs2.cpp b/src/core/libraries/ngs2/ngs2.cpp index f2b507ad5..0b42e2471 100644 --- a/src/core/libraries/ngs2/ngs2.cpp +++ b/src/core/libraries/ngs2/ngs2.cpp @@ -44,7 +44,7 @@ s32 PS4_SYSV_ABI sceNgs2ParseWaveformFile(const char* path, u64 offset, s32 PS4_SYSV_ABI sceNgs2ParseWaveformUser(OrbisNgs2ParseReadHandler handler, uintptr_t userData, OrbisNgs2WaveformInfo* outInfo) { LOG_INFO(Lib_Ngs2, "userData = {}", userData); - if (handler == nullptr) { + if (!handler) { LOG_ERROR(Lib_Ngs2, "handler is nullptr"); return ORBIS_NGS2_ERROR_INVALID_HANDLE; } @@ -56,7 +56,7 @@ s32 PS4_SYSV_ABI sceNgs2RackCreate(OrbisNgs2Handle systemHandle, u32 rackId, const OrbisNgs2ContextBufferInfo* bufferInfo, OrbisNgs2Handle* outHandle) { LOG_INFO(Lib_Ngs2, "rackId = {}", rackId); - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -68,7 +68,7 @@ s32 PS4_SYSV_ABI sceNgs2RackCreateWithAllocator(OrbisNgs2Handle systemHandle, u3 const OrbisNgs2BufferAllocator* allocator, OrbisNgs2Handle* outHandle) { LOG_INFO(Lib_Ngs2, "rackId = {}", rackId); - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -77,7 +77,7 @@ s32 PS4_SYSV_ABI sceNgs2RackCreateWithAllocator(OrbisNgs2Handle systemHandle, u3 s32 PS4_SYSV_ABI sceNgs2RackDestroy(OrbisNgs2Handle rackHandle, OrbisNgs2ContextBufferInfo* outBufferInfo) { - if (rackHandle == nullptr) { + if (!rackHandle) { LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; } @@ -88,7 +88,7 @@ s32 PS4_SYSV_ABI sceNgs2RackDestroy(OrbisNgs2Handle rackHandle, s32 PS4_SYSV_ABI sceNgs2RackGetInfo(OrbisNgs2Handle rackHandle, OrbisNgs2RackInfo* outInfo, size_t infoSize) { LOG_INFO(Lib_Ngs2, "infoSize = {}", infoSize); - if (rackHandle == nullptr) { + if (!rackHandle) { LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; } @@ -96,7 +96,7 @@ s32 PS4_SYSV_ABI sceNgs2RackGetInfo(OrbisNgs2Handle rackHandle, OrbisNgs2RackInf } s32 PS4_SYSV_ABI sceNgs2RackGetUserData(OrbisNgs2Handle rackHandle, uintptr_t* outUserData) { - if (rackHandle == nullptr) { + if (!rackHandle) { LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; } @@ -107,7 +107,7 @@ s32 PS4_SYSV_ABI sceNgs2RackGetUserData(OrbisNgs2Handle rackHandle, uintptr_t* o s32 PS4_SYSV_ABI sceNgs2RackGetVoiceHandle(OrbisNgs2Handle rackHandle, u32 voiceIndex, OrbisNgs2Handle* outHandle) { LOG_INFO(Lib_Ngs2, "voiceIndex = {}", voiceIndex); - if (rackHandle == nullptr) { + if (!rackHandle) { LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; } @@ -115,7 +115,7 @@ s32 PS4_SYSV_ABI sceNgs2RackGetVoiceHandle(OrbisNgs2Handle rackHandle, u32 voice } s32 PS4_SYSV_ABI sceNgs2RackLock(OrbisNgs2Handle rackHandle) { - if (rackHandle == nullptr) { + if (!rackHandle) { LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; } @@ -124,14 +124,14 @@ s32 PS4_SYSV_ABI sceNgs2RackLock(OrbisNgs2Handle rackHandle) { } s32 PS4_SYSV_ABI sceNgs2RackQueryBufferSize(u32 rackId, const OrbisNgs2RackOption* option, - OrbisNgs2ContextBufferInfo* outBufferInf) { + OrbisNgs2ContextBufferInfo* outBufferInfo) { LOG_INFO(Lib_Ngs2, "rackId = {}", rackId); return ORBIS_OK; } s32 PS4_SYSV_ABI sceNgs2RackSetUserData(OrbisNgs2Handle rackHandle, uintptr_t userData) { LOG_INFO(Lib_Ngs2, "userData = {}", userData); - if (rackHandle == nullptr) { + if (!rackHandle) { LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; } @@ -139,7 +139,7 @@ s32 PS4_SYSV_ABI sceNgs2RackSetUserData(OrbisNgs2Handle rackHandle, uintptr_t us } s32 PS4_SYSV_ABI sceNgs2RackUnlock(OrbisNgs2Handle rackHandle) { - if (rackHandle == nullptr) { + if (!rackHandle) { LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; } @@ -150,20 +150,74 @@ s32 PS4_SYSV_ABI sceNgs2RackUnlock(OrbisNgs2Handle rackHandle) { s32 PS4_SYSV_ABI sceNgs2SystemCreate(const OrbisNgs2SystemOption* option, const OrbisNgs2ContextBufferInfo* bufferInfo, OrbisNgs2Handle* outHandle) { + s32 result; + OrbisNgs2ContextBufferInfo localInfo; + if (!bufferInfo || !outHandle) { + if (!bufferInfo) { + result = ORBIS_NGS2_ERROR_INVALID_BUFFER_INFO; + LOG_ERROR(Lib_Ngs2, "Invalid system buffer info {}", (void*)bufferInfo); + } else { + result = ORBIS_NGS2_ERROR_INVALID_OUT_ADDRESS; + LOG_ERROR(Lib_Ngs2, "Invalid system handle address {}", (void*)outHandle); + } + + // TODO: Report errors? + } else { + // Make bufferInfo copy + localInfo.hostBuffer = bufferInfo->hostBuffer; + localInfo.hostBufferSize = bufferInfo->hostBufferSize; + for (int i = 0; i < 5; i++) { + localInfo.reserved[i] = bufferInfo->reserved[i]; + } + localInfo.userData = bufferInfo->userData; + + result = SystemSetup(option, &localInfo, 0, outHandle); + } + + // TODO: API reporting? + LOG_INFO(Lib_Ngs2, "called"); - return ORBIS_OK; + return result; } s32 PS4_SYSV_ABI sceNgs2SystemCreateWithAllocator(const OrbisNgs2SystemOption* option, const OrbisNgs2BufferAllocator* allocator, OrbisNgs2Handle* outHandle) { + s32 result; + if (allocator && allocator->allocHandler != 0) { + OrbisNgs2BufferAllocHandler hostAlloc = allocator->allocHandler; + if (outHandle) { + OrbisNgs2BufferFreeHandler hostFree = allocator->freeHandler; + OrbisNgs2ContextBufferInfo* bufferInfo = 0; + result = SystemSetup(option, bufferInfo, 0, 0); + if (result >= 0) { + uintptr_t sysUserData = allocator->userData; + result = hostAlloc(bufferInfo); + if (result >= 0) { + OrbisNgs2Handle* handleCopy = outHandle; + result = SystemSetup(option, bufferInfo, hostFree, handleCopy); + if (result < 0) { + if (hostFree) { + hostFree(bufferInfo); + } + } + } + } + } else { + result = ORBIS_NGS2_ERROR_INVALID_OUT_ADDRESS; + LOG_ERROR(Lib_Ngs2, "Invalid system handle address {}", (void*)outHandle); + } + } else { + result = ORBIS_NGS2_ERROR_INVALID_BUFFER_ALLOCATOR; + LOG_ERROR(Lib_Ngs2, "Invalid system buffer allocator {}", (void*)allocator); + } LOG_INFO(Lib_Ngs2, "called"); - return ORBIS_OK; + return result; } s32 PS4_SYSV_ABI sceNgs2SystemDestroy(OrbisNgs2Handle systemHandle, OrbisNgs2ContextBufferInfo* outBufferInfo) { - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -179,7 +233,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemEnumHandles(OrbisNgs2Handle* aOutHandle, u32 maxHa s32 PS4_SYSV_ABI sceNgs2SystemEnumRackHandles(OrbisNgs2Handle systemHandle, OrbisNgs2Handle* aOutHandle, u32 maxHandles) { LOG_INFO(Lib_Ngs2, "maxHandles = {}", maxHandles); - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -189,7 +243,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemEnumRackHandles(OrbisNgs2Handle systemHandle, s32 PS4_SYSV_ABI sceNgs2SystemGetInfo(OrbisNgs2Handle rackHandle, OrbisNgs2SystemInfo* outInfo, size_t infoSize) { LOG_INFO(Lib_Ngs2, "infoSize = {}", infoSize); - if (rackHandle == nullptr) { + if (!rackHandle) { LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; } @@ -197,7 +251,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemGetInfo(OrbisNgs2Handle rackHandle, OrbisNgs2Syste } s32 PS4_SYSV_ABI sceNgs2SystemGetUserData(OrbisNgs2Handle systemHandle, uintptr_t* outUserData) { - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -206,7 +260,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemGetUserData(OrbisNgs2Handle systemHandle, uintptr_ } s32 PS4_SYSV_ABI sceNgs2SystemLock(OrbisNgs2Handle systemHandle) { - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -216,15 +270,23 @@ s32 PS4_SYSV_ABI sceNgs2SystemLock(OrbisNgs2Handle systemHandle) { s32 PS4_SYSV_ABI sceNgs2SystemQueryBufferSize(const OrbisNgs2SystemOption* option, OrbisNgs2ContextBufferInfo* outBufferInfo) { - LOG_INFO(Lib_Ngs2, "called"); - return ORBIS_OK; + s32 result; + if (outBufferInfo) { + result = SystemSetup(option, outBufferInfo, 0, 0); + LOG_INFO(Lib_Ngs2, "called"); + } else { + result = ORBIS_NGS2_ERROR_INVALID_OUT_ADDRESS; + LOG_ERROR(Lib_Ngs2, "Invalid system buffer info {}", (void*)outBufferInfo); + } + + return result; } s32 PS4_SYSV_ABI sceNgs2SystemRender(OrbisNgs2Handle systemHandle, const OrbisNgs2RenderBufferInfo* aBufferInfo, u32 numBufferInfo) { LOG_INFO(Lib_Ngs2, "numBufferInfo = {}", numBufferInfo); - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -235,8 +297,10 @@ static s32 PS4_SYSV_ABI sceNgs2SystemResetOption(OrbisNgs2SystemOption* outOptio static const OrbisNgs2SystemOption option = { sizeof(OrbisNgs2SystemOption), "", 0, 512, 256, 48000, {0}}; - if (outOption == NULL) + if (!outOption) { + LOG_ERROR(Lib_Ngs2, "Invalid system option address {}", (void*)outOption); return ORBIS_NGS2_ERROR_INVALID_OPTION_ADDRESS; + } *outOption = option; LOG_INFO(Lib_Ngs2, "called"); @@ -245,7 +309,7 @@ static s32 PS4_SYSV_ABI sceNgs2SystemResetOption(OrbisNgs2SystemOption* outOptio s32 PS4_SYSV_ABI sceNgs2SystemSetGrainSamples(OrbisNgs2Handle systemHandle, u32 numSamples) { LOG_INFO(Lib_Ngs2, "numSamples = {}", numSamples); - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -254,7 +318,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemSetGrainSamples(OrbisNgs2Handle systemHandle, u32 s32 PS4_SYSV_ABI sceNgs2SystemSetSampleRate(OrbisNgs2Handle systemHandle, u32 sampleRate) { LOG_INFO(Lib_Ngs2, "sampleRate = {}", sampleRate); - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -263,7 +327,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemSetSampleRate(OrbisNgs2Handle systemHandle, u32 sa s32 PS4_SYSV_ABI sceNgs2SystemSetUserData(OrbisNgs2Handle systemHandle, uintptr_t userData) { LOG_INFO(Lib_Ngs2, "userData = {}", userData); - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -271,7 +335,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemSetUserData(OrbisNgs2Handle systemHandle, uintptr_ } s32 PS4_SYSV_ABI sceNgs2SystemUnlock(OrbisNgs2Handle systemHandle) { - if (systemHandle == nullptr) { + if (!systemHandle) { LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; } @@ -281,7 +345,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemUnlock(OrbisNgs2Handle systemHandle) { s32 PS4_SYSV_ABI sceNgs2VoiceControl(OrbisNgs2Handle voiceHandle, const OrbisNgs2VoiceParamHeader* paramList) { - if (voiceHandle == nullptr) { + if (!voiceHandle) { LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE; } @@ -292,7 +356,7 @@ s32 PS4_SYSV_ABI sceNgs2VoiceControl(OrbisNgs2Handle voiceHandle, s32 PS4_SYSV_ABI sceNgs2VoiceGetMatrixInfo(OrbisNgs2Handle voiceHandle, u32 matrixId, OrbisNgs2VoiceMatrixInfo* outInfo, size_t outInfoSize) { LOG_INFO(Lib_Ngs2, "matrixId = {}, outInfoSize = {}", matrixId, outInfoSize); - if (voiceHandle == nullptr) { + if (!voiceHandle) { LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE; } @@ -301,7 +365,7 @@ s32 PS4_SYSV_ABI sceNgs2VoiceGetMatrixInfo(OrbisNgs2Handle voiceHandle, u32 matr s32 PS4_SYSV_ABI sceNgs2VoiceGetOwner(OrbisNgs2Handle voiceHandle, OrbisNgs2Handle* outRackHandle, u32* outVoiceId) { - if (voiceHandle == nullptr) { + if (!voiceHandle) { LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE; } @@ -312,7 +376,7 @@ s32 PS4_SYSV_ABI sceNgs2VoiceGetOwner(OrbisNgs2Handle voiceHandle, OrbisNgs2Hand s32 PS4_SYSV_ABI sceNgs2VoiceGetPortInfo(OrbisNgs2Handle voiceHandle, u32 port, OrbisNgs2VoicePortInfo* outInfo, size_t outInfoSize) { LOG_INFO(Lib_Ngs2, "port = {}, outInfoSize = {}", port, outInfoSize); - if (voiceHandle == nullptr) { + if (!voiceHandle) { LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE; } @@ -322,7 +386,7 @@ s32 PS4_SYSV_ABI sceNgs2VoiceGetPortInfo(OrbisNgs2Handle voiceHandle, u32 port, s32 PS4_SYSV_ABI sceNgs2VoiceGetState(OrbisNgs2Handle voiceHandle, OrbisNgs2VoiceState* outState, size_t stateSize) { LOG_INFO(Lib_Ngs2, "stateSize = {}", stateSize); - if (voiceHandle == nullptr) { + if (!voiceHandle) { LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE; } @@ -330,7 +394,7 @@ s32 PS4_SYSV_ABI sceNgs2VoiceGetState(OrbisNgs2Handle voiceHandle, OrbisNgs2Voic } s32 PS4_SYSV_ABI sceNgs2VoiceGetStateFlags(OrbisNgs2Handle voiceHandle, u32* outStateFlags) { - if (voiceHandle == nullptr) { + if (!voiceHandle) { LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE; } @@ -344,7 +408,7 @@ s32 PS4_SYSV_ABI sceNgs2CustomRackGetModuleInfo(OrbisNgs2Handle rackHandle, u32 OrbisNgs2CustomModuleInfo* outInfo, size_t infoSize) { LOG_INFO(Lib_Ngs2, "moduleIndex = {}, infoSize = {}", moduleIndex, infoSize); - if (rackHandle == nullptr) { + if (!rackHandle) { LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; } @@ -369,11 +433,9 @@ s32 PS4_SYSV_ABI sceNgs2GeomCalcListener(const OrbisNgs2GeomListenerParam* param return ORBIS_OK; } -s32 PS4_SYSV_ABI -sceNgs2GeomApply(const OrbisNgs2GeomListenerWork* listener, // Pointer to listener Work - const OrbisNgs2GeomSourceParam* source, // Pointer to source Param - OrbisNgs2GeomAttribute* outAttrib, // Pointer to attribute - u32 flags) { +s32 PS4_SYSV_ABI sceNgs2GeomApply(const OrbisNgs2GeomListenerWork* listener, + const OrbisNgs2GeomSourceParam* source, + OrbisNgs2GeomAttribute* outAttrib, u32 flags) { LOG_INFO(Lib_Ngs2, "flags = {}", flags); return ORBIS_OK; } @@ -399,7 +461,7 @@ s32 PS4_SYSV_ABI sceNgs2PanGetVolumeMatrix(OrbisNgs2PanWork* work, const OrbisNg s32 PS4_SYSV_ABI sceNgs2ReportRegisterHandler(u32 reportType, OrbisNgs2ReportHandler handler, uintptr_t userData, OrbisNgs2Handle* outHandle) { LOG_INFO(Lib_Ngs2, "reportType = {}, userData = {}", reportType, userData); - if (handler == nullptr) { + if (!handler) { LOG_ERROR(Lib_Ngs2, "handler is nullptr"); return ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE; } @@ -407,7 +469,7 @@ s32 PS4_SYSV_ABI sceNgs2ReportRegisterHandler(u32 reportType, OrbisNgs2ReportHan } s32 PS4_SYSV_ABI sceNgs2ReportUnregisterHandler(OrbisNgs2Handle reportHandle) { - if (reportHandle == nullptr) { + if (!reportHandle) { LOG_ERROR(Lib_Ngs2, "reportHandle is nullptr"); return ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE; } diff --git a/src/core/libraries/ngs2/ngs2.h b/src/core/libraries/ngs2/ngs2.h index b1a3136ea..ce4e10307 100644 --- a/src/core/libraries/ngs2/ngs2.h +++ b/src/core/libraries/ngs2/ngs2.h @@ -3,10 +3,14 @@ #pragma once +#include "core/libraries/ngs2/ngs2_impl.h" + #include #include "common/types.h" #include +#include #include +#include namespace Core::Loader { class SymbolsResolver; @@ -14,8 +18,6 @@ class SymbolsResolver; namespace Libraries::Ngs2 { -class Ngs2; - typedef s32 (*OrbisNgs2ParseReadHandler)(uintptr_t userData, u32 offset, void* data, size_t size); enum class OrbisNgs2HandleType : u32 { @@ -28,13 +30,9 @@ enum class OrbisNgs2HandleType : u32 { static const int ORBIS_NGS2_MAX_VOICE_CHANNELS = 8; static const int ORBIS_NGS2_WAVEFORM_INFO_MAX_BLOCKS = 4; -static const int ORBIS_NGS2_SYSTEM_NAME_LENGTH = 16; -static const int ORBIS_NGS2_RACK_NAME_LENGTH = 16; static const int ORBIS_NGS2_MAX_MATRIX_LEVELS = (ORBIS_NGS2_MAX_VOICE_CHANNELS * ORBIS_NGS2_MAX_VOICE_CHANNELS); -using OrbisNgs2Handle = Ngs2*; - struct OrbisNgs2WaveformFormat { u32 waveformType; u32 numChannels; @@ -149,52 +147,12 @@ struct OrbisNgs2UserFx2ProcessContext { typedef s32 (*OrbisNgs2UserFx2ProcessHandler)(OrbisNgs2UserFx2ProcessContext* context); -struct OrbisNgs2ContextBufferInfo { - void* hostBuffer; - size_t hostBufferSize; - uintptr_t reserved[5]; - uintptr_t userData; -}; - -typedef s32 (*OrbisNgs2BufferAllocHandler)(OrbisNgs2ContextBufferInfo* ioBufferInfo); -typedef s32 (*OrbisNgs2BufferFreeHandler)(OrbisNgs2ContextBufferInfo* ioBufferInfo); - struct OrbisNgs2BufferAllocator { OrbisNgs2BufferAllocHandler allocHandler; OrbisNgs2BufferFreeHandler freeHandler; uintptr_t userData; }; -struct OrbisNgs2SystemOption { - size_t size; - char name[ORBIS_NGS2_SYSTEM_NAME_LENGTH]; - - u32 flags; - u32 maxGrainSamples; - u32 numGrainSamples; - u32 sampleRate; - u32 aReserved[6]; -}; - -struct OrbisNgs2SystemInfo { - char name[ORBIS_NGS2_SYSTEM_NAME_LENGTH]; - - OrbisNgs2Handle systemHandle; - OrbisNgs2ContextBufferInfo bufferInfo; - - u32 uid; - u32 minGrainSamples; - u32 maxGrainSamples; - - u32 stateFlags; - u32 rackCount; - float lastRenderRatio; - s64 lastRenderTick; - s64 renderCount; - u32 sampleRate; - u32 numGrainSamples; -}; - struct OrbisNgs2RenderBufferInfo { void* buffer; size_t bufferSize; @@ -215,33 +173,6 @@ struct OrbisNgs2RackOption { u32 aReserved[20]; }; -struct OrbisNgs2RackInfo { - char name[ORBIS_NGS2_RACK_NAME_LENGTH]; - - OrbisNgs2Handle rackHandle; - OrbisNgs2ContextBufferInfo bufferInfo; - - OrbisNgs2Handle ownerSystemHandle; - - u32 type; - u32 rackId; - u32 uid; - u32 minGrainSamples; - u32 maxGrainSamples; - u32 maxVoices; - u32 maxChannelWorks; - u32 maxInputs; - u32 maxMatrices; - u32 maxPorts; - - u32 stateFlags; - float lastProcessRatio; - u64 lastProcessTick; - u64 renderCount; - u32 activeVoiceCount; - u32 activeChannelWorkCount; -}; - struct OrbisNgs2VoiceParamHeader { u16 size; s16 next; diff --git a/src/core/libraries/ngs2/ngs2_impl.cpp b/src/core/libraries/ngs2/ngs2_impl.cpp index 7e5122e17..75a71631f 100644 --- a/src/core/libraries/ngs2/ngs2_impl.cpp +++ b/src/core/libraries/ngs2/ngs2_impl.cpp @@ -12,25 +12,172 @@ using namespace Libraries::Kernel; namespace Libraries::Ngs2 { -s32 Ngs2::HandleReportInvalid(OrbisNgs2Handle* handle, u32 handle_type) const { - uintptr_t hAddress = reinterpret_cast(handle); - switch (handle_type) { +s32 HandleReportInvalid(OrbisNgs2Handle handle, u32 handleType) { + switch (handleType) { case 1: - LOG_ERROR(Lib_Ngs2, "Invalid system handle {}", hAddress); + LOG_ERROR(Lib_Ngs2, "Invalid system handle {}", handle); return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; case 2: - LOG_ERROR(Lib_Ngs2, "Invalid rack handle {}", hAddress); + LOG_ERROR(Lib_Ngs2, "Invalid rack handle {}", handle); return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; case 4: - LOG_ERROR(Lib_Ngs2, "Invalid voice handle {}", hAddress); + LOG_ERROR(Lib_Ngs2, "Invalid voice handle {}", handle); return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE; case 8: - LOG_ERROR(Lib_Ngs2, "Invalid report handle {}", hAddress); + LOG_ERROR(Lib_Ngs2, "Invalid report handle {}", handle); return ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE; default: - LOG_ERROR(Lib_Ngs2, "Invalid handle {}", hAddress); + LOG_ERROR(Lib_Ngs2, "Invalid handle {}", handle); return ORBIS_NGS2_ERROR_INVALID_HANDLE; } } +void* MemoryClear(void* buffer, size_t size) { + return memset(buffer, 0, size); +} + +s32 StackBufferClose(StackBuffer* stackBuffer, size_t* outTotalSize) { + if (outTotalSize) { + *outTotalSize = stackBuffer->usedSize + stackBuffer->alignment; + } + return ORBIS_OK; +} + +s32 StackBufferOpen(StackBuffer* stackBuffer, void* bufferStart, size_t bufferSize, void** outBuffer, + u8 flags) { + stackBuffer->top = outBuffer; + stackBuffer->base = bufferStart; + stackBuffer->size = (size_t)bufferStart; + stackBuffer->currentOffset = (size_t)bufferStart; + stackBuffer->usedSize = 0; + stackBuffer->totalSize = bufferSize; + stackBuffer->alignment = 8; // this is a fixed value + stackBuffer->flags = flags; + + if (outBuffer != NULL) { + *outBuffer = NULL; + } + + return ORBIS_OK; +} + +s32 SystemCleanup(OrbisNgs2Handle systemHandle, OrbisNgs2ContextBufferInfo* outInfo) { + if (!systemHandle) { + return ORBIS_NGS2_ERROR_INVALID_HANDLE; + } + + // TODO + + return ORBIS_OK; +} + +s32 SystemSetupCore(StackBuffer* stackBuffer, const OrbisNgs2SystemOption* option, + SystemInternal* outSystem) { + u32 maxGrainSamples = 512; + u32 numGrainSamples = 256; + u32 sampleRate = 48000; + + if (option) { + sampleRate = option->sampleRate; + maxGrainSamples = option->maxGrainSamples; + numGrainSamples = option->numGrainSamples; + } + + if (maxGrainSamples < 64 || maxGrainSamples > 1024 || (maxGrainSamples & 63) != 0) { + LOG_ERROR(Lib_Ngs2, "Invalid system option (maxGrainSamples={},x64)", maxGrainSamples); + return ORBIS_NGS2_ERROR_INVALID_MAX_GRAIN_SAMPLES; + } + + if (numGrainSamples < 64 || numGrainSamples > 1024 || (numGrainSamples & 63) != 0) { + LOG_ERROR(Lib_Ngs2, "Invalid system option (numGrainSamples={},x64)", numGrainSamples); + return ORBIS_NGS2_ERROR_INVALID_NUM_GRAIN_SAMPLES; + } + + if (sampleRate != 11025 && sampleRate != 12000 && sampleRate != 22050 && sampleRate != 24000 && + sampleRate != 44100 && sampleRate != 48000 && sampleRate != 88200 && sampleRate != 96000 && + sampleRate != 176400 && sampleRate != 192000) { + LOG_ERROR(Lib_Ngs2, "Invalid system option(sampleRate={}:44.1/48kHz series)", sampleRate); + return ORBIS_NGS2_ERROR_INVALID_SAMPLE_RATE; + } + + return ORBIS_OK; +} + +s32 SystemSetup(const OrbisNgs2SystemOption* option, OrbisNgs2ContextBufferInfo* hostBufferInfo, + OrbisNgs2BufferFreeHandler hostFree, OrbisNgs2Handle* outHandle) { + u8 optionFlags = 0; + StackBuffer stackBuffer; + SystemInternal setupResult; + void* systemList = NULL; + size_t requiredBufferSize = 0; + u32 result = ORBIS_NGS2_ERROR_INVALID_BUFFER_SIZE; + + if (option) { + if (option->size != 64) { + LOG_ERROR(Lib_Ngs2, "Invalid system option size ({})", option->size); + return ORBIS_NGS2_ERROR_INVALID_OPTION_SIZE; + } + optionFlags = option->flags >> 31; + } + + // Init + StackBufferOpen(&stackBuffer, NULL, 0, NULL, optionFlags); + result = SystemSetupCore(&stackBuffer, option, 0); + + if (result < 0) { + return result; + } + + StackBufferClose(&stackBuffer, &requiredBufferSize); + + // outHandle unprovided + if (!outHandle) { + hostBufferInfo->hostBuffer = NULL; + hostBufferInfo->hostBufferSize = requiredBufferSize; + MemoryClear(&hostBufferInfo->reserved, sizeof(hostBufferInfo->reserved)); + return ORBIS_OK; + } + + if (!hostBufferInfo->hostBuffer) { + LOG_ERROR(Lib_Ngs2, "Invalid system buffer address ({})", hostBufferInfo->hostBuffer); + return ORBIS_NGS2_ERROR_INVALID_BUFFER_ADDRESS; + } + + if (hostBufferInfo->hostBufferSize < requiredBufferSize) { + LOG_ERROR(Lib_Ngs2, "Invalid system buffer size ({}<{}[byte])", hostBufferInfo->hostBufferSize, + requiredBufferSize); + return ORBIS_NGS2_ERROR_INVALID_BUFFER_SIZE; + } + + // Setup + StackBufferOpen(&stackBuffer, hostBufferInfo->hostBuffer, hostBufferInfo->hostBufferSize, + &systemList, + optionFlags); + result = SystemSetupCore(&stackBuffer, option, &setupResult); + + if (result < 0) { + return result; + } + + StackBufferClose(&stackBuffer, &requiredBufferSize); + + // Copy buffer results + setupResult.bufferInfo = *hostBufferInfo; + setupResult.hostFree = hostFree; + //setupResult.extraSystemData = + setupResult.systemListHead = systemList; + + OrbisNgs2Handle systemHandle = setupResult.systemHandle; + if (hostBufferInfo->hostBufferSize >= requiredBufferSize) { + *outHandle = systemHandle; + return ORBIS_OK; + } + + SystemCleanup(systemHandle, 0); + + LOG_ERROR(Lib_Ngs2, "Invalid system buffer size ({}<{}[byte])", hostBufferInfo->hostBufferSize, + requiredBufferSize); + return ORBIS_NGS2_ERROR_INVALID_BUFFER_SIZE; +} + } // namespace Libraries::Ngs2 diff --git a/src/core/libraries/ngs2/ngs2_impl.h b/src/core/libraries/ngs2/ngs2_impl.h index fbb2b1bbf..99b847861 100644 --- a/src/core/libraries/ngs2/ngs2_impl.h +++ b/src/core/libraries/ngs2/ngs2_impl.h @@ -3,15 +3,176 @@ #pragma once -#include "ngs2.h" +#include "core/libraries/kernel/thread_management.h" namespace Libraries::Ngs2 { -class Ngs2 { -public: - s32 HandleReportInvalid(OrbisNgs2Handle* handle, u32 handle_type) const; +static const int ORBIS_NGS2_SYSTEM_NAME_LENGTH = 16; +static const int ORBIS_NGS2_RACK_NAME_LENGTH = 16; -private: +typedef uintptr_t OrbisNgs2Handle; + +struct OrbisNgs2ContextBufferInfo { + void* hostBuffer; + size_t hostBufferSize; + uintptr_t reserved[5]; + uintptr_t userData; }; +struct OrbisNgs2SystemOption { + size_t size; + char name[ORBIS_NGS2_SYSTEM_NAME_LENGTH]; + + u32 flags; + u32 maxGrainSamples; + u32 numGrainSamples; + u32 sampleRate; + u32 aReserved[6]; +}; + +typedef s32 (*OrbisNgs2BufferAllocHandler)(OrbisNgs2ContextBufferInfo* ioBufferInfo); +typedef s32 (*OrbisNgs2BufferFreeHandler)(OrbisNgs2ContextBufferInfo* ioBufferInfo); + +struct OrbisNgs2SystemInfo { + char name[ORBIS_NGS2_SYSTEM_NAME_LENGTH]; // 0 + + OrbisNgs2Handle systemHandle; // 16 + OrbisNgs2ContextBufferInfo bufferInfo; // 24 + + u32 uid; // 88 + u32 minGrainSamples; // 92 + u32 maxGrainSamples; // 96 + + u32 stateFlags; // 100 + u32 rackCount; // 104 + float lastRenderRatio; // 108 + s64 lastRenderTick; // 112 + s64 renderCount; // 120 + u32 sampleRate; // 128 + u32 numGrainSamples; // 132 +}; + +struct OrbisNgs2RackInfo { + char name[ORBIS_NGS2_RACK_NAME_LENGTH]; // 0 + + OrbisNgs2Handle rackHandle; // 16 + OrbisNgs2ContextBufferInfo bufferInfo; // 24 + + OrbisNgs2Handle ownerSystemHandle; // 88 + + u32 type; // 96 + u32 rackId; // 100 + u32 uid; // 104 + u32 minGrainSamples; // 108 + u32 maxGrainSamples; // 112 + u32 maxVoices; // 116 + u32 maxChannelWorks; // 120 + u32 maxInputs; // 124 + u32 maxMatrices; // 128 + u32 maxPorts; // 132 + + u32 stateFlags; // 136 + float lastProcessRatio; // 140 + u64 lastProcessTick; // 144 + u64 renderCount; // 152 + u32 activeVoiceCount; // 160 + u32 activeChannelWorkCount; // 164 +}; + +struct StackBuffer { + void** top; + void* base; + size_t size; + size_t currentOffset; + size_t usedSize; + size_t totalSize; + size_t alignment; + u8 flags; + char padding[7]; +}; + +struct SystemInternal { + // setup init + char name[ORBIS_NGS2_SYSTEM_NAME_LENGTH]; // 0 + OrbisNgs2ContextBufferInfo bufferInfo; // 16 + OrbisNgs2BufferFreeHandler hostFree; // 80 + OrbisNgs2Handle systemHandle; // 88 + void* unknown1; // 96 + void* unknown2; // 104 + OrbisNgs2Handle rackHandle; // 112 + uintptr_t* userData; // 120 + SystemInternal* systemList; // 128 + StackBuffer* stackBuffer; // 136 + OrbisNgs2SystemInfo ownerSystemInfo; // 144 + + struct rackList { + void* prev; + void* next; + void* unknown; + }; + + rackList rackListPreset; // 152 + rackList rackListNormal; // 176 + rackList rackListMaster; // 200 + + void* unknown3; // 208 + void* systemListPrev; // 216 + void* unknown4; // 224 + void* systemListNext; // 232 + void* rackFunction; // 240 + + Kernel::ScePthreadMutex processLock; // 248 + u32 hasProcessMutex; // 256 + u32 unknown5; // 260 + Kernel::ScePthreadMutex flushLock; // 264 + u32 hasFlushMutex; // 272 + u32 unknown6; // 276 + + // info + u64 lastRenderTick; // 280 + u64 renderCount; // 288 + u32 isActive; // 296 + std::atomic lockCount; // 300 + u32 uid; // 304 + u32 systemType; // 308 + + struct { + u8 isBufferValid : 1; + u8 isRendering : 1; + u8 isSorted : 1; + u8 isFlushReady : 1; + } flags; // 312 + + u16 currentMaxGrainSamples; // 316 + u16 minGrainSamples; // 318 + u16 maxGrainSamples; // 320 + u16 numGrainSamples; // 322 + u32 currentNumGrainSamples; // 324 + u32 sampleRate; // 328 + u32 currentSampleRate; // 332 + u32 rackCount; // 336 + float lastRenderRatio; // 340 + float cpuLoad; // 344 +}; + +struct HandleInternal { + HandleInternal* selfPtr; // 0 + SystemInternal* systemData; // 8 + std::atomic refCount; // 16 + u32 handleType; // 24 + u32 handleID; // 28 +}; + +s32 StackBufferClose(StackBuffer* stackBuffer, size_t* outTotalSize); +s32 StackBufferOpen(StackBuffer* stackBuffer, void* buffer, size_t bufferSize, void** outBuffer, + u8 flags); +s32 SystemSetupCore(StackBuffer* stackBuffer, const OrbisNgs2SystemOption* option, + SystemInternal* outSystem); + +s32 HandleReportInvalid(OrbisNgs2Handle handle, u32 handleType); +void* MemoryClear(void* buffer, size_t size); +s32 SystemCleanup(OrbisNgs2Handle systemHandle, OrbisNgs2ContextBufferInfo* outInfo); +s32 SystemSetup(const OrbisNgs2SystemOption* option, OrbisNgs2ContextBufferInfo* hostBufferInfo, + OrbisNgs2BufferFreeHandler hostFree, OrbisNgs2Handle* outHandle); + } // namespace Libraries::Ngs2