Game Save + Load From VMU

This commit is contained in:
Josh Pearson 2025-02-25 13:36:26 -07:00
parent 4a453e3604
commit 2f45ee419a
3 changed files with 106 additions and 29 deletions

View file

@ -41,6 +41,8 @@
#include "Timecycle.h"
#include "Fluff.h"
#include "../vmu/vmu.h"
#define BLOCK_COUNT 22
#define SIZE_OF_SIMPLEVARS 0xE4
@ -94,11 +96,10 @@ PopulateRadioStationPositionList()
#define LoadSaveDataBlock()\
do {\
if (!ReadDataFromFile(file, (uint8 *) &size, 4))\
return false;\
size = align4bytes(size);\
if (!ReadDataFromFile(file, work_buff, size))\
return false;\
size = C_PcSave::PcClassLoadRoutine(file, work_buff); \
if (!size) {\
return false; \
} \
buf = work_buff;\
} while (0)
@ -285,6 +286,7 @@ GenericSave(int file)
bool
GenericLoad()
{
printf("GenericLoad\n");
uint8 *buf;
int32 file;
uint32 size;
@ -299,12 +301,14 @@ GenericLoad()
CheckSum = 0;
CDate dummy; // unused
CPad::ResetCheats();
if (!ReadInSizeofSaveFileBuffer(file, size))
return false;
size = align4bytes(size);
ReadDataFromFile(file, work_buff, size);
file = CFileMgr::OpenFile(LoadFileName, "rb");
assert(file != 0);
size = C_PcSave::PcClassLoadRoutine(file, work_buff);
assert(size != 0);
buf = (work_buff + 0x40);
ReadDataFromBufferPointer(buf, saveSize);
#ifdef MISSION_REPLAY // a hack to keep compatibility but get new data from save
qs = saveSize >> 24;
#endif
@ -562,13 +566,8 @@ CheckDataNotCorrupt(int32 slot, char *name)
strcpy(name, filename);
while (SIZE_OF_ONE_GAME_IN_BYTES - sizeof(uint32) > bytes_processed && blocknum < 40) {
int32 blocksize;
if (!ReadDataFromFile(file, (uint8*)&blocksize, sizeof(blocksize))) {
CloseFile(file);
return false;
}
if (blocksize > align4bytes(sizeof(work_buff)))
blocksize = sizeof(work_buff) - sizeof(uint32);
if (!ReadDataFromFile(file, work_buff, align4bytes(blocksize))) {
blocksize = C_PcSave::PcClassLoadRoutine(file, work_buff);
if (blocksize == 0) {
CloseFile(file);
return false;
}
@ -606,14 +605,16 @@ CheckDataNotCorrupt(int32 slot, char *name)
bool
RestoreForStartLoad()
{
uint8 buf[999];
int file = CFileMgr::OpenFile(LoadFileName, "rb");
if (file == 0) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_OPEN;
return false;
}
ReadDataFromFile(file, buf, sizeof(buf));
uint32_t size = C_PcSave::PcClassLoadRoutine(file, work_buff);
assert(size != 0);
uint8 *buf = work_buff;
if (CFileMgr::GetErrorReadWrite(file)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ;
if (!CloseFile(file))

View file

@ -12,6 +12,11 @@
#include "PCSave.h"
#include "Text.h"
#include "minilzo.h"
#include "main.h"
#include "../vmu/vmu.h"
const char* _psGetUserFilesFolder();
C_PcSave PcSaveHelper;
@ -19,7 +24,11 @@ C_PcSave PcSaveHelper;
void
C_PcSave::SetSaveDirectory(const char *path)
{
#if defined(RW_DC)
sprintf(DefaultPCSaveFileName, "%s/%s", path, "GTAVCsf");
#else
sprintf(DefaultPCSaveFileName, "%s\\%s", path, "GTAVCsf");
#endif
}
bool
@ -65,14 +74,39 @@ C_PcSave::SaveSlot(int32 slot)
bool
C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
{
CFileMgr::Write(file, (const char*)&size, sizeof(size));
if (CFileMgr::GetErrorReadWrite(file)) {
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
void* wrkmem = malloc(LZO1X_1_MEM_COMPRESS);
uint8* compressed = (uint8*)malloc(size*2);
lzo_uint compressed_size;
int crv = lzo1x_1_compress(data, size, compressed, &compressed_size, wrkmem);
free(wrkmem);
if (crv == LZO_E_OK) {
uint32_t compressed_size32 = compressed_size | 0x80000000;
CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32));
if (CFileMgr::GetErrorReadWrite(file)) {
free(compressed);
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
return false;
}
CFileMgr::Write(file, (const char*)compressed, compressed_size);
free(compressed);
} else if (crv == LZO_E_NOT_COMPRESSIBLE) {
free(compressed);
uint32_t compressed_size32 = size;
CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32));
if (CFileMgr::GetErrorReadWrite(file)) {
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
return false;
}
CFileMgr::Write(file, (const char*)data, align4bytes(size));
} else {
free(compressed);
return false;
}
CFileMgr::Write(file, (const char*)data, align4bytes(size));
CheckSum += (uint8) size;
CheckSum += (uint8) (size >> 8);
CheckSum += (uint8) (size >> 16);
@ -89,6 +123,44 @@ C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
return true;
}
uint32_t C_PcSave::PcClassLoadRoutine(int32 file, uint8 *data) {
uint32 size;
CFileMgr::Read(file, (char*)&size, sizeof(size));
assert(data == work_buff);
if (!(size & 0x80000000)) {
assert(align4bytes(size) == size);
CFileMgr::Read(file, (char*)data, align4bytes(size));
if (CFileMgr::GetErrorReadWrite(file)) {
return 0;
}
return size;
} else {
size &= ~0x80000000;
uint8* compressed = (uint8*)malloc(size);
CFileMgr::Read(file, (const char*)compressed, size);
if (CFileMgr::GetErrorReadWrite(file)) {
free(compressed);
return 0;
}
lzo_uint decompressed_size = 0;
auto crv = lzo1x_decompress(compressed, size, data, &decompressed_size, NULL);
free(compressed);
if (crv != LZO_E_OK) {
return 0;
}
if (align4bytes(decompressed_size) != decompressed_size) {
return 0;
}
return decompressed_size;
}
}
void
C_PcSave::PopulateSlotInfo()
{
@ -103,16 +175,16 @@ C_PcSave::PopulateSlotInfo()
#else
char savename[52];
#endif
struct {
int size;
struct header_t {
wchar FileName[24];
SYSTEMTIME SaveDateTime;
} header;
sprintf(savename, "%s%i%s", DefaultPCSaveFileName, i + 1, ".b");
int file = CFileMgr::OpenFile(savename, "rb");
if (file != 0) {
CFileMgr::Read(file, (char*)&header, sizeof(header));
if (strncmp((char*)&header, TopLineEmptyFile, sizeof(TopLineEmptyFile)-1) != 0) {
if (C_PcSave::PcClassLoadRoutine(file, (uint8*)work_buff)) {
header = *(header_t*)work_buff;
Slots[i] = SLOT_OK;
memcpy(SlotFileName[i], &header.FileName, sizeof(header.FileName));
@ -120,6 +192,9 @@ C_PcSave::PopulateSlotInfo()
}
CFileMgr::CloseFile(file);
}
#if defined(RW_DC)
return;
#endif
if (Slots[i] == SLOT_OK) {
if (CheckDataNotCorrupt(i, savename)) {
#ifdef FIX_INCOMPATIBLE_SAVES
@ -163,4 +238,4 @@ C_PcSave::PopulateSlotInfo()
}
}
}
}
}

View file

@ -34,6 +34,7 @@ public:
bool DeleteSlot(int32 slot);
int8 SaveSlot(int32 slot);
bool PcClassSaveRoutine(int32 file, uint8 *data, uint32 size);
static uint32_t PcClassLoadRoutine(int32 file, uint8 *data);
static void SetSaveDirectory(const char *path);
};