This commit is contained in:
Stolas 2024-08-18 19:17:09 -03:00 committed by GitHub
commit 232608c956
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 370 additions and 0 deletions

View File

@ -270,6 +270,8 @@ set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
)
set(MISC_LIBS src/core/libraries/screenshot/screenshot.cpp
src/core/libraries/screenshot/screenshot.h
src/core/libraries/ult/ult.cpp
src/core/libraries/ult/ult.h
)
set(COMMON src/common/logging/backend.cpp

View File

@ -100,6 +100,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, NpScore) \
SUB(Lib, NpTrophy) \
SUB(Lib, Screenshot) \
SUB(Lib, Ult) \
SUB(Lib, LibCInternal) \
SUB(Lib, AppContent) \
SUB(Lib, Rtc) \

View File

@ -67,6 +67,7 @@ enum class Class : u8 {
Lib_NpScore, ///< The LibSceNpScore implementation
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
Lib_Screenshot, ///< The LibSceScreenshot implementation
Lib_Ult, ///< The LibSceUlt implementation
Lib_LibCInternal, ///< The LibCInternal implementation.
Lib_AppContent, ///< The LibSceAppContent implementation.
Lib_Rtc, ///< The LibSceRtc implementation.

View File

@ -472,3 +472,11 @@ constexpr int ORBIS_AVPLAYER_ERROR_INFO_OTHER_ENCRY = 0x806A00BF;
// AppContent library
constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002;
// Ult Library
constexpr int ORBIS_ULT_ERROR_STATE = 0x80810006;
constexpr int ORBIS_ULT_ERROR_NULL = 0x80810001;
constexpr int ORBIS_ULT_ERROR_ALIGNMENT = 0x80810002;
constexpr int ORBIS_ULT_ERROR_INVALID = 0x80810004;
constexpr int ORBIS_ULT_ERROR_NOT_INITIALIZE = 0x8081000A;
constexpr int ORBIS_ULT_ERROR_PERMISSION = 0x80810005;

View File

@ -24,6 +24,7 @@
#include "core/libraries/rtc/rtc.h"
#include "core/libraries/save_data/savedata.h"
#include "core/libraries/screenshot/screenshot.h"
#include "core/libraries/ult/ult.h"
#include "core/libraries/system/commondialog.h"
#include "core/libraries/system/msgdialog.h"
#include "core/libraries/system/posix.h"
@ -69,6 +70,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::NpScore::RegisterlibSceNpScore(sym);
Libraries::NpTrophy::RegisterlibSceNpTrophy(sym);
Libraries::ScreenShot::RegisterlibSceScreenShot(sym);
Libraries::Ult::RegisterlibSceUlt(sym);
Libraries::AppContent::RegisterlibSceAppContent(sym);
Libraries::PngDec::RegisterlibScePngDec(sym);
Libraries::PlayGo::RegisterlibScePlayGo(sym);

View File

@ -0,0 +1,222 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "ult.h"
namespace Libraries::Ult {
bool isUltInitialized = false;
int PS4_SYSV_ABI sceUltInitialize() {
LOG_INFO(Lib_Ult, "called");
if (isUltInitialized) {
return ORBIS_ULT_ERROR_STATE;
}
isUltInitialized = true;
return ORBIS_OK;
}
int PS4_SYSV_ABI _sceUltUlthreadRuntimeCreate(OrbisUltUlthreadRuntime* runtime, const char* name,
uint32_t maxNumUlthread, uint32_t numWorkerThread,
void* workArea,
OrbisUltUlthreadRuntimeOptParam* optParam) {
LOG_ERROR(Lib_Ult, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI _sceUltUlthreadCreate(OrbisUltUlthread* ulthread, const char* name,
OrbisUltUlthreadEntry entry, uint64_t arg, void* context,
uint64_t sizeContext, OrbisUltUlthreadRuntime* runtime,
OrbisUltUlthreadOptParam* optParam) {
LOG_ERROR(Lib_Ult, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI _sceUltWaitingQueueResourcePoolCreate(
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;
if (name != nullptr)
LOG_INFO(Lib_Ult, "Creating WaitingQueueResourcePool for {}", name);
// TODO: Check memory alignment
// TODO: Set ORBIS_ULT_ERROR_NOT_INITIALIZE
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) {
pool->workArea = workArea;
}
// IF NO ERROR
strncpy((char*)pool, name, 0x1f);
pool->field32_0x20 = 0x100; // ??
pool->field33_0x22 = '\x06'; // ??
pool->numThreads = numThreads * 2;
pool->numSyncObjects = numSyncObjects;
// 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) {
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;
pool->workArea = workArea;
// 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;
queue->datasize = dataSize;
} 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;
}
int PS4_SYSV_ABI sceUltQueueTryPush(OrbisUltQueue* queue, void* data) {
LOG_ERROR(Lib_Ult, "(STUBBED) called");
return ORBIS_OK;
}
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;
// If there is no data in the queue when sceUltQueuePop() is executed, the thread is in the wait
// state until data is added to the queue.
void* addr = (char*)queue->waitingWorkArea + (queue->datasize) * (queue->uk5);
if (!addr) // Empty
return ORBIS_OK;
memcpy(addr, data, queue->datasize);
queue->uk5++;
return ORBIS_OK;
}
int PS4_SYSV_ABI sceUltQueueTryPop(OrbisUltQueue* queue, void* data) {
LOG_ERROR(Lib_Ult, "(STUBBED) called");
return ORBIS_OK;
}
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;
if (queue->uk5 < 1) // Thread should wait
return ORBIS_OK;
// If there is no data in the queue when sceUltQueuePop() is executed, the thread is in the wait state until data is added to the queue.
void* addr = (char*)queue->waitingWorkArea + (queue->datasize) * (queue->uk5 - 1);
if (!addr) // Empty
return ORBIS_OK;
memcpy(data, addr, queue->datasize);
queue->uk5--;
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);
LIB_FUNCTION("uZz3ci7XYqc", "libSceUlt", 1, "libSceUlt", 1, 1, sceUltQueueTryPop);
LIB_FUNCTION("RVSq2tsm2yw", "libSceUlt", 1, "libSceUlt", 1, 1, sceUltQueuePop);
LIB_FUNCTION("znI3q8S7KQ4", "libSceUlt", 1, "libSceUlt", 1, 1, _sceUltUlthreadCreate);
LIB_FUNCTION("6Mc2Xs7pI1I", "libSceUlt", 1, "libSceUlt", 1, 1, sceUltQueueTryPush);
LIB_FUNCTION("dUwpX3e5NDE", "libSceUlt", 1, "libSceUlt", 1, 1, sceUltQueuePush);
LIB_FUNCTION("YiHujOG9vXY", "libSceUlt", 1, "libSceUlt", 1, 1,
_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);
};
} // namespace Libraries::Ult

