diff Engine/SaveLoad.cpp @ 2565:117c219bf913

Party, items and stuff are abstracted from savegame file representation
author a.parshin
date Wed, 20 May 2015 15:12:33 +0200
parents 65c97624c047
children d87bfbd3bb3b
line wrap: on
line diff
--- a/Engine/SaveLoad.cpp	Wed May 20 00:56:07 2015 +0200
+++ b/Engine/SaveLoad.cpp	Wed May 20 15:12:33 2015 +0200
@@ -1,30 +1,31 @@
 #define _CRTDBG_MAP_ALLOC
+#define _CRT_SECURE_NO_WARNINGS
 #include <stdlib.h>
 #include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
 #include <io.h>
 #include <direct.h>
 
 #include "Engine/Engine.h"
-
-#include "ZlibWrapper.h"
-#include "SaveLoad.h"
-#include "Party.h"
-#include "LOD.h"
+#include "Engine/texts.h"
+#include "Engine/ZlibWrapper.h"
+#include "Engine/SaveLoad.h"
+#include "Engine/Party.h"
+#include "Engine/LOD.h"
+#include "Engine/Timer.h"
+#include "Engine/stru123.h"
 #include "Engine/Graphics/Outdoor.h"
-#include "Media/Audio/AudioPlayer.h"
+#include "Engine/Graphics/Overlays.h"
+#include "Engine/Graphics/Viewport.h"
+#include "Engine/Graphics/Level/Decoration.h"
 #include "Engine/Objects/Actor.h"
 #include "Engine/Objects/Chest.h"
-#include "Timer.h"
+#include "Engine/Objects/SpriteObject.h"
+#include "Engine/Serialization/LegacyImages.h"
+
 #include "GUI/GUIWindow.h"
 #include "GUI/GUIFont.h"
-#include "Engine/Graphics/Overlays.h"
-#include "Engine/Objects/SpriteObject.h"
-#include "Engine/Graphics/Viewport.h"
-#include "stru123.h"
-#include "texts.h"
-#include "Engine/Graphics/Level/Decoration.h"
+
+#include "Media/Audio/AudioPlayer.h"
 
 #include "MMT.h"
 
@@ -36,6 +37,8 @@
 std::array<struct RGBTexture, 45> pSavegameThumbnails;
 std::array<SavegameHeader, 45> pSavegameHeader;
 
