diff --git a/src/core/libraries/error_codes.h b/src/core/libraries/error_codes.h index ad973ce3b..123edcee8 100644 --- a/src/core/libraries/error_codes.h +++ b/src/core/libraries/error_codes.h @@ -471,57 +471,4 @@ constexpr int ORBIS_AVPLAYER_ERROR_INFO_AES_ENCRY = 0x806A00B5; constexpr int ORBIS_AVPLAYER_ERROR_INFO_OTHER_ENCRY = 0x806A00BF; // AppContent library -constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002; - -// Ngs2 library -constexpr int ORBIS_NGS2_ERROR_INVALID_PARAMETERS = 0x804A0001; -constexpr int ORBIS_NGS2_ERROR_INVALID_MAXIMUM_GRAIN_SAMPLES = 0x804A0050; -constexpr int ORBIS_NGS2_ERROR_INVALID_GRAIN_SAMPLES = 0x804A0051; -constexpr int ORBIS_NGS2_ERROR_INVALID_CHANNELS = 0x804A0052; -constexpr int ORBIS_NGS2_ERROR_INVALD_ADDRESS = 0x804A0053; -constexpr int ORBIS_NGS2_ERROR_INVALD_SIZE = 0x804A0054; -constexpr int ORBIS_NGS2_ERROR_INVALID_OPTION_SIZE = 0x804A0081; -constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_MATRICES = 0x804A0100; -constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_PORTS = 0x804A0101; -constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_INPUT_DELAY_BLOCKS = 0x804A0102; -constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_LEVELS = 0x804A0150; -constexpr int ORBIS_NGS2_ERROR_SAMPLER_WAVEFORM_TERMINATED = 0x804A0151; -constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_POINTS = 0x804A0152; -constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_LEVEL_ADDRESS = 0x804A0153; -constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_BLOCK_ADDRESS = 0x804A0154; -constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_POINT_ADDRESS = 0x804A0155; -constexpr int ORBIS_NGS2_ERROR_INVALID_HANDLE = 0x804A0200; -constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLE_RATE = 0x804A0201; -constexpr int ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE = 0x804A0204; -constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_INFO = 0x804A0206; -constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ADDRESS = 0x804A0207; -constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ALIGNMENT = 0x804A0208; -constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_SIZE = 0x804A0209; -constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ALLOCATOR = 0x804A020A; -constexpr int ORBIS_NGS2_ERROR_BUFFER_VERIFY_FAILED = 0x804A020B; -constexpr int ORBIS_NGS2_ERROR_MODULE_PLAYER_DATA_EMPTY = 0x804A020C; -constexpr int ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE = 0x804A0230; -constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_ID = 0x804A0260; -constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE = 0x804A0261; -constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE = 0x804A0300; -constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_INDEX = 0x804A0302; -constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_EVENT = 0x804A0303; -constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_PORT_INDEX = 0x804A0304; -constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_INPUT_OR_RACK_OCCUPIED = 0x804A0305; -constexpr int ORBIS_NGS2_ERROR_INVALID_CONTROL_ID = 0x804A0308; -constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_CONTROL_PARAMETER = 0x804A0309; -constexpr int ORBIS_NGS2_ERROR_INVALID_PARAMETER_SIZE = 0x804A030A; -constexpr int ORBIS_NGS2_ERROR_DETECTED_CIRCULAR_VOICE_CONTROL = 0x804A030B; -constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_DATA = 0x804A0400; -constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_FORMAT = 0x804A0401; -constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_TYPE_NO_ATRAC9_DECODERS = 0x804A0402; -constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_ATRAC9_CONFIG_DATA = 0x804A0403; -constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_SAMPLE_RATE = 0x804A0404; -constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_FRAME = 0x804A0405; -constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_ADDRESS = 0x804A0406; -constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_CURVE = 0x804A0500; -constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_INDEX = 0x804A0600; -constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_TYPE = 0x804A0601; -constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_LOCATION = 0x804A0602; -constexpr int ORBIS_NGS2_ERROR_INVALID_LFE_CUT_OFF_FREQUENCY = 0x804A0603; -constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_INDEX_OR_TYPE = 0x804A0700; \ No newline at end of file +constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002; \ No newline at end of file diff --git a/src/core/libraries/libs.cpp b/src/core/libraries/libs.cpp index 8f9a118f2..20efd3c0e 100644 --- a/src/core/libraries/libs.cpp +++ b/src/core/libraries/libs.cpp @@ -38,7 +38,6 @@ #include "src/core/libraries/dialogs/error_dialog.h" #include "src/core/libraries/dialogs/ime_dialog.h" #include "src/core/libraries/libpng/pngdec.h" -#include "src/core/libraries/ngs2/ngs2.h" namespace Libraries { @@ -80,7 +79,6 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) { Libraries::ErrorDialog::RegisterlibSceErrorDialog(sym); Libraries::ImeDialog::RegisterlibSceImeDialog(sym); Libraries::AvPlayer::RegisterlibSceAvPlayer(sym); - Libraries::Ngs2::RegisterlibSceNgs2(sym); } } // namespace Libraries diff --git a/src/core/libraries/ngs2/ngs2.cpp b/src/core/libraries/ngs2/ngs2.cpp index fac72da78..b66c9b15b 100644 --- a/src/core/libraries/ngs2/ngs2.cpp +++ b/src/core/libraries/ngs2/ngs2.cpp @@ -1,97 +1,16 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -// Generated By moduleGenerator +#include "ngs2.h" +#include "ngs2_error.h" +#include "ngs2_impl.h" + #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" -#include "core/libraries/ngs2/ngs2.h" namespace Libraries::Ngs2 { -struct StackBuffer { - void** top; - void* base; - void* curr; - size_t usedSize; - size_t totalSize; - size_t alignment; - char isVerifyEnabled; - char padding[7]; -}; - -int StackBufferOpen(StackBuffer* buf, void* base_addr, size_t size, void** stackTop, bool verify) { - buf->top = stackTop; - buf->base = base_addr; - buf->curr = base_addr; - buf->usedSize = 0; - buf->totalSize = size; - buf->alignment = 8; - buf->isVerifyEnabled = verify; - - if (stackTop) { - *stackTop = nullptr; - } - - return ORBIS_OK; -} - -int StackBufferClose(StackBuffer* buf, size_t* usedSize) { - if (usedSize) { - *usedSize = buf->usedSize + buf->alignment; - } - - return ORBIS_OK; -} - -struct SystemOptions { - char padding[6]; - s32 maxGrainSamples; - s32 numGrainSamples; - s32 sampleRate; -}; - -struct SystemState { - // TODO -}; - -int64_t sceNgs2SystemSetupCore(void* stackBuffer, SystemOptions* options, SystemState** outSystem) { - int32_t maxGrainSamples = 512; - int32_t numGrainSamples = 256; - int32_t sampleRate = 48000; - - if (options) { - maxGrainSamples = options->maxGrainSamples; - numGrainSamples = options->numGrainSamples; - sampleRate = options->sampleRate; - } - - // Validate maxGrainSamples - if (maxGrainSamples < 64 || maxGrainSamples > 1024 || (maxGrainSamples & 0x3F) != 0) { - // return sceNgs2ReportError(0, 2152333392, "Invalid system option - // (maxGrainSamples=%d:%d~%d,x64)", maxGrainSamples); - } - - // Validate numGrainSamples - if (numGrainSamples < 64 || numGrainSamples > 1024 || (numGrainSamples & 0x3F) != 0) { - // return sceNgs2ReportError(0, 2152333393, "Invalid system option - // (numGrainSamples=%d:%d~%d,x64)", numGrainSamples); - } - - // Validate sampleRate - if (sampleRate != 11025 && sampleRate != 12000 && sampleRate != 22050 && sampleRate != 24000 && - sampleRate != 44100 && sampleRate != 48000 && sampleRate != 88200 && sampleRate != 96000) { - // return sceNgs2ReportError(0, 2152333825, "Invalid system option(sampleRate=%d:44.1/48kHz - // series)", sampleRate); - } - - int result = ORBIS_OK; - - // TODO - - return result; // Success -} - int PS4_SYSV_ABI sceNgs2CalcWaveformBlock() { LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); return ORBIS_OK; diff --git a/src/core/libraries/ngs2/ngs2.h b/src/core/libraries/ngs2/ngs2.h index 12cbfb832..0698141a1 100644 --- a/src/core/libraries/ngs2/ngs2.h +++ b/src/core/libraries/ngs2/ngs2.h @@ -5,78 +5,67 @@ #include "common/types.h" +#include + namespace Core::Loader { class SymbolsResolver; } namespace Libraries::Ngs2 { -int PS4_SYSV_ABI sceNgs2CalcWaveformBlock(); -int PS4_SYSV_ABI sceNgs2CustomRackGetModuleInfo(); -int PS4_SYSV_ABI sceNgs2FftInit(); -int PS4_SYSV_ABI sceNgs2FftProcess(); -int PS4_SYSV_ABI sceNgs2FftQuerySize(); -int PS4_SYSV_ABI sceNgs2GeomApply(); -int PS4_SYSV_ABI sceNgs2GeomCalcListener(); -int PS4_SYSV_ABI sceNgs2GeomResetListenerParam(); -int PS4_SYSV_ABI sceNgs2GeomResetSourceParam(); -int PS4_SYSV_ABI sceNgs2GetWaveformFrameInfo(); -int PS4_SYSV_ABI sceNgs2JobSchedulerResetOption(); -int PS4_SYSV_ABI sceNgs2ModuleArrayEnumItems(); -int PS4_SYSV_ABI sceNgs2ModuleEnumConfigs(); -int PS4_SYSV_ABI sceNgs2ModuleQueueEnumItems(); -int PS4_SYSV_ABI sceNgs2PanGetVolumeMatrix(); -int PS4_SYSV_ABI sceNgs2PanInit(); -int PS4_SYSV_ABI sceNgs2ParseWaveformData(); -int PS4_SYSV_ABI sceNgs2ParseWaveformFile(); -int PS4_SYSV_ABI sceNgs2ParseWaveformUser(); -int PS4_SYSV_ABI sceNgs2RackCreate(); -int PS4_SYSV_ABI sceNgs2RackCreateWithAllocator(); -int PS4_SYSV_ABI sceNgs2RackDestroy(); -int PS4_SYSV_ABI sceNgs2RackGetInfo(); -int PS4_SYSV_ABI sceNgs2RackGetUserData(); -int PS4_SYSV_ABI sceNgs2RackGetVoiceHandle(); -int PS4_SYSV_ABI sceNgs2RackLock(); -int PS4_SYSV_ABI sceNgs2RackQueryBufferSize(); -int PS4_SYSV_ABI sceNgs2RackQueryInfo(); -int PS4_SYSV_ABI sceNgs2RackRunCommands(); -int PS4_SYSV_ABI sceNgs2RackSetUserData(); -int PS4_SYSV_ABI sceNgs2RackUnlock(); -int PS4_SYSV_ABI sceNgs2ReportRegisterHandler(); -int PS4_SYSV_ABI sceNgs2ReportUnregisterHandler(); -int PS4_SYSV_ABI sceNgs2SystemCreate(); -int PS4_SYSV_ABI sceNgs2SystemCreateWithAllocator(); -int PS4_SYSV_ABI sceNgs2SystemDestroy(); -int PS4_SYSV_ABI sceNgs2SystemEnumHandles(); -int PS4_SYSV_ABI sceNgs2SystemEnumRackHandles(); -int PS4_SYSV_ABI sceNgs2SystemGetInfo(); -int PS4_SYSV_ABI sceNgs2SystemGetUserData(); -int PS4_SYSV_ABI sceNgs2SystemLock(); -int PS4_SYSV_ABI sceNgs2SystemQueryBufferSize(); -int PS4_SYSV_ABI sceNgs2SystemQueryInfo(); -int PS4_SYSV_ABI sceNgs2SystemRender(); -int PS4_SYSV_ABI sceNgs2SystemResetOption(); -int PS4_SYSV_ABI sceNgs2SystemRunCommands(); -int PS4_SYSV_ABI sceNgs2SystemSetGrainSamples(); -int PS4_SYSV_ABI sceNgs2SystemSetLoudThreshold(); -int PS4_SYSV_ABI sceNgs2SystemSetSampleRate(); -int PS4_SYSV_ABI sceNgs2SystemSetUserData(); -int PS4_SYSV_ABI sceNgs2SystemUnlock(); -int PS4_SYSV_ABI sceNgs2StreamCreate(); -int PS4_SYSV_ABI sceNgs2StreamCreateWithAllocator(); -int PS4_SYSV_ABI sceNgs2StreamDestroy(); -int PS4_SYSV_ABI sceNgs2StreamQueryBufferSize(); -int PS4_SYSV_ABI sceNgs2StreamQueryInfo(); -int PS4_SYSV_ABI sceNgs2StreamResetOption(); -int PS4_SYSV_ABI sceNgs2StreamRunCommands(); -int PS4_SYSV_ABI sceNgs2VoiceControl(); -int PS4_SYSV_ABI sceNgs2VoiceGetMatrixInfo(); -int PS4_SYSV_ABI sceNgs2VoiceGetOwner(); -int PS4_SYSV_ABI sceNgs2VoiceGetPortInfo(); -int PS4_SYSV_ABI sceNgs2VoiceGetState(); -int PS4_SYSV_ABI sceNgs2VoiceGetStateFlags(); -int PS4_SYSV_ABI sceNgs2VoiceQueryInfo(); -int PS4_SYSV_ABI sceNgs2VoiceRunCommands(); +class Ngs2; + +using SceNgs2Handle = Ngs2*; + +enum SceNgs2HandleType { SCE_NGS2_HANDLE_TYPE_SYSTEM = 0 }; + +struct Ngs2Handle { + void* selfPointer; + void* dataPointer; + std::atomic* atomicPtr; + u32 handleType; + u32 flags_unk; + + u32 uid; + u16 maxGrainSamples; + u16 minGrainSamples; + u16 currentGrainSamples; + u16 numGrainSamples; + u16 unknown2; + u32 sampleRate; + u32 unknown3; + + void* flushMutex; + u32 flushMutexInitialized; + void* processMutex; + u32 processMutexInitialized; + + // Linked list pointers for system list + Ngs2Handle* prev; + Ngs2Handle* next; +}; + +struct SystemOptions { + char padding[6]; + s32 maxGrainSamples; + s32 numGrainSamples; + s32 sampleRate; +}; + +struct SystemState { + // TODO +}; + +struct StackBuffer { + void** top; + void* base; + void* curr; + size_t usedSize; + size_t totalSize; + size_t alignment; + char isVerifyEnabled; + char padding[7]; +}; void RegisterlibSceNgs2(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::Ngs2 \ No newline at end of file diff --git a/src/core/libraries/ngs2/ngs2_error.h b/src/core/libraries/ngs2/ngs2_error.h new file mode 100644 index 000000000..254ae26e6 --- /dev/null +++ b/src/core/libraries/ngs2/ngs2_error.h @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +constexpr int ORBIS_NGS2_ERROR_INVALID_PARAMETERS = 0x804A0001; +constexpr int ORBIS_NGS2_ERROR_INVALID_MAXIMUM_GRAIN_SAMPLES = 0x804A0050; +constexpr int ORBIS_NGS2_ERROR_INVALID_GRAIN_SAMPLES = 0x804A0051; +constexpr int ORBIS_NGS2_ERROR_INVALID_CHANNELS = 0x804A0052; +constexpr int ORBIS_NGS2_ERROR_INVALD_ADDRESS = 0x804A0053; +constexpr int ORBIS_NGS2_ERROR_INVALD_SIZE = 0x804A0054; +constexpr int ORBIS_NGS2_ERROR_INVALID_OPTION_SIZE = 0x804A0081; +constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_MATRICES = 0x804A0100; +constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_PORTS = 0x804A0101; +constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_INPUT_DELAY_BLOCKS = 0x804A0102; +constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_LEVELS = 0x804A0150; +constexpr int ORBIS_NGS2_ERROR_SAMPLER_WAVEFORM_TERMINATED = 0x804A0151; +constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_POINTS = 0x804A0152; +constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_LEVEL_ADDRESS = 0x804A0153; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_BLOCK_ADDRESS = 0x804A0154; +constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_POINT_ADDRESS = 0x804A0155; +constexpr int ORBIS_NGS2_ERROR_INVALID_HANDLE = 0x804A0200; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLE_RATE = 0x804A0201; +constexpr int ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE = 0x804A0204; +constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_INFO = 0x804A0206; +constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ADDRESS = 0x804A0207; +constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ALIGNMENT = 0x804A0208; +constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_SIZE = 0x804A0209; +constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ALLOCATOR = 0x804A020A; +constexpr int ORBIS_NGS2_ERROR_BUFFER_VERIFY_FAILED = 0x804A020B; +constexpr int ORBIS_NGS2_ERROR_MODULE_PLAYER_DATA_EMPTY = 0x804A020C; +constexpr int ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE = 0x804A0230; +constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_ID = 0x804A0260; +constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE = 0x804A0261; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE = 0x804A0300; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_INDEX = 0x804A0302; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_EVENT = 0x804A0303; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_PORT_INDEX = 0x804A0304; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_INPUT_OR_RACK_OCCUPIED = 0x804A0305; +constexpr int ORBIS_NGS2_ERROR_INVALID_CONTROL_ID = 0x804A0308; +constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_CONTROL_PARAMETER = 0x804A0309; +constexpr int ORBIS_NGS2_ERROR_INVALID_PARAMETER_SIZE = 0x804A030A; +constexpr int ORBIS_NGS2_ERROR_DETECTED_CIRCULAR_VOICE_CONTROL = 0x804A030B; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_DATA = 0x804A0400; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_FORMAT = 0x804A0401; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_TYPE_NO_ATRAC9_DECODERS = 0x804A0402; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_ATRAC9_CONFIG_DATA = 0x804A0403; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_SAMPLE_RATE = 0x804A0404; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_FRAME = 0x804A0405; +constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_ADDRESS = 0x804A0406; +constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_CURVE = 0x804A0500; +constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_INDEX = 0x804A0600; +constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_TYPE = 0x804A0601; +constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_LOCATION = 0x804A0602; +constexpr int ORBIS_NGS2_ERROR_INVALID_LFE_CUT_OFF_FREQUENCY = 0x804A0603; +constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_INDEX_OR_TYPE = 0x804A0700; \ No newline at end of file diff --git a/src/core/libraries/ngs2/ngs2_impl.cpp b/src/core/libraries/ngs2/ngs2_impl.cpp new file mode 100644 index 000000000..9c61ac790 --- /dev/null +++ b/src/core/libraries/ngs2/ngs2_impl.cpp @@ -0,0 +1,165 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "ngs2_error.h" +#include "ngs2_impl.h" + +#include "common/logging/log.h" +#include "core/libraries/error_codes.h" +#include "core/libraries/kernel/libkernel.h" + +using namespace Libraries::Kernel; + +namespace Libraries::Ngs2 { + + s32 Ngs2::ReportInvalid(u32 handle_type) const { + switch (handle_type) { + case 1: + LOG_ERROR(Lib_Ngs2, "Invalid system handle {}", this); + return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE; + case 2: + LOG_ERROR(Lib_Ngs2, "Invalid rack handle {}", this); + return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE; + case 4: + LOG_ERROR(Lib_Ngs2, "Invalid voice handle {}", this); + return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE; + case 8: + LOG_ERROR(Lib_Ngs2, "Invalid report handle {}", this); + return ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE; + default: + LOG_ERROR(Lib_Ngs2, "Invalid handle {}", this); + return ORBIS_NGS2_ERROR_INVALID_HANDLE; + } + } + + s32 Ngs2::HandleSetup(Ngs2Handle* handle, void* data, std::atomic* atomic, u32 type, + u32 flags) { + handle->dataPointer = data; + handle->atomicPtr = atomic; + handle->handleType = type; + handle->flags_unk = flags; + return ORBIS_OK; + } + + s32 Ngs2::HandleCleanup(Ngs2Handle* handle, u32 hType, void* dataOut) { + if (handle && handle->selfPointer == handle) { + std::atomic* tmp_atomic = handle->atomicPtr; + if (tmp_atomic && handle->handleType == hType) { + while (tmp_atomic->load() != 0) { + u32 expected = 1; + if (tmp_atomic->compare_exchange_strong(expected, 0)) { + if (dataOut) { + dataOut = handle->dataPointer; + } + // sceNgs2MemoryClear(handle, 32); + return ORBIS_OK; + } + tmp_atomic = handle->atomicPtr; + } + } + } + return HandleReportInvalid(handle, hType); + } + + s32 Ngs2::HandleEnter(Ngs2Handle* handle, u32 hType, Ngs2Handle* handleOut) { + if (!handle) { + return HandleReportInvalid(handle, 0); + } + + if (handle->selfPointer != handle || !handle->atomicPtr || !handle->dataPointer || + (~hType & handle->handleType)) { + return HandleReportInvalid(handle, handle->handleType); + } + + std::atomic* atomic = handle->atomicPtr; + while (true) { + u32 i = atomic->load(); + if (i == 0) { + return HandleReportInvalid(handle, handle->handleType); + } + if (atomic->compare_exchange_strong(i, i + 1)) { + break; + } + } + + if (handleOut) { + *handleOut = handle; + } + return ORBIS_OK; + } + + s32 Ngs2::HandleLeave(Ngs2Handle* handle) { + std::atomic* tmp_atomic; + u32 i; + do { + tmp_atomic = handle->atomicPtr; + i = tmp_atomic->load(); + } while (!tmp_atomic->compare_exchange_strong(i, i - 1)); + return ORBIS_OK; + } + + s32 Ngs2::StackBufferOpen(StackBuffer* buf, void* base_addr, size_t size, void** stackTop, + bool verify) { + buf->top = stackTop; + buf->base = base_addr; + buf->curr = base_addr; + buf->usedSize = 0; + buf->totalSize = size; + buf->alignment = 8; + buf->isVerifyEnabled = verify; + + if (stackTop) { + *stackTop = nullptr; + } + + return ORBIS_OK; + } + + s32 Ngs2::StackBufferClose(StackBuffer* buf, size_t* usedSize) { + if (usedSize) { + *usedSize = buf->usedSize + buf->alignment; + } + + return ORBIS_OK; + } + + s32 Ngs2::SystemSetupCore(StackBuffer* buf, SystemOptions* options, Ngs2Handle** sysOut) { + u32 maxGrainSamples = 512; + u32 numGrainSamples = 256; + u32 sampleRate = 48000; + + if (options) { + maxGrainSamples = options->maxGrainSamples; + numGrainSamples = options->numGrainSamples; + sampleRate = options->sampleRate; + } + + // Validate maxGrainSamples + if (maxGrainSamples < 64 || maxGrainSamples > 1024 || (maxGrainSamples & 0x3F) != 0) { + LOG_ERROR(Lib_Ngs2, "Invalid system option (maxGrainSamples={},x64)", maxGrainSamples); + return ORBIS_NGS2_ERROR_INVALID_MAXIMUM_GRAIN_SAMPLES; + } + + // Validate numGrainSamples + if (numGrainSamples < 64 || numGrainSamples > 1024 || (numGrainSamples & 0x3F) != 0) { + LOG_ERROR(Lib_Ngs2, "Invalid system option (numGrainSamples={},x64)", numGrainSamples); + return ORBIS_NGS2_ERROR_INVALID_GRAIN_SAMPLES; + } + + // Validate sampleRate + if (sampleRate != 11025 && sampleRate != 12000 && sampleRate != 22050 && + sampleRate != 24000 && sampleRate != 44100 && sampleRate != 48000 && + sampleRate != 88200 && sampleRate != 96000) { + LOG_ERROR(Lib_Ngs2, "Invalid system option(sampleRate={}:44.1/48kHz series)", + sampleRate); + return ORBIS_NGS2_ERROR_INVALID_SAMPLE_RATE; + } + + int result = ORBIS_OK; + + // TODO + + return result; // Success + } + +} // namespace Libraries::Ngs2 diff --git a/src/core/libraries/ngs2/ngs2_impl.h b/src/core/libraries/ngs2/ngs2_impl.h new file mode 100644 index 000000000..016412f63 --- /dev/null +++ b/src/core/libraries/ngs2/ngs2_impl.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "ngs2.h" + +namespace Libraries::Ngs2 { + +class Ngs2 { +public: + s32 ReportInvalid(u32 handle_type) const; + s32 HandleSetup(Ngs2Handle* handle, void* data, std::atomic* atomic, u32 type, u32 flags); + s32 Ngs2::HandleCleanup(Ngs2Handle* handle, u32 hType, void* dataOut); + s32 Ngs2::HandleEnter(Ngs2Handle* handle, u32 hType, Ngs2Handle* handleOut); + s32 Ngs2::HandleLeave(Ngs2Handle* handle); + s32 Ngs2::StackBufferOpen(StackBuffer* buf, void* base_addr, size_t size, void** stackTop, + bool verify); + s32 Ngs2::StackBufferClose(StackBuffer* buf, size_t* usedSize); + s32 Ngs2::SystemSetupCore(StackBuffer* buf, SystemOptions* options, Ngs2Handle** sysOut); + +private: +}; + +} // namespace Libraries::Ngs2