diff --git a/CMakeLists.txt b/CMakeLists.txt index 9898e406..679325ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,6 +127,8 @@ set(AUDIO_LIB src/core/libraries/audio/audioin.cpp src/core/libraries/audio/audioout.h src/core/libraries/ajm/ajm.cpp src/core/libraries/ajm/ajm.h + src/core/libraries/ngs2/ngs2.cpp + src/core/libraries/ngs2/ngs2.h ) set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 2c4a20de..ab3468ca 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -112,6 +112,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { SUB(Lib, ErrorDialog) \ SUB(Lib, ImeDialog) \ SUB(Lib, AvPlayer) \ + SUB(Lib, Ngs2) \ CLS(Frontend) \ CLS(Render) \ SUB(Render, Vulkan) \ diff --git a/src/common/logging/types.h b/src/common/logging/types.h index dccb838a..dd2376ea 100644 --- a/src/common/logging/types.h +++ b/src/common/logging/types.h @@ -79,6 +79,7 @@ enum class Class : u8 { Lib_ErrorDialog, ///< The LibSceErrorDialog implementation. Lib_ImeDialog, ///< The LibSceImeDialog implementation. Lib_AvPlayer, ///< The LibSceAvPlayer implementation. + Lib_Ngs2, ///< The LibSceNgs2 implementation. Frontend, ///< Emulator UI Render, ///< Video Core Render_Vulkan, ///< Vulkan backend diff --git a/src/core/libraries/error_codes.h b/src/core/libraries/error_codes.h index 74aeef67..123edcee 100644 --- a/src/core/libraries/error_codes.h +++ b/src/core/libraries/error_codes.h @@ -471,4 +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; +constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002; \ No newline at end of file diff --git a/src/core/libraries/ngs2/ngs2.cpp b/src/core/libraries/ngs2/ngs2.cpp new file mode 100644 index 00000000..b66c9b15 --- /dev/null +++ b/src/core/libraries/ngs2/ngs2.cpp @@ -0,0 +1,419 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#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" + +namespace Libraries::Ngs2 { + +int PS4_SYSV_ABI sceNgs2CalcWaveformBlock() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2CustomRackGetModuleInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2FftInit() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2FftProcess() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2FftQuerySize() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2GeomApply() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2GeomCalcListener() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2GeomResetListenerParam() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2GeomResetSourceParam() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2GetWaveformFrameInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2JobSchedulerResetOption() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ModuleArrayEnumItems() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ModuleEnumConfigs() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ModuleQueueEnumItems() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2PanGetVolumeMatrix() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2PanInit() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ParseWaveformData() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ParseWaveformFile() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ParseWaveformUser() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackCreate() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackCreateWithAllocator() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackDestroy() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackGetInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackGetUserData() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackGetVoiceHandle() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackLock() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackQueryBufferSize() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackQueryInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackRunCommands() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackSetUserData() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2RackUnlock() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ReportRegisterHandler() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2ReportUnregisterHandler() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemCreate() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemCreateWithAllocator() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemDestroy() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemEnumHandles() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemEnumRackHandles() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemGetInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemGetUserData() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemLock() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemQueryBufferSize() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemQueryInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemRender() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemResetOption() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemRunCommands() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemSetGrainSamples() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemSetLoudThreshold() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemSetSampleRate() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemSetUserData() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2SystemUnlock() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamCreate() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamCreateWithAllocator() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamDestroy() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamQueryBufferSize() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamQueryInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamResetOption() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2StreamRunCommands() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceControl() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceGetMatrixInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceGetOwner() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceGetPortInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceGetState() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceGetStateFlags() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceQueryInfo() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNgs2VoiceRunCommands() { + LOG_ERROR(Lib_Ngs2, "(STUBBED) called"); + return ORBIS_OK; +} + +void RegisterlibSceNgs2(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("3pCNbVM11UA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2CalcWaveformBlock); + LIB_FUNCTION("6qN1zaEZuN0", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2CustomRackGetModuleInfo); + LIB_FUNCTION("Kg1MA5j7KFk", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2FftInit); + LIB_FUNCTION("D8eCqBxSojA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2FftProcess); + LIB_FUNCTION("-YNfTO6KOMY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2FftQuerySize); + LIB_FUNCTION("eF8yRCC6W64", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomApply); + LIB_FUNCTION("1WsleK-MTkE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomCalcListener); + LIB_FUNCTION("7Lcfo8SmpsU", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomResetListenerParam); + LIB_FUNCTION("0lbbayqDNoE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomResetSourceParam); + LIB_FUNCTION("ekGJmmoc8j4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GetWaveformFrameInfo); + LIB_FUNCTION("BcoPfWfpvVI", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2JobSchedulerResetOption); + LIB_FUNCTION("EEemGEQCjO8", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ModuleArrayEnumItems); + LIB_FUNCTION("TaoNtmMKkXQ", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ModuleEnumConfigs); + LIB_FUNCTION("ve6bZi+1sYQ", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ModuleQueueEnumItems); + LIB_FUNCTION("gbMKV+8Enuo", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2PanGetVolumeMatrix); + LIB_FUNCTION("xa8oL9dmXkM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2PanInit); + LIB_FUNCTION("hyVLT2VlOYk", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ParseWaveformData); + LIB_FUNCTION("iprCTXPVWMI", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ParseWaveformFile); + LIB_FUNCTION("t9T0QM17Kvo", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ParseWaveformUser); + LIB_FUNCTION("cLV4aiT9JpA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackCreate); + LIB_FUNCTION("U546k6orxQo", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2RackCreateWithAllocator); + LIB_FUNCTION("lCqD7oycmIM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackDestroy); + LIB_FUNCTION("M4LYATRhRUE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackGetInfo); + LIB_FUNCTION("Mn4XNDg03XY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackGetUserData); + LIB_FUNCTION("MwmHz8pAdAo", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackGetVoiceHandle); + LIB_FUNCTION("MzTa7VLjogY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackLock); + LIB_FUNCTION("0eFLVCfWVds", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackQueryBufferSize); + LIB_FUNCTION("TZqb8E-j3dY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackQueryInfo); + LIB_FUNCTION("MI2VmBx2RbM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackRunCommands); + LIB_FUNCTION("JNTMIaBIbV4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackSetUserData); + LIB_FUNCTION("++YZ7P9e87U", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackUnlock); + LIB_FUNCTION("uBIN24Tv2MI", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ReportRegisterHandler); + LIB_FUNCTION("nPzb7Ly-VjE", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2ReportUnregisterHandler); + LIB_FUNCTION("koBbCMvOKWw", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemCreate); + LIB_FUNCTION("mPYgU4oYpuY", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2SystemCreateWithAllocator); + LIB_FUNCTION("u-WrYDaJA3k", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemDestroy); + LIB_FUNCTION("vubFP0T6MP0", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemEnumHandles); + LIB_FUNCTION("U-+7HsswcIs", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemEnumRackHandles); + LIB_FUNCTION("vU7TQ62pItw", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemGetInfo); + LIB_FUNCTION("4lFaRxd-aLs", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemGetUserData); + LIB_FUNCTION("gThZqM5PYlQ", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemLock); + LIB_FUNCTION("pgFAiLR5qT4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemQueryBufferSize); + LIB_FUNCTION("3oIK7y7O4k0", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemQueryInfo) + LIB_FUNCTION("i0VnXM-C9fc", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemRender); + LIB_FUNCTION("AQkj7C0f3PY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemResetOption); + LIB_FUNCTION("gXiormHoZZ4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemRunCommands); + LIB_FUNCTION("l4Q2dWEH6UM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetGrainSamples); + LIB_FUNCTION("Wdlx0ZFTV9s", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetLoudThreshold); + LIB_FUNCTION("-tbc2SxQD60", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetSampleRate); + LIB_FUNCTION("GZB2v0XnG0k", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetUserData); + LIB_FUNCTION("JXRC5n0RQls", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemUnlock); + LIB_FUNCTION("sU2St3agdjg", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamCreate); + LIB_FUNCTION("I+RLwaauggA", "libSceNgs2", 1, "libSceNgs2", 1, 1, + sceNgs2StreamCreateWithAllocator); + LIB_FUNCTION("bfoMXnTRtwE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamDestroy); + LIB_FUNCTION("dxulc33msHM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamQueryBufferSize); + LIB_FUNCTION("rfw6ufRsmow", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamQueryInfo); + LIB_FUNCTION("q+2W8YdK0F8", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamResetOption); + LIB_FUNCTION("qQHCi9pjDps", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamRunCommands); + LIB_FUNCTION("uu94irFOGpA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceControl); + LIB_FUNCTION("jjBVvPN9964", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetMatrixInfo); + LIB_FUNCTION("W-Z8wWMBnhk", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetOwner); + LIB_FUNCTION("WCayTgob7-o", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetPortInfo); + LIB_FUNCTION("-TOuuAQ-buE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetState); + LIB_FUNCTION("rEh728kXk3w", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetStateFlags); + LIB_FUNCTION("9eic4AmjGVI", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceQueryInfo); + LIB_FUNCTION("AbYvTOZ8Pts", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceRunCommands); +}; + +} // namespace Libraries::Ngs2 \ No newline at end of file diff --git a/src/core/libraries/ngs2/ngs2.h b/src/core/libraries/ngs2/ngs2.h new file mode 100644 index 00000000..0df83f56 --- /dev/null +++ b/src/core/libraries/ngs2/ngs2.h @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +#include +#include + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::Ngs2 { + +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 00000000..254ae26e --- /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 00000000..185be94d --- /dev/null +++ b/src/core/libraries/ngs2/ngs2_impl.cpp @@ -0,0 +1,163 @@ +// 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 00000000..36001779 --- /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 HandleCleanup(Ngs2Handle* handle, u32 hType, void* dataOut); + s32 HandleEnter(Ngs2Handle* handle, u32 hType, Ngs2Handle* handleOut); + s32 HandleLeave(Ngs2Handle* handle); + s32 StackBufferOpen(StackBuffer* buf, void* base_addr, size_t size, void** stackTop, + bool verify); + s32 StackBufferClose(StackBuffer* buf, size_t* usedSize); + s32 SystemSetupCore(StackBuffer* buf, SystemOptions* options, Ngs2Handle** sysOut); + +private: +}; + +} // namespace Libraries::Ngs2 diff --git a/src/emulator.cpp b/src/emulator.cpp index 4990b4aa..12e89349 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -22,6 +22,7 @@ #include "core/libraries/libc/libc.h" #include "core/libraries/libc_internal/libc_internal.h" #include "core/libraries/libs.h" +#include "core/libraries/ngs2/ngs2.h" #include "core/libraries/rtc/rtc.h" #include "core/libraries/videoout/video_out.h" #include "core/linker.h" @@ -184,7 +185,7 @@ void Emulator::Run(const std::filesystem::path& file) { void Emulator::LoadSystemModules(const std::filesystem::path& file) { constexpr std::array ModulesToLoad{ - {{"libSceNgs2.sprx", nullptr}, + {{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2}, {"libSceFiber.sprx", nullptr}, {"libSceUlt.sprx", nullptr}, {"libSceJson.sprx", nullptr},