+
+
 //----- (0045EE8A) --------------------------------------------------------
 void __fastcall LoadGame(unsigned int uSlot)
 {
@@ -94,51 +97,76 @@
   Assert(sizeof(SavegameHeader) == 100);
   fread(&header, sizeof(SavegameHeader), 1, file);
 
-  file = pNew_LOD->FindContainer("party.bin", 1);
-  if (!file)
   {
-    sprintf(Str, pGlobalTXT_LocalizationStrings[612], 101);//Сохраненная игра повреждена! Code=%d
-    Log::Warning(L"%S", Str);
-    MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:559", 0);
+      file = pNew_LOD->FindContainer("party.bin", 1);
+      if (!file)
+      {
+          sprintf(Str, pGlobalTXT_LocalizationStrings[612], 101);//Сохраненная игра повреждена! Code=%d
+          Log::Warning(L"%S", Str);
+          MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:559", 0);
+      }
+      else
+      {
+          Party_Image_MM7 serialization;
+          fread(&serialization, sizeof(serialization), 1, file);
+
+          serialization.Deserialize(pParty);
+      }
   }
-  if (sizeof(Party) != 0x16238)
-    Log::Warning(L"class Party: deserialization warning");
-  fread(pParty, sizeof(Party), 1, file);
 
+    {
+        file = pNew_LOD->FindContainer("clock.bin", 1);
+        if (!file)
+        {
+            sprintf(Str, pGlobalTXT_LocalizationStrings[612], 102);//Сохраненная игра повреждена! Code=%d
+            Log::Warning(L"%S", Str);
+            MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:569", 0);
+        }
+        else
+        {
+            Timer_Image_MM7 serialization;
+            fread(&serialization, sizeof(serialization), 1, file);
 
-  file = pNew_LOD->FindContainer("clock.bin", 1);
-  if (!file)
-  {
-    sprintf(Str, pGlobalTXT_LocalizationStrings[612], 102);//Сохраненная игра повреждена! Code=%d
-    Log::Warning(L"%S", Str);
-    MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:569", 0);
-  }
-  if (sizeof(Timer) != 0x28)
-    Log::Warning(L"class Timer: deserialization warning");
-  fread(pEventTimer, sizeof(Timer), 1, file);
+            serialization.Deserialize(pEventTimer);
+        }
+    }
 
-  file = pNew_LOD->FindContainer("overlay.bin", 1);
-  if (!file)
-  {
-    sprintf(Str, pGlobalTXT_LocalizationStrings[612], 103);//Сохраненная игра повреждена! Code=%d
-    Log::Warning(L"%S", Str);
-    MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:579", 0);
-  }
-  if (sizeof(OtherOverlayList) != 0x3F0)
-    Log::Warning(L"class OtherOverlayList: deserialization warning");
-  fread(pOtherOverlayList, sizeof(OtherOverlayList), 1, file);
+    {
+        file = pNew_LOD->FindContainer("overlay.bin", 1);
+        if (!file)
+        {
+            sprintf(Str, pGlobalTXT_LocalizationStrings[612], 103);//Сохраненная игра повреждена! Code=%d
+            Log::Warning(L"%S", Str);
+            MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:579", 0);
+        }
+        else
+        {
+            OtherOverlayList_Image_MM7 serialization;
+            fread(&serialization, sizeof(serialization), 1, file);
+
+            serialization.Deserialize(pOtherOverlayList);
+        }
+    }
 
-  file = pNew_LOD->FindContainer("npcdata.bin", 0);
-  if (!file)
-  {
-    sprintf(Str, pGlobalTXT_LocalizationStrings[612], 104);//Сохраненная игра повреждена! Code=%d
-    Log::Warning(L"%S", Str);
-    MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:590", 0);
-  }
-  if (sizeof(pNPCStats->pNewNPCData) != 0x94BC)
-    Log::Warning(L"NPCStats: deserialization warning");
-  fread(pNPCStats->pNewNPCData, sizeof(pNPCStats->pNewNPCData), 1, file);
-  pNPCStats->_476C60();
+    {
+        file = pNew_LOD->FindContainer("npcdata.bin", 0);
+        if (!file)
+        {
+            sprintf(Str, pGlobalTXT_LocalizationStrings[612], 104);//Сохраненная игра повреждена! Code=%d
+            Log::Warning(L"%S", Str);
+            MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:590", 0);
+        }
+        else
+        {
+            NPCData_Image_MM7 serialization[501];
+            fread(serialization, sizeof(serialization), 1, file);
+
+            for (unsigned int i = 0; i < 501; ++i)
+                serialization[i].Deserialize(pNPCStats->pNewNPCData + i);
+
+            pNPCStats->_476C60_on_load_game();
+        }
+    }
 
   file = pNew_LOD->FindContainer("npcgroup.bin", 0);
   if (!file)
@@ -219,121 +247,147 @@
 }
 
 //----- (0045F469) --------------------------------------------------------
