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

View file

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

View file

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