View File

@ -0,0 +1,134 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/types.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Ult {
typedef int32_t (*OrbisUltUlthreadEntry)(uint64_t arg);
struct OrbisUltQueue {
char queue_name[31];
char uk[8];
u64 uk2;
u64 uk3;
u64 uk4;
void* ukP;
u32 uk5;
char uk6[131];
void* waitingWorkArea;
void* dataWorkArea;
char unknown2[24];
size_t datasize;
// private
};
struct OrbisUltUlthreadRuntimeOptParam {
uint64_t oneShotThreadStackSize;
u64 workerThreadCpuAffinityMask;
int32_t workerThreadPriority;
int inheritSched;
/* other members are private */
};
struct OrbisUltUlthreadRuntime {
// private
};
struct OrbisUltUlthread {
// private
};
struct OrbisUltUlthreadOptParam {
uint32_t attribute;
// rest private
};
struct OrbisUltWaitingQueueResourcePool {
char queue_name[31];
char unknown_char;
u16 field32_0x20;
char field33_0x22;
char unknkown_char3;
u32 numThreads;
u32 numSyncObjects;
char unkown_padding2[4];
void* workArea;
// More unkowns...
};
struct OrbisUltWaitingQueueResourcePoolOptParam {
// private
};
struct OrbisUltQueueDataResourcePool {
char queue_name[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
};
struct OrbisUltQueueDataResourcePoolOptParam {
// private
};
struct OrbisUltQueueOptParam {
// Private
};
int PS4_SYSV_ABI sceUltInitialize();
int PS4_SYSV_ABI _sceUltUlthreadRuntimeCreate(OrbisUltUlthreadRuntime* runtime, const char* name,
uint32_t maxNumUlthread, uint32_t numWorkerThread,
void* workArea,
OrbisUltUlthreadRuntimeOptParam* optParam);
int PS4_SYSV_ABI _sceUltUlthreadCreate(OrbisUltUlthread* ulthread, const char* name,
OrbisUltUlthreadEntry entry, uint64_t arg, void* context,
uint64_t sizeContext, OrbisUltUlthreadRuntime* runtime,
OrbisUltUlthreadOptParam* optParam);
int PS4_SYSV_ABI _sceUltWaitingQueueResourcePoolCreate(
OrbisUltWaitingQueueResourcePool* pool, const char* name, uint32_t numThreads,
uint32_t numSyncObjects, void* workArea, OrbisUltWaitingQueueResourcePoolOptParam* optParam);
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);
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