-void SaveGame( bool IsAutoSAve, bool NotSaveWorld )
+void SaveGame(bool IsAutoSAve, bool NotSaveWorld)
 {
-  int text_pos; // eax@6
-  FILE *pLLoidFile; // edi@24
-  char* compressed_buf; // edi@30
-  char *data_write_pos; // esi@41
-  CHAR Buffer[128]; // [sp+Ch] [bp-264h]@59
-  char Dir[255]; // [sp+8Ch] [bp-1E4h]@51
-  char Drive[255]; // [sp+ACh] [bp-1C4h]@51
-  SavegameHeader save_header; // [sp+CCh] [bp-1A4h]@10
-  char Filename[255]; // [sp+130h] [bp-140h]@51
-  char Ext[255]; // [sp+150h] [bp-120h]@51
-  char Source[32]; // [sp+170h] [bp-100h]@51
-  char work_string[120]; // [sp+190h] [bp-E0h]@8
-  int pPositionY; // [sp+208h] [bp-68h]@2
-  int pPositionX; // [sp+20Ch] [bp-64h]@2
-  int sPRotationY; // [sp+210h] [bp-60h]@2
-  int sPRotationX; // [sp+214h] [bp-5Ch]@2
-  ODMHeader odm_data; // [sp+218h] [bp-58h]@30
-  int res; // [sp+224h] [bp-4Ch]@30
-  int pPositionZ; // [sp+228h] [bp-48h]@2
-  size_t Size; // [sp+250h] [bp-20h]@26
-  char *uncompressed_buff; // [sp+258h] [bp-18h]@2
-  unsigned int compressed_block_size; // [sp+260h] [bp-10h]@23
- 
-  //v66 = a2;
-  strcpy(byte_6BE3B0.data(), pCurrentMapName);//byte_6BE3B0 - save_map_name
-  if (!_stricmp(pCurrentMapName, "d05.blv")) // arena
-    return;
+    int text_pos; // eax@6
+    FILE *pLLoidFile; // edi@24
+    char* compressed_buf; // edi@30
+    char *data_write_pos; // esi@41
+    CHAR Buffer[128]; // [sp+Ch] [bp-264h]@59
+    char Dir[255]; // [sp+8Ch] [bp-1E4h]@51
+    char Drive[255]; // [sp+ACh] [bp-1C4h]@51
+    SavegameHeader save_header; // [sp+CCh] [bp-1A4h]@10
+    char Filename[255]; // [sp+130h] [bp-140h]@51
+    char Ext[255]; // [sp+150h] [bp-120h]@51
+    char Source[32]; // [sp+170h] [bp-100h]@51
+    char work_string[120]; // [sp+190h] [bp-E0h]@8
+    int pPositionY; // [sp+208h] [bp-68h]@2
+    int pPositionX; // [sp+20Ch] [bp-64h]@2
+    int sPRotationY; // [sp+210h] [bp-60h]@2
+    int sPRotationX; // [sp+214h] [bp-5Ch]@2
+    ODMHeader odm_data; // [sp+218h] [bp-58h]@30
+    int res; // [sp+224h] [bp-4Ch]@30
+    int pPositionZ; // [sp+228h] [bp-48h]@2
+    size_t Size; // [sp+250h] [bp-20h]@26
+    char *uncompressed_buff; // [sp+258h] [bp-18h]@2
+    unsigned int compressed_block_size; // [sp+260h] [bp-10h]@23
+
+    //v66 = a2;
+    strcpy(byte_6BE3B0.data(), pCurrentMapName);//byte_6BE3B0 - save_map_name
+    if (!_stricmp(pCurrentMapName, "d05.blv")) // arena
+        return;
+
+    uncompressed_buff = (char*)malloc(1000000);
 
-  uncompressed_buff = (char*)malloc(1000000);
+    LOD::Directory pLodDirectory; // [sp+22Ch] [bp-44h]@2
+    pPositionX = pParty->vPosition.x;
+    pPositionY = pParty->vPosition.y;
+    pPositionZ = pParty->vPosition.z;
+    sPRotationY = pParty->sRotationY;
+    sPRotationX = pParty->sRotationX;
+    pParty->vPosition.x = pParty->vPrevPosition.x;
+    pParty->vPosition.z = pParty->vPrevPosition.z;
+    pParty->vPosition.y = pParty->vPrevPosition.y;
 
-  LOD::Directory pLodDirectory; // [sp+22Ch] [bp-44h]@2
-  pPositionX = pParty->vPosition.x;
-  pPositionY = pParty->vPosition.y;
-  pPositionZ = pParty->vPosition.z;
-  sPRotationY = pParty->sRotationY;
-  sPRotationX = pParty->sRotationX;
-  pParty->vPosition.x = pParty->vPrevPosition.x;
-  pParty->vPosition.z = pParty->vPrevPosition.z;
-  pParty->vPosition.y = pParty->vPrevPosition.y;
+    pParty->uFallStartY = pParty->vPrevPosition.z;
 
-  pParty->uFallStartY = pParty->vPrevPosition.z;
+    pParty->sRotationY = pParty->sPrevRotationY;
+    pParty->sRotationX = pParty->sPrevRotationX;
+    if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+        pIndoor->stru1.uLastVisitDay = pParty->uTimePlayed;
+    else
+        pOutdoor->loc_time.uLastVisitDay = pParty->uTimePlayed;
+
+    pRenderer->PackScreenshot(150, 112, uncompressed_buff, 1000000, &pLodDirectory.uDataSize);//создание скриншота
+    strcpy(pLodDirectory.pFilename, "image.pcx");
 
-  pParty->sRotationY = pParty->sPrevRotationY;
-  pParty->sRotationX = pParty->sPrevRotationX;
-  if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
-    pIndoor->stru1.uLastVisitDay = pParty->uTimePlayed;
-  else
-    pOutdoor->loc_time.uLastVisitDay = pParty->uTimePlayed;
-
-  pRenderer->PackScreenshot(150, 112, uncompressed_buff, 1000000, &pLodDirectory.uDataSize);//создание скриншота
-  strcpy(pLodDirectory.pFilename, "image.pcx");
+    if (current_screen_type == SCREEN_SAVEGAME)
+    {
+        pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_loadsave));
+        pRenderer->DrawTextureIndexed(18, 141, pIcons_LOD->GetTexture(uTextureID_save_up));
+        text_pos = pFontSmallnum->AlignText_Center(186, pGlobalTXT_LocalizationStrings[190]);
+        pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, text_pos + 25, 219, 0, pGlobalTXT_LocalizationStrings[190], 0, 0, 0); //Сохранение
+        text_pos = pFontSmallnum->AlignText_Center(186, pSavegameHeader[uLoadGameUI_SelectedSlot].pName);
+        pGUIWindow_CurrentMenu->DrawTextInRect(pFontSmallnum, text_pos + 25, 259, 0, pSavegameHeader[uLoadGameUI_SelectedSlot].pName, 185, 0);
+        text_pos = pFontSmallnum->AlignText_Center(186, pGlobalTXT_LocalizationStrings[165]);
+        pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, text_pos + 25, 299, 0, pGlobalTXT_LocalizationStrings[165], 0, 0, 0); //Пожалуйста, подождите
+        pRenderer->Present();
+    }
 
