From 470afd78d5e2ac52c87047456e95329e7279a6d4 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 8 Sep 2014 04:54:17 +0400 Subject: [PATCH] WIP (cellPngDec refactoring) --- Utilities/BEType.h | 6 +- rpcs3/Emu/Memory/vm_ptr.h | 12 + rpcs3/Emu/SysCalls/Modules/cellPng.h | 174 +++++ rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 694 +++++++++++++++---- rpcs3/Emu/SysCalls/Modules/cellPngDec.h | 358 ++++++++-- rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 19 +- rpcs3/Emu/SysCalls/SC_FUNC.h | 29 +- rpcs3/emucore.vcxproj | 1 + rpcs3/emucore.vcxproj.filters | 3 + 9 files changed, 1081 insertions(+), 215 deletions(-) create mode 100644 rpcs3/Emu/SysCalls/Modules/cellPng.h diff --git a/Utilities/BEType.h b/Utilities/BEType.h index a261146e8c..50058489d4 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -438,9 +438,9 @@ public: } } - template be_t operator & (const be_t& right) const { const T res; res = ToBE() & right.ToBE(); return (be_t&)res; } - template be_t operator | (const be_t& right) const { const T res; res = ToBE() | right.ToBE(); return (be_t&)res; } - template be_t operator ^ (const be_t& right) const { const T res; res = ToBE() ^ right.ToBE(); return (be_t&)res; } + template be_t operator & (const be_t& right) const { const T res = ToBE() & right.ToBE(); return (be_t&)res; } + template be_t operator | (const be_t& right) const { const T res = ToBE() | right.ToBE(); return (be_t&)res; } + template be_t operator ^ (const be_t& right) const { const T res = ToBE() ^ right.ToBE(); return (be_t&)res; } template bool operator == (T1 right) const { return (T1)ToLE() == right; } template bool operator != (T1 right) const { return !(*this == right); } diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index 385d34f1aa..24824b382f 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -238,6 +238,13 @@ namespace vm return (_ptr_base&)addr; } + template + operator const _ptr_base() const + { + typename std::remove_const::type addr; addr = m_addr; + return (_ptr_base&)addr; + } + static _ptr_base make(AT addr) { return (_ptr_base&)addr; @@ -352,15 +359,20 @@ namespace vm AT m_addr; static_assert(!std::is_floating_point::value, "TODO: Unsupported callback result type (floating point)"); + static_assert(!std::is_same::value, "TODO: Unsupported callback result type (vector)"); static_assert(!std::is_pointer::value, "Invalid callback result type (pointer)"); + static_assert(!std::is_reference::value, "Invalid callback result type (reference)"); template struct _func_arg { static_assert(!std::is_floating_point::value, "TODO: Unsupported callback argument type (floating point)"); + static_assert(!std::is_same::value, "TODO: Unsupported callback argument type (vector)"); + static_assert(sizeof(TT) <= 8, "Invalid callback argument type"); static_assert(!std::is_pointer::value, "Invalid callback argument type (pointer)"); + static_assert(!std::is_reference::value, "Invalid callback argument type (reference)"); __forceinline static u64 get_value(const TT& arg) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellPng.h b/rpcs3/Emu/SysCalls/Modules/cellPng.h new file mode 100644 index 0000000000..79c88a83fe --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellPng.h @@ -0,0 +1,174 @@ +#pragma once + +enum CellPngTxtType +{ + CELL_PNG_TEXT = 0, + CELL_PNG_ZTXT = 1, + CELL_PNG_ITXT = 2, +}; + +struct CellPngPLTEentry +{ + u8 red; + u8 green; + u8 blue; +}; + +struct CellPngPaletteEntries +{ + be_t red; + be_t green; + be_t blue; + be_t alpha; + be_t frequency; +}; + +struct CellPngSPLTentry +{ + vm::bptr paletteName; + u8 sampleDepth; + vm::bptr paletteEntries; + be_t paletteEntriesNumber; +}; + +enum CellPngUnknownLocation +{ + CELL_PNG_BEFORE_PLTE = 1, + CELL_PNG_BEFORE_IDAT = 2, + CELL_PNG_AFTER_IDAT = 8, +}; + +struct CellPngTextInfo +{ + be_t txtType; + vm::bptr keyword; + vm::bptr text; + be_t textLength; + vm::bptr languageTag; + vm::bptr translatedKeyword; +}; + +struct CellPngPLTE +{ + be_t paletteEntriesNumber; + vm::bptr paletteEntries; +}; + +struct CellPngGAMA +{ + be_t gamma; +}; + +struct CellPngSRGB +{ + be_t renderingIntent; +}; + +struct CellPngICCP +{ + vm::bptr profileName; + vm::bptr profile; + be_t profileLength; +}; + +struct CellPngSBIT +{ + be_t red; + be_t green; + be_t blue; + be_t gray; + be_t alpha; +}; + +struct CellPngTRNS +{ + vm::bptr alphaForPaletteIndex; + be_t alphaForPaletteIndexNumber; + be_t red; + be_t green; + be_t blue; + be_t gray; +}; + +struct CellPngHIST +{ + vm::bptr histgramEntries; + be_t histgramEntriesNumber; +}; + +struct CellPngTIME +{ + be_t year; + u8 month; + u8 day; + u8 hour; + u8 minute; + u8 second; +}; + +struct CellPngBKGD +{ + u8 paletteIndex; + be_t red; + be_t green; + be_t blue; + be_t gray; +}; + +struct CellPngSPLT +{ + vm::bptr sPLTentries; + be_t sPLTentriesNumber; +}; + +struct CellPngOFFS +{ + be_t xPosition; + be_t yPosition; + be_t unitSpecifier; +}; + +struct CellPngPHYS +{ + be_t xAxis; + be_t yAxis; + be_t unitSpecifier; +}; + +struct CellPngSCAL +{ + be_t unitSpecifier; + be_t pixelWidth; + be_t pixelHeight; +}; + +struct CellPngCHRM +{ + be_t whitePointX; + be_t whitePointY; + be_t redX; + be_t redY; + be_t greenX; + be_t greenY; + be_t blueX; + be_t blueY; +}; + +struct CellPngPCAL +{ + vm::bptr calibrationName; + be_t x0; + be_t x1; + be_t equationType; + be_t numberOfParameters; + vm::bptr unitName; + vm::bptr parameter; +}; + +struct CellPngUnknownChunk +{ + char chunkType[5]; + vm::bptr chunkData; + be_t length; + be_t location; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index af26cb2a59..1b2557945c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Emu/Memory/Memory.h" +#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "stblib/stb_image.h" @@ -11,149 +12,111 @@ //Module cellPngDec(0x0018, cellPngDec_init); Module *cellPngDec = nullptr; -static std::map cellPngDecMap; +#ifdef PRX_DEBUG +#include "prx_libpngdec.h" +u32 libpngdec; +u32 libpngdec_rtoc; +#endif -CellPngDecMainHandle *getCellPngDecCtx(u32 mainHandle) { - if (cellPngDecMap.find(mainHandle) == cellPngDecMap.end()) - return nullptr; - - return cellPngDecMap[mainHandle]; -} - -int cellPngDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) +u32 pngDecCreate(vm::ptr param, vm::ptr ext = {}) { - cellPngDec->Warning("cellPngDecCreate(mainHandle=0x%x, threadInParam=0x%x, threadOutParam=0x%x)", mainHandle, threadInParam, threadOutParam); - CellPngDecMainHandle *ctx = new CellPngDecMainHandle; - if (cellPngDecMap.find(mainHandle) != cellPngDecMap.end()) { - delete cellPngDecMap[mainHandle]; - cellPngDecMap.erase(mainHandle); + // alloc memory (should probably use param->cbCtrlMallocFunc) + auto dec = CellPngDecMainHandle::make(Memory.Alloc(sizeof(PngDecoder), 128)); + + // initialize decoder + dec->malloc = param->cbCtrlMallocFunc; + dec->malloc_arg = param->cbCtrlMallocArg; + dec->free = param->cbCtrlFreeFunc; + dec->free_arg = param->cbCtrlFreeArg; + + if (ext) + { } - cellPngDecMap[mainHandle] = ctx; - - ctx->threadInParam = threadInParam; - ctx->threadOutParam = threadOutParam; - - return CELL_OK; + + // use virtual memory address as a handle + return dec.addr(); } -int cellPngDecDestroy(u32 mainHandle) +void pngDecDestroy(CellPngDecMainHandle dec) { - cellPngDec->Warning("cellPngDecDestroy(mainHandle=0x%x)", mainHandle); - CellPngDecMainHandle *ctx = getCellPngDecCtx(mainHandle); - if (!ctx) { - cellPngDec->Warning("cellPngDecDestroy(mainHandle=0x%x): bad handle", mainHandle); - return -1; - } - - delete ctx; - cellPngDecMap.erase(mainHandle); - - return CELL_OK; + Memory.Free(dec.addr()); } -int cellPngDecOpen(u32 mainHandle, vm::ptr> subHandle, vm::ptr src, u32 openInfo) +u32 pngDecOpen(CellPngDecMainHandle dec, vm::ptr src, vm::ptr cb = {}, vm::ptr param = {}) { - cellPngDec->Warning("cellPngDecOpen(mainHandle=0x%x, subHandle=0x%x, src_addr=0x%x, openInfo=0x%x)", - mainHandle, subHandle.addr(), src.addr(), openInfo); + // alloc memory (should probably use dec->malloc) + auto stream = CellPngDecSubHandle::make(Memory.Alloc(sizeof(PngStream), 128)); + + // initialize stream + stream->fd = 0; + stream->src = *src; - CellPngDecSubHandle *current_subHandle = new CellPngDecSubHandle; - current_subHandle->fd = 0; - current_subHandle->src = *src; - - switch(src->srcSelect.ToBE()) + switch (src->srcSelect.ToBE()) { case se32(CELL_PNGDEC_BUFFER): - current_subHandle->fileSize = src->streamSize.ToLE(); + stream->fileSize = src->streamSize.ToLE(); break; case se32(CELL_PNGDEC_FILE): // Get file descriptor vm::var> fd; int ret = cellFsOpen(vm::ptr::make(src->fileName.addr()), 0, fd, vm::ptr>::make(0), 0); - current_subHandle->fd = fd->ToLE(); - if(ret != CELL_OK) return CELL_PNGDEC_ERROR_OPEN_FILE; + stream->fd = fd->ToLE(); + if (ret != CELL_OK) return CELL_PNGDEC_ERROR_OPEN_FILE; // Get size of file vm::var sb; // Alloc a CellFsStat struct - ret = cellFsFstat(current_subHandle->fd, sb); - if(ret != CELL_OK) return ret; - current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size + ret = cellFsFstat(stream->fd, sb); + if (ret != CELL_OK) return ret; + stream->fileSize = sb->st_size; // Get CellFsStat.st_size break; } - // From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct. - *subHandle = cellPngDec->GetNewId(current_subHandle); + if (cb) + { + // TODO: callback + } - return CELL_OK; + if (param) + { + // TODO: param->selectChunk + } + + // use virtual memory address as a handle + return stream.addr(); } -int cellPngDecExtOpen(u32 mainHandle, vm::ptr> subHandle, vm::ptr src, u32 openInfo, vm::ptr cbCtrlStrm, vm::ptr opnParam) +void pngDecClose(CellPngDecSubHandle stream) { - cellPngDec->Warning("cellPngDecExtOpen(mainHandle=0x%x, subHandle=0x%x, src_addr=0x%x, openInfo=0x%x, cbCtrlStrm_addr=0x%x, opnParam=0x%x)", - mainHandle, subHandle.addr(), src.addr(), openInfo, cbCtrlStrm.addr(), opnParam.addr()); - - cellPngDec->Warning("*** cbCtrlStrm->cbCtrlStrmFunc_addr=0x%x", cbCtrlStrm->cbCtrlStrmFunc.addr()); - - vm::var streamInfo; - vm::var streamParam; - - int res = cellPngDecOpen(mainHandle, subHandle, src, openInfo); - - if (!res) cbCtrlStrm->cbCtrlStrmFunc(streamInfo, streamParam, cbCtrlStrm->cbCtrlStrmArg); - - return res; + cellFsClose(stream->fd); + Memory.Free(stream.addr()); } -int cellPngDecClose(u32 mainHandle, u32 subHandle) +void pngReadHeader(CellPngDecSubHandle stream, vm::ptr info, vm::ptr extInfo = {}) { - cellPngDec->Warning("cellPngDecClose(mainHandle=0x%x,subHandle=0x%x)", mainHandle, subHandle); + CellPngDecInfo& current_info = stream->info; - CellPngDecSubHandle* subHandle_data; - if(!cellPngDec->CheckId(subHandle, subHandle_data)) - return CELL_PNGDEC_ERROR_FATAL; + assert(stream->fileSize >= 29); // Error: The file is smaller than the length of a PNG header - cellFsClose(subHandle_data->fd); - cellPngDec->RemoveId(subHandle); - - return CELL_OK; -} - -int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr info) -{ - cellPngDec->Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle, subHandle, info.addr()); - CellPngDecSubHandle* subHandle_data; - if(!cellPngDec->CheckId(subHandle, subHandle_data)) - return CELL_PNGDEC_ERROR_FATAL; - - const u32& fd = subHandle_data->fd; - const u64& fileSize = subHandle_data->fileSize; - CellPngDecInfo& current_info = subHandle_data->info; - - //Check size of file - if(fileSize < 29) return CELL_PNGDEC_ERROR_HEADER; // Error: The file is smaller than the length of a PNG header - //Write the header to buffer vm::var buffer; // Alloc buffer for PNG header auto buffer_32 = buffer.To>(); vm::var> pos, nread; - switch(subHandle_data->src.srcSelect.ToBE()) + switch (stream->src.srcSelect.ToBE()) { case se32(CELL_PNGDEC_BUFFER): - memmove(buffer.begin(), vm::get_ptr(subHandle_data->src.streamPtr), buffer.size()); + memmove(buffer.begin(), vm::get_ptr(stream->src.streamPtr), buffer.size()); break; case se32(CELL_PNGDEC_FILE): - cellFsLseek(fd, 0, CELL_SEEK_SET, pos); - cellFsRead(fd, vm::ptr::make(buffer.addr()), buffer.size(), nread); + cellFsLseek(stream->fd, 0, CELL_SEEK_SET, pos); + cellFsRead(stream->fd, vm::ptr::make(buffer.addr()), buffer.size(), nread); break; } - if (buffer_32[0].ToBE() != se32(0x89504E47) || - buffer_32[1].ToBE() != se32(0x0D0A1A0A) || // Error: The first 8 bytes are not a valid PNG signature - buffer_32[3].ToBE() != se32(0x49484452)) // Error: The PNG file does not start with an IHDR chunk - { - return CELL_PNGDEC_ERROR_HEADER; - } + assert(buffer_32[0].ToBE() == se32(0x89504E47) && + buffer_32[1].ToBE() == se32(0x0D0A1A0A) && // Error: The first 8 bytes are not a valid PNG signature + buffer_32[3].ToBE() == se32(0x49484452)); // Error: The PNG file does not start with an IHDR chunk switch (buffer[25]) { @@ -162,27 +125,19 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr case 3: current_info.colorSpace = CELL_PNGDEC_PALETTE; current_info.numComponents = 1; break; case 4: current_info.colorSpace = CELL_PNGDEC_GRAYSCALE_ALPHA; current_info.numComponents = 2; break; case 6: current_info.colorSpace = CELL_PNGDEC_RGBA; current_info.numComponents = 4; break; - default: return CELL_PNGDEC_ERROR_HEADER; // Not supported color type + default: assert(!"Unknown color type"); return; // Not supported color type } - current_info.imageWidth = buffer_32[4]; - current_info.imageHeight = buffer_32[5]; - current_info.bitDepth = buffer[24]; - current_info.interlaceMethod = buffer[28]; + current_info.imageWidth = buffer_32[4]; + current_info.imageHeight = buffer_32[5]; + current_info.bitDepth = buffer[24]; + current_info.interlaceMethod = (CellPngDecInterlaceMode)buffer[28]; current_info.chunkInformation = 0; // Unimplemented *info = current_info; - - return CELL_OK; } -int cellPngDecExtReadHeader(u32 mainHandle, u32 subHandle, vm::ptr info, vm::ptr extInfo) -{ - cellPngDec->Warning("cellPngDecExtReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x, extInfo_addr=0x%x)", - mainHandle, subHandle, info.addr(), extInfo.addr()); - - return cellPngDecReadHeader(mainHandle, subHandle, info); -} +/* int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo) { @@ -367,39 +322,496 @@ int cellPngDecExtSetParameter(u32 mainHandle, u32 subHandle, vm::ptr mainHandle, vm::ptr threadInParam, vm::ptr threadOutParam) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x295C, libpngdec_rtoc); +#else + cellPngDec->Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x)", + mainHandle.addr(), threadInParam.addr(), threadOutParam.addr()); + + *mainHandle = pngDecCreate(threadInParam); + + // set codec version + threadOutParam->pngCodecVersion = PNGDEC_CODEC_VERSION; + + return CELL_OK; +#endif +} + +s32 cellPngDecExtCreate( + vm::ptr mainHandle, + vm::ptr threadInParam, + vm::ptr threadOutParam, + vm::ptr extThreadInParam, + vm::ptr extThreadOutParam) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x296C, libpngdec_rtoc); +#else + cellPngDec->Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x, extThreadInParam_addr=0x%x, extThreadOutParam_addr=0x%x)", + mainHandle.addr(), threadInParam.addr(), threadOutParam.addr(), extThreadInParam.addr(), extThreadOutParam.addr()); + + // create decoder + *mainHandle = pngDecCreate(threadInParam, extThreadInParam); + + // set codec version + threadOutParam->pngCodecVersion = PNGDEC_CODEC_VERSION; + + extThreadOutParam->reserved = 0; + + return CELL_OK; +#endif +} + +s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x1E6C, libpngdec_rtoc); +#else + cellPngDec->Warning("cellPngDecDestroy(mainHandle=0x%x)", mainHandle.addr()); + + pngDecDestroy(mainHandle); + return CELL_OK; +#endif +} + +s32 cellPngDecOpen( + CellPngDecMainHandle mainHandle, + vm::ptr subHandle, + vm::ptr src, + vm::ptr openInfo) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x3F3C, libpngdec_rtoc); +#else + cellPngDec->Warning("cellPngDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", + mainHandle.addr(), subHandle.addr(), src.addr(), openInfo.addr()); + + // create stream handle + *subHandle = pngDecOpen(mainHandle, src); + + // set memory info + openInfo->initSpaceAllocated = 4096; + + return CELL_OK; +#endif +} + +s32 cellPngDecExtOpen( + CellPngDecMainHandle mainHandle, + vm::ptr subHandle, + vm::ptr src, + vm::ptr openInfo, + vm::ptr cbCtrlStrm, + vm::ptr opnParam) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x3F34, libpngdec_rtoc); +#else + cellPngDec->Warning("cellPngDecExtOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x, cbCtrlStrm_addr=0x%x, opnParam_addr=0x%x)", + mainHandle.addr(), subHandle.addr(), src.addr(), openInfo.addr(), cbCtrlStrm.addr(), opnParam.addr()); + + // create stream handle + *subHandle = pngDecOpen(mainHandle, src, cbCtrlStrm, opnParam); + + // set memory info + openInfo->initSpaceAllocated = 4096; + + return CELL_OK; +#endif +} + +s32 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x066C, libpngdec_rtoc); +#else + cellPngDec->Warning("cellPngDecClose(mainHandle=0x%x, subHandle=0x%x)", mainHandle.addr(), subHandle.addr()); + + pngDecClose(subHandle); + + return CELL_OK; +#endif +} + +s32 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr info) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x3A3C, libpngdec_rtoc); +#else + cellPngDec->Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", + mainHandle.addr(), subHandle.addr(), info.addr()); + + pngReadHeader(subHandle, info); + + return CELL_OK; +#endif +} + +s32 cellPngDecExtReadHeader( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr info, + vm::ptr extInfo) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x3A34, libpngdec_rtoc); +#else + cellPngDec->Warning("cellPngDecExtReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x, extInfo_addr=0x%x)", + mainHandle.addr(), subHandle.addr(), info.addr(), extInfo.addr()); + + pngReadHeader(subHandle, info, extInfo); + + return CELL_OK; +#endif +} + +s32 cellPngDecSetParameter( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr inParam, + vm::ptr outParam) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x33F4, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecExtSetParameter( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr inParam, + vm::ptr outParam, + vm::ptr extInParam, + vm::ptr extOutParam) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x33EC, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecDecodeData( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr data, + vm::ptr dataCtrlParam, + vm::ptr dataOutInfo) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x5D40, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecExtDecodeData( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr data, + vm::ptr dataCtrlParam, + vm::ptr dataOutInfo, + vm::ptr cbCtrlDisp, + vm::ptr dispParam) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x5D38, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetUnknownChunks( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr unknownChunk, + vm::ptr unknownChunkNumber) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x03EC, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr pcal) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x0730, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr chrm) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x0894, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetsCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr scal) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x09EC, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetpHYs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr phys) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x0B14, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetoFFs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr offs) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x0C58, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetsPLT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr splt) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x0D9C, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetbKGD(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr bkgd) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x0ED0, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGettIME(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr time) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x1024, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGethIST(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr hist) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x116C, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGettRNS(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr trns) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x12A4, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetsBIT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr sbit) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x1420, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetiCCP(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr iccp) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x1574, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetsRGB(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr srgb) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x16B4, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetgAMA(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr gama) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x17CC, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr plte) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x18E4, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif +} + +s32 cellPngDecGetTextChunk( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr textInfoNum, + vm::ptr textInfo) +{ +#ifdef PRX_DEBUG + cellPngDec->Warning("%s()", __FUNCTION__); + return GetCurrentPPUThread().FastCall2(libpngdec + 0x19FC, libpngdec_rtoc); +#else + UNIMPLEMENTED_FUNC(cellPngDec); + return CELL_OK; +#endif } void cellPngDec_init() { - cellPngDec->AddFunc(0x157d30c5, cellPngDecCreate); - cellPngDec->AddFunc(0x820dae1a, cellPngDecDestroy); - cellPngDec->AddFunc(0xd2bc5bfd, cellPngDecOpen); - cellPngDec->AddFunc(0x5b3d1ff1, cellPngDecClose); - cellPngDec->AddFunc(0x9ccdcc95, cellPngDecReadHeader); - cellPngDec->AddFunc(0x2310f155, cellPngDecDecodeData); - cellPngDec->AddFunc(0xe97c9bd4, cellPngDecSetParameter); + REG_FUNC(cellPngDec, cellPngDecGetUnknownChunks); + REG_FUNC(cellPngDec, cellPngDecClose); + REG_FUNC(cellPngDec, cellPngDecGetpCAL); + REG_FUNC(cellPngDec, cellPngDecGetcHRM); + REG_FUNC(cellPngDec, cellPngDecGetsCAL); + REG_FUNC(cellPngDec, cellPngDecGetpHYs); + REG_FUNC(cellPngDec, cellPngDecGetoFFs); + REG_FUNC(cellPngDec, cellPngDecGetsPLT); + REG_FUNC(cellPngDec, cellPngDecGetbKGD); + REG_FUNC(cellPngDec, cellPngDecGettIME); + REG_FUNC(cellPngDec, cellPngDecGethIST); + REG_FUNC(cellPngDec, cellPngDecGettRNS); + REG_FUNC(cellPngDec, cellPngDecGetsBIT); + REG_FUNC(cellPngDec, cellPngDecGetiCCP); + REG_FUNC(cellPngDec, cellPngDecGetsRGB); + REG_FUNC(cellPngDec, cellPngDecGetgAMA); + REG_FUNC(cellPngDec, cellPngDecGetPLTE); + REG_FUNC(cellPngDec, cellPngDecGetTextChunk); + REG_FUNC(cellPngDec, cellPngDecDestroy); + REG_FUNC(cellPngDec, cellPngDecCreate); + REG_FUNC(cellPngDec, cellPngDecExtCreate); + REG_FUNC(cellPngDec, cellPngDecExtSetParameter); + REG_FUNC(cellPngDec, cellPngDecSetParameter); + REG_FUNC(cellPngDec, cellPngDecExtReadHeader); + REG_FUNC(cellPngDec, cellPngDecReadHeader); + REG_FUNC(cellPngDec, cellPngDecExtOpen); + REG_FUNC(cellPngDec, cellPngDecOpen); + REG_FUNC(cellPngDec, cellPngDecExtDecodeData); + REG_FUNC(cellPngDec, cellPngDecDecodeData); - cellPngDec->AddFunc(0x0c515302, cellPngDecExtOpen); - cellPngDec->AddFunc(0x8b33f863, cellPngDecExtReadHeader); - cellPngDec->AddFunc(0x726fc1d0, cellPngDecExtDecodeData); - cellPngDec->AddFunc(0x9e9d7d42, cellPngDecExtSetParameter); +#ifdef PRX_DEBUG + CallAfter([]() + { + libpngdec = (u32)Memory.PRXMem.AllocAlign(sizeof(libpngdec_data), 4096); + memcpy(vm::get_ptr(libpngdec), libpngdec_data, sizeof(libpngdec_data)); + libpngdec_rtoc = libpngdec + 0x49710; - /*cellPngDec->AddFunc(0x48436b2d, cellPngDecExtCreate); - cellPngDec->AddFunc(0x7585a275, cellPngDecGetbKGD); - cellPngDec->AddFunc(0x7a062d26, cellPngDecGetcHRM); - cellPngDec->AddFunc(0xb153629c, cellPngDecGetgAMA); - cellPngDec->AddFunc(0xb905ebb7, cellPngDecGethIST); - cellPngDec->AddFunc(0xf44b6c30, cellPngDecGetiCCP); - cellPngDec->AddFunc(0x27c921b5, cellPngDecGetoFFs); - cellPngDec->AddFunc(0xb4fe75e1, cellPngDecGetpCAL); - cellPngDec->AddFunc(0x3d50016a, cellPngDecGetpHYs); - cellPngDec->AddFunc(0x30cb334a, cellPngDecGetsBIT); - cellPngDec->AddFunc(0xc41e1198, cellPngDecGetsCAL); - cellPngDec->AddFunc(0xa5cdf57e, cellPngDecGetsPLT); - cellPngDec->AddFunc(0xe4416e82, cellPngDecGetsRGB); - cellPngDec->AddFunc(0x35a6846c, cellPngDecGettIME); - cellPngDec->AddFunc(0xb96fb26e, cellPngDecGettRNS); - cellPngDec->AddFunc(0xe163977f, cellPngDecGetPLTE); - cellPngDec->AddFunc(0x609ec7d5, cellPngDecUnknownChunks); - cellPngDec->AddFunc(0xb40ca175, cellPngDecGetTextChunk);*/ + extern Module* sysPrxForUser; + extern Module* cellSpurs; + extern Module* sys_fs; + + FIX_IMPORT(sysPrxForUser, _sys_snprintf , libpngdec + 0x1E6D0); + FIX_IMPORT(sysPrxForUser, _sys_strlen , libpngdec + 0x1E6F0); + fix_import(sysPrxForUser, 0x3EF17F8C , libpngdec + 0x1E710); + FIX_IMPORT(sysPrxForUser, _sys_memset , libpngdec + 0x1E730); + FIX_IMPORT(sysPrxForUser, _sys_memcpy , libpngdec + 0x1E750); + FIX_IMPORT(sysPrxForUser, _sys_strcpy , libpngdec + 0x1E770); + FIX_IMPORT(sysPrxForUser, _sys_strncpy , libpngdec + 0x1E790); + FIX_IMPORT(sysPrxForUser, _sys_memcmp , libpngdec + 0x1E7B0); + FIX_IMPORT(cellSpurs, cellSpursQueueDetachLv2EventQueue , libpngdec + 0x1E7D0); + FIX_IMPORT(cellSpurs, cellSpursAttributeSetNamePrefix , libpngdec + 0x1E7F0); + FIX_IMPORT(cellSpurs, _cellSpursQueueInitialize , libpngdec + 0x1E810); + FIX_IMPORT(cellSpurs, _cellSpursTasksetAttributeInitialize, libpngdec + 0x1E830); + FIX_IMPORT(cellSpurs, cellSpursTasksetAttributeSetName , libpngdec + 0x1E850); + FIX_IMPORT(cellSpurs, cellSpursTaskGetReadOnlyAreaPattern , libpngdec + 0x1E870); + FIX_IMPORT(cellSpurs, cellSpursTaskGetContextSaveAreaSize , libpngdec + 0x1E890); + FIX_IMPORT(cellSpurs, cellSpursQueuePopBody , libpngdec + 0x1E8B0); + FIX_IMPORT(cellSpurs, cellSpursQueuePushBody , libpngdec + 0x1E8D0); + FIX_IMPORT(cellSpurs, _cellSpursAttributeInitialize , libpngdec + 0x1E8F0); + FIX_IMPORT(cellSpurs, cellSpursJoinTaskset , libpngdec + 0x1E910); + FIX_IMPORT(cellSpurs, cellSpursShutdownTaskset , libpngdec + 0x1E930); + FIX_IMPORT(cellSpurs, cellSpursInitializeWithAttribute , libpngdec + 0x1E950); + FIX_IMPORT(cellSpurs, cellSpursCreateTask , libpngdec + 0x1E970); + FIX_IMPORT(cellSpurs, cellSpursCreateTasksetWithAttribute , libpngdec + 0x1E990); + FIX_IMPORT(cellSpurs, cellSpursFinalize , libpngdec + 0x1E9B0); + FIX_IMPORT(cellSpurs, cellSpursQueueAttachLv2EventQueue , libpngdec + 0x1E9D0); + FIX_IMPORT(sys_fs, cellFsClose , libpngdec + 0x1E9F0); + FIX_IMPORT(sys_fs, cellFsRead , libpngdec + 0x1EA10); + FIX_IMPORT(sys_fs, cellFsOpen , libpngdec + 0x1EA30); + FIX_IMPORT(sys_fs, cellFsLseek , libpngdec + 0x1EA50); + + fix_relocs(cellPngDec, libpngdec, 0x41C30, 0x47AB0, 0x40A00); + }); +#endif } diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h index c436ad5fc3..a411d704d6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h @@ -1,6 +1,18 @@ #pragma once +#include "cellPng.h" -//Return Codes +enum : u32 +{ + PNGDEC_CODEC_VERSION = 0x00420000, +}; + +struct PngDecoder; +struct PngStream; + +typedef vm::ptr CellPngDecMainHandle; +typedef vm::ptr CellPngDecSubHandle; + +// Return Codes enum { CELL_PNGDEC_ERROR_HEADER = 0x80611201, @@ -15,6 +27,7 @@ enum CELL_PNGDEC_ERROR_CB_PARAM = 0x8061120a, }; +// Consts enum CellPngDecColorSpace { CELL_PNGDEC_GRAYSCALE = 1, @@ -25,10 +38,10 @@ enum CellPngDecColorSpace CELL_PNGDEC_ARGB = 20, }; -enum CellPngDecDecodeStatus +enum CellPngDecSpuThreadEna : u32 { - CELL_PNGDEC_DEC_STATUS_FINISH = 0, //Decoding finished - CELL_PNGDEC_DEC_STATUS_STOP = 1, //Decoding halted + CELL_PNGDEC_SPU_THREAD_DISABLE = 0, + CELL_PNGDEC_SPU_THREAD_ENABLE = 1, }; enum CellPngDecStreamSrcSel @@ -49,19 +62,77 @@ enum CellPngDecOutputMode CELL_PNGDEC_BOTTOM_TO_TOP = 1, }; - -// Structs -struct CellPngDecDataOutInfo +enum CellPngDecPackFlag { - be_t chunkInformation; - be_t numText; - be_t numUnknownChunk; - be_t status; + CELL_PNGDEC_1BYTE_PER_NPIXEL = 0, + CELL_PNGDEC_1BYTE_PER_1PIXEL = 1, }; -struct CellPngDecDataCtrlParam +enum CellPngDecAlphaSelect { - be_t outputBytesPerLine; + CELL_PNGDEC_STREAM_ALPHA = 0, + CELL_PNGDEC_FIX_ALPHA = 1, +}; + +enum CellPngDecCommand +{ + CELL_PNGDEC_CONTINUE = 0, + CELL_PNGDEC_STOP = 1, +}; + +enum CellPngDecDecodeStatus +{ + CELL_PNGDEC_DEC_STATUS_FINISH = 0, + CELL_PNGDEC_DEC_STATUS_STOP = 1, +}; + +// Callbacks +typedef vm::ptr(*CellPngDecCbControlMalloc)(u32 size, vm::ptr cbCtrlMallocArg); +typedef s32(*CellPngDecCbControlFree)(vm::ptr ptr, vm::ptr cbCtrlFreeArg); + +// Structs +struct CellPngDecThreadInParam +{ + be_t spuThreadEnable; + be_t ppuThreadPriority; + be_t spuThreadPriority; + vm::bptr cbCtrlMallocFunc; + be_t> cbCtrlMallocArg; // rough attempt (it's hard to pass vm::bptr as vm::ptr in function argument) + vm::bptr cbCtrlFreeFunc; + be_t> cbCtrlFreeArg; +}; + +struct CellPngDecExtThreadInParam +{ + be_t spurs_addr; // it could be vm::bptr, but nobody will use SPURS in HLE implementation + u8 priority[8]; + be_t maxContention; +}; + +struct CellPngDecThreadOutParam +{ + be_t pngCodecVersion; +}; + +struct CellPngDecExtThreadOutParam +{ + be_t reserved; +}; + +struct CellPngDecSrc +{ + be_t srcSelect; + vm::bptr fileName; + be_t fileOffset; + be_t fileSize; + vm::bptr streamPtr; + be_t streamSize; + be_t spuThreadEnable; +}; + +struct CellPngDecOpnInfo +{ + be_t initSpaceAllocated; }; struct CellPngDecInfo @@ -69,31 +140,20 @@ struct CellPngDecInfo be_t imageWidth; be_t imageHeight; be_t numComponents; - be_t colorSpace; // CellPngDecColorSpace + be_t colorSpace; be_t bitDepth; - be_t interlaceMethod; // CellPngDecInterlaceMode + be_t interlaceMethod; be_t chunkInformation; }; -struct CellPngDecSrc -{ - be_t srcSelect; // CellPngDecStreamSrcSel - vm::bptr fileName; - be_t fileOffset; - be_t fileSize; - be_t streamPtr; - be_t streamSize; - be_t spuThreadEnable; // CellPngDecSpuThreadEna -}; - struct CellPngDecInParam { - be_t commandPtr; - be_t outputMode; // CellPngDecOutputMode - be_t outputColorSpace; // CellPngDecColorSpace + vm::bptr commandPtr; + be_t outputMode; + be_t outputColorSpace; be_t outputBitDepth; - be_t outputPackFlag; // CellPngDecPackFlag - be_t outputAlphaSelect; // CellPngDecAlphaSelect + be_t outputPackFlag; + be_t outputAlphaSelect; be_t outputColorAlpha; }; @@ -104,11 +164,114 @@ struct CellPngDecOutParam be_t outputHeight; be_t outputComponents; be_t outputBitDepth; - be_t outputMode; // CellPngDecOutputMode - be_t outputColorSpace; // CellPngDecColorSpace + be_t outputMode; + be_t outputColorSpace; be_t useMemorySpace; }; +struct CellPngDecDataCtrlParam +{ + be_t outputBytesPerLine; +}; + +struct CellPngDecDataOutInfo +{ + be_t chunkInformation; + be_t numText; + be_t numUnknownChunk; + be_t status; +}; + +// Functions +s32 cellPngDecCreate(vm::ptr mainHandle, vm::ptr threadInParam, vm::ptr threadOutParam); + +s32 cellPngDecExtCreate( + vm::ptr mainHandle, + vm::ptr threadInParam, + vm::ptr threadOutParam, + vm::ptr extThreadInParam, + vm::ptr extThreadOutParam); + +s32 cellPngDecOpen( + CellPngDecMainHandle mainHandle, + vm::ptr subHandle, + vm::ptr src, + vm::ptr openInfo); + +s32 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr info); + +s32 cellPngDecSetParameter( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr inParam, + vm::ptr outParam); + +s32 cellPngDecDecodeData( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr data, + vm::ptr dataCtrlParam, + vm::ptr dataOutInfo); + +s32 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle); + +s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle); + +s32 cellPngDecGetTextChunk( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr textInfoNum, + vm::ptr textInfo); + +s32 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr plte); + +s32 cellPngDecGetgAMA(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr gama); + +s32 cellPngDecGetsRGB(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr srgb); + +s32 cellPngDecGetiCCP(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr iccp); + +s32 cellPngDecGetsBIT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr sbit); + +s32 cellPngDecGettRNS(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr trns); + +s32 cellPngDecGethIST(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr hist); + +s32 cellPngDecGettIME(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr time); + +s32 cellPngDecGetbKGD(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr bkgd); + +s32 cellPngDecGetsPLT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr splt); + +s32 cellPngDecGetoFFs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr offs); + +s32 cellPngDecGetpHYs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr phys); + +s32 cellPngDecGetsCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr scal); + +s32 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr chrm); + +s32 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr pcal); + +s32 cellPngDecGetUnknownChunks( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr unknownChunk, + vm::ptr unknownChunkNumber); + + +enum CellPngDecBufferMode +{ + CELL_PNGDEC_LINE_MODE = 1, +}; + +enum CellPngDecSpuMode +{ + CELL_PNGDEC_RECEIVE_EVENT = 0, + CELL_PNGDEC_TRYRECEIVE_EVENT = 1, +}; + +// Structs struct CellPngDecStrmInfo { be_t decodedStrmSize; @@ -116,25 +279,49 @@ struct CellPngDecStrmInfo struct CellPngDecStrmParam { - be_t strmPtr; + vm::bptr strmPtr; be_t strmSize; }; -struct CellPngDecCbCtrlStrm -{ - vm::bptr strmInfo, vm::ptr strmParam, u32 cbCtrlStrmArg)> cbCtrlStrmFunc; - be_t cbCtrlStrmArg; -}; +typedef s32(*CellPngDecCbControlStream)( + vm::ptr strmInfo, + vm::ptr strmParam, + vm::ptr cbCtrlStrmArg + ); -struct CellPngDecCbCtrlDisp +struct CellPngDecDispInfo { - be_t cbCtrlDispFunc_addr; - be_t cbCtrlDispArg; + be_t outputFrameWidthByte; + be_t outputFrameHeight; + be_t outputStartXByte; + be_t outputStartY; + be_t outputWidthByte; + be_t outputHeight; + be_t outputBitDepth; + be_t outputComponents; + be_t nextOutputStartY; + be_t scanPassCount; + vm::bptr outputImage; }; struct CellPngDecDispParam { - be_t nextOutputImage_addr; + vm::bptr nextOutputImage; +}; + +// Callback +typedef s32(*CellPngDecCbControlDisp)(vm::ptr dispInfo, vm::ptr dispParam, vm::ptr cbCtrlDispArg); + +// Structs +struct CellPngDecOpnParam +{ + be_t selectChunk; +}; + +struct CellPngDecCbCtrlStrm +{ + vm::bptr cbCtrlStrmFunc; + be_t> cbCtrlStrmArg; }; struct CellPngDecExtInfo @@ -144,9 +331,9 @@ struct CellPngDecExtInfo struct CellPngDecExtInParam { - be_t bufferMode; // CellPngDecBufferMode + be_t bufferMode; be_t outputCounts; - be_t spuMode; // CellPngDecSpuMode + be_t spuMode; }; struct CellPngDecExtOutParam @@ -155,25 +342,80 @@ struct CellPngDecExtOutParam be_t outputHeight; }; -struct CellPngDecOpnParam +struct CellPngDecCbCtrlDisp { - be_t selectChunk; + vm::bptr cbCtrlDispFunc; + be_t> cbCtrlDispArg; }; +// Functions +s32 cellPngDecExtOpen( + CellPngDecMainHandle mainHandle, + vm::ptr subHandle, + vm::ptr src, + vm::ptr openInfo, + vm::ptr cbCtrlStrm, + vm::ptr opnParam); -// Custom structs -struct CellPngDecSubHandle +s32 cellPngDecExtReadHeader( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr info, + vm::ptr extInfo); + +s32 cellPngDecExtSetParameter( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr inParam, + vm::ptr outParam, + vm::ptr extInParam, + vm::ptr extOutParam); + +s32 cellPngDecExtDecodeData( + CellPngDecMainHandle mainHandle, + CellPngDecSubHandle subHandle, + vm::ptr data, + vm::ptr dataCtrlParam, + vm::ptr dataOutInfo, + vm::ptr cbCtrlDisp, + vm::ptr dispParam); + +//// Custom structs +//struct CellPngDecSubHandle +//{ +// be_t fd; +// be_t fileSize; +// CellPngDecInfo info; +// CellPngDecOutParam outParam; +// CellPngDecSrc src; +//}; +// +//struct CellPngDecMainHandle +//{ +// be_t mainHandle; +// be_t threadInParam; +// be_t threadOutParam; +//}; + +struct PngDecoder { - be_t fd; - be_t fileSize; + vm::ptr malloc; + vm::ptr malloc_arg; + vm::ptr free; + vm::ptr free_arg; +}; + +struct PngStream +{ + CellPngDecMainHandle dec; + + // old data: + u32 fd; + u64 fileSize; CellPngDecInfo info; CellPngDecOutParam outParam; CellPngDecSrc src; -}; -struct CellPngDecMainHandle -{ - be_t mainHandle; - be_t threadInParam; - be_t threadOutParam; -}; + CellPngDecStrmInfo streamInfo; + CellPngDecStrmParam streamParam; +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 2a9835a27c..b01d5e6c68 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Emu/Memory/Memory.h" +#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "Emu/FS/vfsFile.h" @@ -299,12 +300,26 @@ s64 _sys_spu_printf_detach_thread(u32 arg) return GetCurrentPPUThread().FastCall(vm::read32(spu_printf_dtcb), vm::read32(spu_printf_dtcb + 4), arg); } +s32 _sys_snprintf(vm::ptr dst, u32 count, vm::ptr fmt, u32 a1, u32 a2) // va_args... +{ + sysPrxForUser->Todo("_sys_snprintf(dst_addr=0x%x, count=%d, fmt_addr=0x%x['%s'], ...)", dst.addr(), count, fmt.addr(), fmt.get_ptr()); + + if (std::string(fmt.get_ptr()) == "%s_%08x") + { + return snprintf(dst.get_ptr(), count, fmt.get_ptr(), vm::get_ptr(a1), a2); + } + + Emu.Pause(); + return 0; +} + s32 _sys_printf(vm::ptr fmt) { sysPrxForUser->Todo("_sys_printf(fmt_addr=0x%x, ...)", fmt.addr()); // probably, assertion failed sysPrxForUser->Warning("_sys_printf: \n%s", fmt.get_ptr()); + Emu.Pause(); return CELL_OK; } @@ -395,7 +410,6 @@ void sysPrxForUser_init() REG_FUNC(sysPrxForUser, _sys_strncat); REG_FUNC(sysPrxForUser, _sys_strcpy); REG_FUNC(sysPrxForUser, _sys_strncpy); - sysPrxForUser->AddFunc(0xe75c40f2, _unnamed_E75C40F2); // real name is unknown REG_FUNC(sysPrxForUser, _sys_spu_printf_initialize); REG_FUNC(sysPrxForUser, _sys_spu_printf_finalize); @@ -404,7 +418,10 @@ void sysPrxForUser_init() REG_FUNC(sysPrxForUser, _sys_spu_printf_attach_thread); REG_FUNC(sysPrxForUser, _sys_spu_printf_detach_thread); + REG_FUNC(sysPrxForUser, _sys_snprintf); + REG_FUNC(sysPrxForUser, _sys_printf); + sysPrxForUser->AddFunc(0xe75c40f2, _unnamed_E75C40F2); // real name is unknown } void sysPrxForUser_load() diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index 68039bf993..f01cc741d4 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -24,7 +24,7 @@ namespace detail template struct bind_arg { - static_assert(sizeof(T) <= 8, "Wrong argument type for ARG_GENERAL"); + static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_GENERAL"); static __forceinline T func(PPUThread& CPU) { @@ -35,7 +35,7 @@ namespace detail template struct bind_arg { - static_assert(sizeof(T) <= 8, "Wrong argument type for ARG_FLOAT"); + static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_FLOAT"); static __forceinline T func(PPUThread& CPU) { @@ -46,7 +46,7 @@ namespace detail template struct bind_arg { - static_assert(std::is_same::value, "Wrong argument type for ARG_VECTOR"); + static_assert(std::is_same::value, "Invalid function argument type for ARG_VECTOR"); static __forceinline T func(PPUThread& CPU) { @@ -57,11 +57,14 @@ namespace detail template struct bind_arg { - static_assert(sizeof(T) <= 8 && v_count <= 12, "Wrong argument type for ARG_STACK"); + static_assert(f_count <= 12, "TODO: Unsupported stack argument type (float)"); + static_assert(v_count <= 12, "TODO: Unsupported stack argument type (vector)"); + static_assert(sizeof(T) <= 8, "Invalid function argument type (ARG_STACK)"); static __forceinline T func(PPUThread& CPU) { - const u64 res = CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 12, 0)); + // TODO: check stack argument displacement + const u64 res = CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 12, 0) + std::max(v_count - 12, 0)); return (T&)res; } }; @@ -69,18 +72,19 @@ namespace detail template struct bind_result { - static_assert(!std::is_pointer::value, "Invalid function result type: pointer"); static_assert(sizeof(T) <= 8, "Invalid function result type"); + static_assert(!std::is_pointer::value, "Invalid function result type (pointer)"); + static_assert(!std::is_reference::value, "Invalid function result type (reference)"); - static __forceinline void func(PPUThread& CPU, T value) + static __forceinline void func(PPUThread& CPU, T result) { if (std::is_floating_point::value) { - CPU.FPR[1] = (double)value; + CPU.FPR[1] = (double)result; } else { - (T&)CPU.GPR[3] = value; + (T&)CPU.GPR[3] = result; } } }; @@ -88,9 +92,9 @@ namespace detail template<> struct bind_result { - static __forceinline void func(PPUThread& CPU, u128 value) + static __forceinline void func(PPUThread& CPU, u128 result) { - CPU.VPR[2] = value; + CPU.VPR[2] = result; } }; @@ -128,7 +132,8 @@ namespace detail template static __forceinline std::tuple iterate(PPUThread& CPU) { - static_assert(!std::is_pointer::value, "Invalid function argument type: pointer"); + static_assert(!std::is_pointer::value, "Invalid function argument type (pointer)"); + static_assert(!std::is_reference::value, "Invalid function argument type (reference)"); // TODO: check calculations const bool is_float = std::is_floating_point::value; const bool is_vector = std::is_same::value; diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index f2e3905be6..b8b7237a8a 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -377,6 +377,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index e0d50650bc..b129a2094e 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1210,5 +1210,8 @@ Header Files + + Emu\SysCalls\Modules + \ No newline at end of file