From a09ad031ec9210156cab5dc74826d4cbd4c1db4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Mon, 31 Mar 2014 20:30:07 +0200 Subject: [PATCH] cellSaveData* (cellSysutil) improvements * cellSaveData improvements: cellSaveDataListLoad2 should work perfectly (ignoring the fact that there is no dialog, and the first entry is chosen automatically). cellSaveDataListSave2 has improved too. Some code refactoring is required though. * Reverted (deleted) Emu/SysCalls/Dialogs/ folder which I accidentally included while merging Nekotekina's branch (including minor SaveData changes). * Modified some small things in cellGcmSys. --- rpcs3/Emu/SysCalls/Dialogs/Dialog.cpp | 2 - rpcs3/Emu/SysCalls/Dialogs/Dialog.h | 8 - rpcs3/Emu/SysCalls/Dialogs/MessageDialog.cpp | 7 - rpcs3/Emu/SysCalls/Dialogs/MessageDialog.h | 15 -- rpcs3/Emu/SysCalls/Dialogs/SaveDataList.cpp | 37 ---- rpcs3/Emu/SysCalls/Dialogs/SaveDataList.h | 9 - rpcs3/Emu/SysCalls/Dialogs/UserList.cpp | 2 - rpcs3/Emu/SysCalls/Dialogs/UserList.h | 0 rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 110 ++++------- .../SysCalls/Modules/cellSysutil_SaveData.cpp | 184 +++++++++++++++--- .../SysCalls/Modules/cellSysutil_SaveData.h | 16 +- 11 files changed, 215 insertions(+), 175 deletions(-) delete mode 100644 rpcs3/Emu/SysCalls/Dialogs/Dialog.cpp delete mode 100644 rpcs3/Emu/SysCalls/Dialogs/Dialog.h delete mode 100644 rpcs3/Emu/SysCalls/Dialogs/MessageDialog.cpp delete mode 100644 rpcs3/Emu/SysCalls/Dialogs/MessageDialog.h delete mode 100644 rpcs3/Emu/SysCalls/Dialogs/SaveDataList.cpp delete mode 100644 rpcs3/Emu/SysCalls/Dialogs/SaveDataList.h delete mode 100644 rpcs3/Emu/SysCalls/Dialogs/UserList.cpp delete mode 100644 rpcs3/Emu/SysCalls/Dialogs/UserList.h diff --git a/rpcs3/Emu/SysCalls/Dialogs/Dialog.cpp b/rpcs3/Emu/SysCalls/Dialogs/Dialog.cpp deleted file mode 100644 index 80e37ceb0c..0000000000 --- a/rpcs3/Emu/SysCalls/Dialogs/Dialog.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "stdafx.h" -#include "Dialog.h" \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Dialogs/Dialog.h b/rpcs3/Emu/SysCalls/Dialogs/Dialog.h deleted file mode 100644 index 0a4e38e58e..0000000000 --- a/rpcs3/Emu/SysCalls/Dialogs/Dialog.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -class Dialog -{ -public: - void Show(); - void Close(); -}; diff --git a/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.cpp b/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.cpp deleted file mode 100644 index 2390ca5601..0000000000 --- a/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "stdafx.h" -#include "MessageDialog.h" - -MessageDialog::MessageDialog(std::string message, std::string title, int flags, char* icon) -{ - // TODO: Use RSX post-drawing instead of wxWidgets -} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.h b/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.h deleted file mode 100644 index 9201122fa1..0000000000 --- a/rpcs3/Emu/SysCalls/Dialogs/MessageDialog.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "Dialog.h" - -enum MessageDialogFlags -{ - MessageDialog_Button_Enter = 0x1, - MessageDialog_Button_Back = 0x2, - - MessageDialog_Controls_YesNo = 0x4, -}; - -class MessageDialog : public Dialog -{ - MessageDialog(std::string message, std::string title, int flags, char* icon); -}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.cpp b/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.cpp deleted file mode 100644 index b8ffafdda7..0000000000 --- a/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "stdafx.h" -#include "SaveDataList.h" - -void SaveDataList::Load(const std::vector& entries) -{ - wxDialog dialog(NULL, wxID_ANY, "test", wxDefaultPosition, wxSize(450, 680)); - - wxPanel *panel = new wxPanel(&dialog, -1); - wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); - wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); - wxListCtrl* list = new wxListCtrl(&dialog, wxID_ANY, wxPoint(10,10), wxSize(400,600)); - - list->InsertColumn(0, "Icon"); - list->InsertColumn(1, "Information"); - wxImageList* pImageList = new wxImageList(320,176); - - for (int i=0; iInsertItem (i, i); - list->SetItemColumnImage (i, 0, i); - list->SetItem (i, 1, wxString::Format("%d",i+1)); - - wxImage img(320, 176, entries[i].iconBuffer); - pImageList->Add(img); - } - list->SetImageList(pImageList, wxIMAGE_LIST_SMALL); - - panel->AddChild(list); - - vbox->Add(panel, 1); - vbox->Add(hbox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10); - - dialog.SetSizer(vbox); - dialog.Centre(); - dialog.ShowModal(); - dialog.Destroy(); -} diff --git a/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.h b/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.h deleted file mode 100644 index 0a9e5db1ef..0000000000 --- a/rpcs3/Emu/SysCalls/Dialogs/SaveDataList.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "Dialog.h" -#include "Emu/SysCalls/Modules/cellSysutil_SaveData.h" - -class SaveDataList : public Dialog -{ -public: - void Load(const std::vector& entries); -}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Dialogs/UserList.cpp b/rpcs3/Emu/SysCalls/Dialogs/UserList.cpp deleted file mode 100644 index 4f2fcb076d..0000000000 --- a/rpcs3/Emu/SysCalls/Dialogs/UserList.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "stdafx.h" -#include "UserList.h" diff --git a/rpcs3/Emu/SysCalls/Dialogs/UserList.h b/rpcs3/Emu/SysCalls/Dialogs/UserList.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 16db0c32d7..ea68e5b871 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -4,9 +4,9 @@ #include "Emu/GS/GCM.h" void cellGcmSys_init(); -void cellGcmSys_Load(); -void cellGcmSys_Unload(); -Module cellGcmSys(0x0010, cellGcmSys_init, cellGcmSys_Load, cellGcmSys_Unload); +void cellGcmSys_load(); +void cellGcmSys_unload(); +Module cellGcmSys(0x0010, cellGcmSys_init, cellGcmSys_load, cellGcmSys_unload); u32 local_size = 0; u32 local_addr = NULL; @@ -24,9 +24,9 @@ enum // Function declaration int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id); -/*------------------------------------------------------------ - Memory Mapping -------------------------------------------------------------*/ +//---------------------------------------------------------------------------- +// Memory Mapping +//---------------------------------------------------------------------------- struct gcm_offset { @@ -853,88 +853,64 @@ int cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co void cellGcmSys_init() { - //------------------------------------------------------------------------ - // Generating Render Commands - //------------------------------------------------------------------------ - - // TODO - - //------------------------------------------------------------------------ // Data Retrieval - //------------------------------------------------------------------------ - // cellGcmGetCurrentField + //cellGcmSys.AddFunc(0xc8f3bd09, cellGcmGetCurrentField); cellGcmSys.AddFunc(0xf80196c1, cellGcmGetLabelAddress); - // cellGcmGetNotifyDataAddress - // cellGcmGetReport - // cellGcmGetReportDataAddress + //cellGcmSys.AddFunc(0x21cee035, cellGcmGetNotifyDataAddress); + //cellGcmSys.AddFunc(0x99d397ac, cellGcmGetReport); + //cellGcmSys.AddFunc(0x9a0159af, cellGcmGetReportDataAddress); cellGcmSys.AddFunc(0x8572bce2, cellGcmGetReportDataAddressLocation); - // cellGcmGetReportDataLocation + //cellGcmSys.AddFunc(0xa6b180ac, cellGcmGetReportDataLocation); cellGcmSys.AddFunc(0x5a41c10f, cellGcmGetTimeStamp); - // cellGcmGetTimeStampLocation + //cellGcmSys.AddFunc(0x2ad4951b, cellGcmGetTimeStampLocation); - //------------------------------------------------------------------------ - // Data Transfer and Format Conversion - //------------------------------------------------------------------------ - - // TODO - - //------------------------------------------------------------------------ // Command Buffer Control - //------------------------------------------------------------------------ - // cellGcmCallbackForSnc - // cellGcmFinish - // cellGcmFlush + //cellGcmSys.AddFunc(, cellGcmCallbackForSnc); + //cellGcmSys.AddFunc(, cellGcmFinish); + //cellGcmSys.AddFunc(, cellGcmFlush); cellGcmSys.AddFunc(0xa547adde, cellGcmGetControlRegister); cellGcmSys.AddFunc(0x5e2ee0f0, cellGcmGetDefaultCommandWordSize); cellGcmSys.AddFunc(0x8cdf8c70, cellGcmGetDefaultSegmentWordSize); cellGcmSys.AddFunc(0xcaabd992, cellGcmInitDefaultFifoMode); - // cellGcmReserveMethodSize - // cellGcmResetDefaultCommandBuffer - // cellGcmSetCallCommand + //cellGcmSys.AddFunc(, cellGcmReserveMethodSize); + //cellGcmSys.AddFunc(, cellGcmResetDefaultCommandBuffer); cellGcmSys.AddFunc(0x9ba451e4, cellGcmSetDefaultFifoSize); - // cellGcmSetJumpCommand - // cellGcmSetNopCommand - // cellGcmSetReturnCommand - // cellGcmSetSkipNop - // cellGcmSetupContextData - // cellGcmSetUserCommand + //cellGcmSys.AddFunc(, cellGcmSetupContextData); - //------------------------------------------------------------------------ // Hardware Resource Management - //------------------------------------------------------------------------ cellGcmSys.AddFunc(0x4524cccd, cellGcmBindTile); cellGcmSys.AddFunc(0x9dc04436, cellGcmBindZcull); - // cellGcmDumpGraphicsError + //cellGcmSys.AddFunc(0x1f61b3ff, cellGcmDumpGraphicsError); cellGcmSys.AddFunc(0xe315a0b2, cellGcmGetConfiguration); - // cellGcmGetDisplayBufferByFlipIndex + //cellGcmSys.AddFunc(0x371674cf, cellGcmGetDisplayBufferByFlipIndex); cellGcmSys.AddFunc(0x72a577ce, cellGcmGetFlipStatus); - // cellGcmgetLastFlipTime - // cellGcmGetLastSecondVTime + //cellGcmSys.AddFunc(0x63387071, cellGcmgetLastFlipTime); + //cellGcmSys.AddFunc(0x23ae55a3, cellGcmGetLastSecondVTime); cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize); - // cellGcmGetVBlankCount + //cellGcmSys.AddFunc(0x723bbc7e, cellGcmGetVBlankCount); cellGcmSys.AddFunc(0x15bae46b, cellGcmInit); - // cellGcmInitSystemMode + //cellGcmSys.AddFunc(0xfce9e764, cellGcmInitSystemMode); cellGcmSys.AddFunc(0xb2e761d4, cellGcmResetFlipStatus); cellGcmSys.AddFunc(0x51c9d62b, cellGcmSetDebugOutputLevel); cellGcmSys.AddFunc(0xa53d12ae, cellGcmSetDisplayBuffer); cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip); cellGcmSys.AddFunc(0xa41ef7e8, cellGcmSetFlipHandler); - // cellGcmSetFlipImmediate + //cellGcmSys.AddFunc(0xacee8542, cellGcmSetFlipImmediate); cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode); cellGcmSys.AddFunc(0xa47c09ff, cellGcmSetFlipStatus); - // cellGcmSetFlipWithWaitLabel - // cellGcmSetGraphicsHandler + //cellGcmSys.AddFunc(, cellGcmSetFlipWithWaitLabel); + //cellGcmSys.AddFunc(0xd01b570d, cellGcmSetGraphicsHandler); cellGcmSys.AddFunc(0x0b4b62d5, cellGcmSetPrepareFlip); - //cellGcmSetQueueHandler + //cellGcmSys.AddFunc(0x0a862772, cellGcmSetQueueHandler); cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency); - // cellGcmSetSecondVHandler + //cellGcmSys.AddFunc(0xdc494430, cellGcmSetSecondVHandler); cellGcmSys.AddFunc(0xbd100dbc, cellGcmSetTileInfo); cellGcmSys.AddFunc(0x06edea9e, cellGcmSetUserHandler); - // cellGcmSetVBlankFrequency + //cellGcmSys.AddFunc(0xffe0160e, cellGcmSetVBlankFrequency); cellGcmSys.AddFunc(0xa91b0402, cellGcmSetVBlankHandler); cellGcmSys.AddFunc(0x983fb9aa, cellGcmSetWaitFlip); cellGcmSys.AddFunc(0xd34a420d, cellGcmSetZcull); - // cellGcmSortRemapEaIoAddress + //cellGcmSys.AddFunc(0x25b40ab4, cellGcmSortRemapEaIoAddress); cellGcmSys.AddFunc(0xd9b7653e, cellGcmUnbindTile); cellGcmSys.AddFunc(0xa75640e8, cellGcmUnbindZcull); cellGcmSys.AddFunc(0x657571f7, cellGcmGetTileInfo); @@ -942,9 +918,7 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x0e6b0dae, cellGcmGetDisplayInfo); cellGcmSys.AddFunc(0x93806525, cellGcmGetCurrentDisplayBufferId); - //------------------------------------------------------------------------ - //Memory Mapping - //------------------------------------------------------------------------ + // Memory Mapping cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset); cellGcmSys.AddFunc(0xfb81c03e, cellGcmGetMaxIoMapSize); cellGcmSys.AddFunc(0x2922aed0, cellGcmGetOffsetTable); @@ -958,9 +932,7 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0xdb23e867, cellGcmUnmapIoAddress); cellGcmSys.AddFunc(0x3b9bd5bd, cellGcmUnreserveIoMapSize); - //------------------------------------------------------------------------ // Cursor - //------------------------------------------------------------------------ cellGcmSys.AddFunc(0x107bf3a1, cellGcmInitCursor); cellGcmSys.AddFunc(0xc47d0812, cellGcmSetCursorEnable); cellGcmSys.AddFunc(0x69c6cc82, cellGcmSetCursorDisable); @@ -968,25 +940,21 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x1a0de550, cellGcmSetCursorPosition); cellGcmSys.AddFunc(0xbd2fa0a7, cellGcmUpdateCursor); - //------------------------------------------------------------------------ // Functions for Maintaining Compatibility - //------------------------------------------------------------------------ - // cellGcmGetCurrentBuffer - // cellGcmSetCurrentBuffer + //cellGcmSys.AddFunc(, cellGcmGetCurrentBuffer); + //cellGcmSys.AddFunc(, cellGcmSetCurrentBuffer); cellGcmSys.AddFunc(0xbc982946, cellGcmSetDefaultCommandBuffer); - // cellGcmSetDefaultCommandBufferAndSegmentWordSize - // cellGcmSetUserCallback + //cellGcmSys.AddFunc(, cellGcmSetDefaultCommandBufferAndSegmentWordSize); + //cellGcmSys.AddFunc(, cellGcmSetUserCallback); - //------------------------------------------------------------------------ // Other - //------------------------------------------------------------------------ cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand); cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15); cellGcmSys.AddFunc(0xd8f88e1a, cellGcmSetFlipCommandWithWaitLabel); cellGcmSys.AddFunc(0xd0b1d189, cellGcmSetTile); } -void cellGcmSys_Load() +void cellGcmSys_load() { current_config.ioAddress = NULL; current_config.localAddress = NULL; @@ -994,6 +962,6 @@ void cellGcmSys_Load() local_addr = NULL; } -void cellGcmSys_Unload() +void cellGcmSys_unload() { -} \ No newline at end of file +} diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp index 8f4ab520cd..6fe5e52b86 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.cpp @@ -7,8 +7,6 @@ #include "Loader/PSF.h" #include "stblib/stb_image.h" -//#include "Emu/SysCalls/Dialogs/SaveDataList.h" - extern Module cellSysutil; // Auxiliary Classes @@ -75,7 +73,7 @@ void addSaveDataEntry(std::vector& saveEntries, const std::st saveEntry.title = psf.GetString("TITLE"); saveEntry.subtitle = psf.GetString("SUB_TITLE"); saveEntry.details = psf.GetString("DETAIL"); - saveEntry.sizeKb = getSaveDataSize(saveDir)/1024; + saveEntry.sizeKB = getSaveDataSize(saveDir)/1024; saveEntry.st_atime_ = 0; // TODO saveEntry.st_mtime_ = 0; // TODO saveEntry.st_ctime_ = 0; // TODO @@ -102,6 +100,7 @@ void addNewSaveDataEntry(std::vector& saveEntries, mem_ptr_t< u32 focusSaveDataEntry(const std::vector& saveEntries, u32 focusPosition) { + // TODO: Get the correct index. Right now, this returns the first element of the list. return 0; } @@ -126,14 +125,97 @@ void setSaveDataEntries(std::vector& saveEntries, mem_ptr_t statGet) +{ + if (entry.isNew) + statGet->isNewData = CELL_SAVEDATA_ISNEWDATA_YES; + else + statGet->isNewData = CELL_SAVEDATA_ISNEWDATA_NO; + + statGet->bind = 0; // TODO ? + statGet->sizeKB = entry.sizeKB; + statGet->hddFreeSizeKB = 40000000; // 40 GB. TODO ? + statGet->sysSizeKB = 0; // TODO: This is the size of PARAM.SFO + PARAM.PDF + statGet->dir.st_atime_ = 0; // TODO ? + statGet->dir.st_mtime_ = 0; // TODO ? + statGet->dir.st_ctime_ = 0; // TODO ? + memcpy(statGet->dir.dirName, entry.dirName.c_str(), CELL_SAVEDATA_DIRNAME_SIZE); + + statGet->getParam.attribute = 0; // TODO ? + memcpy(statGet->getParam.title, entry.title.c_str(), CELL_SAVEDATA_SYSP_TITLE_SIZE); + memcpy(statGet->getParam.subTitle, entry.subtitle.c_str(), CELL_SAVEDATA_SYSP_SUBTITLE_SIZE); + memcpy(statGet->getParam.detail, entry.details.c_str(), CELL_SAVEDATA_SYSP_DETAIL_SIZE); + memcpy(statGet->getParam.listParam, entry.listParam.c_str(), CELL_SAVEDATA_SYSP_LPARAM_SIZE); + + statGet->fileNum = 0; + statGet->fileList.SetAddr(0); + statGet->fileListNum = 0; + std::string saveDir = "/dev_hdd0/home/00000001/savedata/" + entry.dirName; // TODO: Get the path of the current user + vfsDir dir(saveDir); + if (!dir.IsOpened()) + return; + + std::vector fileEntries; + for(const DirEntryInfo* dirEntry = dir.Read(); dirEntry; dirEntry = dir.Read()) { + if (dirEntry->flags & DirEntry_TypeFile) { + if (dirEntry->name == "PARAM.SFO" || dirEntry->name == "PARAM.PFD") + continue; + + statGet->fileNum++; + statGet->fileListNum++; + CellSaveDataFileStat fileEntry; + vfsFile file(saveDir + "/" + dirEntry->name); + + if (dirEntry->name == "ICON0.PNG") fileEntry.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_ICON0; + if (dirEntry->name == "ICON1.PAM") fileEntry.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_ICON1; + if (dirEntry->name == "PIC1.PNG") fileEntry.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_PIC1; + if (dirEntry->name == "SND0.AT3") fileEntry.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_SND0; + fileEntry.st_size = file.GetSize(); + fileEntry.st_atime_ = 0; // TODO ? + fileEntry.st_mtime_ = 0; // TODO ? + fileEntry.st_ctime_ = 0; // TODO ? + memcpy(fileEntry.fileName, (const char*)dirEntry->name.mb_str(), CELL_SAVEDATA_FILENAME_SIZE); + + fileEntries.push_back(fileEntry); + } + } + + statGet->fileList.SetAddr(Memory.Alloc(sizeof(CellSaveDataFileStat) * fileEntries.size(), sizeof(CellSaveDataFileStat))); + for (u32 i=0; ifileList[i], &fileEntries[i], sizeof(CellSaveDataFileStat)); +} + +s32 readSaveDataFile(mem_ptr_t fileSet, const std::string& saveDir) +{ + void* dest = NULL; + std::string filepath = saveDir + '/' + (char*)Memory.VirtualToRealAddr(fileSet->fileName_addr); + vfsFile file(filepath); + + switch (fileSet->fileType) + { + case CELL_SAVEDATA_FILETYPE_SECUREFILE: + case CELL_SAVEDATA_FILETYPE_NORMALFILE: + case CELL_SAVEDATA_FILETYPE_CONTENT_ICON0: + case CELL_SAVEDATA_FILETYPE_CONTENT_ICON1: + case CELL_SAVEDATA_FILETYPE_CONTENT_PIC1: + case CELL_SAVEDATA_FILETYPE_CONTENT_SND0: + dest = Memory.VirtualToRealAddr(fileSet->fileBuf_addr); + return file.Read(dest, min(fileSet->fileSize, fileSet->fileBufSize)); // TODO: This may fail for big files because of the dest pointer. + + default: + ConLog.Error("readSaveDataFile: Unknown type! Aborting..."); + return -1; + } +} + // Functions int cellSaveDataListSave2(u32 version, mem_ptr_t setList, mem_ptr_t setBuf, mem_func_ptr_t funcList, mem_func_ptr_t funcStat, mem_func_ptr_t funcFile, - u32 container, u32 userdata) + u32 container, u32 userdata_addr) { cellSysutil.Warning("cellSaveDataListSave2(version=%d, setList_addr=0x%x, setBuf=0x%x, funcList=0x%x, funcStat=0x%x, funcFile=0x%x, container=%d, userdata_addr=0x%x)", - version, setList.GetAddr(), setBuf.GetAddr(), funcList.GetAddr(), funcStat.GetAddr(), funcFile.GetAddr(), container, userdata); + version, setList.GetAddr(), setBuf.GetAddr(), funcList.GetAddr(), funcStat.GetAddr(), funcFile.GetAddr(), container, userdata_addr); if (!setList.IsGood() || !setBuf.IsGood() || !funcList.IsGood() || !funcStat.IsGood() || !funcFile.IsGood()) return CELL_SAVEDATA_ERROR_PARAM; @@ -174,15 +256,41 @@ int cellSaveDataListSave2(u32 version, mem_ptr_t setList, m } funcList(result.GetAddr(), listGet.GetAddr(), listSet.GetAddr()); + if (result->result < 0) { + ConLog.Error("cellSaveDataListSave2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + return CELL_SAVEDATA_ERROR_CBRESULT; + } + if (!listSet->fixedList.IsGood()) + return CELL_SAVEDATA_ERROR_PARAM; + + setSaveDataEntries(saveEntries, (u32)listSet->fixedList.GetAddr(), listSet->fixedListNum); + if (listSet->newData.IsGood()) + addNewSaveDataEntry(saveEntries, (u32)listSet->newData.GetAddr()); + if (saveEntries.size() == 0) { + ConLog.Warning("cellSaveDataListSave2: No save entries found!"); // TODO: Find a better way to handle this error + return CELL_SAVEDATA_RET_OK; + } MemoryAllocator statGet; MemoryAllocator statSet; + u32 focusIndex = focusSaveDataEntry(saveEntries, listSet->focusPosition); + // TODO: Display the dialog here + u32 selectedIndex = focusIndex; // TODO: Until the dialog is implemented, select always the focused entry + getSaveDataStat(saveEntries[selectedIndex], statGet.GetAddr()); + result->userdata_addr = userdata_addr; + funcStat(result.GetAddr(), statGet.GetAddr(), statSet.GetAddr()); + Memory.Free(statGet->fileList.GetAddr()); + if (result->result < 0) { + ConLog.Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + return CELL_SAVEDATA_ERROR_CBRESULT; + } MemoryAllocator fileGet; MemoryAllocator fileSet; funcFile(result.GetAddr(), fileGet.GetAddr(), fileSet.GetAddr()); + // TODO: There are other returns in this function that doesn't free the memory. Fix it (without using goto's, please). for (auto& entry : saveEntries) { delete[] entry.iconBuf; entry.iconBuf = nullptr; @@ -193,10 +301,10 @@ int cellSaveDataListSave2(u32 version, mem_ptr_t setList, m int cellSaveDataListLoad2(u32 version, mem_ptr_t setList, mem_ptr_t setBuf, mem_func_ptr_t funcList, mem_func_ptr_t funcStat, mem_func_ptr_t funcFile, - u32 container, u32 userdata) + u32 container, u32 userdata_addr) { cellSysutil.Warning("cellSaveDataListLoad2(version=%d, setList_addr=0x%x, setBuf=0x%x, funcList=0x%x, funcStat=0x%x, funcFile=0x%x, container=%d, userdata_addr=0x%x)", - version, setList.GetAddr(), setBuf.GetAddr(), funcList.GetAddr(), funcStat.GetAddr(), funcFile.GetAddr(), container, userdata); + version, setList.GetAddr(), setBuf.GetAddr(), funcList.GetAddr(), funcStat.GetAddr(), funcFile.GetAddr(), container, userdata_addr); if (!setList.IsGood() || !setBuf.IsGood() || !funcList.IsGood() || !funcStat.IsGood() || !funcFile.IsGood()) return CELL_SAVEDATA_ERROR_PARAM; @@ -204,6 +312,10 @@ int cellSaveDataListLoad2(u32 version, mem_ptr_t setList, m MemoryAllocator result; MemoryAllocator listGet; MemoryAllocator listSet; + MemoryAllocator statGet; + MemoryAllocator statSet; + MemoryAllocator fileGet; + MemoryAllocator fileSet; std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user vfsDir dir(saveBaseDir); @@ -237,34 +349,60 @@ int cellSaveDataListLoad2(u32 version, mem_ptr_t setList, m } funcList(result.GetAddr(), listGet.GetAddr(), listSet.GetAddr()); - if (result->result < 0) { ConLog.Error("cellSaveDataListLoad2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } - if (!listSet->fixedList.IsGood()) { + if (!listSet->fixedList.IsGood()) return CELL_SAVEDATA_ERROR_PARAM; - } + setSaveDataEntries(saveEntries, (u32)listSet->fixedList.GetAddr(), listSet->fixedListNum); + if (listSet->newData.IsGood()) + addNewSaveDataEntry(saveEntries, (u32)listSet->newData.GetAddr()); + if (saveEntries.size() == 0) { + ConLog.Warning("cellSaveDataListLoad2: No save entries found!"); // TODO: Find a better way to handle this error + return CELL_SAVEDATA_RET_OK; + } + u32 focusIndex = focusSaveDataEntry(saveEntries, listSet->focusPosition); - - MemoryAllocator statGet; - MemoryAllocator statSet; - // TODO: Display the dialog here - ConLog.Warning("cellSaveDataListLoad2:"); + u32 selectedIndex = focusIndex; // TODO: Until the dialog is implemented, select always the focused entry + getSaveDataStat(saveEntries[selectedIndex], statGet.GetAddr()); + result->userdata_addr = userdata_addr; - statGet->isNewData = CELL_SAVEDATA_ISNEWDATA_NO; // You can *never* load new data - //statGet->dir = - - - funcStat(result.GetAddr(), statGet.GetAddr(), statSet.GetAddr()); + Memory.Free(statGet->fileList.GetAddr()); + if (result->result < 0) { + ConLog.Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + return CELL_SAVEDATA_ERROR_CBRESULT; + } + if (statSet->setParam.IsGood()) + addNewSaveDataEntry(saveEntries, (u32)listSet->newData.GetAddr()); - MemoryAllocator fileGet; - MemoryAllocator fileSet; - funcFile(result.GetAddr(), fileGet.GetAddr(), fileSet.GetAddr()); + fileGet->excSize = 0; + while(true) + { + funcFile(result.GetAddr(), fileGet.GetAddr(), fileSet.GetAddr()); + if (result->result < 0) { + ConLog.Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + return CELL_SAVEDATA_ERROR_CBRESULT; + } + if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) + break; + switch (fileSet->fileOperation) + { + case CELL_SAVEDATA_FILEOP_READ: + fileGet->excSize = readSaveDataFile(fileSet.GetAddr(), saveBaseDir + (char*)statGet->dir.dirName); + break; + case CELL_SAVEDATA_FILEOP_WRITE: + case CELL_SAVEDATA_FILEOP_DELETE: + case CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC: + ConLog.Warning("cellSaveDataListLoad2: TODO: fileSet->fileOperation not yet implemented"); + break; + } + } + // TODO: There are other returns in this function that doesn't free the memory. Fix it (without using goto's, please). for (auto& entry : saveEntries) { delete[] entry.iconBuf; entry.iconBuf = nullptr; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.h b/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.h index 0ebcc172f9..8a7d127f97 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil_SaveData.h @@ -71,6 +71,20 @@ enum CELL_SAVEDATA_FOCUSPOS_LATEST = 3, CELL_SAVEDATA_FOCUSPOS_OLDEST = 4, CELL_SAVEDATA_FOCUSPOS_NEWDATA = 5, + + // CellSaveDataFileOperation + CELL_SAVEDATA_FILEOP_READ = 0, + CELL_SAVEDATA_FILEOP_WRITE = 1, + CELL_SAVEDATA_FILEOP_DELETE = 2, + CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC = 3, + + // CellSaveDataFileType + CELL_SAVEDATA_FILETYPE_SECUREFILE = 0, + CELL_SAVEDATA_FILETYPE_NORMALFILE = 1, + CELL_SAVEDATA_FILETYPE_CONTENT_ICON0 = 2, + CELL_SAVEDATA_FILETYPE_CONTENT_ICON1 = 3, + CELL_SAVEDATA_FILETYPE_CONTENT_PIC1 = 4, + CELL_SAVEDATA_FILETYPE_CONTENT_SND0 = 5, }; @@ -248,7 +262,7 @@ struct SaveDataListEntry std::string title; std::string subtitle; std::string details; - u32 sizeKb; + u32 sizeKB; s64 st_atime_; s64 st_mtime_; s64 st_ctime_;