diff --git a/rpcs3/Emu/GS/GCM.h b/rpcs3/Emu/GS/GCM.h index 8d57541ff6..11871121cf 100644 --- a/rpcs3/Emu/GS/GCM.h +++ b/rpcs3/Emu/GS/GCM.h @@ -576,6 +576,8 @@ enum NV3089_IMAGE_IN_FORMAT = 0x0000C404, NV3089_IMAGE_IN_OFFSET = 0x0000C408, NV3089_IMAGE_IN = 0x0000C40C, + + GCM_SET_USER_COMMAND = 0x0000EB00, }; static const std::string GetMethodName(const u32 id) diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index d5f92c29b2..a7f2d30286 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -1815,6 +1815,14 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 } break; + case GCM_SET_USER_COMMAND: + { + const u32 cause = ARGS(0); + m_user_handler.Handle(cause); + m_user_handler.Branch(false); + } + break; + default: { std::string log = GetMethodName(cmd); @@ -1870,6 +1878,40 @@ void RSXThread::Task() OnInitThread(); + volatile bool is_vblank_stopped = false; + + thread vblank("VBlank thread", [&]() + { + const u64 start_time = get_system_time(); + + m_vblank_count = 0; + + while (!TestDestroy()) + { + if (Emu.IsStopped()) + { + LOG_WARNING(RSX, "VBlank thread aborted"); + return; + } + + if (get_system_time() - start_time > m_vblank_count * 1000000 / 60) + { + m_vblank_count++; + if (m_vblank_handler) + { + m_vblank_handler.Handle(1); + m_vblank_handler.Branch(false); + } + continue; + } + + Sleep(1); + } + + is_vblank_stopped = true; + }); + vblank.detach(); + while(!TestDestroy()) { if (Emu.IsStopped()) @@ -1961,6 +2003,11 @@ void RSXThread::Task() //memset(Memory.GetMemFromAddr(p.m_ioAddress + get), 0, (count + 1) * 4); } + while (!is_vblank_stopped) + { + Sleep(1); + } + LOG_NOTICE(RSX, "RSX thread ended"); OnExitThread(); diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index e1068c4c55..05ef3587b8 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -152,6 +152,9 @@ public: SSemaphore m_sem_flush; SSemaphore m_sem_flip; Callback m_flip_handler; + Callback m_user_handler; + u64 m_vblank_count; + Callback m_vblank_handler; public: // Dither diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 02af4d083c..7a1a42d02a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -51,6 +51,8 @@ enum CELL_GAME_GAMETYPE_DISC = 1, CELL_GAME_GAMETYPE_HDD = 2, + + CELL_GAME_GAMETYPE_GAMEDATA = 3, CELL_GAME_SIZEKB_NOTCALC = -1, @@ -117,6 +119,9 @@ struct CellGameContentSize be_t sysSizeKB; }; +std::string contentInfo = ""; +std::string usrdir = ""; + int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t size, mem_list_ptr_t dirName) { cellGame->Warning("cellGameBootCheck(type_addr=0x%x, attributes_addr=0x%x, size_addr=0x%x, dirName_addr=0x%x)", @@ -124,61 +129,197 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_tWarning("cellGameBootCheck returns CELL_GAME_ERROR_PARAM. As a result size->hddFreeSizeKB may be 0."); + cellGame->Error("cellGameBootCheck(): CELL_GAME_ERROR_PARAM"); return CELL_GAME_ERROR_PARAM; } - // TODO: Only works for HDD games - type = CELL_GAME_GAMETYPE_HDD; - attributes = 0; - size->hddFreeSizeKB = 40000000; //40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run. - size->sizeKB = CELL_GAME_SIZEKB_NOTCALC; - size->sysSizeKB = 0; + // TODO: Use the free space of the computer's HDD where RPCS3 is being run. + size->hddFreeSizeKB = 40000000; // 40 GB + + // TODO: Calculate data size for HG and DG games, if necessary. + size->sizeKB = CELL_GAME_SIZEKB_NOTCALC; + size->sysSizeKB = 0; - // TODO: Locate the PARAM.SFO. The following path may be wrong. vfsFile f("/app_home/PARAM.SFO"); + if (!f.IsOpened()) + { + cellGame->Error("cellGameBootCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot open PARAM.SFO)"); + return CELL_GAME_ERROR_ACCESS_ERROR; + } + PSFLoader psf(f); - if(!psf.Load(false)) + if (!psf.Load(false)) + { + cellGame->Error("cellGameBootCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)"); + return CELL_GAME_ERROR_ACCESS_ERROR; + } + + std::string category = psf.GetString("CATEGORY"); + if (category.substr(0, 2) == "DG") + { + type = CELL_GAME_GAMETYPE_DISC; + attributes = 0; // TODO + Memory.WriteString(dirName.GetAddr(), ""); // ??? + contentInfo = "/dev_bdvd/PS3_GAME"; + usrdir = "/dev_bdvd/PS3_GAME/USRDIR"; + } + else if (category.substr(0, 2) == "HG") + { + std::string titleId = psf.GetString("TITLE_ID"); + type = CELL_GAME_GAMETYPE_HDD; + attributes = 0; // TODO + Memory.WriteString(dirName.GetAddr(), titleId); + contentInfo = "/dev_hdd0/game/" + titleId; + usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR"; + } + else if (category.substr(0, 2) == "GD") + { + std::string titleId = psf.GetString("TITLE_ID"); + type = CELL_GAME_GAMETYPE_DISC; + attributes = CELL_GAME_ATTRIBUTE_PATCH; // TODO + Memory.WriteString(dirName.GetAddr(), titleId); // ??? + contentInfo = "/dev_bdvd/PS3_GAME"; + usrdir = "/dev_bdvd/PS3_GAME/USRDIR"; + } + else + { + cellGame->Error("cellGameBootCheck(): CELL_GAME_ERROR_FAILURE (unknown CATEGORY)"); return CELL_GAME_ERROR_FAILURE; + } + + return CELL_GAME_RET_OK; +} + +int cellGamePatchCheck(mem_ptr_t size, u32 reserved_addr) +{ + cellGame->Warning("cellGamePatchCheck(size_addr=0x%x, reserved_addr=0x%x)", size.GetAddr(), reserved_addr); + + if (!size.IsGood() || reserved_addr != 0) + { + cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_PARAM"); + return CELL_GAME_ERROR_PARAM; + } + + // TODO: Use the free space of the computer's HDD where RPCS3 is being run. + size->hddFreeSizeKB = 40000000; // 40 GB + + // TODO: Calculate data size for patch data, if necessary. + size->sizeKB = CELL_GAME_SIZEKB_NOTCALC; + size->sysSizeKB = 0; + + vfsFile f("/app_home/PARAM.SFO"); + if (!f.IsOpened()) + { + cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot open PARAM.SFO)"); + return CELL_GAME_ERROR_ACCESS_ERROR; + } + + PSFLoader psf(f); + if (!psf.Load(false)) + { + cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)"); + return CELL_GAME_ERROR_ACCESS_ERROR; + } + + std::string category = psf.GetString("CATEGORY"); + if (category.substr(0, 2) != "GD") + { + cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_NOTPATCH"); + return CELL_GAME_ERROR_NOTPATCH; + } + std::string titleId = psf.GetString("TITLE_ID"); - - Memory.WriteString(dirName.GetAddr(), titleId); - return CELL_OK; + contentInfo = "/dev_hdd0/game/" + titleId; + usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR"; + + return CELL_GAME_RET_OK; } -int cellGamePatchCheck() +int cellGameDataCheck(u32 type, const mem_list_ptr_t dirName, mem_ptr_t size) { - UNIMPLEMENTED_FUNC(cellGame); - return CELL_OK; + cellGame->Warning("cellGameDataCheck(type=0x%x, dirName_addr=0x%x, size_addr=0x%x)", type, dirName.GetAddr(), size.GetAddr()); + + if ((type - 1) >= 3 || !size.IsGood() || !dirName.IsGood()) + { + cellGame->Error("cellGameDataCheck(): CELL_GAME_ERROR_PARAM"); + return CELL_GAME_ERROR_PARAM; + } + + // TODO: Use the free space of the computer's HDD where RPCS3 is being run. + size->hddFreeSizeKB = 40000000; //40 GB + + // TODO: Calculate data size for game data, if necessary. + size->sizeKB = CELL_GAME_SIZEKB_NOTCALC; + size->sysSizeKB = 0; + + if (type == CELL_GAME_GAMETYPE_DISC) + { + // TODO: not sure what should be checked there + + if (!Emu.GetVFS().ExistsDir("/dev_bdvd/PS3_GAME")) + { + cellGame->Warning("cellGameDataCheck(): /dev_bdvd/PS3_GAME not found"); + return CELL_GAME_RET_NONE; + } + contentInfo = "/dev_bdvd/PS3_GAME"; + usrdir = "/dev_bdvd/PS3_GAME/USRDIR"; + } + else + { + std::string dir = "/dev_hdd0/game/" + std::string(dirName.GetString()); + + if (!Emu.GetVFS().ExistsDir(dir)) + { + cellGame->Warning("cellGameDataCheck(): '%s' directory not found", dir.c_str()); + return CELL_GAME_RET_NONE; + } + contentInfo = dir; + usrdir = dir + "/USRDIR"; + } + + return CELL_GAME_RET_OK; } -int cellGameDataCheck() -{ - UNIMPLEMENTED_FUNC(cellGame); - return CELL_OK; -} - -int cellGameContentPermit(mem_list_ptr_t contentInfoPath, mem_list_ptr_t usrdirPath) +int cellGameContentPermit(mem_list_ptr_t contentInfoPath, mem_list_ptr_t usrdirPath) { cellGame->Warning("cellGameContentPermit(contentInfoPath_addr=0x%x, usrdirPath_addr=0x%x)", contentInfoPath.GetAddr(), usrdirPath.GetAddr()); if (!contentInfoPath.IsGood() || !usrdirPath.IsGood()) + { + cellGame->Error("cellGameContentPermit(): CELL_GAME_ERROR_PARAM"); return CELL_GAME_ERROR_PARAM; - - // TODO: Locate the PARAM.SFO. The following path may be wrong. - vfsFile f("/app_home/PARAM.SFO"); - PSFLoader psf(f); - if(!psf.Load(false)) - return CELL_GAME_ERROR_FAILURE; - std::string titleId = psf.GetString("TITLE_ID"); + } - // TODO: Only works for HDD games - Memory.WriteString(contentInfoPath.GetAddr(), "/dev_hdd0/game/"+titleId); - Memory.WriteString(usrdirPath.GetAddr(), "/dev_hdd0/game/"+titleId+"/USRDIR"); + if (contentInfo == "" && usrdir == "") + { + cellGame->Error("cellGameContentPermit(): CELL_GAME_ERROR_FAILURE (calling order is invalid)"); + return CELL_GAME_ERROR_FAILURE; + } + + // TODO: make it better + Memory.WriteString(contentInfoPath.GetAddr(), contentInfo); + Memory.WriteString(usrdirPath.GetAddr(), usrdir); + + contentInfo = ""; + usrdir = ""; + + return CELL_GAME_RET_OK; +} + +int cellGameDataCheckCreate2(u32 version, u32 dirName_addr, u32 errDialog, u32 funcStat_addr, u32 container) +{ + cellGame->Error("cellGameDataCheckCreate2(version=0x%x, dirName_addr=0x%x, errDialog=0x%x, funcStat_addr=0x%x, container=%d)", + version, dirName_addr, errDialog, funcStat_addr, container); return CELL_OK; } +int cellGameDataCheckCreate(u32 version, u32 dirName_addr, u32 errDialog, u32 funcStat_addr, u32 container) +{ + // probably identical + return cellGameDataCheckCreate2(version, dirName_addr, errDialog, funcStat_addr, container); +} + int cellGameCreateGameData() { UNIMPLEMENTED_FUNC(cellGame); @@ -198,6 +339,7 @@ int cellGameGetParamInt(u32 id, mem32_t value) if(!value.IsGood()) return CELL_GAME_ERROR_PARAM; + // TODO: Access through cellGame***Check functions // TODO: Locate the PARAM.SFO. The following path may be wrong. vfsFile f("/app_home/PARAM.SFO"); PSFLoader psf(f); @@ -224,6 +366,7 @@ int cellGameGetParamString(u32 id, u32 buf_addr, u32 bufsize) if(!Memory.IsGoodAddr(buf_addr)) return CELL_GAME_ERROR_PARAM; + // TODO: Access through cellGame***Check functions // TODO: Locate the PARAM.SFO. The following path may be wrong. vfsFile f("/app_home/PARAM.SFO"); PSFLoader psf(f); @@ -342,6 +485,9 @@ void cellGame_init() cellGame->AddFunc(0x42a2e133, cellGameCreateGameData); cellGame->AddFunc(0xb367c6e3, cellGameDeleteGameData); + cellGame->AddFunc(0xe7951dee, cellGameDataCheckCreate); + cellGame->AddFunc(0xc9645c41, cellGameDataCheckCreate2); + cellGame->AddFunc(0xb7a45caf, cellGameGetParamInt); //cellGame->AddFunc(, cellGameSetParamInt); cellGame->AddFunc(0x3a5d726a, cellGameGetParamString); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 2133bac53f..6d22b47da8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -421,18 +421,16 @@ int cellGcmSetFlip(mem_ptr_t ctxt, u32 id) return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; } -int cellGcmSetFlipHandler(u32 handler_addr) +void cellGcmSetFlipHandler(u32 handler_addr) { cellGcmSys->Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler_addr); if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr)) { - cellGcmSys->Error("cellGcmSetFlipHandler : CELL_EFAULT"); - return CELL_EFAULT; + cellGcmSys->Error("cellGcmSetFlipHandler(handler_addr=%d): invalid address", handler_addr); } Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr); - return CELL_OK; } int cellGcmSetFlipMode(u32 mode) @@ -567,16 +565,28 @@ int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u return CELL_OK; } -u32 cellGcmSetUserHandler(u32 handler) +void cellGcmSetUserHandler(u32 handler_addr) { - cellGcmSys->Warning("cellGcmSetUserHandler(handler=0x%x)", handler); - return handler; + cellGcmSys->Warning("cellGcmSetUserHandler(handler_addr=0x%x)", handler_addr); + + if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr)) + { + cellGcmSys->Error("cellGcmSetUserHandler(handler_addr=%d): invalid address", handler_addr); + } + + Emu.GetGSManager().GetRender().m_user_handler.SetAddr(handler_addr); } -int cellGcmSetVBlankHandler() +void cellGcmSetVBlankHandler(u32 handler_addr) { - UNIMPLEMENTED_FUNC(cellGcmSys); - return CELL_OK; + cellGcmSys->Warning("cellGcmSetVBlankHandler(handler_addr=0x%x)", handler_addr); + + if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr)) + { + cellGcmSys->Error("cellGcmSetVBlankHandler(handler_addr=%d): invalid address", handler_addr); + } + + Emu.GetGSManager().GetRender().m_vblank_handler.SetAddr(handler_addr); } int cellGcmSetWaitFlip(mem_ptr_t ctxt) @@ -699,7 +709,7 @@ int cellGcmGetDisplayBufferByFlipIndex() return CELL_OK; } -int cellGcmgetLastFlipTime() +int cellGcmGetLastFlipTime() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; @@ -711,10 +721,11 @@ int cellGcmGetLastSecondVTime() return CELL_OK; } -int cellGcmGetVBlankCount() +u64 cellGcmGetVBlankCount() { - UNIMPLEMENTED_FUNC(cellGcmSys); - return CELL_OK; + cellGcmSys->Log("cellGcmGetVBlankCount()"); + + return Emu.GetGSManager().GetRender().m_vblank_count; } int cellGcmInitSystemMode() @@ -1156,7 +1167,7 @@ void cellGcmSys_init() cellGcmSys->AddFunc(0xe315a0b2, cellGcmGetConfiguration); cellGcmSys->AddFunc(0x371674cf, cellGcmGetDisplayBufferByFlipIndex); cellGcmSys->AddFunc(0x72a577ce, cellGcmGetFlipStatus); - cellGcmSys->AddFunc(0x63387071, cellGcmgetLastFlipTime); + cellGcmSys->AddFunc(0x63387071, cellGcmGetLastFlipTime); cellGcmSys->AddFunc(0x23ae55a3, cellGcmGetLastSecondVTime); cellGcmSys->AddFunc(0x055bd74d, cellGcmGetTiledPitchSize); cellGcmSys->AddFunc(0x723bbc7e, cellGcmGetVBlankCount); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 4ffcc7d04f..ebdce664a4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -93,6 +93,16 @@ int cellPngDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t s return CELL_OK; } +int cellPngDecExtOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t src, u32 openInfo, mem_ptr_t cbCtrlStrm, mem_ptr_t opnParam) +{ + 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.GetAddr(), src.GetAddr(), openInfo, cbCtrlStrm.GetAddr(), opnParam.GetAddr()); + + cellPngDec->Warning("*** cbCtrlStrm->cbCtrlStrmFunc_addr=0x%x", (u32)cbCtrlStrm->cbCtrlStrmFunc_addr); + + return cellPngDecOpen(mainHandle, subHandle, src, openInfo); +} + int cellPngDecClose(u32 mainHandle, u32 subHandle) { cellPngDec->Warning("cellPngDecClose(mainHandle=0x%x,subHandle=0x%x)", mainHandle, subHandle); @@ -112,7 +122,7 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_tWarning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr()); + cellPngDec->Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle, subHandle, info.GetAddr()); CellPngDecSubHandle* subHandle_data; if(!cellPngDec->CheckId(subHandle, subHandle_data)) return CELL_PNGDEC_ERROR_FATAL; @@ -167,6 +177,14 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t info, mem_ptr_t extInfo) +{ + cellPngDec->Warning("cellPngDecExtReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x, extInfo_addr=0x%x)", + mainHandle, subHandle, info.GetAddr(), extInfo.GetAddr()); + + return cellPngDecReadHeader(mainHandle, subHandle, info); +} + int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_ptr_t dataCtrlParam, mem_ptr_t dataOutInfo) { if (!data.IsGood() || !dataCtrlParam.IsGood() || !dataOutInfo.IsGood()) @@ -292,6 +310,17 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m return CELL_OK; } +int cellPngDecExtDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_ptr_t dataCtrlParam, + mem_ptr_t dataOutInfo, mem_ptr_t cbCtrlDisp, mem_ptr_t dispParam) +{ + cellPngDec->Warning("cellPngDecExtDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x, cbCtrlDisp_addr=0x%x, dispParam=0x%x", + mainHandle, subHandle, data.GetAddr(), dataCtrlParam.GetAddr(), dataOutInfo.GetAddr(), cbCtrlDisp.GetAddr(), dispParam.GetAddr()); + + cellPngDec->Warning("*** cbCtrlDisp->cbCtrlDispFunc_addr=0x%x", (u32)scbCtrlDisp->cbCtrlDispFunc_addr); + + return cellPngDecDecodeData(mainHandle, subHandle, data, dataCtrlParam, dataOutInfo); +} + int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t inParam, mem_ptr_t outParam) { if (!inParam.IsGood() || !outParam.IsGood()) @@ -333,6 +362,15 @@ int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t inParam, mem_ptr_t outParam, + mem_ptr_t extInParam, mem_ptr_t extOutParam) +{ + cellPngDec->Warning("cellPngDecExtSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x, extInParam=0x%x, extOutParam=0x%x", + mainHandle, subHandle, inParam.GetAddr(), outParam.GetAddr(), extInParam.GetAddr(), extOutParam.GetAddr()); + + return cellPngDecSetParameter(mainHandle, subHandle, inParam, outParam); +} + void cellPngDec_init() { cellPngDec->AddFunc(0x157d30c5, cellPngDecCreate); @@ -343,11 +381,12 @@ void cellPngDec_init() cellPngDec->AddFunc(0x2310f155, cellPngDecDecodeData); cellPngDec->AddFunc(0xe97c9bd4, cellPngDecSetParameter); - /*cellPngDec->AddFunc(0x48436b2d, cellPngDecExtCreate); cellPngDec->AddFunc(0x0c515302, cellPngDecExtOpen); cellPngDec->AddFunc(0x8b33f863, cellPngDecExtReadHeader); cellPngDec->AddFunc(0x726fc1d0, cellPngDecExtDecodeData); cellPngDec->AddFunc(0x9e9d7d42, cellPngDecExtSetParameter); + + /*cellPngDec->AddFunc(0x48436b2d, cellPngDecExtCreate); cellPngDec->AddFunc(0x7585a275, cellPngDecGetbKGD); cellPngDec->AddFunc(0x7a062d26, cellPngDecGetcHRM); cellPngDec->AddFunc(0xb153629c, cellPngDecGetgAMA); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h index 9d48c68b01..9db3ac8bcb 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h @@ -124,3 +124,43 @@ struct CellPngDecMainHandle be_t threadInParam; be_t threadOutParam; }; + +struct CellPngDecCbCtrlStrm +{ + be_t cbCtrlStrmFunc_addr; + be_t cbCtrlStrmArg; +}; + +struct CellPngDecCbCtrlDisp +{ + be_t cbCtrlDispFunc_addr; + be_t cbCtrlDispArg; +}; + +struct CellPngDecDispParam +{ + be_t nextOutputImage_addr; +}; + +struct CellPngDecExtInfo +{ + be_t reserved; +}; + +struct CellPngDecExtInParam +{ + be_t bufferMode; // CellPngDecBufferMode + be_t outputCounts; + be_t spuMode; // CellPngDecSpuMode +}; + +struct CellPngDecExtOutParam +{ + be_t outputWidthByte; + be_t outputHeight; +}; + +struct CellPngDecOpnParam +{ + be_t selectChunk; +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index ea9047f1b3..05381883e0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -80,7 +80,7 @@ CCellRescInternal* s_rescInternalInstance = nullptr; // Extern Functions extern int cellGcmSetFlipMode(u32 mode); -extern int cellGcmSetFlipHandler(u32 handler_addr); +extern void cellGcmSetFlipHandler(u32 handler_addr); extern int32_t cellGcmAddressToOffset(u64 address, mem32_t offset); extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height); extern int cellGcmSetPrepareFlip(mem_ptr_t ctx, u32 id); @@ -857,19 +857,16 @@ int cellRescSetBufferAddress(mem32_t colorBuffers, mem32_t vertexArray, mem32_t return CELL_OK; } -int cellRescSetFlipHandler(u32 handler_addr) +void cellRescSetFlipHandler(u32 handler_addr) { cellResc->Warning("cellRescSetFlipHandler(handler_addr=0x%x)", handler_addr); if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr)) { - cellResc->Error("cellRescSetFlipHandler : CELL_EFAULT"); - return CELL_EFAULT; + cellResc->Error("cellRescSetFlipHandler(handler_addr=%d): invalid address", handler_addr); } Emu.GetGSManager().GetRender().m_flip_handler.SetAddr(handler_addr); - - return CELL_OK; } void cellRescResetFlipStatus() @@ -904,10 +901,16 @@ int cellRescSetRegisterCount() return CELL_OK; } -int cellRescSetVBlankHandler() +void cellRescSetVBlankHandler(u32 handler_addr) { - UNIMPLEMENTED_FUNC(cellResc); - return CELL_OK; + cellResc->Warning("cellRescSetVBlankHandler(handler_addr=0x%x)", handler_addr); + + if (handler_addr != 0 && !Memory.IsGoodAddr(handler_addr)) + { + cellResc->Error("cellRescSetVBlankHandler(handler_addr=%d): invalid address", handler_addr); + } + + Emu.GetGSManager().GetRender().m_vblank_handler.SetAddr(handler_addr); } int cellRescCreateInterlaceTable() diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 250e919a76..1cc47aeb07 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -382,6 +382,9 @@ int cellSysutilUnregisterCallback(int slot) int cellMsgDialogOpen2(u32 type, char* msgString, mem_func_ptr_t callback, mem_ptr_t userData, u32 extParam) { + cellSysutil->Warning("cellMsgDialogOpen2(type=0x%x, msgString_addr=0x%x, callback_addr=0x%x, userData=0x%x, extParam=0x%x)", + type, (u32)msgString, callback.GetAddr(), userData.GetAddr(), extParam); + long style = 0; if(type & CELL_MSGDIALOG_DIALOG_TYPE_NORMAL) diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 1d35191bd7..63de40521f 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -114,16 +114,16 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) { const std::string& path = Memory.ReadString(path_addr); - sys_fs->Warning("cellFsSdataOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx)", + sys_fs->Warning("cellFsSdataOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx) -> cellFsOpen()", path.c_str(), flags, fd.GetAddr(), arg.GetAddr(), size); - if (!fd.IsGood() || (!arg.IsGood() && size)) + /*if (!fd.IsGood() || (!arg.IsGood() && size)) return CELL_EFAULT; if (flags != CELL_O_RDONLY) return CELL_EINVAL; - std::string suffix = path.substr(path.length() - 5, 4); + std::string suffix = path.substr(path.length() - 5, 5); if (suffix != ".sdat" && suffix != ".SDAT") return CELL_ENOTSDATA; @@ -135,7 +135,9 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) fd = sys_fs->GetNewId(Emu.GetVFS().OpenFile(unpacked_path, vfsRead), flags); - return CELL_OK; + return CELL_OK;*/ + + return cellFsOpen(path_addr, flags, fd, arg, size); } std::atomic g_FsAioReadID( 0 ); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 6c3d3667f1..857b172e86 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -11,6 +11,7 @@ #include "Emu/Cell/SPUThread.h" #include "Emu/Cell/PPUInstrTable.h" #include "Emu/FS/vfsFile.h" +#include "Emu/FS/vfsDeviceLocalFile.h" #include "Emu/CPU/CPUThreadManager.h" //gui dependency @@ -163,6 +164,18 @@ void Emulator::Load() { LOG_NOTICE(LOADER, "%s -> %s", m_vfs.m_devices[i]->GetPs3Path().c_str(), m_vfs.m_devices[i]->GetLocalPath().c_str()); } + // bdvd inserting imitation + vfsFile f1("/app_home/dev_bdvd.path"); + if (f1.IsOpened()) + { + std::string bdvd; + bdvd.resize(f1.GetSize()); + f1.Read(&bdvd[0], bdvd.size()); + + // load desired /dev_bdvd/ real directory and remount + Emu.GetVFS().Mount("/dev_bdvd/", bdvd, new vfsDeviceLocalFile()); + LOG_NOTICE(LOADER, "/dev_bdvd/ remounted into %s", bdvd.c_str()); + } LOG_NOTICE(LOADER, " ");//used to be skip_line if(m_elf_path.empty())