diff options
Diffstat (limited to 'src/save/GenericGameStorage.cpp')
-rw-r--r-- | src/save/GenericGameStorage.cpp | 63 |
1 files changed, 57 insertions, 6 deletions
diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp index d080512e..b68b805a 100644 --- a/src/save/GenericGameStorage.cpp +++ b/src/save/GenericGameStorage.cpp @@ -478,7 +478,7 @@ DoGameSpecificStuffAfterSucessLoad() CGame::TidyUpMemory(true, false); StillToFadeOut = true; JustLoadedDontFadeInYet = true; - TheCamera.Fade(0.0f, 0); + TheCamera.Fade(0.0f, FADE_OUT); CTheScripts::Process(); } @@ -693,6 +693,7 @@ enum SAVE_TYPE_64_BIT = 2, SAVE_TYPE_MSVC = 4, SAVE_TYPE_GCC = 8, + SAVE_TYPE_STEAM = 16, }; uint8 @@ -707,6 +708,14 @@ GetSaveType(char *savename) uint8 *buf = work_buff; CFileMgr::Read(file, (const char *)work_buff, size); // simple vars + scripts + buf += 0x40 + sizeof(int32) + sizeof(int32) + sizeof(float) * 3; + + int8 steam_byte; + ReadDataFromBufferPointer(buf, steam_byte); + + if (steam_byte == -3) + save_type |= SAVE_TYPE_STEAM; + LoadSaveDataBlockNoCheck(buf, file, size); // ped pool LoadSaveDataBlockNoCheck(buf, file, size); // garages @@ -758,6 +767,29 @@ GetSaveType(char *savename) } static void +FixSimpleVarsAndScripts(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size) +{ + uint8 *buf_start = buf; + uint8 *buf2_start = buf2; + uint32 read = *size; + uint32 written = *size - (sizeof(int8) + 3); + + uint32 pre_steam = 0x40 + sizeof(int32) + sizeof(int32) + sizeof(float) * 3; + uint32 post_steam = *size - (sizeof(int8) + 3) - pre_steam; + + CopyBuf(buf, buf2, pre_steam); + SkipBuf(buf, sizeof(int8) + 3); + CopyBuf(buf, buf2, post_steam); + + *size = 0; + + assert(buf - buf_start == read); + assert(buf2 - buf2_start == written); + + *size = written; +} + +static void FixGarages(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size) { // hardcoded: 7876 @@ -1018,7 +1050,7 @@ FixScriptPaths(uint8 save_type, uint8 *buf, uint8 *buf2, uint32 *size) bool FixSave(int32 slot, uint8 save_type) { - if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_MSVC) + if (save_type & SAVE_TYPE_32_BIT && save_type & SAVE_TYPE_MSVC && !(save_type & SAVE_TYPE_STEAM)) return true; bool success = false; @@ -1044,17 +1076,29 @@ FixSave(int32 slot, uint8 save_type) totalSize = 0; CFileMgr::Read(file_in, (const char *)&size, sizeof(size)); + size = align4bytes(size); buf = work_buff; CFileMgr::Read(file_in, (const char *)work_buff, size); // simple vars + scripts - WriteSavaDataBlockNoFunc(buf, file_out, size); + if (save_type & SAVE_TYPE_STEAM && save_type & SAVE_TYPE_MSVC && save_type & SAVE_TYPE_32_BIT) { + memset(work_buff2, 0, sizeof(work_buff2)); + buf2 = work_buff2; + FixSimpleVarsAndScripts(save_type, buf, buf2, &size); + if (!PcSaveHelper.PcClassSaveRoutine(file_out, work_buff2, size)) + goto fail; + totalSize += size; + } else + WriteSavaDataBlockNoFunc(buf, file_out, size); LoadSaveDataBlockNoCheck(buf, file_in, size); // ped pool WriteSavaDataBlockNoFunc(buf, file_out, size); LoadSaveDataBlockNoCheck(buf, file_in, size); // garages - FixSaveDataBlock(FixGarages, file_out, size); // garages need to be fixed in either case + if (!(save_type & SAVE_TYPE_STEAM && save_type & SAVE_TYPE_MSVC && save_type & SAVE_TYPE_32_BIT)) + FixSaveDataBlock(FixGarages, file_out, size); + else + WriteSavaDataBlockNoFunc(buf, file_out, size); LoadSaveDataBlockNoCheck(buf, file_in, size); // game logic WriteSavaDataBlockNoFunc(buf, file_out, size); @@ -1176,13 +1220,20 @@ void DisplaySaveResult(int unk, char* name) bool SaveGameForPause(int type) { - if (AllowMissionReplay != 0 || type != 3 && WaitForSave > CTimer::GetTimeInMilliseconds()) + if (AllowMissionReplay != MISSION_RETRY_STAGE_NORMAL && AllowMissionReplay != MISSION_RETRY_STAGE_WAIT_FOR_TIMER_AFTER_RESTART) { + debug("SaveGameForPause failed during AllowMissionReplay %d", AllowMissionReplay); return false; + } + if (type != SAVE_TYPE_QUICKSAVE_FOR_MISSION_REPLAY && WaitForSave > CTimer::GetTimeInMilliseconds()) { + debug("SaveGameForPause failed WaitForSave"); + return false; + } WaitForSave = 0; - if (gGameState != GS_PLAYING_GAME || CTheScripts::IsPlayerOnAMission() || CStats::LastMissionPassedName[0] == '\0') { + if (gGameState != GS_PLAYING_GAME || (CTheScripts::bAlreadyRunningAMissionScript && type != SAVE_TYPE_QUICKSAVE_FOR_SCRIPT_ON_A_MISSION)) { DisplaySaveResult(3, CStats::LastMissionPassedName); return false; } + debug("SaveGameForPause ******************************** %s doSave %d", CStats::LastMissionPassedName, !CTheScripts::bAlreadyRunningAMissionScript); IsQuickSave = type; MissionStartTime = 0; int res = PcSaveHelper.SaveSlot(PAUSE_SAVE_SLOT); |