diff --git a/modules/external/libSceZlib/README.md b/modules/external/libSceZlib/README.md new file mode 100644 index 00000000..d76c9b14 --- /dev/null +++ b/modules/external/libSceZlib/README.md @@ -0,0 +1,23 @@ +# How to ZLib + +## ZLib thread +From what I see, the Library should create separate thread for ZLib data processing. This thread should be put to sleep by condition variable, when there's no requests (and `sceZlibInflate` should signal this variable ofc). + +## sceZlibInitialize +Creates the ZLib processing thread. Passed buffer should not be used, moreover should set it to `nullptr`. + +## sceZlibFinalize +Terminates ZLib processing thread and destroys every active request in queue. + +## sceZlibInflate +Function `sceZlibInflate` creates decompression request and puts it into queue. The thread should process all the requests and store unpacked data for each request to `dst` pointer set by inflate call. The created request should be stored to `reqId` pointer passed to inflate function. + +## sceZlibWaitForDone +Game should call `sceZlibWaitForDone` to check if there's any ready to use inflated blocks, the library stores `reqId` for finished block and returns `Ok`. However there's a `timeout` parameter, this function should return `Err::Zlib::TIMEDOUT` if every decompression request is pending (or the queue is empty). + +## sceZlibGetResult +This function returns the decompressed data length and decompression status for specified request. Probably it should lock the thread if data is not ready yet. + + +## Notes +* There's a hard `64 KiB` limit for decompressed block size, if the decompressed block exceeds this limit, the `sceZlibGetResult` should return `Err::Zlib::NOSPACE` error code. diff --git a/modules/external/libSceZlib/codes.h b/modules/external/libSceZlib/codes.h index f158822a..68d383b6 100644 --- a/modules/external/libSceZlib/codes.h +++ b/modules/external/libSceZlib/codes.h @@ -1,4 +1,17 @@ #pragma once #include -namespace Err {} // namespace Err \ No newline at end of file +namespace Err { +namespace Zlib { +constexpr int32_t FATAL = -2129526529; +constexpr int32_t ALREADY_INITIALIZED = -2129526733; +constexpr int32_t NOT_INITIALIZED = -2129526734; +constexpr int32_t TIMEDOUT = -2129526745; +constexpr int32_t NOT_SUPPORTED = -2129526747; +constexpr int32_t NOSPACE = -2129526756; +constexpr int32_t INVALID = -2129526762; +constexpr int32_t FAULT = -2129526770; +constexpr int32_t AGAIN = -2129526773; +constexpr int32_t NOT_FOUND = -2129526782; +} // namespace Zlib +} // namespace Err diff --git a/modules/external/libSceZlib/entry.cpp b/modules/external/libSceZlib/entry.cpp index 7dcc8c9b..d72417dc 100644 --- a/modules/external/libSceZlib/entry.cpp +++ b/modules/external/libSceZlib/entry.cpp @@ -4,15 +4,51 @@ LOG_DEFINE_MODULE(libSceZlib); -namespace {} // namespace +namespace { +static bool g_bInitialized = false; +static uint64_t g_reqId = 0; +} // namespace extern "C" { EXPORT const char* MODULE_NAME = "libSceZlib"; -EXPORT SYSV_ABI int32_t sceZlibInitialize(const void* buffer, size_t length) { +EXPORT SYSV_ABI int32_t sceZlibInitialize(const void* buffer, size_t len) { + if (g_bInitialized) return Err::Zlib::ALREADY_INITIALIZED; LOG_USE_MODULE(libSceZlib); LOG_ERR(L"todo %S", __FUNCTION__); + g_bInitialized = true; return Ok; } -} \ No newline at end of file + +EXPORT SYSV_ABI int32_t sceZlibFinalize() { + if (!g_bInitialized) return Err::Zlib::NOT_INITIALIZED; + LOG_USE_MODULE(libSceZlib); + LOG_ERR(L"todo %S", __FUNCTION__); + g_bInitialized = false; + return Ok; +} + +EXPORT SYSV_ABI int32_t sceZlibInflate(const void* src, uint32_t srcLen, void* dst, uint32_t dstLen, uint64_t* reqId) { + if (!g_bInitialized) return Err::Zlib::NOT_INITIALIZED; + LOG_USE_MODULE(libSceZlib); + LOG_ERR(L"todo %S", __FUNCTION__); + *reqId = ++g_reqId; + return Ok; +} + +EXPORT SYSV_ABI int32_t sceZlibWaitForDone(uint64_t* reqId, uint32_t* timeout) { + if (!g_bInitialized) return Err::Zlib::NOT_INITIALIZED; + LOG_USE_MODULE(libSceZlib); + LOG_TRACE(L"todo %S", __FUNCTION__); + return Err::Zlib::TIMEDOUT; +} + +EXPORT SYSV_ABI int32_t sceZlibGetResult(uint64_t reqId, uint32_t* dstLen, int* status) { + if (!g_bInitialized) return Err::Zlib::NOT_INITIALIZED; + LOG_USE_MODULE(libSceZlib); + LOG_TRACE(L"todo %S", __FUNCTION__); + *status = -1; + return Err::Zlib::NOT_FOUND; +} +}