mirror of
https://gitlab.com/skmp/dca3-game.git
synced 2025-04-28 13:07:59 +03:00
Game Save + Load From VMU
This commit is contained in:
parent
4a453e3604
commit
2f45ee419a
3 changed files with 106 additions and 29 deletions
|
@ -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))
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue