diff --git a/src/core/libraries/ult/ult.cpp b/src/core/libraries/ult/ult.cpp index 91cee321c..5df8631e6 100644 --- a/src/core/libraries/ult/ult.cpp +++ b/src/core/libraries/ult/ult.cpp @@ -35,13 +35,10 @@ int PS4_SYSV_ABI _sceUltUlthreadCreate(OrbisUltUlthread* ulthread, const char* n } int PS4_SYSV_ABI _sceUltWaitingQueueResourcePoolCreate( - OrbisUltWaitingQueueResourcePool* pool, const char* name, - uint32_t numThreads, uint32_t numSyncObjects, - void* workArea, - OrbisUltWaitingQueueResourcePoolOptParam* optParam) -{ + OrbisUltWaitingQueueResourcePool* pool, const char* name, uint32_t numThreads, + uint32_t numSyncObjects, void* workArea, OrbisUltWaitingQueueResourcePoolOptParam* optParam) { LOG_ERROR(Lib_Ult, "(STUBBED) called"); - + if (pool == nullptr) return ORBIS_ULT_ERROR_NULL; @@ -51,41 +48,86 @@ int PS4_SYSV_ABI _sceUltWaitingQueueResourcePoolCreate( // TODO: Check memory alignment // TODO: Set ORBIS_ULT_ERROR_NOT_INITIALIZE - if (optParam != nullptr) - { + if (optParam != nullptr) { // TODO: Check memory alignment // TODO: FUN_0100678(optParam) } // TODO: FUN_01011b10(&pool->field41_0x30,numThreads,numSyncObjects,(long)workArea); - if (numThreads > 0 && numSyncObjects > 0 && workArea != nullptr) - { + if (numThreads > 0 && numSyncObjects > 0 && workArea != nullptr) { pool->workArea = workArea; void* w = (void*)((long)workArea + 0x20); } // IF NO ERROR - //FUN_0101e800((char *)pool,name) - pool->field32_0x20 = 0x100; // ?? + // FUN_0101e800((char *)pool,name) + pool->field32_0x20 = 0x100; // ?? pool->field33_0x22 = '\x06'; // ?? pool->numThreads = numThreads * 2; pool->numSyncObjects = numSyncObjects; - //BG26hBGiNlw(pool, 0x16, &pool->field178_0xc0); - // ENDIF + // BG26hBGiNlw(pool, 0x16, &pool->field178_0xc0); + // ENDIF return ORBIS_OK; } int PS4_SYSV_ABI _sceUltQueueDataResourcePoolCreate( - OrbisUltQueueDataResourcePool* pool, const char* name, - uint32_t numData, uint64_t dataSize, - uint32_t numQueueObjects, - OrbisUltWaitingQueueResourcePool* waitingQueueResourcePool, - void* workArea, - OrbisUltQueueDataResourcePoolOptParam* optParam) -{ + OrbisUltQueueDataResourcePool* pool, const char* name, uint32_t numData, uint64_t dataSize, + uint32_t numQueueObjects, OrbisUltWaitingQueueResourcePool* waitingQueueResourcePool, + void* workArea, OrbisUltQueueDataResourcePoolOptParam* optParam) { + LOG_ERROR(Lib_Ult, "(STUBBED) called"); + + if (pool == nullptr) + return ORBIS_ULT_ERROR_NULL; + + // TODO: Check 8 bit alignment + + strncpy((char*)pool, name, 0x1f); + + pool->uk_200 = 0x200; // TODO: Why? + pool->uk_a = '\a'; // TODO: Why? + pool->numData = numData; + pool->numQueueObjects = numQueueObjects; + pool->waitingPool = waitingQueueResourcePool; + + // TODO: BG26hBGiNlw(pool,0x17,&pool->field347_0x170); + + return ORBIS_OK; +} + +int PS4_SYSV_ABI _sceUltQueueCreate(OrbisUltQueue* queue, const char* name, uint64_t dataSize, + OrbisUltQueueDataResourcePool* queueDataResourcePool, + OrbisUltWaitingQueueResourcePool* waitingQueueResourcePool, + OrbisUltQueueOptParam* optParam) { + LOG_ERROR(Lib_Ult, "(STUBBED) called"); + + // TODO: Put data pool + Waiting Pool into Queue + + if (queue != nullptr && name != nullptr && waitingQueueResourcePool->workArea != nullptr) { + // TODO: Check 8bit alignment + if (optParam == nullptr) { + // TODO: Check 8bit alignment + // TODO: Handle default args. It looks like it just sets everything to 0. + } else { + // TODO: Handle optional params + } + + // TODO: Do this in a more readable way + strncpy((char*)queue, name, 0x1f); + + queue->waitingWorkArea = waitingQueueResourcePool->workArea; + queue->dataWorkArea = queueDataResourcePool->workArea; + + } else { + return ORBIS_ULT_ERROR_NULL; + } + + return ORBIS_OK; +} + +int PS4_SYSV_ABI _sceUltQueueOptParamInitialize(OrbisUltQueueOptParam* optParam) { LOG_ERROR(Lib_Ult, "(STUBBED) called"); return ORBIS_OK; } @@ -97,6 +139,10 @@ int PS4_SYSV_ABI sceUltQueueTryPush(OrbisUltQueue* queue, void* data) { int PS4_SYSV_ABI sceUltQueuePush(OrbisUltQueue* queue, void* data) { LOG_ERROR(Lib_Ult, "(STUBBED) called"); + + if (queue == nullptr || data == nullptr) + return ORBIS_ULT_ERROR_NULL; + return ORBIS_OK; } @@ -107,9 +153,27 @@ int PS4_SYSV_ABI sceUltQueueTryPop(OrbisUltQueue* queue, void* data) { int PS4_SYSV_ABI sceUltQueuePop(OrbisUltQueue* queue, void* data) { LOG_ERROR(Lib_Ult, "(STUBBED) called"); + + if (queue == nullptr || data == nullptr) + return ORBIS_ULT_ERROR_NULL; + return ORBIS_OK; } +u64 PS4_SYSV_ABI sceUltWaitingQueueResourcePoolGetWorkAreaSize(uint32_t numThreads, + uint32_t numSyncObjects) { + u64 size = (numSyncObjects + 2 + numThreads * 2) << 5; + LOG_INFO(Lib_Ult, "WaitingQueueResourcePoolSize: {}", size); + return size; +} + +u64 PS4_SYSV_ABI sceUltQueueDataResourcePoolGetWorkAreaSize(uint32_t numData, uint64_t dataSize, + uint32_t numQueueObjects) { + u64 size = numData * dataSize + (numQueueObjects + 3 + numData * 2) * 0x20; + LOG_INFO(Lib_Ult, "QueueDataResourcePoolSize: {}", size); + return size; +} + void RegisterlibSceUlt(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("hZIg1EWGsHM", "libSceUlt", 1, "libSceUlt", 1, 1, sceUltInitialize); LIB_FUNCTION("jw9FkZBXo-g", "libSceUlt", 1, "libSceUlt", 1, 1, _sceUltUlthreadRuntimeCreate); @@ -122,6 +186,12 @@ void RegisterlibSceUlt(Core::Loader::SymbolsResolver* sym) { _sceUltWaitingQueueResourcePoolCreate); LIB_FUNCTION("TFHm6-N6vks", "libSceUlt", 1, "libSceUlt", 1, 1, _sceUltQueueDataResourcePoolCreate); + LIB_FUNCTION("9Y5keOvb6ok", "libSceUlt", 1, "libSceUlt", 1, 1, _sceUltQueueCreate); + LIB_FUNCTION("TkASc9I-xX0", "libSceUlt", 1, "libSceUlt", 1, 1, _sceUltQueueOptParamInitialize); + LIB_FUNCTION("WIWV1Qd7PFU", "libSceUlt", 1, "libSceUlt", 1, 1, + sceUltWaitingQueueResourcePoolGetWorkAreaSize); + LIB_FUNCTION("evj9YPkS8s4", "libSceUlt", 1, "libSceUlt", 1, 1, + sceUltQueueDataResourcePoolGetWorkAreaSize); }; -} \ No newline at end of file +} // namespace Libraries::Ult \ No newline at end of file diff --git a/src/core/libraries/ult/ult.h b/src/core/libraries/ult/ult.h index 6aaffea49..d8d5163ab 100644 --- a/src/core/libraries/ult/ult.h +++ b/src/core/libraries/ult/ult.h @@ -14,7 +14,12 @@ namespace Libraries::Ult { typedef int32_t (*OrbisUltUlthreadEntry)(uint64_t arg); struct OrbisUltQueue { - //private + char unknown[208]; + void* waitingWorkArea; + void* dataWorkArea; + char unknown2[24]; + size_t datasize; + // private }; struct OrbisUltUlthreadRuntimeOptParam { @@ -39,7 +44,7 @@ struct OrbisUltUlthreadOptParam { }; struct OrbisUltWaitingQueueResourcePool { - char unknown_padding1[30]; + char unknown_padding1[31]; char unknown_char; u16 field32_0x20; char field33_0x22; @@ -56,6 +61,17 @@ struct OrbisUltWaitingQueueResourcePoolOptParam { }; struct OrbisUltQueueDataResourcePool { + char unknown_padding1[31]; + short uk_200; + char uk_a; + char unknown_char; + u32 numData; + u32 numQueueObjects; + char unknkown_char3[4]; + void* workArea; + char padd[130]; + char unkown_padding2[4]; + OrbisUltWaitingQueueResourcePool* waitingPool; // private }; @@ -63,6 +79,10 @@ struct OrbisUltQueueDataResourcePoolOptParam { // private }; +struct OrbisUltQueueOptParam { + // Private +}; + int PS4_SYSV_ABI sceUltInitialize(); int PS4_SYSV_ABI _sceUltUlthreadRuntimeCreate(OrbisUltUlthreadRuntime* runtime, const char* name, @@ -84,11 +104,24 @@ int PS4_SYSV_ABI _sceUltQueueDataResourcePoolCreate( uint32_t numQueueObjects, OrbisUltWaitingQueueResourcePool* waitingQueueResourcePool, void* workArea, OrbisUltQueueDataResourcePoolOptParam* optParam); +int PS4_SYSV_ABI _sceUltQueueCreate(OrbisUltQueue* queue, const char* name, uint64_t dataSize, + OrbisUltQueueDataResourcePool* queueDataResourcePool, + OrbisUltWaitingQueueResourcePool* waitingQueueResourcePool, + OrbisUltQueueOptParam* optParam); + +int PS4_SYSV_ABI _sceUltQueueOptParamInitialize(OrbisUltQueueOptParam* optParam); + int PS4_SYSV_ABI sceUltQueueTryPush(OrbisUltQueue* queue, void* data); int PS4_SYSV_ABI sceUltQueuePush(OrbisUltQueue* queue, void* data); int PS4_SYSV_ABI sceUltQueueTryPop(OrbisUltQueue* queue, void* data); int PS4_SYSV_ABI sceUltQueuePop(OrbisUltQueue* queue, void* data); +u64 PS4_SYSV_ABI sceUltWaitingQueueResourcePoolGetWorkAreaSize(uint32_t numThreads, + uint32_t numSyncObjects); + +u64 PS4_SYSV_ABI sceUltQueueDataResourcePoolGetWorkAreaSize(uint32_t numData, uint64_t dataSize, + uint32_t numQueueObjects); + void RegisterlibSceUlt(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::Ult \ No newline at end of file