From 458322e548c09926b5ad5a8a3f1d3533df75be56 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 26 Jun 2014 18:17:07 +0400 Subject: [PATCH 01/13] SC_Event_flag: test passed --- rpcs3/Emu/SysCalls/lv2/SC_Event_flag.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Event_flag.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Event_flag.cpp index 02d551dbab..83d1fdbec7 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Event_flag.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Event_flag.cpp @@ -142,8 +142,6 @@ int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64 { SMutexLocker lock(ef->m_mutex); - ef->signal.unlock(tid); - u64 flags = ef->flags; for (u32 i = 0; i < ef->waiters.size(); i++) @@ -161,6 +159,17 @@ int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64 ef->flags = 0; } + if (u32 target = ef->check()) + { + // if signal, leave both mutexes locked... + ef->signal.unlock(tid, target); + ef->m_mutex.unlock(tid, target); + } + else + { + ef->signal.unlock(tid); + } + if (result.IsGood()) { result = flags; @@ -175,6 +184,7 @@ int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, mem64_t result, u64 } } + ef->signal.unlock(tid); return CELL_ECANCELED; } From 5ef3b80596a2bbf225f30b300998cc4c2cb39a0e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 27 Jun 2014 15:11:56 +0400 Subject: [PATCH 02/13] cellSysutilBgmPlayback fix --- rpcs3/Emu/Audio/sysutil_audio.h | 35 ++++++++++----- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 51 ++++++++++++---------- 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/rpcs3/Emu/Audio/sysutil_audio.h b/rpcs3/Emu/Audio/sysutil_audio.h index 94ea6dafd0..2fd567461f 100644 --- a/rpcs3/Emu/Audio/sysutil_audio.h +++ b/rpcs3/Emu/Audio/sysutil_audio.h @@ -257,23 +257,38 @@ struct CellAudioInDeviceConfiguration u8 reserved[31]; }; -enum CellBgmPlaybackStatusState +enum CellSysutilBgmPlaybackStatusState { - CELL_BGMPLAYBACK_STATUS_PLAY = 0, - CELL_BGMPLAYBACK_STATUS_STOP = 1 + CELL_SYSUTIL_BGMPLAYBACK_STATUS_PLAY = 0, + CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP = 1 }; -enum CellBgmPlaybackStatusEnabled +enum CellSysutilBgmPlaybackStatusEnabled { - CELL_BGMPLAYBACK_STATUS_ENABLE = 0, - CELL_BGMPLAYBACK_STATUS_DISABLE = 1 + CELL_SYSUTIL_BGMPLAYBACK_STATUS_ENABLE = 0, + CELL_SYSUTIL_BGMPLAYBACK_STATUS_DISABLE = 1 }; -struct CellBgmPlaybackStatus +struct CellSysutilBgmPlaybackStatus { - u8 playbackState; - u8 enabled; + u8 playerState; + u8 enableState; char contentId[16]; - u8 fadeRatio; + u8 currentFadeRatio; char reserved[13]; }; + +struct CellSysutilBgmPlaybackStatus2 +{ + u8 playerState; + char reserved[7]; +}; + +struct CellSysutilBgmPlaybackExtraParam +{ + be_t systemBgmFadeInTime; + be_t systemBgmFadeOutTime; + be_t gameBgmFadeInTime; + be_t gameBgmFadeOutTime; + char reserved[8]; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 317a927b23..f7e8781448 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -919,22 +919,24 @@ int cellHddGameCheck(u32 version, u32 dirName_addr, u32 errDialog, mem_func_ptr_ return CELL_OK; } -bool bgm_playback_enabled = false; +bool bgm_playback_enabled = true; int cellSysutilEnableBgmPlayback() { cellSysutil->Warning("cellSysutilEnableBgmPlayback()"); + // TODO bgm_playback_enabled = true; return CELL_OK; } -int cellSysutilEnableBgmPlaybackEx() +int cellSysutilEnableBgmPlaybackEx(mem_ptr_t param) { - cellSysutil->Warning("cellSysutilEnableBgmPlaybackEx()"); + cellSysutil->Warning("cellSysutilEnableBgmPlaybackEx(param_addr=0x%x)", param.GetAddr()); - bgm_playback_enabled = true; + // TODO + bgm_playback_enabled = true; return CELL_OK; } @@ -943,42 +945,43 @@ int cellSysutilDisableBgmPlayback() { cellSysutil->Warning("cellSysutilDisableBgmPlayback()"); + // TODO bgm_playback_enabled = false; return CELL_OK; } -int cellSysutilDisableBgmPlaybackEx() +int cellSysutilDisableBgmPlaybackEx(mem_ptr_t param) { - cellSysutil->Warning("cellSysutilDisableBgmPlaybackEx()"); - - bgm_playback_enabled = false; - - return CELL_OK; -} - -int cellSysutilGetBgmPlaybackStatus(mem_ptr_t status) -{ - cellSysutil->Warning("cellSysutilGetBgmPlaybackStatus(status=0x%x)", status.GetAddr()); + cellSysutil->Warning("cellSysutilDisableBgmPlaybackEx(param_addr=0x%x)", param.GetAddr()); // TODO - status->playbackState = CELL_BGMPLAYBACK_STATUS_STOP; - status->enabled = bgm_playback_enabled ? CELL_BGMPLAYBACK_STATUS_ENABLE : CELL_BGMPLAYBACK_STATUS_DISABLE; - status->fadeRatio = 0; // volume ratio + bgm_playback_enabled = false; + + return CELL_OK; +} + +int cellSysutilGetBgmPlaybackStatus(mem_ptr_t status) +{ + cellSysutil->Log("cellSysutilGetBgmPlaybackStatus(status_addr=0x%x)", status.GetAddr()); + + // TODO + status->playerState = CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP; + status->enableState = bgm_playback_enabled ? CELL_SYSUTIL_BGMPLAYBACK_STATUS_ENABLE : CELL_SYSUTIL_BGMPLAYBACK_STATUS_DISABLE; + status->currentFadeRatio = 0; // current volume ratio (0%) memset(status->contentId, 0, sizeof(status->contentId)); + memset(status->reserved, 0, sizeof(status->reserved)); return CELL_OK; } -int cellSysutilGetBgmPlaybackStatus2(mem_ptr_t status2) +int cellSysutilGetBgmPlaybackStatus2(mem_ptr_t status2) { - cellSysutil->Warning("cellSysutilGetBgmPlaybackStatus2(status=0x%x)", status2.GetAddr()); + cellSysutil->Log("cellSysutilGetBgmPlaybackStatus2(status2_addr=0x%x)", status2.GetAddr()); // TODO - status2->playbackState = CELL_BGMPLAYBACK_STATUS_STOP; - status2->enabled = bgm_playback_enabled ? CELL_BGMPLAYBACK_STATUS_ENABLE : CELL_BGMPLAYBACK_STATUS_DISABLE; - status2->fadeRatio = 0; // volume ratio - memset(status2->contentId, 0, sizeof(status2->contentId)); + status2->playerState = CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP; + memset(status2->reserved, 0, sizeof(status2->reserved)); return CELL_OK; } From b11e08658919b55a403e2f155ed1672cf20c2abb Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 28 Jun 2014 05:19:44 +0400 Subject: [PATCH 03/13] Small changes --- rpcs3/Emu/GS/GCM.h | 2 + rpcs3/Emu/GS/RSXThread.cpp | 47 +++++ rpcs3/Emu/GS/RSXThread.h | 3 + rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 210 +++++++++++++++++---- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 41 ++-- rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 43 ++++- rpcs3/Emu/SysCalls/Modules/cellPngDec.h | 40 ++++ rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 21 ++- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 3 + rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 10 +- rpcs3/Emu/System.cpp | 13 ++ 11 files changed, 371 insertions(+), 62 deletions(-) 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()) From 8987350b5b4f96b12856fe53f26f59bd5cf0cc1c Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 29 Jun 2014 07:21:57 +0400 Subject: [PATCH 04/13] Small changes 2 --- Utilities/SQueue.h | 47 ++++++++++++----------- rpcs3/Emu/GS/GL/GLGSRender.cpp | 10 +++-- rpcs3/Emu/GS/RSXThread.cpp | 2 + rpcs3/Emu/SysCalls/Modules/cellAdec.cpp | 27 ++++++++----- rpcs3/Emu/SysCalls/Modules/cellAdec.h | 2 + rpcs3/Emu/SysCalls/Modules/cellDmux.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 19 +++++++-- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 7 ++-- rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 13 +++++-- rpcs3/Emu/SysCalls/Modules/cellPngDec.h | 13 ++++++- rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 7 ++-- rpcs3/Emu/SysCalls/Modules/cellVdec.cpp | 32 ++++++++------- rpcs3/Emu/SysCalls/Modules/cellVdec.h | 2 + 13 files changed, 118 insertions(+), 65 deletions(-) diff --git a/Utilities/SQueue.h b/Utilities/SQueue.h index 4e3b317a9d..52b68979f0 100644 --- a/Utilities/SQueue.h +++ b/Utilities/SQueue.h @@ -4,8 +4,6 @@ template class SQueue { std::mutex m_mutex; - NamedThreadBase* push_waiter; - NamedThreadBase* pop_waiter; u32 m_pos; u32 m_count; T m_data[SQSize]; @@ -14,8 +12,6 @@ public: SQueue() : m_pos(0) , m_count(0) - , push_waiter(nullptr) - , pop_waiter(nullptr) { } @@ -26,9 +22,6 @@ public: bool Push(const T& data) { - NamedThreadBase* t = GetCurrentNamedThread(); - push_waiter = t; - while (true) { if (m_count >= SQSize) @@ -46,11 +39,9 @@ public: std::lock_guard lock(m_mutex); if (m_count >= SQSize) continue; - if (pop_waiter && !m_count) pop_waiter->Notify(); m_data[(m_pos + m_count++) % SQSize] = data; - push_waiter = nullptr; return true; } } @@ -58,9 +49,6 @@ public: bool Pop(T& data) { - NamedThreadBase* t = GetCurrentNamedThread(); - pop_waiter = t; - while (true) { if (!m_count) @@ -78,43 +66,44 @@ public: std::lock_guard lock(m_mutex); if (!m_count) continue; - if (push_waiter && m_count >= SQSize) push_waiter->Notify(); data = m_data[m_pos]; m_pos = (m_pos + 1) % SQSize; m_count--; - pop_waiter = nullptr; return true; } } } - volatile u32 GetCount() // may be thread unsafe + u32 GetCount() + { + std::lock_guard lock(m_mutex); + return m_count; + } + + u32 GetCountUnsafe() { return m_count; } - volatile bool IsEmpty() // may be thread unsafe + bool IsEmpty() { + std::lock_guard lock(m_mutex); return !m_count; } void Clear() { std::lock_guard lock(m_mutex); - if (push_waiter && m_count >= SQSize) push_waiter->Notify(); m_count = 0; } T& Peek(u32 pos = 0) { - NamedThreadBase* t = GetCurrentNamedThread(); - pop_waiter = t; - while (true) { - if (!m_count) + if (m_count <= pos) { if (Emu.IsStopped()) { @@ -127,13 +116,25 @@ public: { std::lock_guard lock(m_mutex); - if (m_count) + if (m_count > pos) { - pop_waiter = nullptr; break; } } } return m_data[(m_pos + pos) % SQSize]; } + + T& PeekIfExist(T& def, u32 pos = 0) + { + std::lock_guard lock(m_mutex); + if (m_count <= pos) + { + return def; + } + else + { + return m_data[(m_pos + pos) % SQSize]; + } + } }; diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 9309eae93c..c7f6f80404 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -355,8 +355,9 @@ bool GLGSRender::LoadProgram() if(m_fp_buf_num == -1) { LOG_WARNING(RSX, "FP not found in buffer!"); - m_shader_prog.DecompileAsync(*m_cur_shader_prog); - m_shader_prog.Wait(); + //m_shader_prog.DecompileAsync(*m_cur_shader_prog); + //m_shader_prog.Wait(); + m_shader_prog.Decompile(*m_cur_shader_prog); m_shader_prog.Compile(); checkForGlError("m_shader_prog.Compile"); @@ -367,8 +368,9 @@ bool GLGSRender::LoadProgram() if(m_vp_buf_num == -1) { LOG_WARNING(RSX, "VP not found in buffer!"); - m_vertex_prog.DecompileAsync(*m_cur_vertex_prog); - m_vertex_prog.Wait(); + //m_vertex_prog.DecompileAsync(*m_cur_vertex_prog); + //m_vertex_prog.Wait(); + m_vertex_prog.Decompile(*m_cur_vertex_prog); m_vertex_prog.Compile(); checkForGlError("m_vertex_prog.Compile"); diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index a7f2d30286..614bdafe85 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -197,6 +197,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 //if(cmd == 0xfeadffff) { Flip(); + m_last_flip_time = get_system_time(); m_gcm_current_buffer = ARGS(0); m_read_buffer = true; @@ -1878,6 +1879,7 @@ void RSXThread::Task() OnInitThread(); + m_last_flip_time = get_system_time(); volatile bool is_vblank_stopped = false; thread vblank("VBlank thread", [&]() diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index aa72d95f64..fec90b45d1 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -32,7 +32,7 @@ int adecRawRead(void* opaque, u8* buf, int buf_size) next: if (adec.reader.size < (u32)buf_size /*&& !adec.just_started*/) { - while (adec.job.IsEmpty()) + while (!adec.job.GetCountUnsafe()) { if (Emu.IsStopped()) { @@ -45,6 +45,7 @@ next: switch (adec.job.Peek().type) { case adecEndSeq: + case adecClose: { buf_size = adec.reader.size; } @@ -209,7 +210,7 @@ u32 adecOpen(AudioDecoder* data) break; } - if (adec.job.IsEmpty() && adec.is_running) + if (!adec.job.GetCountUnsafe() && adec.is_running) { Sleep(1); continue; @@ -255,10 +256,8 @@ u32 adecOpen(AudioDecoder* data) cb.Branch(true); // ???*/ adec.adecCb->ExecAsCallback(adec.cbFunc, true, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); - avcodec_close(adec.ctx); - avformat_close_input(&adec.fmt); - adec.is_running = false; + adec.just_finished = true; } break; @@ -312,7 +311,14 @@ u32 adecOpen(AudioDecoder* data) dump.Close(); }*/ - if (adec.just_started) // deferred initialization + if (adec.just_started && adec.just_finished) + { + avcodec_flush_buffers(adec.ctx); + adec.reader.init = true; + adec.just_finished = false; + adec.just_started = false; + } + else if (adec.just_started) // deferred initialization { err = avformat_open_input(&adec.fmt, NULL, av_find_input_format("oma"), NULL); if (err) @@ -353,7 +359,7 @@ u32 adecOpen(AudioDecoder* data) av_dict_set(&opts, "refcounted_frames", "1", 0); { std::lock_guard lock(g_mutex_avcodec_open2); - // not multithread-safe + // not multithread-safe (???) err = avcodec_open2(adec.ctx, codec, &opts); } if (err) @@ -605,7 +611,7 @@ int cellAdecClose(u32 handle) adec->job.Push(AdecTask(adecClose)); - while (!adec->is_finished || !adec->frames.IsEmpty()) + while (!adec->is_finished) { if (Emu.IsStopped()) { @@ -789,13 +795,14 @@ int cellAdecGetPcmItem(u32 handle, mem32_t pcmItem_ptr) return CELL_ADEC_ERROR_FATAL; } - AdecFrame& af = adec->frames.Peek(); - if (adec->frames.IsEmpty()) { + Sleep(1); // hack return CELL_ADEC_ERROR_EMPTY; } + AdecFrame& af = adec->frames.Peek(); + AVFrame* frame = af.data; mem_ptr_t pcm(adec->memAddr + adec->memBias); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.h b/rpcs3/Emu/SysCalls/Modules/cellAdec.h index 88a6e6bf47..65ce820f13 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.h @@ -1076,6 +1076,7 @@ public: volatile bool is_running; volatile bool is_finished; bool just_started; + bool just_finished; AVCodecContext* ctx; AVFormatContext* fmt; @@ -1127,6 +1128,7 @@ public: , is_running(false) , is_finished(false) , just_started(false) + , just_finished(false) , ctx(nullptr) , fmt(nullptr) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index ee799261b7..377ebf22dc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -71,7 +71,7 @@ u32 dmuxOpen(Demuxer* data) break; } - if (dmux.job.IsEmpty() && dmux.is_running) + if (!dmux.job.GetCountUnsafe() && dmux.is_running) { // default task (demuxing) (if there is no other work) be_t code; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 7a1a42d02a..9a7471f63d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -119,6 +119,15 @@ struct CellGameContentSize be_t sysSizeKB; }; +struct CellGameSetInitParams +{ + char title[CELL_GAME_SYSP_TITLE_SIZE]; + char titleId[CELL_GAME_SYSP_TITLEID_SIZE]; + char reserved0[2]; + char version[CELL_GAME_SYSP_VERSION_SIZE]; + char reserved1[66]; +}; + std::string contentInfo = ""; std::string usrdir = ""; @@ -293,7 +302,7 @@ int cellGameContentPermit(mem_list_ptr_t contentInfoPath, mem_list_ptr_t if (contentInfo == "" && usrdir == "") { - cellGame->Error("cellGameContentPermit(): CELL_GAME_ERROR_FAILURE (calling order is invalid)"); + cellGame->Warning("cellGameContentPermit(): CELL_GAME_ERROR_FAILURE (no permission given)"); return CELL_GAME_ERROR_FAILURE; } @@ -320,9 +329,13 @@ int cellGameDataCheckCreate(u32 version, u32 dirName_addr, u32 errDialog, u32 fu return cellGameDataCheckCreate2(version, dirName_addr, errDialog, funcStat_addr, container); } -int cellGameCreateGameData() +int cellGameCreateGameData(mem_ptr_t init, mem_list_ptr_t tmp_contentInfoPath, mem_list_ptr_t tmp_usrdirPath) { - UNIMPLEMENTED_FUNC(cellGame); + cellGame->Error("cellGameCreateGameData(init_addr=0x%x, tmp_contentInfoPath_addr=0x%x, tmp_usrdirPath_addr=0x%x)", + init.GetAddr(), tmp_contentInfoPath.GetAddr(), tmp_usrdirPath.GetAddr()); + + // TODO: create temporary game directory, set initial PARAM.SFO parameters + // cellGameContentPermit should then move files in non-temporary location and return their non-temporary displacement return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 6d22b47da8..f91232d0c4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -709,10 +709,11 @@ int cellGcmGetDisplayBufferByFlipIndex() return CELL_OK; } -int cellGcmGetLastFlipTime() +u64 cellGcmGetLastFlipTime() { - UNIMPLEMENTED_FUNC(cellGcmSys); - return CELL_OK; + cellGcmSys->Log("cellGcmGetLastFlipTime()"); + + return Emu.GetGSManager().GetRender().m_last_flip_time; } int cellGcmGetLastSecondVTime() diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index ebdce664a4..5f61fb8aa1 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -98,9 +98,16 @@ int cellPngDecExtOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_tWarning("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); + cellPngDec->Warning("*** cbCtrlStrm->cbCtrlStrmFunc_addr=0x%x", cbCtrlStrm->cbCtrlStrmFunc.GetAddr()); - return cellPngDecOpen(mainHandle, subHandle, src, openInfo); + MemoryAllocator streamInfo; + MemoryAllocator streamParam; + + int res = cellPngDecOpen(mainHandle, subHandle, src, openInfo); + + if (!res) cbCtrlStrm->cbCtrlStrmFunc(streamInfo.GetAddr(), streamParam.GetAddr(), cbCtrlStrm->cbCtrlStrmArg); + + return res; } int cellPngDecClose(u32 mainHandle, u32 subHandle) @@ -316,7 +323,7 @@ int cellPngDecExtDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, cons 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); + if (cbCtrlDisp.GetAddr()) cellPngDec->Warning("*** cbCtrlDisp->cbCtrlDispFunc_addr=0x%x", (u32)cbCtrlDisp->cbCtrlDispFunc_addr); return cellPngDecDecodeData(mainHandle, subHandle, data, dataCtrlParam, dataOutInfo); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h index 9db3ac8bcb..b93f82ba8e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h @@ -125,9 +125,20 @@ struct CellPngDecMainHandle be_t threadOutParam; }; +struct CellPngDecStrmInfo +{ + be_t decodedStrmSize; +}; + +struct CellPngDecStrmParam +{ + be_t strmPtr; + be_t strmSize; +}; + struct CellPngDecCbCtrlStrm { - be_t cbCtrlStrmFunc_addr; + mem_func_beptr_t strmInfo, mem_ptr_t strmParam, u32 cbCtrlStrmArg)> cbCtrlStrmFunc; be_t cbCtrlStrmArg; }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 05381883e0..c8a84b13ad 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -889,10 +889,11 @@ int cellRescGetRegisterCount() return CELL_OK; } -int cellRescGetLastFlipTime() +u64 cellRescGetLastFlipTime() { - UNIMPLEMENTED_FUNC(cellResc); - return CELL_OK; + cellResc->Log("cellRescGetLastFlipTime()"); + + return Emu.GetGSManager().GetRender().m_last_flip_time; } int cellRescSetRegisterCount() diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index 29b12f10f7..c1551e842e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -31,7 +31,7 @@ int vdecRead(void* opaque, u8* buf, int buf_size) next: if (vdec.reader.size < (u32)buf_size /*&& !vdec.just_started*/) { - while (vdec.job.IsEmpty()) + while (!vdec.job.GetCountUnsafe()) { if (Emu.IsStopped()) { @@ -44,6 +44,7 @@ next: switch (vdec.job.Peek().type) { case vdecEndSeq: + case vdecClose: { buf_size = vdec.reader.size; } @@ -147,7 +148,7 @@ u32 vdecOpen(VideoDecoder* data) break; } - if (vdec.job.IsEmpty() && vdec.is_running) + if (!vdec.job.GetCountUnsafe() && vdec.is_running) { Sleep(1); continue; @@ -189,10 +190,8 @@ u32 vdecOpen(VideoDecoder* data) cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg); cb.Branch(true); // ???*/ - avcodec_close(vdec.ctx); - avformat_close_input(&vdec.fmt); - vdec.is_running = false; + vdec.just_finished = true; } break; @@ -244,7 +243,13 @@ u32 vdecOpen(VideoDecoder* data) } au(0); - if (vdec.just_started) // deferred initialization + if (vdec.just_started && vdec.just_finished) + { + avcodec_flush_buffers(vdec.ctx); + vdec.just_started = false; + vdec.just_finished = false; + } + else if (vdec.just_started) // deferred initialization { err = avformat_open_input(&vdec.fmt, NULL, av_find_input_format("mpeg"), NULL); if (err) @@ -285,7 +290,7 @@ u32 vdecOpen(VideoDecoder* data) av_dict_set(&opts, "refcounted_frames", "1", 0); { std::lock_guard lock(g_mutex_avcodec_open2); - // not multithread-safe + // not multithread-safe (???) err = avcodec_open2(vdec.ctx, codec, &opts); } if (err) @@ -294,8 +299,6 @@ u32 vdecOpen(VideoDecoder* data) Emu.Pause(); break; } - //vdec.ctx->flags |= CODEC_FLAG_TRUNCATED; - //vdec.ctx->flags2 |= CODEC_FLAG2_CHUNKS; vdec.just_started = false; } @@ -303,8 +306,9 @@ u32 vdecOpen(VideoDecoder* data) while (true) { - if (Emu.IsStopped()) + if (Emu.IsStopped() || vdec.job.PeekIfExist(VdecTask()).type == vdecClose) { + vdec.is_finished = true; LOG_WARNING(HLE, "vdecDecodeAu: aborted"); return; } @@ -498,7 +502,7 @@ int cellVdecClose(u32 handle) vdec->job.Push(VdecTask(vdecClose)); - while (!vdec->is_finished || !vdec->frames.IsEmpty()) + while (!vdec->is_finished) { if (Emu.IsStopped()) { @@ -674,14 +678,14 @@ int cellVdecGetPicItem(u32 handle, mem32_t picItem_ptr) return CELL_VDEC_ERROR_FATAL; } - VdecFrame& vf = vdec->frames.Peek(); - if (vdec->frames.IsEmpty()) { - Sleep(1); + Sleep(1); // hack return CELL_VDEC_ERROR_EMPTY; } + VdecFrame& vf = vdec->frames.Peek(); + AVFrame& frame = *vf.data; mem_ptr_t info(vdec->memAddr + vdec->memBias); diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.h b/rpcs3/Emu/SysCalls/Modules/cellVdec.h index 7c9508d049..4731d50e3d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.h @@ -697,6 +697,7 @@ public: volatile bool is_running; volatile bool is_finished; bool just_started; + bool just_finished; AVCodecContext* ctx; AVFormatContext* fmt; @@ -735,6 +736,7 @@ public: , is_finished(false) , is_running(false) , just_started(false) + , just_finished(false) , ctx(nullptr) , vdecCb(nullptr) { From cf98ddf979a810cf12f82ca2329b063fc45b9f66 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 30 Jun 2014 01:08:56 +0400 Subject: [PATCH 05/13] Small fixes --- rpcs3/Emu/GS/RSXThread.h | 1 + rpcs3/Emu/SysCalls/Modules/cellAdec.h | 1 + rpcs3/Emu/SysCalls/Modules/cellDmux.cpp | 34 +++++++++++-------------- rpcs3/Emu/SysCalls/Modules/cellVdec.h | 1 + rpcs3/Gui/ConLogFrame.cpp | 2 +- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index 05ef3587b8..db4f9c3563 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -151,6 +151,7 @@ public: std::mutex m_cs_main; SSemaphore m_sem_flush; SSemaphore m_sem_flip; + u64 m_last_flip_time; Callback m_flip_handler; Callback m_user_handler; u64 m_vblank_count; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.h b/rpcs3/Emu/SysCalls/Modules/cellAdec.h index 65ce820f13..108844f22c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.h @@ -1158,6 +1158,7 @@ public: ~AudioDecoder() { + // TODO: check finalization if (ctx) { for (u32 i = frames.GetCount() - 1; ~i; i--) diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 377ebf22dc..3bde3766ac 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -145,22 +145,20 @@ u32 dmuxOpen(Demuxer* data) if (esATX[ch]) { ElementaryStream& es = *esATX[ch]; - while (es.isfull()) - { - if (Emu.IsStopped()) - { - LOG_WARNING(HLE, "esATX[%d] was full, waiting aborted", ch); - return; - } - Sleep(1); - } - - if (es.hasunseen()) // hack, probably useless + if (es.isfull()) { stream = backup; + Sleep(1); continue; } + /*if (es.hasunseen()) // hack, probably useless + { + stream = backup; + Sleep(1); + continue; + }*/ + stream.skip(4); len -= 4; @@ -194,14 +192,10 @@ u32 dmuxOpen(Demuxer* data) if (esAVC[ch]) { ElementaryStream& es = *esAVC[ch]; - while (es.isfull()) + if (es.isfull()) { - if (Emu.IsStopped()) - { - LOG_WARNING(HLE, "esAVC[%d] was full, waiting aborted", ch); - return; - } Sleep(1); + continue; } DemuxerStream backup = stream; @@ -217,11 +211,12 @@ u32 dmuxOpen(Demuxer* data) if (pes.new_au && es.hasdata()) // new AU detected { - if (es.hasunseen()) // hack, probably useless + /*if (es.hasunseen()) // hack, probably useless { stream = backup; + Sleep(1); continue; - } + }*/ es.finish(stream); // callback mem_ptr_t esMsg(a128(dmux.memAddr) + (cb_add ^= 16)); @@ -242,6 +237,7 @@ u32 dmuxOpen(Demuxer* data) if (es.isfull()) { stream = backup; + Sleep(1); continue; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.h b/rpcs3/Emu/SysCalls/Modules/cellVdec.h index 4731d50e3d..7f323c94b7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.h @@ -766,6 +766,7 @@ public: ~VideoDecoder() { + // TODO: check finalization if (ctx) { for (u32 i = frames.GetCount() - 1; ~i; i--) diff --git a/rpcs3/Gui/ConLogFrame.cpp b/rpcs3/Gui/ConLogFrame.cpp index 3e5a7056a8..be7f4fc6ef 100644 --- a/rpcs3/Gui/ConLogFrame.cpp +++ b/rpcs3/Gui/ConLogFrame.cpp @@ -88,7 +88,7 @@ struct wxWriter : Log::LogListener default: break; } - llogcon->AppendText(wxString(msg.mText)); + llogcon->AppendText(fmt::FromUTF8(msg.mText)); } } if (m_log->GetLastPosition() > GUI_BUFFER_MAX_SIZE) From 06868cb694f47dbfe00bff97f7b5ab85c0076a3e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 1 Jul 2014 02:53:29 +0400 Subject: [PATCH 06/13] cellGameDataCheckCreate2 implemented --- rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 235 ++++++++++----------- rpcs3/Emu/SysCalls/Modules/cellGame.h | 202 ++++++++++++++++++ rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 10 + rpcs3/emucore.vcxproj | 1 + rpcs3/emucore.vcxproj.filters | 3 + 5 files changed, 325 insertions(+), 126 deletions(-) create mode 100644 rpcs3/Emu/SysCalls/Modules/cellGame.h diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 9a7471f63d..43aec8a1f0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -10,124 +10,12 @@ #include "Loader/PSF.h" +#include "cellGame.h" + //void cellGame_init(); //Module cellGame(0x003e, cellGame_init); extern Module *cellGame = nullptr; -// Return Codes -enum -{ - CELL_GAME_RET_OK = 0, - CELL_GAME_RET_CANCEL = 1, - CELL_GAME_RET_NONE = 2, - CELL_GAME_ERROR_NOTFOUND = 0x8002cb04, - CELL_GAME_ERROR_BROKEN = 0x8002cb05, - CELL_GAME_ERROR_INTERNAL = 0x8002cb06, - CELL_GAME_ERROR_PARAM = 0x8002cb07, - CELL_GAME_ERROR_NOAPP = 0x8002cb08, - CELL_GAME_ERROR_ACCESS_ERROR = 0x8002cb09, - CELL_GAME_ERROR_NOSPACE = 0x8002cb20, - CELL_GAME_ERROR_NOTSUPPORTED = 0x8002cb21, - CELL_GAME_ERROR_FAILURE = 0x8002cb22, - CELL_GAME_ERROR_BUSY = 0x8002cb23, - CELL_GAME_ERROR_IN_SHUTDOWN = 0x8002cb24, - CELL_GAME_ERROR_INVALID_ID = 0x8002cb25, - CELL_GAME_ERROR_EXIST = 0x8002cb26, - CELL_GAME_ERROR_NOTPATCH = 0x8002cb27, - CELL_GAME_ERROR_INVALID_THEME_FILE = 0x8002cb28, - CELL_GAME_ERROR_BOOTPATH = 0x8002cb50, -}; - -// Definitions -enum -{ - CELL_GAME_PATH_MAX = 128, - CELL_GAME_DIRNAME_SIZE = 32, - CELL_GAME_THEMEFILENAME_SIZE = 48, - CELL_GAME_SYSP_TITLE_SIZE = 128, - CELL_GAME_SYSP_TITLEID_SIZE = 10, - CELL_GAME_SYSP_VERSION_SIZE = 6, - CELL_GAME_SYSP_APP_VER_SIZE = 6, - - CELL_GAME_GAMETYPE_DISC = 1, - CELL_GAME_GAMETYPE_HDD = 2, - - CELL_GAME_GAMETYPE_GAMEDATA = 3, - - CELL_GAME_SIZEKB_NOTCALC = -1, - - CELL_GAME_ATTRIBUTE_PATCH = 0x1, - CELL_GAME_ATTRIBUTE_APP_HOME = 0x2, - CELL_GAME_ATTRIBUTE_DEBUG = 0x4, - CELL_GAME_ATTRIBUTE_XMBBUY = 0x8, - CELL_GAME_ATTRIBUTE_COMMERCE2_BROWSER = 0x10, - CELL_GAME_ATTRIBUTE_INVITE_MESSAGE = 0x20, - CELL_GAME_ATTRIBUTE_CUSTOM_DATA_MESSAGE = 0x40, - CELL_GAME_ATTRIBUTE_WEB_BROWSER = 0x100, -}; - -//Parameter IDs of PARAM.SFO -enum -{ - //Integers - CELL_GAME_PARAMID_PARENTAL_LEVEL = 102, - CELL_GAME_PARAMID_RESOLUTION = 103, - CELL_GAME_PARAMID_SOUND_FORMAT = 104, - - //Strings - CELL_GAME_PARAMID_TITLE = 0, - CELL_GAME_PARAMID_TITLE_DEFAULT = 1, - CELL_GAME_PARAMID_TITLE_JAPANESE = 2, - CELL_GAME_PARAMID_TITLE_ENGLISH = 3, - CELL_GAME_PARAMID_TITLE_FRENCH = 4, - CELL_GAME_PARAMID_TITLE_SPANISH = 5, - CELL_GAME_PARAMID_TITLE_GERMAN = 6, - CELL_GAME_PARAMID_TITLE_ITALIAN = 7, - CELL_GAME_PARAMID_TITLE_DUTCH = 8, - CELL_GAME_PARAMID_TITLE_PORTUGUESE = 9, - CELL_GAME_PARAMID_TITLE_RUSSIAN = 10, - CELL_GAME_PARAMID_TITLE_KOREAN = 11, - CELL_GAME_PARAMID_TITLE_CHINESE_T = 12, - CELL_GAME_PARAMID_TITLE_CHINESE_S = 13, - CELL_GAME_PARAMID_TITLE_FINNISH = 14, - CELL_GAME_PARAMID_TITLE_SWEDISH = 15, - CELL_GAME_PARAMID_TITLE_DANISH = 16, - CELL_GAME_PARAMID_TITLE_NORWEGIAN = 17, - CELL_GAME_PARAMID_TITLE_POLISH = 18, - CELL_GAME_PARAMID_TITLE_PORTUGUESE_BRAZIL = 19, - CELL_GAME_PARAMID_TITLE_ENGLISH_UK = 20, - CELL_GAME_PARAMID_TITLE_ID = 100, - CELL_GAME_PARAMID_VERSION = 101, - CELL_GAME_PARAMID_APP_VER = 106, -}; - -//Error dialog types -enum -{ - CELL_GAME_ERRDIALOG_BROKEN_GAMEDATA = 0, - CELL_GAME_ERRDIALOG_BROKEN_HDDGAME = 1, - CELL_GAME_ERRDIALOG_NOSPACE = 2, - CELL_GAME_ERRDIALOG_BROKEN_EXIT_GAMEDATA = 100, - CELL_GAME_ERRDIALOG_BROKEN_EXIT_HDDGAME = 101, - CELL_GAME_ERRDIALOG_NOSPACE_EXIT = 102, -}; - -struct CellGameContentSize -{ - be_t hddFreeSizeKB; - be_t sizeKB; - be_t sysSizeKB; -}; - -struct CellGameSetInitParams -{ - char title[CELL_GAME_SYSP_TITLE_SIZE]; - char titleId[CELL_GAME_SYSP_TITLEID_SIZE]; - char reserved0[2]; - char version[CELL_GAME_SYSP_VERSION_SIZE]; - char reserved1[66]; -}; - std::string contentInfo = ""; std::string usrdir = ""; @@ -316,17 +204,117 @@ int cellGameContentPermit(mem_list_ptr_t contentInfoPath, mem_list_ptr_t return CELL_GAME_RET_OK; } -int cellGameDataCheckCreate2(u32 version, u32 dirName_addr, u32 errDialog, u32 funcStat_addr, u32 container) +int cellGameDataCheckCreate2(u32 version, const mem_list_ptr_t dirName, u32 errDialog, + mem_func_ptr_t cbResult, mem_ptr_t get, mem_ptr_t set)> funcStat, 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; + cellGame->Warning("cellGameDataCheckCreate2(version=0x%x, dirName_addr=0x%x, errDialog=0x%x, funcStat_addr=0x%x, container=%d)", + version, dirName.GetAddr(), errDialog, funcStat.GetAddr(), container); + + if (version != CELL_GAMEDATA_VERSION_CURRENT || !dirName.IsGood() || errDialog > 1 || !funcStat.IsGood()) + { + cellGame->Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_PARAM"); + return CELL_GAMEDATA_ERROR_PARAM; + } + + // TODO: output errors (errDialog) + + const std::string dir = "/dev_hdd0/game/" + std::string(dirName.GetString()); + + if (!Emu.GetVFS().ExistsDir(dir)) + { + cellGame->Error("cellGameDataCheckCreate2(): TODO: creating directory '%s'", dir.c_str()); + // TODO: create data + return CELL_GAMEDATA_RET_OK; + } + + vfsFile f(dir + "/PARAM.SFO"); + if (!f.IsOpened()) + { + cellGame->Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_BROKEN (cannot open PARAM.SFO)"); + return CELL_GAMEDATA_ERROR_BROKEN; + } + + PSFLoader psf(f); + if (!psf.Load(false)) + { + cellGame->Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_BROKEN (cannot read PARAM.SFO)"); + return CELL_GAMEDATA_ERROR_BROKEN; + } + + // TODO: use memory container + MemoryAllocator cbResult; + MemoryAllocator cbGet; + MemoryAllocator cbSet; + + memset(cbGet.GetPtr(), 0, sizeof(CellGameDataStatGet)); + + // TODO: Use the free space of the computer's HDD where RPCS3 is being run. + cbGet->hddFreeSizeKB = 40000000; //40 GB + + cbGet->isNewData = CELL_GAMEDATA_ISNEWDATA_NO; + strncpy_s(cbGet->contentInfoPath, dir.c_str(), _TRUNCATE); + strncpy_s(cbGet->gameDataPath, (dir + "/USRDIR").c_str(), _TRUNCATE); + + // TODO: set correct time + cbGet->st_atime = 0; + cbGet->st_ctime = 0; + cbGet->st_mtime = 0; + + // TODO: calculate data size, if necessary + cbGet->sizeKB = CELL_GAMEDATA_SIZEKB_NOTCALC; + cbGet->sysSizeKB = 0; + + cbGet->getParam.attribute = CELL_GAMEDATA_ATTR_NORMAL; + cbGet->getParam.parentalLevel = psf.GetInteger("PARENTAL_LEVEL"); + strncpy_s(cbGet->getParam.dataVersion, psf.GetString("APP_VER").c_str(), _TRUNCATE); + strncpy_s(cbGet->getParam.titleId, psf.GetString("TITLE_ID").c_str(), _TRUNCATE); + strncpy_s(cbGet->getParam.title, psf.GetString("TITLE").c_str(), _TRUNCATE); + // TODO: write lang titles + + funcStat(cbResult.GetAddr(), cbGet.GetAddr(), cbSet.GetAddr()); + + if (cbSet->setParam.GetAddr()) + { + // TODO: write PARAM.SFO from cbSet + cellGame->Error("cellGameDataCheckCreate2(): TODO: writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam.GetAddr()); + } + + switch (cbResult->result.ToBE()) + { + case se32(CELL_GAMEDATA_CBRESULT_OK_CANCEL): + // TODO: do not process game data + cellGame->Warning("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL"); + + case se32(CELL_GAMEDATA_CBRESULT_OK): + return CELL_GAMEDATA_RET_OK; + + case se32(CELL_GAMEDATA_CBRESULT_ERR_NOSPACE): // TODO: process errors, error message and needSizeKB result + cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE"); + return CELL_GAMEDATA_ERROR_CBRESULT; + + case se32(CELL_GAMEDATA_CBRESULT_ERR_BROKEN): + cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_BROKEN"); + return CELL_GAMEDATA_ERROR_CBRESULT; + + case se32(CELL_GAMEDATA_CBRESULT_ERR_NODATA): + cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NODATA"); + return CELL_GAMEDATA_ERROR_CBRESULT; + + case se32(CELL_GAMEDATA_CBRESULT_ERR_INVALID): + cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID"); + return CELL_GAMEDATA_ERROR_CBRESULT; + + default: + cellGame->Error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x)"); + return CELL_GAMEDATA_ERROR_CBRESULT; + } } -int cellGameDataCheckCreate(u32 version, u32 dirName_addr, u32 errDialog, u32 funcStat_addr, u32 container) +int cellGameDataCheckCreate(u32 version, const mem_list_ptr_t dirName, u32 errDialog, + mem_func_ptr_t cbResult, mem_ptr_t get, mem_ptr_t set)> funcStat, u32 container) { - // probably identical - return cellGameDataCheckCreate2(version, dirName_addr, errDialog, funcStat_addr, container); + // TODO: almost identical, the only difference is that this function will always calculate the size of game data + return cellGameDataCheckCreate2(version, dirName, errDialog, funcStat, container); } int cellGameCreateGameData(mem_ptr_t init, mem_list_ptr_t tmp_contentInfoPath, mem_list_ptr_t tmp_usrdirPath) @@ -353,7 +341,6 @@ int cellGameGetParamInt(u32 id, mem32_t value) 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); if(!psf.Load(false)) @@ -380,7 +367,6 @@ int cellGameGetParamString(u32 id, u32 buf_addr, u32 bufsize) 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); if(!psf.Load(false)) @@ -498,9 +484,6 @@ 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/cellGame.h b/rpcs3/Emu/SysCalls/Modules/cellGame.h new file mode 100644 index 0000000000..06d214215a --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.h @@ -0,0 +1,202 @@ +#pragma once + +// Return Codes +enum +{ + CELL_GAME_RET_OK = 0, + CELL_GAME_RET_CANCEL = 1, + CELL_GAME_RET_NONE = 2, + CELL_GAME_ERROR_NOTFOUND = 0x8002cb04, + CELL_GAME_ERROR_BROKEN = 0x8002cb05, + CELL_GAME_ERROR_INTERNAL = 0x8002cb06, + CELL_GAME_ERROR_PARAM = 0x8002cb07, + CELL_GAME_ERROR_NOAPP = 0x8002cb08, + CELL_GAME_ERROR_ACCESS_ERROR = 0x8002cb09, + CELL_GAME_ERROR_NOSPACE = 0x8002cb20, + CELL_GAME_ERROR_NOTSUPPORTED = 0x8002cb21, + CELL_GAME_ERROR_FAILURE = 0x8002cb22, + CELL_GAME_ERROR_BUSY = 0x8002cb23, + CELL_GAME_ERROR_IN_SHUTDOWN = 0x8002cb24, + CELL_GAME_ERROR_INVALID_ID = 0x8002cb25, + CELL_GAME_ERROR_EXIST = 0x8002cb26, + CELL_GAME_ERROR_NOTPATCH = 0x8002cb27, + CELL_GAME_ERROR_INVALID_THEME_FILE = 0x8002cb28, + CELL_GAME_ERROR_BOOTPATH = 0x8002cb50, +}; + +// Definitions +enum +{ + CELL_GAME_PATH_MAX = 128, + CELL_GAME_DIRNAME_SIZE = 32, + CELL_GAME_THEMEFILENAME_SIZE = 48, + CELL_GAME_SYSP_LANGUAGE_NUM = 20, + CELL_GAME_SYSP_TITLE_SIZE = 128, + CELL_GAME_SYSP_TITLEID_SIZE = 10, + CELL_GAME_SYSP_VERSION_SIZE = 6, + CELL_GAME_SYSP_APP_VER_SIZE = 6, + + CELL_GAME_GAMETYPE_DISC = 1, + CELL_GAME_GAMETYPE_HDD = 2, + + CELL_GAME_GAMETYPE_GAMEDATA = 3, + + CELL_GAME_SIZEKB_NOTCALC = -1, + + CELL_GAME_ATTRIBUTE_PATCH = 0x1, + CELL_GAME_ATTRIBUTE_APP_HOME = 0x2, + CELL_GAME_ATTRIBUTE_DEBUG = 0x4, + CELL_GAME_ATTRIBUTE_XMBBUY = 0x8, + CELL_GAME_ATTRIBUTE_COMMERCE2_BROWSER = 0x10, + CELL_GAME_ATTRIBUTE_INVITE_MESSAGE = 0x20, + CELL_GAME_ATTRIBUTE_CUSTOM_DATA_MESSAGE = 0x40, + CELL_GAME_ATTRIBUTE_WEB_BROWSER = 0x100, +}; + +//Parameter IDs of PARAM.SFO +enum +{ + //Integers + CELL_GAME_PARAMID_PARENTAL_LEVEL = 102, + CELL_GAME_PARAMID_RESOLUTION = 103, + CELL_GAME_PARAMID_SOUND_FORMAT = 104, + + //Strings + CELL_GAME_PARAMID_TITLE = 0, + CELL_GAME_PARAMID_TITLE_DEFAULT = 1, + CELL_GAME_PARAMID_TITLE_JAPANESE = 2, + CELL_GAME_PARAMID_TITLE_ENGLISH = 3, + CELL_GAME_PARAMID_TITLE_FRENCH = 4, + CELL_GAME_PARAMID_TITLE_SPANISH = 5, + CELL_GAME_PARAMID_TITLE_GERMAN = 6, + CELL_GAME_PARAMID_TITLE_ITALIAN = 7, + CELL_GAME_PARAMID_TITLE_DUTCH = 8, + CELL_GAME_PARAMID_TITLE_PORTUGUESE = 9, + CELL_GAME_PARAMID_TITLE_RUSSIAN = 10, + CELL_GAME_PARAMID_TITLE_KOREAN = 11, + CELL_GAME_PARAMID_TITLE_CHINESE_T = 12, + CELL_GAME_PARAMID_TITLE_CHINESE_S = 13, + CELL_GAME_PARAMID_TITLE_FINNISH = 14, + CELL_GAME_PARAMID_TITLE_SWEDISH = 15, + CELL_GAME_PARAMID_TITLE_DANISH = 16, + CELL_GAME_PARAMID_TITLE_NORWEGIAN = 17, + CELL_GAME_PARAMID_TITLE_POLISH = 18, + CELL_GAME_PARAMID_TITLE_PORTUGUESE_BRAZIL = 19, + CELL_GAME_PARAMID_TITLE_ENGLISH_UK = 20, + CELL_GAME_PARAMID_TITLE_ID = 100, + CELL_GAME_PARAMID_VERSION = 101, + CELL_GAME_PARAMID_APP_VER = 106, +}; + +//Error dialog types +enum +{ + CELL_GAME_ERRDIALOG_BROKEN_GAMEDATA = 0, + CELL_GAME_ERRDIALOG_BROKEN_HDDGAME = 1, + CELL_GAME_ERRDIALOG_NOSPACE = 2, + CELL_GAME_ERRDIALOG_BROKEN_EXIT_GAMEDATA = 100, + CELL_GAME_ERRDIALOG_BROKEN_EXIT_HDDGAME = 101, + CELL_GAME_ERRDIALOG_NOSPACE_EXIT = 102, +}; + +struct CellGameContentSize +{ + be_t hddFreeSizeKB; + be_t sizeKB; + be_t sysSizeKB; +}; + +struct CellGameSetInitParams +{ + char title[CELL_GAME_SYSP_TITLE_SIZE]; + char titleId[CELL_GAME_SYSP_TITLEID_SIZE]; + char reserved0[2]; + char version[CELL_GAME_SYSP_VERSION_SIZE]; + char reserved1[66]; +}; + +struct CellGameDataCBResult +{ + be_t result; + be_t errNeedSizeKB; + be_t invalidMsg_addr; + be_t reserved; +}; + +enum // old consts +{ + CELL_GAMEDATA_CBRESULT_OK_CANCEL = 1, + CELL_GAMEDATA_CBRESULT_OK = 0, + CELL_GAMEDATA_CBRESULT_ERR_NOSPACE = -1, + CELL_GAMEDATA_CBRESULT_ERR_BROKEN = -3, + CELL_GAMEDATA_CBRESULT_ERR_NODATA = -4, + CELL_GAMEDATA_CBRESULT_ERR_INVALID = -5, + + CELL_GAMEDATA_RET_OK = 0, + CELL_GAMEDATA_RET_CANCEL = 1, + + CELL_GAMEDATA_ERROR_CBRESULT = 0x8002b601, + CELL_GAMEDATA_ERROR_ACCESS_ERROR = 0x8002b602, + CELL_GAMEDATA_ERROR_INTERNAL = 0x8002b603, + + CELL_GAMEDATA_ERROR_PARAM = 0x8002b604, + CELL_GAMEDATA_ERROR_NOSPACE = 0x8002b605, + CELL_GAMEDATA_ERROR_BROKEN = 0x8002b606, + + CELL_GAMEDATA_ERROR_FAILURE = 0x8002b607, + + CELL_GAMEDATA_ATTR_NORMAL = 0, + CELL_GAMEDATA_VERSION_CURRENT = 0, + + CELL_GAMEDATA_INVALIDMSG_MAX = 256, + CELL_GAMEDATA_PATH_MAX = 1055, + CELL_GAMEDATA_DIRNAME_SIZE = 32, + + CELL_GAMEDATA_SIZEKB_NOTCALC = -1, + + CELL_GAMEDATA_SYSP_LANGUAGE_NUM = 20, + CELL_GAMEDATA_SYSP_TITLE_SIZE = 128, + CELL_GAMEDATA_SYSP_TITLEID_SIZE = 10, + CELL_GAMEDATA_SYSP_VERSION_SIZE = 6, + + CELL_GAMEDATA_ISNEWDATA_NO = 0, + CELL_GAMEDATA_ISNEWDATA_YES = 1, + + CELL_GAMEDATA_ERRDIALOG_NONE = 0, + CELL_GAMEDATA_ERRDIALOG_ALWAYS = 1, +}; + +struct CellGameDataSystemFileParam +{ + char title[CELL_GAMEDATA_SYSP_TITLE_SIZE]; + char titleLang[CELL_GAMEDATA_SYSP_LANGUAGE_NUM][CELL_GAMEDATA_SYSP_TITLE_SIZE]; + char titleId[CELL_GAMEDATA_SYSP_TITLEID_SIZE]; + char reserved0[2]; + char dataVersion[CELL_GAMEDATA_SYSP_VERSION_SIZE]; + char reserved1[2]; + be_t parentalLevel; + be_t attribute; + char reserved2[256]; +}; + +struct CellGameDataStatGet +{ + be_t hddFreeSizeKB; + be_t isNewData; + char contentInfoPath[CELL_GAMEDATA_PATH_MAX]; + char gameDataPath[CELL_GAMEDATA_PATH_MAX]; + char reserved0[2]; + be_t st_atime; + be_t st_mtime; + be_t st_ctime; + CellGameDataSystemFileParam getParam; + be_t sizeKB; + be_t sysSizeKB; + char reserved1[68]; +}; + +struct CellGameDataStatSet +{ + mem_beptr_t setParam; + be_t reserved; +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 1cc47aeb07..0ae10874d6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -10,6 +10,7 @@ #include "cellSysutil.h" #include "cellSysutil_SaveData.h" +#include "cellGame.h" #include "Loader/PSF.h" @@ -997,6 +998,12 @@ int cellWebBrowserEstimate2(mem8_ptr_t _config, mem32_ptr_t memSize) return CELL_OK; } +extern int cellGameDataCheckCreate2(u32 version, const mem_list_ptr_t dirName, u32 errDialog, + mem_func_ptr_t cbResult, mem_ptr_t get, mem_ptr_t set)> funcStat, u32 container); + +extern int cellGameDataCheckCreate(u32 version, const mem_list_ptr_t dirName, u32 errDialog, + mem_func_ptr_t cbResult, mem_ptr_t get, mem_ptr_t set)> funcStat, u32 container); + void cellSysutil_init() { cellSysutil->AddFunc(0x40e895d3, cellSysutilGetSystemParamInt); @@ -1074,4 +1081,7 @@ void cellSysutil_init() //cellSysutil->AddFunc(0xe7fa820b, cellSaveDataEnableOverlay); cellSysutil->AddFunc(0x6d087930, cellWebBrowserEstimate2); + + cellSysutil->AddFunc(0xe7951dee, cellGameDataCheckCreate); + cellSysutil->AddFunc(0xc9645c41, cellGameDataCheckCreate2); } diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 02e2f292b5..fb34b8f476 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -339,6 +339,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 03b8528f49..cc85fc9f6c 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1072,5 +1072,8 @@ Utilities + + Emu\SysCalls\Modules + \ No newline at end of file From 2d1409c7063be5c5e7fad0564b04dbae71687b49 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 1 Jul 2014 16:21:55 +0400 Subject: [PATCH 07/13] FileExists() fixed --- rpcs3/Emu/FS/vfsLocalFile.cpp | 5 +++++ rpcs3/Emu/FS/vfsLocalFile.h | 1 + rpcs3/Emu/SysCalls/Modules/sceNp.cpp | 6 ++++++ rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp | 8 +++++++- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/FS/vfsLocalFile.cpp b/rpcs3/Emu/FS/vfsLocalFile.cpp index 7eceb1e8d6..7a6e71c09c 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.cpp +++ b/rpcs3/Emu/FS/vfsLocalFile.cpp @@ -115,3 +115,8 @@ bool vfsLocalFile::IsOpened() const { return m_file.IsOpened() && vfsFileBase::IsOpened(); } + +bool vfsLocalFile::Exists(const std::string& path) +{ + return rFileExists(path); +} \ No newline at end of file diff --git a/rpcs3/Emu/FS/vfsLocalFile.h b/rpcs3/Emu/FS/vfsLocalFile.h index a7aac7b1ea..c61dd495e7 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.h +++ b/rpcs3/Emu/FS/vfsLocalFile.h @@ -12,6 +12,7 @@ public: virtual bool Open(const std::string& path, vfsOpenMode mode = vfsRead) override; virtual bool Create(const std::string& path) override; virtual bool Close() override; + virtual bool Exists(const std::string& path) override; virtual u64 GetSize() override; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp index aaff7e08b1..20dc321c69 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp @@ -30,6 +30,12 @@ int sceNpDrmIsAvailable(u32 k_licensee_addr, u32 drm_path_addr) sceNp->Warning("sceNpDrmIsAvailable(k_licensee_addr=0x%x, drm_path_addr=0x%x)", k_licensee_addr, drm_path_addr); std::string drm_path = Memory.ReadString(drm_path_addr); + if (!Emu.GetVFS().ExistsFile(drm_path)) + { + sceNp->Warning("sceNpDrmIsAvailable(): '%s' not found", drm_path.c_str()); + return CELL_ENOENT; + } + std::string k_licensee_str; u8 k_licensee[0x10]; for(int i = 0; i < 0x10; i++) diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index 6e8a6c4e01..15fe4a6d86 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -116,6 +116,12 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) return CELL_EINVAL; } + if (!Emu.GetVFS().ExistsFile(ppath)) + { + sys_fs->Error("\"%s\" not found! flags: 0x%08x", ppath.c_str(), flags); + return CELL_ENOENT; + } + vfsFileBase* stream = Emu.GetVFS().OpenFile(ppath, o_mode); if(!stream || !stream->IsOpened()) @@ -126,7 +132,7 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) } fd = sys_fs->GetNewId(stream, IDFlag_File); - LOG_WARNING(HLE, "*** cellFsOpen(path=\"%s\"): fd = %d", path.c_str(), fd.GetValue()); + LOG_WARNING(HLE, "\"%s\" opened: fd = %d", path.c_str(), fd.GetValue()); return CELL_OK; } From 2eeab1feb00defc95ff8152a3a35e0c3b88e587d Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 1 Jul 2014 19:34:25 +0400 Subject: [PATCH 08/13] Compilation fix --- Utilities/GNU.h | 8 ++++++++ rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 24 ++++++++++++------------ rpcs3/Emu/SysCalls/Modules/cellGame.h | 6 +++--- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/Utilities/GNU.h b/Utilities/GNU.h index a3a2ba48e5..a79dfbf3d0 100644 --- a/Utilities/GNU.h +++ b/Utilities/GNU.h @@ -6,6 +6,14 @@ #define thread_local __thread #endif +template +void strcpy_trunc(char (&dst)[size], const std::string& src) +{ + const size_t count = (src.size() >= size) ? size - 1 /* truncation */ : src.size(); + memcpy(dst, src.c_str(), count); + dst[count] = 0; +} + #if defined(__GNUG__) #include #include diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 43aec8a1f0..d247780327 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -24,7 +24,7 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_tWarning("cellGameBootCheck(type_addr=0x%x, attributes_addr=0x%x, size_addr=0x%x, dirName_addr=0x%x)", type.GetAddr(), attributes.GetAddr(), size.GetAddr(), dirName.GetAddr()); - if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || !dirName.IsGood()) + if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || (dirName.GetAddr() && !dirName.IsGood())) { cellGame->Error("cellGameBootCheck(): CELL_GAME_ERROR_PARAM"); return CELL_GAME_ERROR_PARAM; @@ -56,7 +56,7 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t dirName, u32 cbGet->hddFreeSizeKB = 40000000; //40 GB cbGet->isNewData = CELL_GAMEDATA_ISNEWDATA_NO; - strncpy_s(cbGet->contentInfoPath, dir.c_str(), _TRUNCATE); - strncpy_s(cbGet->gameDataPath, (dir + "/USRDIR").c_str(), _TRUNCATE); + strcpy_trunc(cbGet->contentInfoPath, dir); + strcpy_trunc(cbGet->gameDataPath, dir + "/USRDIR"); // TODO: set correct time - cbGet->st_atime = 0; - cbGet->st_ctime = 0; - cbGet->st_mtime = 0; + cbGet->st_atime_ = 0; + cbGet->st_ctime_ = 0; + cbGet->st_mtime_ = 0; // TODO: calculate data size, if necessary cbGet->sizeKB = CELL_GAMEDATA_SIZEKB_NOTCALC; @@ -266,9 +266,9 @@ int cellGameDataCheckCreate2(u32 version, const mem_list_ptr_t dirName, u32 cbGet->getParam.attribute = CELL_GAMEDATA_ATTR_NORMAL; cbGet->getParam.parentalLevel = psf.GetInteger("PARENTAL_LEVEL"); - strncpy_s(cbGet->getParam.dataVersion, psf.GetString("APP_VER").c_str(), _TRUNCATE); - strncpy_s(cbGet->getParam.titleId, psf.GetString("TITLE_ID").c_str(), _TRUNCATE); - strncpy_s(cbGet->getParam.title, psf.GetString("TITLE").c_str(), _TRUNCATE); + strcpy_trunc(cbGet->getParam.dataVersion, psf.GetString("APP_VER")); + strcpy_trunc(cbGet->getParam.titleId, psf.GetString("TITLE_ID")); + strcpy_trunc(cbGet->getParam.title, psf.GetString("TITLE")); // TODO: write lang titles funcStat(cbResult.GetAddr(), cbGet.GetAddr(), cbSet.GetAddr()); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.h b/rpcs3/Emu/SysCalls/Modules/cellGame.h index 06d214215a..12a0165eba 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.h @@ -186,9 +186,9 @@ struct CellGameDataStatGet char contentInfoPath[CELL_GAMEDATA_PATH_MAX]; char gameDataPath[CELL_GAMEDATA_PATH_MAX]; char reserved0[2]; - be_t st_atime; - be_t st_mtime; - be_t st_ctime; + be_t st_atime_; + be_t st_mtime_; + be_t st_ctime_; CellGameDataSystemFileParam getParam; be_t sizeKB; be_t sysSizeKB; From 5f6a2365503506269d15c7b777a97eec37b68339 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 1 Jul 2014 20:04:58 +0400 Subject: [PATCH 09/13] Compilation fix 2 --- Utilities/SQueue.h | 6 ++++-- rpcs3/Emu/SysCalls/Modules/cellVdec.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/cellVdec.h | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Utilities/SQueue.h b/Utilities/SQueue.h index 52b68979f0..9aa7e58356 100644 --- a/Utilities/SQueue.h +++ b/Utilities/SQueue.h @@ -125,12 +125,14 @@ public: return m_data[(m_pos + pos) % SQSize]; } - T& PeekIfExist(T& def, u32 pos = 0) + T& PeekIfExist(u32 pos = 0) { + static T def_value; + std::lock_guard lock(m_mutex); if (m_count <= pos) { - return def; + return def_value; } else { diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index c1551e842e..d76d846c4d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -306,7 +306,7 @@ u32 vdecOpen(VideoDecoder* data) while (true) { - if (Emu.IsStopped() || vdec.job.PeekIfExist(VdecTask()).type == vdecClose) + if (Emu.IsStopped() || vdec.job.PeekIfExist().type == vdecClose) { vdec.is_finished = true; LOG_WARNING(HLE, "vdecDecodeAu: aborted"); diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.h b/rpcs3/Emu/SysCalls/Modules/cellVdec.h index 7f323c94b7..5b6a5633d2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.h @@ -647,6 +647,7 @@ struct CellVdecMpeg2Info enum VdecJobType : u32 { + vdecInvalid, vdecStartSeq, vdecEndSeq, vdecDecodeAu, @@ -675,6 +676,7 @@ struct VdecTask } VdecTask() + : type(vdecInvalid) { } }; From 8736a14599e6fc702141b42e4fdd837fc4afd866 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 1 Jul 2014 21:39:03 +0400 Subject: [PATCH 10/13] Compilation fix 3 --- rpcs3/Emu/SysCalls/Modules/cellGame.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.h b/rpcs3/Emu/SysCalls/Modules/cellGame.h index 12a0165eba..963a8cfc62 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.h @@ -127,10 +127,10 @@ enum // old consts { CELL_GAMEDATA_CBRESULT_OK_CANCEL = 1, CELL_GAMEDATA_CBRESULT_OK = 0, - CELL_GAMEDATA_CBRESULT_ERR_NOSPACE = -1, - CELL_GAMEDATA_CBRESULT_ERR_BROKEN = -3, - CELL_GAMEDATA_CBRESULT_ERR_NODATA = -4, - CELL_GAMEDATA_CBRESULT_ERR_INVALID = -5, + CELL_GAMEDATA_CBRESULT_ERR_NOSPACE = 0xffffffff, + CELL_GAMEDATA_CBRESULT_ERR_BROKEN = 0xfffffffd, + CELL_GAMEDATA_CBRESULT_ERR_NODATA = 0xfffffffc, + CELL_GAMEDATA_CBRESULT_ERR_INVALID = 0xfffffffb, CELL_GAMEDATA_RET_OK = 0, CELL_GAMEDATA_RET_CANCEL = 1, From 7f5f67163b36c2b59c6d5f7d8dac25a8e4570f97 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 1 Jul 2014 21:50:57 +0400 Subject: [PATCH 11/13] Compilation fix 4 --- rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 14 +++++++------- rpcs3/Emu/SysCalls/Modules/cellGame.h | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index d247780327..62ed6f9fc2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -279,28 +279,28 @@ int cellGameDataCheckCreate2(u32 version, const mem_list_ptr_t dirName, u32 cellGame->Error("cellGameDataCheckCreate2(): TODO: writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam.GetAddr()); } - switch (cbResult->result.ToBE()) + switch (cbResult->result) { - case se32(CELL_GAMEDATA_CBRESULT_OK_CANCEL): + case CELL_GAMEDATA_CBRESULT_OK_CANCEL: // TODO: do not process game data cellGame->Warning("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL"); - case se32(CELL_GAMEDATA_CBRESULT_OK): + case CELL_GAMEDATA_CBRESULT_OK: return CELL_GAMEDATA_RET_OK; - case se32(CELL_GAMEDATA_CBRESULT_ERR_NOSPACE): // TODO: process errors, error message and needSizeKB result + case CELL_GAMEDATA_CBRESULT_ERR_NOSPACE: // TODO: process errors, error message and needSizeKB result cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE"); return CELL_GAMEDATA_ERROR_CBRESULT; - case se32(CELL_GAMEDATA_CBRESULT_ERR_BROKEN): + case CELL_GAMEDATA_CBRESULT_ERR_BROKEN: cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_BROKEN"); return CELL_GAMEDATA_ERROR_CBRESULT; - case se32(CELL_GAMEDATA_CBRESULT_ERR_NODATA): + case CELL_GAMEDATA_CBRESULT_ERR_NODATA: cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NODATA"); return CELL_GAMEDATA_ERROR_CBRESULT; - case se32(CELL_GAMEDATA_CBRESULT_ERR_INVALID): + case CELL_GAMEDATA_CBRESULT_ERR_INVALID: cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID"); return CELL_GAMEDATA_ERROR_CBRESULT; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.h b/rpcs3/Emu/SysCalls/Modules/cellGame.h index 963a8cfc62..12a0165eba 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.h @@ -127,10 +127,10 @@ enum // old consts { CELL_GAMEDATA_CBRESULT_OK_CANCEL = 1, CELL_GAMEDATA_CBRESULT_OK = 0, - CELL_GAMEDATA_CBRESULT_ERR_NOSPACE = 0xffffffff, - CELL_GAMEDATA_CBRESULT_ERR_BROKEN = 0xfffffffd, - CELL_GAMEDATA_CBRESULT_ERR_NODATA = 0xfffffffc, - CELL_GAMEDATA_CBRESULT_ERR_INVALID = 0xfffffffb, + CELL_GAMEDATA_CBRESULT_ERR_NOSPACE = -1, + CELL_GAMEDATA_CBRESULT_ERR_BROKEN = -3, + CELL_GAMEDATA_CBRESULT_ERR_NODATA = -4, + CELL_GAMEDATA_CBRESULT_ERR_INVALID = -5, CELL_GAMEDATA_RET_OK = 0, CELL_GAMEDATA_RET_CANCEL = 1, From fdc84796357ddaab5030198a39828486e9f2f99c Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 1 Jul 2014 22:06:15 +0400 Subject: [PATCH 12/13] Compilation fix 5 --- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 0ae10874d6..b8bf9ec0a2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -381,10 +381,10 @@ int cellSysutilUnregisterCallback(int slot) return CELL_OK; } -int cellMsgDialogOpen2(u32 type, char* msgString, mem_func_ptr_t callback, mem_ptr_t userData, u32 extParam) +int cellMsgDialogOpen2(u32 type, mem_list_ptr_t 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); + type, msgString.GetAddr(), callback.GetAddr(), userData.GetAddr(), extParam); long style = 0; @@ -406,7 +406,7 @@ int cellMsgDialogOpen2(u32 type, char* msgString, mem_func_ptr_t Date: Tue, 1 Jul 2014 22:42:05 +0400 Subject: [PATCH 13/13] Compilation fix 6 --- rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 62ed6f9fc2..1d0dfef4e9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -279,7 +279,7 @@ int cellGameDataCheckCreate2(u32 version, const mem_list_ptr_t dirName, u32 cellGame->Error("cellGameDataCheckCreate2(): TODO: writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam.GetAddr()); } - switch (cbResult->result) + switch ((s32)cbResult->result) { case CELL_GAMEDATA_CBRESULT_OK_CANCEL: // TODO: do not process game data