-  if (current_screen_type == SCREEN_SAVEGAME)
-  {
-    pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->GetTexture(uTextureID_loadsave));
-    pRenderer->DrawTextureIndexed(18, 141, pIcons_LOD->GetTexture(uTextureID_save_up));
-    text_pos = pFontSmallnum->AlignText_Center(186, pGlobalTXT_LocalizationStrings[190]);
-    pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, text_pos + 25, 219, 0, pGlobalTXT_LocalizationStrings[190], 0, 0, 0); //Сохранение
-    text_pos  = pFontSmallnum->AlignText_Center(186, pSavegameHeader[uLoadGameUI_SelectedSlot].pName);
-    pGUIWindow_CurrentMenu->DrawTextInRect(pFontSmallnum, text_pos  + 25, 259, 0, pSavegameHeader[uLoadGameUI_SelectedSlot].pName, 185, 0);
-    text_pos  = pFontSmallnum->AlignText_Center(186, pGlobalTXT_LocalizationStrings[165]);
-    pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, text_pos  + 25, 299, 0, pGlobalTXT_LocalizationStrings[165], 0, 0, 0); //Пожалуйста, подождите
-    pRenderer->Present();
-  }
+    if (pNew_LOD->Write(&pLodDirectory, uncompressed_buff, 0))
+    {
+        sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 200); //Сохраненная игра повреждена! Code=%d
+        MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:773", 0);
+    }
 
-  if (pNew_LOD->Write(&pLodDirectory, uncompressed_buff, 0))
-  {
-    sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 200); //Сохраненная игра повреждена! Code=%d
-    MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:773", 0);
-  }
+    Assert(sizeof(SavegameHeader) == 100);
+    memset(save_header.pName, 0, 20);
+    memset(save_header.pLocationName, 0, 20);
+    memset(save_header.field_30, 0, 52);
+    strcpy(save_header.pLocationName, pCurrentMapName);
+    save_header.uWordTime = pParty->uTimePlayed;
+    strcpy(pLodDirectory.pFilename, "header.bin");
+    pLodDirectory.uDataSize = sizeof(SavegameHeader);
+    if (pNew_LOD->Write(&pLodDirectory, &save_header, 0))
+    {
+        sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 201);
+        MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:784", 0);
+    }
+
+
+    {
+        Party_Image_MM7 serialization;
+        serialization.Serialize(pParty);
+
+        pLodDirectory.uDataSize = sizeof(serialization);
+        strcpy(pLodDirectory.pFilename, "party.bin");
+        if (pNew_LOD->Write(&pLodDirectory, &serialization, 0))
+        {
+            sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 202);//Save game corrupted!  Code=%d
+            MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:793", 0);
+        }
+    }
 
