feat: copy save (rockefeler)

This commit is contained in:
Fireblade
2026-06-30 22:36:42 -04:00
parent f7ab07067a
commit 8ad0c385de
2 changed files with 111 additions and 3 deletions
@@ -137,6 +137,111 @@ void C4JStorage::CopySaveDataToNewSave(PBYTE pbThumbnail, DWORD cbThumbnail, WCH
;
}
// copy save thingy for loadcreatejoin
// new folder gets a timestamp name so it doesn't overwrite anything
C4JStorage::ESaveGameState C4JStorage::CopySaveData(PSAVE_INFO pSaveInfo, int(*Func)(LPVOID, const bool, C4JStorage::ESaveGameState), bool(*FuncProg)(LPVOID, const int), LPVOID lpParam)
{
if (!pSaveInfo)
{
if (Func) Func(lpParam, false, ESaveGame_Idle);
return ESaveGame_Idle;
}
char curDir[256];
GetCurrentDirectoryA(sizeof(curDir), curDir);
char srcPath[512];
sprintf(srcPath, "%s\\Windows64\\GameHDD\\%s", curDir, pSaveInfo->UTF8SaveFilename);
// unique name so two copies can coexist
_SYSTEMTIME st;
GetSystemTime(&st);
char newUniqueName[64];
sprintf_s(newUniqueName, "%4d%02d%02d%02d%02d%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
char dstPath[512];
sprintf(dstPath, "%s\\Windows64\\GameHDD\\%s", curDir, newUniqueName);
// make the new folder
if (!CreateDirectoryA(dstPath, nullptr))
{
if (Func) Func(lpParam, false, ESaveGame_CopyCompleteFail);
return ESaveGame_Idle;
}
// copy files including subfolders like thumbnails
char searchPattern[512];
sprintf(searchPattern, "%s\\*", srcPath);
WIN32_FIND_DATAA findData;
HANDLE hFind = FindFirstFileA(searchPattern, &findData);
bool bSuccess = true;
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
if (strcmp(findData.cFileName, ".") == 0 || strcmp(findData.cFileName, "..") == 0)
continue;
char srcFile[512];
sprintf(srcFile, "%s\\%s", srcPath, findData.cFileName);
char dstFile[512];
sprintf(dstFile, "%s\\%s", dstPath, findData.cFileName);
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
CreateDirectoryA(dstFile, nullptr);
char subSearch[512];
sprintf(subSearch, "%s\\*", srcFile);
WIN32_FIND_DATAA subFind;
HANDLE hSubFind = FindFirstFileA(subSearch, &subFind);
if (hSubFind != INVALID_HANDLE_VALUE)
{
do
{
if (strcmp(subFind.cFileName, ".") == 0 || strcmp(subFind.cFileName, "..") == 0)
continue;
char subSrc[512];
sprintf(subSrc, "%s\\%s", srcFile, subFind.cFileName);
char subDst[512];
sprintf(subDst, "%s\\%s", dstFile, subFind.cFileName);
if (!CopyFileA(subSrc, subDst, FALSE))
{
bSuccess = false;
break;
}
} while (FindNextFileA(hSubFind, &subFind));
FindClose(hSubFind);
}
}
else
{
if (!CopyFileA(srcFile, dstFile, FALSE))
{
bSuccess = false;
}
}
if (!bSuccess)
break;
} while (FindNextFileA(hFind, &findData));
FindClose(hFind);
}
// tell the ui to refresh the save list if it worked
if (Func)
{
Func(lpParam, bSuccess, bSuccess ? ESaveGame_Idle : ESaveGame_CopyCompleteFail);
}
return ESaveGame_Idle;
}
void C4JStorage::SetSaveDeviceSelected(unsigned int uiPad, bool bSelected)
{
// @Patoke: majorly used in XUI
+6 -3
View File
@@ -133,9 +133,11 @@ public:
ESaveGame_Rename,
ESaveGame_Delete,
ESaveGame_GetSaveThumbnail // Not used as an actual state in the PS4, but the game expects this to be returned to indicate success when getting a thumbnail
ESaveGame_GetSaveThumbnail, // Not used as an actual state in the PS4, but the game expects this to be returned to indicate success when getting a thumbnail
ESaveGame_CopyCompleteSuccess,
ESaveGame_CopyCompleteFail
};
enum ELoadGameStatus
{
ELoadGame_Idle = 0,
@@ -261,7 +263,8 @@ public:
unsigned int GetSaveSize();
void GetSaveData(void* pvData, unsigned int* puiBytes);
PVOID AllocateSaveData(unsigned int uiBytes);
void SetSaveImages(PBYTE pbThumbnail, DWORD dwThumbnailBytes, PBYTE pbImage, DWORD dwImageBytes, PBYTE pbTextData, DWORD dwTextDataBytes); // Sets the thumbnail & image for the save, optionally setting the metadata in the png
void SetSaveImages(PBYTE pbThumbnail, DWORD dwThumbnailBytes, PBYTE pbImage, DWORD dwImageBytes, PBYTE pbTextData, DWORD dwTextDataBytes);
C4JStorage::ESaveGameState CopySaveData(PSAVE_INFO pSaveInfo, int (*Func)(LPVOID, const bool, C4JStorage::ESaveGameState), bool (*FuncProg)(LPVOID, const int), LPVOID lpParam); // Sets the thumbnail & image for the save, optionally setting the metadata in the png
C4JStorage::ESaveGameState SaveSaveData(int(*Func)(LPVOID, const bool), LPVOID lpParam);
void CopySaveDataToNewSave(PBYTE pbThumbnail, DWORD cbThumbnail, WCHAR* wchNewName, int (*Func)(LPVOID lpParam, bool), LPVOID lpParam);
void SetSaveDeviceSelected(unsigned int uiPad, bool bSelected);