Added LibPngDec

(tested with Metal Slug 3, Risk of Rain, Deadbolt and Nidhogg)
This commit is contained in:
raziel1000 2024-06-14 01:37:26 -06:00
parent 31bd502764
commit 080ec3e23e
9 changed files with 336 additions and 12 deletions

View File

@ -190,6 +190,10 @@ set(PAD_LIB src/core/libraries/pad/pad.cpp
src/core/libraries/pad/pad.h src/core/libraries/pad/pad.h
) )
set(PNG_LIB src/core/libraries/libpng/pngdec.cpp
src/core/libraries/libpng/pngdec.h
)
set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
src/core/libraries/np_manager/np_manager.h src/core/libraries/np_manager/np_manager.h
src/core/libraries/np_score/np_score.cpp src/core/libraries/np_score/np_score.cpp
@ -290,6 +294,7 @@ set(CORE src/core/aerolib/stubs.cpp
${PAD_LIB} ${PAD_LIB}
${VIDEOOUT_LIB} ${VIDEOOUT_LIB}
${NP_LIBS} ${NP_LIBS}
${PNG_LIB}
${MISC_LIBS} ${MISC_LIBS}
src/core/linker.cpp src/core/linker.cpp
src/core/linker.h src/core/linker.h

View File

@ -104,6 +104,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, AppContent) \ SUB(Lib, AppContent) \
SUB(Lib, Rtc) \ SUB(Lib, Rtc) \
SUB(Lib, DiscMap) \ SUB(Lib, DiscMap) \
SUB(Lib, Png) \
CLS(Frontend) \ CLS(Frontend) \
CLS(Render) \ CLS(Render) \
SUB(Render, Vulkan) \ SUB(Render, Vulkan) \

View File