-  Assert(sizeof(SavegameHeader) == 100);
-  memset(save_header.pName, 0, 20);
-  memset(save_header.pLocationName, 0, 20);
-  memset(save_header.field_30, 0, 52);
-  strcpy(save_header.pLocationName, pCurrentMapName);
-  save_header.uWordTime = pParty->uTimePlayed;
-  strcpy(pLodDirectory.pFilename, "header.bin");
-  pLodDirectory.uDataSize = sizeof(SavegameHeader);
-  if (pNew_LOD->Write(&pLodDirectory, &save_header, 0))
-  {
-    sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 201);
-    MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:784", 0);
-  }
-  strcpy(pLodDirectory.pFilename, "party.bin");
-  pLodDirectory.uDataSize = sizeof(Party); //90680;
-  if ( pNew_LOD->Write(&pLodDirectory, pParty, 0) )
-  {
-    sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 202);//Save game corrupted!  Code=%d
-    MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:793", 0);
-  }
-  strcpy(pLodDirectory.pFilename, "clock.bin");
-  pLodDirectory.uDataSize =sizeof(Timer);// 40;
-  if ( pNew_LOD->Write(&pLodDirectory, pEventTimer, 0) )
-  {
-    sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 203);
-    MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:802", 0);
-  }
-  strcpy(pLodDirectory.pFilename, "overlay.bin");
-  pLodDirectory.uDataSize =sizeof(OtherOverlayList);// 1008;
-  if ( pNew_LOD->Write(&pLodDirectory, pOtherOverlayList, 0) )
-  {
-    sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 204);
-    MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:811", 0);
-  }
-  strcpy(pLodDirectory.pFilename, "npcdata.bin");
-  pLodDirectory.uDataSize = 501 * sizeof(NPCData);
-  Assert(pLodDirectory.uDataSize == 38076);
-  if ( pNew_LOD->Write(&pLodDirectory, pNPCStats->pNewNPCData, 0) )
-  {
-    sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 205);
-    MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:820", 0);
-  }
+    {
+        Timer_Image_MM7 serialization;
+        serialization.Serialize(pEventTimer);
+
+        pLodDirectory.uDataSize = sizeof(serialization);
+        strcpy(pLodDirectory.pFilename, "clock.bin");
+        if (pNew_LOD->Write(&pLodDirectory, &serialization, 0))
+        {
+            sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 203);
+            MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:802", 0);
+        }
+    }
+
+    {
+        OtherOverlayList_Image_MM7 serialization;
+        serialization.Serialize(pOtherOverlayList);
+
+        pLodDirectory.uDataSize = sizeof(serialization);
+        strcpy(pLodDirectory.pFilename, "overlay.bin");
+        if (pNew_LOD->Write(&pLodDirectory, &serialization, 0))
+        {
+            sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 204);
+            MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:811", 0);
+        }
+    }
+
+    {
+        NPCData_Image_MM7 serialization[501];
+        for (unsigned int i = 0; i < 501; ++i)
+            serialization[i].Serialize(pNPCStats->pNewNPCData + i);
+
+        pLodDirectory.uDataSize = sizeof(serialization);
+        strcpy(pLodDirectory.pFilename, "npcdata.bin");
+        if (pNew_LOD->Write(&pLodDirectory, serialization, 0))
+        {
+            sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 205);
+            MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:820", 0);
+        }
+    }
+
   strcpy(pLodDirectory.pFilename, "npcgroup.bin");
   pLodDirectory.uDataSize = 102;
   if ( pNew_LOD->Write(&pLodDirectory, pNPCStats->pGroups_copy, 0) )
@@ -341,6 +395,7 @@
     sprintf(work_string, pGlobalTXT_LocalizationStrings[612], 206);
     MessageBoxA(nullptr, work_string, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:829", 0);
   }
+
   for (int i =  1; i <= 4; ++i) // 4 - players
   {
     for (int j =  1; j <= 5; ++j) // 5 - images
@@ -367,6 +422,7 @@
       }
 	}
   }
+
   if ( !NotSaveWorld )//autosave for change location
   {
     //__debugbreak();