@ -71,6 +71,7 @@ enum class Class : u8 {
Lib_AppContent, ///< The LibSceAppContent implementation. Lib_AppContent, ///< The LibSceAppContent implementation.
Lib_Rtc, ///< The LibSceRtc implementation. Lib_Rtc, ///< The LibSceRtc implementation.
Lib_DiscMap, ///< The LibSceDiscMap implementation. Lib_DiscMap, ///< The LibSceDiscMap implementation.
Lib_Png, ///< The LibScePng implementation.
Frontend, ///< Emulator UI Frontend, ///< Emulator UI
Render, ///< Video Core Render, ///< Video Core
Render_Vulkan, ///< Vulkan backend Render_Vulkan, ///< Vulkan backend

View File

@ -679,7 +679,7 @@ int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex*
time.tv_nsec = ((usec % 1000000) * 1000); time.tv_nsec = ((usec % 1000000) * 1000);
int result = pthread_cond_timedwait(&(*cond)->cond, &(*mutex)->pth_mutex, &time); int result = pthread_cond_timedwait(&(*cond)->cond, &(*mutex)->pth_mutex, &time);
LOG_INFO(Kernel_Pthread, "scePthreadCondTimedwait, result={}", result); // LOG_INFO(Kernel_Pthread, "scePthreadCondTimedwait, result={}", result);
switch (result) { switch (result) {
case 0: case 0:
@ -1018,7 +1018,7 @@ int PS4_SYSV_ABI scePthreadCondSignal(ScePthreadCond* cond) {
int result = pthread_cond_signal(&(*cond)->cond); int result = pthread_cond_signal(&(*cond)->cond);
LOG_INFO(Kernel_Pthread, "scePthreadCondSignal, result={}", result); // LOG_INFO(Kernel_Pthread, "scePthreadCondSignal, result={}", result);
switch (result) { switch (result) {
case 0: case 0:
@ -1170,7 +1170,19 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(ScePthread* thread, const ScePthre
int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) { int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) {
return pthread_once(reinterpret_cast<pthread_once_t*>(once_control), init_routine); return pthread_once(reinterpret_cast<pthread_once_t*>(once_control), init_routine);
} }
int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr* attr,
pthreadEntryFunc start_routine, void* arg) {
LOG_INFO(Kernel_Pthread, "posix pthread_create redirect to scePthreadCreate");
int result = scePthreadCreate(thread, attr, start_routine, arg, "");
if (result != 0) {
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
? result + -SCE_KERNEL_ERROR_UNKNOWN
: POSIX_EOTHER;
return rt;
}
return result;
}
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) { void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy); LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy);
LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate); LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate);
@ -1192,7 +1204,8 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("x1X76arYMxU", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGet); LIB_FUNCTION("x1X76arYMxU", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGet);
LIB_FUNCTION("UTXzJbWhhTE", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetstacksize); LIB_FUNCTION("UTXzJbWhhTE", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetstacksize);
LIB_FUNCTION("vNe1w4diLCs", "libkernel", 1, "libkernel", 1, 1, __tls_get_addr); LIB_FUNCTION("vNe1w4diLCs", "libkernel", 1, "libkernel", 1, 1, __tls_get_addr);
LIB_FUNCTION("OxhIB8LB-PQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_create);
LIB_FUNCTION("OxhIB8LB-PQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create);
LIB_FUNCTION("bt3CTBKmGyI", "libkernel", 1, "libkernel", 1, 1, scePthreadSetaffinity); LIB_FUNCTION("bt3CTBKmGyI", "libkernel", 1, "libkernel", 1, 1, scePthreadSetaffinity);
LIB_FUNCTION("6UgtwV+0zb4", "libkernel", 1, "libkernel", 1, 1, scePthreadCreate); LIB_FUNCTION("6UgtwV+0zb4", "libkernel", 1, "libkernel", 1, 1, scePthreadCreate);
LIB_FUNCTION("T72hz6ffq08", "libkernel", 1, "libkernel", 1, 1, scePthreadYield); LIB_FUNCTION("T72hz6ffq08", "libkernel", 1, "libkernel", 1, 1, scePthreadYield);

View File

@ -63,9 +63,7 @@ int PS4_SYSV_ABI sceKernelUsleep(u32 microseconds) {
} }
int PS4_SYSV_ABI posix_usleep(u32 microseconds) { int PS4_SYSV_ABI posix_usleep(u32 microseconds) {
ASSERT(microseconds >= 1000); return sceKernelUsleep(microseconds);
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
return 0;
} }
u32 PS4_SYSV_ABI sceKernelSleep(u32 seconds) { u32 PS4_SYSV_ABI sceKernelSleep(u32 seconds) {
@ -79,11 +77,15 @@ int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, OrbisKernelTimespec* tp) {
} }
clockid_t pclock_id = CLOCK_REALTIME; clockid_t pclock_id = CLOCK_REALTIME;
switch (clock_id) { switch (clock_id) {
case 0: case ORBIS_CLOCK_REALTIME:
case ORBIS_CLOCK_REALTIME_PRECISE:
case ORBIS_CLOCK_REALTIME_FAST:
pclock_id = CLOCK_REALTIME; pclock_id = CLOCK_REALTIME;
break; break;
case 13: case ORBIS_CLOCK_SECOND:
case 4: case ORBIS_CLOCK_MONOTONIC:
case ORBIS_CLOCK_MONOTONIC_PRECISE:
case ORBIS_CLOCK_MONOTONIC_FAST:
pclock_id = CLOCK_MONOTONIC; pclock_id = CLOCK_MONOTONIC;
break; break;
default: default:
@ -100,7 +102,7 @@ int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, OrbisKernelTimespec* tp) {
return SCE_KERNEL_ERROR_EINVAL; return SCE_KERNEL_ERROR_EINVAL;
} }
int PS4_SYSV_ABI clock_gettime(s32 clock_id, OrbisKernelTimespec* time) { int PS4_SYSV_ABI posix_clock_gettime(s32 clock_id, OrbisKernelTimespec* time) {
int result = sceKernelClockGettime(clock_id, time); int result = sceKernelClockGettime(clock_id, time);
if (result < 0) { if (result < 0) {
UNREACHABLE(); // TODO return posix error code UNREACHABLE(); // TODO return posix error code
@ -151,6 +153,37 @@ int PS4_SYSV_ABI gettimeofday(OrbisKernelTimeval* tp, OrbisKernelTimezone* tz) {
return sceKernelGettimeofday(tp); return sceKernelGettimeofday(tp);
} }
int PS4_SYSV_ABI posix_clock_getres(u32 clock_id, OrbisKernelTimespec* res) {
if (res == nullptr) {
return SCE_KERNEL_ERROR_EFAULT;
}
clockid_t pclock_id = CLOCK_REALTIME;
switch (clock_id) {
case ORBIS_CLOCK_REALTIME:
case ORBIS_CLOCK_REALTIME_PRECISE:
case ORBIS_CLOCK_REALTIME_FAST:
pclock_id = CLOCK_REALTIME;
break;
case ORBIS_CLOCK_SECOND:
case ORBIS_CLOCK_MONOTONIC:
case ORBIS_CLOCK_MONOTONIC_PRECISE:
case ORBIS_CLOCK_MONOTONIC_FAST:
pclock_id = CLOCK_MONOTONIC;
break;
default:
UNREACHABLE();
}
timespec t{};
int result = clock_getres(pclock_id, &t);
res->tv_sec = t.tv_sec;
res->tv_nsec = t.tv_nsec;
if (result == 0) {
return SCE_OK;
}
return SCE_KERNEL_ERROR_EINVAL;
}
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) { void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
clock = std::make_unique<Common::NativeClock>(); clock = std::make_unique<Common::NativeClock>();
initial_ptc = clock->GetUptime(); initial_ptc = clock->GetUptime();
@ -163,6 +196,7 @@ void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("ejekcaNQNq0", "libkernel", 1, "libkernel", 1, 1, sceKernelGettimeofday); LIB_FUNCTION("ejekcaNQNq0", "libkernel", 1, "libkernel", 1, 1, sceKernelGettimeofday);
LIB_FUNCTION("n88vx3C5nW8", "libkernel", 1, "libkernel", 1, 1, gettimeofday); LIB_FUNCTION("n88vx3C5nW8", "libkernel", 1, "libkernel", 1, 1, gettimeofday);
LIB_FUNCTION("n88vx3C5nW8", "libScePosix", 1, "libkernel", 1, 1, gettimeofday); LIB_FUNCTION("n88vx3C5nW8", "libScePosix", 1, "libkernel", 1, 1, gettimeofday);
LIB_FUNCTION("QvsZxomvUHs", "libkernel", 1, "libkernel", 1, 1, sceKernelNanosleep);
LIB_FUNCTION("1jfXLRVzisc", "libkernel", 1, "libkernel", 1, 1, sceKernelUsleep); LIB_FUNCTION("1jfXLRVzisc", "libkernel", 1, "libkernel", 1, 1, sceKernelUsleep);
LIB_FUNCTION("QcteRwbsnV0", "libScePosix", 1, "libkernel", 1, 1, posix_usleep); LIB_FUNCTION("QcteRwbsnV0", "libScePosix", 1, "libkernel", 1, 1, posix_usleep);
LIB_FUNCTION("-ZR+hG7aDHw", "libkernel", 1, "libkernel", 1, 1, sceKernelSleep); LIB_FUNCTION("-ZR+hG7aDHw", "libkernel", 1, "libkernel", 1, 1, sceKernelSleep);
@ -170,8 +204,9 @@ void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("yS8U2TGCe1A", "libkernel", 1, "libkernel", 1, 1, posix_nanosleep); LIB_FUNCTION("yS8U2TGCe1A", "libkernel", 1, "libkernel", 1, 1, posix_nanosleep);
LIB_FUNCTION("yS8U2TGCe1A", "libScePosix", 1, "libkernel", 1, 1, posix_nanosleep); LIB_FUNCTION("yS8U2TGCe1A", "libScePosix", 1, "libkernel", 1, 1, posix_nanosleep);
LIB_FUNCTION("QBi7HCK03hw", "libkernel", 1, "libkernel", 1, 1, sceKernelClockGettime); LIB_FUNCTION("QBi7HCK03hw", "libkernel", 1, "libkernel", 1, 1, sceKernelClockGettime);
LIB_FUNCTION("lLMT9vJAck0", "libkernel", 1, "libkernel", 1, 1, clock_gettime); LIB_FUNCTION("lLMT9vJAck0", "libkernel", 1, "libkernel", 1, 1, posix_clock_gettime);
LIB_FUNCTION("lLMT9vJAck0", "libScePosix", 1, "libkernel", 1, 1, clock_gettime); LIB_FUNCTION("lLMT9vJAck0", "libScePosix", 1, "libkernel", 1, 1, posix_clock_gettime);
LIB_FUNCTION("smIj7eqzZE8", "libScePosix", 1, "libkernel", 1, 1, posix_clock_getres);
} }
} // namespace Libraries::Kernel } // namespace Libraries::Kernel

View File

@ -26,6 +26,25 @@ struct OrbisKernelTimespec {
s64 tv_nsec; s64 tv_nsec;
}; };
constexpr int ORBIS_CLOCK_REALTIME = 0;
constexpr int ORBIS_CLOCK_VIRTUAL = 1;
constexpr int ORBIS_CLOCK_PROF = 2;
constexpr int ORBIS_CLOCK_MONOTONIC = 4;
constexpr int ORBIS_CLOCK_UPTIME = 5;
constexpr int ORBIS_CLOCK_UPTIME_PRECISE = 7;
constexpr int ORBIS_CLOCK_UPTIME_FAST = 8;
constexpr int ORBIS_CLOCK_REALTIME_PRECISE = 9;
constexpr int ORBIS_CLOCK_REALTIME_FAST = 10;
constexpr int ORBIS_CLOCK_MONOTONIC_PRECISE = 11;
constexpr int ORBIS_CLOCK_MONOTONIC_FAST = 12;
constexpr int ORBIS_CLOCK_SECOND = 13;
constexpr int ORBIS_CLOCK_THREAD_CPUTIME_ID = 14;
constexpr int ORBIS_CLOCK_PROCTIME = 15;
constexpr int ORBIS_CLOCK_EXT_NETWORK = 16;
constexpr int ORBIS_CLOCK_EXT_DEBUG_NETWORK = 17;
constexpr int ORBIS_CLOCK_EXT_AD_NETWORK = 18;
constexpr int ORBIS_CLOCK_EXT_RAW_NETWORK = 19;
u64 PS4_SYSV_ABI sceKernelGetTscFrequency(); u64 PS4_SYSV_ABI sceKernelGetTscFrequency();
u64 PS4_SYSV_ABI sceKernelGetProcessTime(); u64 PS4_SYSV_ABI sceKernelGetProcessTime();
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter(); u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();

View File

@ -0,0 +1,169 @@
// 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 "externals/stb_image.h"
#include "pngdec.h"
namespace Libraries::PngDec {
void setImageInfoParams(OrbisPngDecImageInfo* imageInfo, int width, int height, int channels,
bool isInterlaced, bool isTransparent) {
if (imageInfo != nullptr) {
imageInfo->imageWidth = width;
imageInfo->imageHeight = height;
imageInfo->bitDepth = 8; // always 8?
switch (channels) { // clut missing
case 1:
imageInfo->colorSpace = OrbisPngDecColorSpace::ORBIS_PNG_DEC_COLOR_SPACE_GRAYSCALE;
break;
case 2:
imageInfo->colorSpace =
OrbisPngDecColorSpace::ORBIS_PNG_DEC_COLOR_SPACE_GRAYSCALE_ALPHA;
break;
case 3:
imageInfo->colorSpace = OrbisPngDecColorSpace::ORBIS_PNG_DEC_COLOR_SPACE_RGB;
break;
case 4:
imageInfo->colorSpace = OrbisPngDecColorSpace::ORBIS_PNG_DEC_COLOR_SPACE_RGBA;
break;
default:
imageInfo->colorSpace = OrbisPngDecColorSpace::ORBIS_PNG_DEC_COLOR_SPACE_RGB;
break;
}
imageInfo->imageFlag = 0;
if (isInterlaced) {
imageInfo->imageFlag |= ORBIS_PNG_DEC_IMAGE_FLAG_ADAM7_INTERLACE;
}
if (isTransparent) {
imageInfo->imageFlag |= ORBIS_PNG_DEC_IMAGE_FLAG_TRNS_CHUNK_EXIST;
}
}
}
bool checktRNS(const u8* png_raw, int size) {
for (int i = 30; i < size - 4; i += 4) {
if (std::memcmp(png_raw + i, "tRNS", 4) == 0) {
return true;
}
}
return false;
}
s32 PS4_SYSV_ABI scePngDecCreate(const OrbisPngDecCreateParam* param, void* memoryAddress,
u32 memorySize, OrbisPngDecHandle* handle) {
if (param == nullptr || param->attribute > 1) {
LOG_ERROR(Lib_Png, "Invalid param!");
return ORBIS_PNG_DEC_ERROR_INVALID_PARAM;
}
if (memoryAddress == nullptr) {
LOG_ERROR(Lib_Png, "Invalid memory address!");
return ORBIS_PNG_DEC_ERROR_INVALID_ADDR;
}
if (param->maxImageWidth - 1 > 1000000) {
LOG_ERROR(Lib_Png, "Invalid size! width = {}", param->maxImageWidth);
return ORBIS_PNG_DEC_ERROR_INVALID_SIZE;
}
const OrbisPngDecCreateParam* nextParam = param + 1;
int ret = (8 << (reinterpret_cast<uintptr_t>(nextParam) & 0x1f)) *
(param->maxImageWidth + 0x47U & 0xfffffff8) +
0xd000;
*handle = reinterpret_cast<OrbisPngDecHandle>(ret);
return ORBIS_OK;
}
s32 PS4_SYSV_ABI scePngDecDecode(OrbisPngDecHandle handle, const OrbisPngDecDecodeParam* param,
OrbisPngDecImageInfo* imageInfo) {
if (handle == nullptr) {
LOG_ERROR(Lib_Png, "invalid handle!");
return ORBIS_PNG_DEC_ERROR_INVALID_HANDLE;
}
if (param == nullptr) {
LOG_ERROR(Lib_Png, "Invalid param!");
return ORBIS_PNG_DEC_ERROR_INVALID_PARAM;
}
if (param->pngMemAddr == nullptr || param->pngMemAddr == nullptr) {
LOG_ERROR(Lib_Png, "invalid image address!");
return ORBIS_PNG_DEC_ERROR_INVALID_ADDR;
}
int width, height, channels;
const u8* png_raw = (const u8*)param->pngMemAddr;
u8* img = stbi_load_from_memory(png_raw, param->pngMemSize, &width, &height, &channels,
STBI_rgb_alpha); // STBI_rgb_alpha?
if (!img) {
LOG_ERROR(Lib_Png, "Decoding failed!");
return ORBIS_PNG_DEC_ERROR_DECODE_ERROR;
}
bool isInterlaced = (png_raw[28] == 1);
bool isTransparent = checktRNS(png_raw, param->pngMemSize);
setImageInfoParams(imageInfo, width, height, channels, isInterlaced, isTransparent);
u8* imageBuffer = (u8*)(param->imageMemAddr);
memcpy(imageBuffer, img, width * height * 4); // copy/pass decoded data
stbi_image_free(img);
return 0;
}
s32 PS4_SYSV_ABI scePngDecDecodeWithInputControl() {
LOG_ERROR(Lib_Png, "(STUBBED)called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI scePngDecDelete(OrbisPngDecHandle handle) {
handle = nullptr; // ?
LOG_ERROR(Lib_Png, "(STUBBED)called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI scePngDecParseHeader(const OrbisPngDecParseParam* param,
OrbisPngDecImageInfo* imageInfo) {
if (param == nullptr) {
LOG_ERROR(Lib_Png, "Invalid param!");
return ORBIS_PNG_DEC_ERROR_INVALID_PARAM;
}
int width, height, channels;
const u8* png_raw = (const u8*)(param->pngMemAddr);
int img = stbi_info_from_memory(png_raw, param->pngMemSize, &width, &height, &channels);
if (img == 0) {
LOG_ERROR(Lib_Png, "Decoding failed!");
return ORBIS_PNG_DEC_ERROR_DECODE_ERROR;
}
bool isInterlaced = (png_raw[28] == 1);
bool isTransparent = checktRNS(png_raw, param->pngMemSize);
setImageInfoParams(imageInfo, width, height, channels, isInterlaced, isTransparent);
return ORBIS_OK;
}
s32 PS4_SYSV_ABI scePngDecQueryMemorySize(const OrbisPngDecCreateParam* param) {
if (param == nullptr) {
LOG_ERROR(Lib_Png, "Invalid param!");
return ORBIS_PNG_DEC_ERROR_INVALID_PARAM;
}
if (param->attribute > 1) {
LOG_ERROR(Lib_Png, "Invalid attribute! attribute = {}", param->attribute);
return ORBIS_PNG_DEC_ERROR_INVALID_ADDR;
}
if (param->maxImageWidth - 1 > 1000000) {
LOG_ERROR(Lib_Png, "Invalid size! width = {}", param->maxImageWidth);
return ORBIS_PNG_DEC_ERROR_INVALID_SIZE;
}
int ret =
(8 << ((u8)param->attribute & 0x1f)) * (param->maxImageWidth + 0x47U & 0xfffffff8) + 0xd090;
return ret;
}
void RegisterlibScePngDec(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("m0uW+8pFyaw", "libScePngDec", 1, "libScePngDec", 1, 1, scePngDecCreate);
LIB_FUNCTION("WC216DD3El4", "libScePngDec", 1, "libScePngDec", 1, 1, scePngDecDecode);
LIB_FUNCTION("cJ--1xAbj-I", "libScePngDec", 1, "libScePngDec", 1, 1,
scePngDecDecodeWithInputControl);
LIB_FUNCTION("QbD+eENEwo8", "libScePngDec", 1, "libScePngDec", 1, 1, scePngDecDelete);
LIB_FUNCTION("U6h4e5JRPaQ", "libScePngDec", 1, "libScePngDec", 1, 1, scePngDecParseHeader);
LIB_FUNCTION("-6srIGbLTIU", "libScePngDec", 1, "libScePngDec", 1, 1, scePngDecQueryMemorySize);
LIB_FUNCTION("cJ--1xAbj-I", "libScePngDec_jvm", 1, "libScePngDec", 1, 1,
scePngDecDecodeWithInputControl);
};
} // namespace Libraries::PngDec

View File

@ -0,0 +1,79 @@
// 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::PngDec {
constexpr int ORBIS_PNG_DEC_ERROR_INVALID_ADDR = 0x80690001;
constexpr int ORBIS_PNG_DEC_ERROR_INVALID_SIZE = 0x80690002;
constexpr int ORBIS_PNG_DEC_ERROR_INVALID_PARAM = 0x80690003;
constexpr int ORBIS_PNG_DEC_ERROR_INVALID_HANDLE = 0x80690004;
constexpr int ORBIS_PNG_DEC_ERROR_INVALID_WORK_MEMORY = 0x80690005;
constexpr int ORBIS_PNG_DEC_ERROR_INVALID_DATA = 0x80690010;
constexpr int ORBIS_PNG_DEC_ERROR_UNSUPPORT_DATA = 0x80690011;
constexpr int ORBIS_PNG_DEC_ERROR_DECODE_ERROR = 0x80690012;
constexpr int ORBIS_PNG_DEC_ERROR_FATAL = 0x80690020;
typedef struct OrbisPngDecParseParam {
const void* pngMemAddr;
u32 pngMemSize;
u32 reserved;
} OrbisPngDecParseParam;
typedef struct OrbisPngDecImageInfo {
u32 imageWidth;
u32 imageHeight;
u16 colorSpace;
u16 bitDepth;
u32 imageFlag;
} OrbisPngDecImageInfo;
typedef enum OrbisPngDecColorSpace {
ORBIS_PNG_DEC_COLOR_SPACE_GRAYSCALE = 2,
ORBIS_PNG_DEC_COLOR_SPACE_RGB,
ORBIS_PNG_DEC_COLOR_SPACE_CLUT,
ORBIS_PNG_DEC_COLOR_SPACE_GRAYSCALE_ALPHA = 18,
ORBIS_PNG_DEC_COLOR_SPACE_RGBA
} ScePngDecColorSpace;
typedef enum OrbisPngDecImageFlag {
ORBIS_PNG_DEC_IMAGE_FLAG_ADAM7_INTERLACE = 1,
ORBIS_PNG_DEC_IMAGE_FLAG_TRNS_CHUNK_EXIST = 2
} OrbisPngDecImageFlag;
typedef struct OrbisPngDecCreateParam {
u32 thisSize;
u32 attribute;
u32 maxImageWidth;
} OrbisPngDecCreateParam;
typedef void* OrbisPngDecHandle;
typedef struct OrbisPngDecDecodeParam {
const void* pngMemAddr;
void* imageMemAddr;
u32 pngMemSize;
u32 imageMemSize;
u16 pixelFormat;
u16 alphaValue;
u32 imagePitch;
} OrbisPngDecDecodeParam;
s32 PS4_SYSV_ABI scePngDecCreate(const OrbisPngDecCreateParam* param, void* memoryAddress,
u32 memorySize, OrbisPngDecHandle* handle);
s32 PS4_SYSV_ABI scePngDecDecode(OrbisPngDecHandle handle, const OrbisPngDecDecodeParam* param,
OrbisPngDecImageInfo* imageInfo);
s32 PS4_SYSV_ABI scePngDecDecodeWithInputControl();
s32 PS4_SYSV_ABI scePngDecDelete(OrbisPngDecHandle handle);
s32 PS4_SYSV_ABI scePngDecParseHeader(const OrbisPngDecParseParam* param,
OrbisPngDecImageInfo* imageInfo);
s32 PS4_SYSV_ABI scePngDecQueryMemorySize(const OrbisPngDecCreateParam* param);
void RegisterlibScePngDec(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::PngDec

View File

@ -30,6 +30,7 @@
#include "core/libraries/system/systemservice.h" #include "core/libraries/system/systemservice.h"
#include "core/libraries/system/userservice.h" #include "core/libraries/system/userservice.h"
#include "core/libraries/videoout/video_out.h" #include "core/libraries/videoout/video_out.h"
#include "src/core/libraries/libpng/pngdec.h"
namespace Libraries { namespace Libraries {
@ -65,6 +66,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::AppContent::RegisterlibSceAppContent(sym); Libraries::AppContent::RegisterlibSceAppContent(sym);
Libraries::Rtc::RegisterlibSceRtc(sym); Libraries::Rtc::RegisterlibSceRtc(sym);
Libraries::DiscMap::RegisterlibSceDiscMap(sym); Libraries::DiscMap::RegisterlibSceDiscMap(sym);
Libraries::PngDec::RegisterlibScePngDec(sym);
} }
} // namespace Libraries } // namespace Libraries