World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
Файл SaveLoad.cpp

См. исходные тексты.

Функции

bool CopyFile (const String &from, const String &to)
 
void LoadGame (unsigned int uSlot)
 
void SaveGame (bool IsAutoSAve, bool NotSaveWorld)
 
void DoSavegame (unsigned int uSlot)
 
void SaveNewGame ()
 

Переменные

struct SavegameListpSavegameList = new SavegameList
 
unsigned int uNumSavegameFiles
 
std::array< unsigned int, MAX_SAVE_SLOTSpSavegameUsedSlots
 
std::array< Image *, MAX_SAVE_SLOTSpSavegameThumbnails
 
std::array< SavegameHeader, MAX_SAVE_SLOTSpSavegameHeader
 

Функции

◆ CopyFile()

bool CopyFile ( const String from,
const String to 
)

См. определение в файле SaveLoad.cpp строка 47

47  {
48  int file_size = -1;
49  int bytes_read = 0;
50  int bytes_wrote = 0;
51 
52  FILE *copy_from = fopen(from.c_str(), "rb");
53  if (copy_from) {
54  FILE *copy_to = fopen(to.c_str(), "wb+");
55  if (copy_to) {
56  fseek(copy_from, 0, SEEK_END);
57  file_size = ftell(copy_from);
58  fseek(copy_from, 0, SEEK_SET);
59 
60  unsigned char *buf = new unsigned char[file_size];
61  if (buf) {
62  bytes_read = fread(buf, 1, file_size, copy_from);
63  if (bytes_read == file_size) {
64  bytes_wrote = fwrite(buf, 1, file_size, copy_to);
65  }
66 
67  delete[] buf;
68  }
69  fclose(copy_to);
70  }
71  fclose(copy_from);
72  }
73 
74  return file_size != -1 && bytes_read == bytes_wrote;
75 }

Используется в DoSavegame(), LoadGame() и SaveGame().

+ Граф вызова функции:

◆ LoadGame()

void LoadGame ( unsigned int  uSlot)

См. определение в файле SaveLoad.cpp строка 77

77  {
79  if (!pSavegameUsedSlots[uSlot]) {
80  pAudioPlayer->PlaySound(SOUND_error, 0, 0, -1, 0, 0);
81  logger->Warning(L"LoadGame: slot %u is empty", uSlot);
82  return;
83  }
84 
86 
87  String filename = "saves\\" + pSavegameList->pFileList[uSlot];
88  filename = MakeDataPath(filename.c_str());
89  String to_file_path = MakeDataPath("data\\new.lod");
90  remove(to_file_path.c_str());
91  if (!CopyFile(filename, to_file_path)) {
92  Error("Failed to copy: %s", filename.c_str());
93  }
94 
95  pNew_LOD->LoadFile(to_file_path, 0);
96 
97  static_assert(sizeof(SavegameHeader) == 100, "Wrong type size");
98  SavegameHeader *header = (SavegameHeader*)pNew_LOD->LoadRaw("header.bin");
99  if (header == nullptr) {
100  logger->Warning(L"%S", localization->FormatString(612, 100).c_str()); // Savegame damaged! Code=%d
101  }
102 
103  {
104  Party_Image_MM7 *serialization = (Party_Image_MM7*)pNew_LOD->LoadRaw("party.bin");
105  if (serialization == nullptr) {
106  logger->Warning(L"%S", localization->FormatString(612, 101).c_str()); // Savegame damaged! Code=%d
107  } else {
108  serialization->Deserialize(pParty);
109  free(serialization);
110 
111  for (size_t i = 0; i < 4; i++) {
112  Player *player = &pParty->pPlayers[i];
113  for (size_t j = 0; j < 5; j++) {
114  if (j >= player->vBeacons.size()) {
115  continue;
116  }
117  LloydBeacon &beacon = player->vBeacons[j];
118  String str = StringPrintf("lloyd%d%d.pcx", i + 1, j + 1);
119  beacon.image = Image::Create(new PCX_LOD_File_Loader(pNew_LOD, str));
120  beacon.image->GetWidth();
121  }
122  }
123  }
124  }
125 
126  {
127  Timer_Image_MM7 *serialization = (Timer_Image_MM7*)pNew_LOD->LoadRaw("clock.bin");
128  if (serialization == nullptr) {
129  logger->Warning(L"%S", localization->FormatString(612, 102).c_str()); // Savegame damaged! Code=%d
130  } else {
131  serialization->Deserialize(pEventTimer);
132  free(serialization);
133  }
134  }
135 
136  {
137  OtherOverlayList_Image_MM7 *serialization = (OtherOverlayList_Image_MM7*)pNew_LOD->LoadRaw("overlay.bin");
138  if (serialization == nullptr) {
139  logger->Warning(L"%S", localization->FormatString(612, 103).c_str()); // Savegame damaged! Code=%d
140  } else {
141  serialization->Deserialize(pOtherOverlayList);
142  free(serialization);
143  }
144  }
145 
146  {
147  NPCData_Image_MM7 *serialization = (NPCData_Image_MM7*)pNew_LOD->LoadRaw("npcdata.bin");
148  if (serialization == nullptr) {
149  logger->Warning(L"%S", localization->FormatString(612, 104).c_str()); // Savegame damaged! Code=%d
150  } else {
151  for (unsigned int i = 0; i < 501; ++i) {
152  serialization[i].Deserialize(pNPCStats->pNewNPCData + i);
153  }
155  free(serialization);
156  }
157  }
158 
159  {
160  void *npcgroup = pNew_LOD->LoadRaw("npcgroup.bin");
161  if (npcgroup == nullptr) {
162  logger->Warning(L"%S", localization->FormatString(612, 105).c_str()); // Savegame damaged! Code=%d
163  __debugbreak();
164  } else if (sizeof(pNPCStats->pGroups_copy) != 102) {
165  logger->Warning(L"NPCStats: deserialization warning");
166  } else {
167  memcpy(pNPCStats->pGroups_copy, npcgroup, sizeof(pNPCStats->pGroups_copy));
168  }
169  free(npcgroup);
170  }
171 
172  uActiveCharacter = 0;
173  for (uint i = 0; i < 4; ++i) {
174  if (pParty->pPlayers[i].CanAct()) {
175  uActiveCharacter = i + 1;
176  break;
177  }
178  }
179 /*
180  for (uint i = 0; i < 4; ++i) {
181  if (pParty->pPlayers[i].uQuickSpell) {
182  AA1058_PartyQuickSpellSound[i].AddPartySpellSound(
183  pParty->pPlayers[i].uQuickSpell, i + 1);
184  }
185 
186  for (uint j = 0; j < 2; ++j) {
187  uint uEquipIdx = pParty->pPlayers[i].pEquipment.pIndices[j];
188  if (uEquipIdx) {
189  int pItemID = pParty->pPlayers[i]
190  .pInventoryItemList[uEquipIdx - 1]
191  .uItemID;
192  if (pItemsTable->pItems[pItemID].uEquipType == EQUIP_WAND &&
193  pItemID) { // жезл
194  __debugbreak(); // looks like offset in player's inventory
195  // and wand_lut much like case in 0042ECB5
196  stru_A750F8[i].AddPartySpellSound(
197  wand_spell_ids[pItemID - ITEM_WAND_FIRE], i + 9);
198  }
199  }
200  }
201  }
202 */
204 
205  viewparams->bRedrawGameUI = true;
206 
208 
209  pEventTimer->Resume();
211 
213  Error("Unable to find: %s!", header->pLocationName);
214  }
215 
216  pCurrentMapName = header->pLocationName;
217  free(header);
218 
219  dword_6BE364_game_settings_1 |= GAME_SETTINGS_2000 | GAME_SETTINGS_0001;
220 
221  for (uint i = 0; i < uNumSavegameFiles; ++i) {
222  if (pSavegameThumbnails[i] != nullptr) {
223  pSavegameThumbnails[i]->Release();
224  pSavegameThumbnails[i] = nullptr;
225  }
226  }
227 
228  pAudioPlayer->SetMusicVolume(engine->config->music_level);
229  pAudioPlayer->SetMasterVolume(engine->config->sound_level);
230  if (engine->config->turn_speed > 0) {
231  pParty->sRotationY = engine->config->turn_speed * pParty->sRotationY / engine->config->turn_speed;
232  }
234  bFlashQuestBook = false;
235  viewparams->bRedrawGameUI = true;
236 }

Перекрестные ссылки NPCStats::_476C60_on_load_game(), __debugbreak(), Party::alignment, bFlashQuestBook, ViewingParams::bRedrawGameUI, LOD::WriteableFile::CloseWriteFile(), CopyFile(), Image::Create(), current_screen_type, NPCData_Image_MM7::Deserialize(), Party_Image_MM7::Deserialize(), Timer_Image_MM7::Deserialize(), OtherOverlayList_Image_MM7::Deserialize(), LOD::File::DoesContainerExist(), dword_6BE364_game_settings_1, engine, Localization::FormatString(), Image::GetWidth(), LloydBeacon::image, LOD::WriteableFile::LoadFile(), LOD::File::LoadRaw(), localization, logger, MakeDataPath(), MapsLongTimers_count, MM7Initialization(), pAudioPlayer, pCurrentMapName, pEventTimer, SavegameList::pFileList, pGames_LOD, NPCStats::pGroups_copy, AudioPlayer::PlaySound(), SavegameHeader::pLocationName, pNew_LOD, NPCStats::pNewNPCData, pNPCStats, pOtherOverlayList, pParty, Party::pPlayers, pSavegameList, pSavegameThumbnails, pSavegameUsedSlots, Timer::Resume(), SCREEN_GAME, AudioPlayer::SetMasterVolume(), AudioPlayer::SetMusicVolume(), SetUserInterface(), SOUND_error, Party::sRotationY, Timer::StopGameTime(), StringPrintf(), uActiveCharacter, uNumSavegameFiles, Player::vBeacons, viewparams и Log::Warning().

Используется в Application::Menu::EventLoop() и Application::Game::GameLoop().

+ Граф вызовов:
+ Граф вызова функции:

◆ SaveGame()

void SaveGame ( bool  IsAutoSAve,
bool  NotSaveWorld 
)

См. определение в файле SaveLoad.cpp строка 238

238  {
240  if (pCurrentMapName == "d05.blv") { // arena
241  return;
242  }
243 
244  char *uncompressed_buff = (char *)malloc(1000000);
245 
246  int pPositionX = pParty->vPosition.x;
247  int pPositionY = pParty->vPosition.y;
248  int pPositionZ = pParty->vPosition.z;
249  int sPRotationY = pParty->sRotationY;
250  int sPRotationX = pParty->sRotationX;
254 
256 
261  else
263 
264  unsigned int buf_size = 0;
265  render->PackScreenshot(150, 112, uncompressed_buff, 1000000, &buf_size); // создание скриншота
266 
267  // saving - please wait
268 
269  // if (current_screen_type == SCREEN_SAVEGAME) {
270  // render->DrawTextureAlphaNew(8 / 640.0f, 8 / 480.0f,
271  // saveload_ui_loadsave);
272  // render->DrawTextureAlphaNew(18 / 640.0f, 141 / 480.0f,
273  // saveload_ui_loadsave);
274  // int text_pos = pFontSmallnum->AlignText_Center(186, localization->GetString(190));
275  // pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, text_pos + 25, 219, 0,
276  // localization->GetString(190), 0, 0,
277  // 0); // Сохранение
278  // text_pos = pFontSmallnum->AlignText_Center(
279  // 186, pSavegameHeader[uLoadGameUI_SelectedSlot].pName);
280  // pGUIWindow_CurrentMenu->DrawTextInRect(
281  // pFontSmallnum, text_pos + 25, 259, 0,
282  // pSavegameHeader[uLoadGameUI_SelectedSlot].pName, 185, 0);
283  // text_pos =
284  // pFontSmallnum->AlignText_Center(186, localization->GetString(165));
285  // pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, text_pos + 25, 299, 0,
286  // localization->GetString(165), 0, 0,
287  // 0); // Пожалуйста, подождите
288  // render->Present();
289  //}
290 
291  if (pNew_LOD->Write("image.pcx", uncompressed_buff, buf_size, 0)) {
292  auto error_message = localization->FormatString(612, 200); // Savegame damaged! Code=%d
293  logger->Warning(L"%S", error_message.c_str());
294  }
295 
296  static_assert(sizeof(SavegameHeader) == 100, "Wrong type size");
297  SavegameHeader save_header;
298  memset(save_header.pName, 0, 20);
299  memset(save_header.pLocationName, 0, 20);
300  memset(save_header.field_30, 0, 52);
301  strcpy(save_header.pLocationName, pCurrentMapName.c_str());
302  save_header.playing_time = pParty->GetPlayingTime();
303  if (pNew_LOD->Write("header.bin", &save_header, sizeof(SavegameHeader), 0)) {
304  auto error_message = localization->FormatString(612, 201);
305  logger->Warning(L"%S", error_message.c_str());
306  }
307 
308  {
309  Party_Image_MM7 serialization;
310  serialization.Serialize(pParty);
311 
312  if (pNew_LOD->Write("party.bin", &serialization, sizeof(serialization), 0)) {
313  auto error_message = localization->FormatString(612, 202);
314  logger->Warning(L"%S", error_message.c_str());
315  }
316  }
317 
318  {
319  Timer_Image_MM7 serialization;
320  serialization.Serialize(pEventTimer);
321 
322  if (pNew_LOD->Write("clock.bin", &serialization, sizeof(serialization), 0)) {
323  auto error_message = localization->FormatString(612, 203);
324  logger->Warning(L"%S", error_message.c_str());
325  }
326  }
327 
328  {
329  OtherOverlayList_Image_MM7 serialization;
330  serialization.Serialize(pOtherOverlayList);
331 
332  if (pNew_LOD->Write("overlay.bin", &serialization, sizeof(serialization), 0)) {
333  auto error_message = localization->FormatString(612, 204);
334  logger->Warning(L"%S", error_message.c_str());
335  }
336  }
337 
338  {
339  NPCData_Image_MM7 serialization[501];
340  for (unsigned int i = 0; i < 501; ++i) {
341  serialization[i].Serialize(pNPCStats->pNewNPCData + i);
342  }
343 
344  if (pNew_LOD->Write("npcdata.bin", serialization, sizeof(serialization), 0)) {
345  auto error_message = localization->FormatString(612, 205);
346  logger->Warning(L"%S", error_message.c_str());
347  }
348  }
349 
350  if (pNew_LOD->Write("npcgroup.bin", pNPCStats->pGroups_copy, sizeof(pNPCStats->pGroups_copy), 0)) {
351  auto error_message = localization->FormatString(612, 206);
352  logger->Warning(L"%S", error_message.c_str());
353  }
354 
355  for (size_t i = 0; i < 4; ++i) { // 4 - players
356  Player *player = &pParty->pPlayers[i];
357  for (size_t j = 0; j < 5; ++j) { // 5 - images
358  if (j >= player->vBeacons.size()) {
359  continue;
360  }
361  LloydBeacon *beacon = &player->vBeacons[j];
362  Image *image = beacon->image;
363  if ((beacon->uBeaconTime != 0) && (image != nullptr)) {
364  const void *pixels = image->GetPixels(IMAGE_FORMAT_R5G6B5);
365  unsigned int pcx_data_size = 30000;
366  void *pcx_data = malloc(pcx_data_size);
367  PCX::Encode16(pixels, image->GetWidth(), image->GetHeight(),
368  pcx_data, pcx_data_size, &pcx_data_size);
369  String str = StringPrintf("lloyd%d%d.pcx", i + 1, j + 1);
370  if (pNew_LOD->Write(str, pcx_data, pcx_data_size, 0)) {
371  auto error_message = localization->FormatString(612, 207);
372  logger->Warning(L"%S", error_message.c_str());
373  }
374  free(pcx_data);
375  }
376  }
377  }
378 
379  if (!NotSaveWorld) { // autosave for change location
381  char *compressed_buf = (char *)malloc(1000000);
382  if (compressed_buf == nullptr) {
383  logger->Warning(L"Malloc error");
384  Error("Malloc"); // is this recoverable
385  }
386  ODMHeader *odm_data = (ODMHeader*)compressed_buf;
387  odm_data->uVersion = 91969;
388  odm_data->pMagic[0] = 'm';
389  odm_data->pMagic[1] = 'v';
390  odm_data->pMagic[2] = 'i';
391  odm_data->pMagic[3] = 'i';
392  odm_data->uCompressedSize = 0;
393  odm_data->uDecompressedSize = 0;
394 
395  char *data_write_pos = uncompressed_buff;
398  pIndoor->dlv.uNumBModels = 0;
400  memcpy(data_write_pos, &pIndoor->dlv, sizeof(DDM_DLV_Header)); // 0x28
401  data_write_pos += sizeof(DDM_DLV_Header);
402  memcpy(data_write_pos, pIndoor->_visible_outlines, 0x36B);
403  data_write_pos += 875;
404  for (int i = 0; i < (signed int)pIndoor->uNumFaces; ++i) {
405  memcpy(data_write_pos, &pIndoor->pFaces[i].uAttributes, 4);
406  data_write_pos += 4;
407  }
408 
409  for (int i = 0; i < (signed int)uNumLevelDecorations; ++i) {
410  memcpy(data_write_pos, &pLevelDecorations[i].uFlags, 2);
411  data_write_pos += 2;
412  }
413  memcpy(data_write_pos, &uNumActors, 4);
414  data_write_pos += 4;
415  memcpy(data_write_pos, &pActors, uNumActors * sizeof(Actor));
416  data_write_pos += uNumActors * sizeof(Actor);
417  memcpy(data_write_pos, &uNumSpriteObjects, 4);
418  data_write_pos += 4;
419  memcpy(data_write_pos, pSpriteObjects.data(),
420  112 * uNumSpriteObjects);
421  data_write_pos += 112 * uNumSpriteObjects;
422 
423  data_write_pos = ChestsSerialize(data_write_pos);
424 
425  memcpy(data_write_pos, pIndoor->pDoors, sizeof(BLVDoor) * 200);
426  data_write_pos += 16000;
427  memcpy(data_write_pos, pIndoor->ptr_0002B4_doors_ddata,
429  data_write_pos += pIndoor->blv.uDoors_ddata_Size;
430  memcpy(data_write_pos, &stru_5E4C90_MapPersistVars, 0xC8);
431  data_write_pos += 200;
432  memcpy(data_write_pos, &pIndoor->stru1, 0x38);
433  data_write_pos += 56;
434 
435  } else { // for Outdoor
437  for (BSPModel &model : pOutdoor->pBModels) {
438  pOutdoor->ddm.uNumFacesInBModels += model.pFaces.size();
439  }
442  memcpy(data_write_pos, &pOutdoor->ddm,
443  sizeof(DDM_DLV_Header)); // 0x28
444  data_write_pos += sizeof(DDM_DLV_Header);
445  memcpy(data_write_pos, pOutdoor->uFullyRevealedCellOnMap, 0x3C8);
446  data_write_pos += 968;
447  memcpy(data_write_pos, pOutdoor->uPartiallyRevealedCellOnMap,
448  0x3C8);
449  data_write_pos += 968;
450  for (BSPModel &model : pOutdoor->pBModels) {
451  for (ODMFace &face : model.pFaces) {
452  memcpy(data_write_pos, &(face.uAttributes), 4);
453  data_write_pos += 4;
454  }
455  }
456 
457  for (size_t i = 0; i < uNumLevelDecorations; ++i) {
458  memcpy(data_write_pos, &pLevelDecorations[i].uFlags, 2);
459  data_write_pos += 2;
460  }
461  memcpy(data_write_pos, &uNumActors, 4);
462  data_write_pos += 4;
463  memcpy(data_write_pos, &pActors, uNumActors * sizeof(Actor));
464  data_write_pos += uNumActors * sizeof(Actor);
465  memcpy(data_write_pos, &uNumSpriteObjects, 4);
466  data_write_pos += 4;
467  memcpy(data_write_pos, &pSpriteObjects,
468  uNumSpriteObjects * sizeof(SpriteObject));
469  data_write_pos += uNumSpriteObjects * sizeof(SpriteObject);
470 
471  data_write_pos = ChestsSerialize(data_write_pos);
472 
473  memcpy(data_write_pos, &stru_5E4C90_MapPersistVars, 0xC8);
474  data_write_pos += 200;
475  memcpy(data_write_pos, &pOutdoor->loc_time, 0x38);
476  data_write_pos += 56;
477  }
478 
479  unsigned int compressed_block_size = 1000000 - sizeof(ODMHeader);
480  size_t Size = data_write_pos - uncompressed_buff;
481  int res = zlib::Compress(compressed_buf + sizeof(ODMHeader), &compressed_block_size, uncompressed_buff, Size);
482  if (res || (compressed_block_size > Size)) {
483  memcpy((void *)(compressed_buf + sizeof(ODMHeader)), uncompressed_buff, Size);
484  compressed_block_size = Size;
485  }
486 
487  odm_data->uCompressedSize = compressed_block_size;
488  odm_data->uDecompressedSize = Size;
489 
490  String file_name = pCurrentMapName;
491  size_t pos = file_name.find_last_of(".");
492  file_name[pos + 1] = 'd';
493  if (pNew_LOD->Write(file_name, compressed_buf, compressed_block_size + sizeof(ODMHeader), 0)) {
494  auto error_message = localization->FormatString(612, 208);
495  logger->Warning(L"%S", error_message.c_str());
496  }
497  free(compressed_buf);
498  }
499  free(uncompressed_buff);
500  if (IsAutoSAve) {
501  if (!CopyFile(MakeDataPath("data\\new.lod"),
502  MakeDataPath("saves\\autosave.mm7"))) {
503  logger->Warning(L"Copy autosave.mm7 failed");
504  }
505  }
506  pParty->vPosition.x = pPositionX;
507  pParty->vPosition.y = pPositionY;
508  pParty->vPosition.z = pPositionZ;
509  pParty->uFallStartY = pPositionZ;
510  pParty->sRotationY = sPRotationY;
511  pParty->sRotationX = sPRotationX;
512 }

Перекрестные ссылки IndoorLocation::_visible_outlines, IndoorLocation::blv, ChestsSerialize(), CompactLayingItemsList(), zlib::Compress(), CopyFile(), OutdoorLocation::ddm, IndoorLocation::dlv, PCX::Encode16(), SavegameHeader::field_30, Localization::FormatString(), Image::GetPixels(), Party::GetPlayingTime(), LloydBeacon::image, IMAGE_FORMAT_R5G6B5, LocationTime_stru1::last_visit, LEVEL_Indoor, OutdoorLocation::loc_time, localization, logger, MakeDataPath(), pActors, OutdoorLocation::pBModels, pCurrentMapName, IndoorLocation::pDoors, pEventTimer, BSPModel::pFaces, IndoorLocation::pFaces, NPCStats::pGroups_copy, pIndoor, SavegameHeader::playing_time, pLevelDecorations, SavegameHeader::pLocationName, ODMHeader::pMagic, SavegameHeader::pName, pNew_LOD, NPCStats::pNewNPCData, pNPCStats, pOtherOverlayList, pOutdoor, pParty, Party::pPlayers, pSpriteObjects, IndoorLocation::ptr_0002B4_doors_ddata, render, s_SavedMapName, NPCData_Image_MM7::Serialize(), Party_Image_MM7::Serialize(), Timer_Image_MM7::Serialize(), OtherOverlayList_Image_MM7::Serialize(), Party::sPrevRotationX, Party::sPrevRotationY, Party::sRotationX, Party::sRotationY, StringPrintf(), IndoorLocation::stru1, stru_5E4C90_MapPersistVars, BLVFace::uAttributes, LloydBeacon::uBeaconTime, ODMHeader::uCompressedSize, uCurrentlyLoadedLevelType, ODMHeader::uDecompressedSize, BLVHeader::uDoors_ddata_Size, Party::uFallStartY, OutdoorLocation::uFullyRevealedCellOnMap, uNumActors, DDM_DLV_Header::uNumBModels, DDM_DLV_Header::uNumDecorations, IndoorLocation::uNumFaces, DDM_DLV_Header::uNumFacesInBModels, uNumLevelDecorations, uNumSpriteObjects, OutdoorLocation::uPartiallyRevealedCellOnMap, ODMHeader::uVersion, Player::vBeacons, Party::vPosition, Party::vPrevPosition, Log::Warning() и LOD::WriteableFile::Write().

Используется в DoSavegame(), Application::Game::EventLoop(), Application::Game::GameLoop(), SaveNewGame(), Transition_StopSound_Autosave() и TravelByTransport().

+ Граф вызовов:
+ Граф вызова функции:

◆ DoSavegame()

void DoSavegame ( unsigned int  uSlot)

См. определение в файле SaveLoad.cpp строка 514

514  {
515  if (pCurrentMapName != "d05.blv") { // Not Arena(не Арена)
516  SaveGame(0, 0);
517  strcpy(pSavegameHeader[uSlot].pLocationName, pCurrentMapName.c_str());
518  pSavegameHeader[uSlot].playing_time = pParty->GetPlayingTime();
519  pNew_LOD->Write("header.bin", &pSavegameHeader[uSlot], sizeof(SavegameHeader), 0);
520  pNew_LOD->CloseWriteFile(); //закрыть
521  String file_path = StringPrintf("saves\\save%03d.mm7", uSlot);
522  file_path = MakeDataPath(file_path.c_str());
523  CopyFile(MakeDataPath("data\\new.lod"), file_path);
524  }
528 
529  viewparams->bRedrawGameUI = true;
530  for (uint i = 0; i < MAX_SAVE_SLOTS; i++) {
531  if (pSavegameThumbnails[i] != nullptr) {
532  pSavegameThumbnails[i]->Release();
533  pSavegameThumbnails[i] = nullptr;
534  }
535  }
536 
537  if (pCurrentMapName != "d05.blv")
538  pNew_LOD->_4621A7();
539  else
540  GameUI_StatusBar_OnEvent(localization->GetString(583), 2); // "No saving in the Arena"
541 
542  pEventTimer->Resume();
543  GameUI_StatusBar_OnEvent(localization->GetString(656), 2); // "Game Saved!"
544  viewparams->bRedrawGameUI = true;
545 }

Перекрестные ссылки LOD::WriteableFile::_4621A7(), ViewingParams::bRedrawGameUI, LOD::WriteableFile::CloseWriteFile(), CopyFile(), current_screen_type, GameUI_StatusBar_OnEvent(), Party::GetPlayingTime(), Localization::GetString(), GUI_UpdateWindows(), localization, MakeDataPath(), MAX_SAVE_SLOTS, pCurrentMapName, pEventTimer, pGUIWindow_CurrentMenu, pNew_LOD, pParty, pSavegameHeader, pSavegameThumbnails, GUIWindow::Release(), Timer::Resume(), SaveGame(), SCREEN_GAME, StringPrintf(), viewparams и LOD::WriteableFile::Write().

Используется в Application::Menu::EventLoop().

+ Граф вызовов:
+ Граф вызова функции:

◆ SaveNewGame()

void SaveNewGame ( )

См. определение в файле SaveLoad.cpp строка 566

566  {
567  if (pNew_LOD != nullptr) {
569  }
570 
571  String file_path = MakeDataPath("data\\new.lod");
572  remove(file_path.c_str()); // удалить new.lod
573 
574  LOD::FileHeader header; // заголовок
575  strcpy(header.LodVersion, "MMVII");
576  strcpy(header.LodDescription, "newmaps for MMVII");
577  header.LODSize = 100;
578  header.dword_0000A8 = 0;
579 
580  pNew_LOD->CreateNewLod(&header, "current", file_path); // создаётся new.lod в дирректории
581  if (pNew_LOD->LoadFile(file_path, false)) { // загрузить файл new.lod(isFileOpened = true)
582  pNew_LOD->CreateTempFile(); // создаётся временный файл OutputFileHandle
584 
585  for (size_t i = pGames_LOD->GetSubNodesCount() / 2; i < pGames_LOD->GetSubNodesCount(); ++i) { // копирование файлов с 76 по 151
587  size_t size = 0;
588  void *data = pGames_LOD->LoadRaw(name, &size);
590  free(data);
591  }
592 
593  strcpy(pSavegameHeader[0].pLocationName, "out01.odm");
594  pNew_LOD->AppendDirectory("header.bin", &pSavegameHeader[0], sizeof(SavegameHeader));
595 
597 
598  pParty->vPrevPosition.x = 12552;
599  pParty->vPrevPosition.y = 1816;
600  pParty->vPrevPosition.z = 0;
601 
602  pParty->vPosition.x = 12552;
603  pParty->vPosition.y = 1816;
604  pParty->vPosition.z = 0;
605 
606  pParty->uFallStartY = 0;
607 
608  pParty->sPrevRotationX = 0;
609  pParty->sPrevRotationY = 512;
610 
611  pParty->sRotationX = 0;
612  pParty->sRotationY = 512;
613 
614  SaveGame(1, 1);
615  }
616 }

Перекрестные ссылки LOD::WriteableFile::AppendDirectory(), LOD::WriteableFile::ClearSubNodes(), LOD::WriteableFile::CloseWriteFile(), LOD::WriteableFile::CreateNewLod(), LOD::WriteableFile::CreateTempFile(), LOD::FileHeader::dword_0000A8, LOD::WriteableFile::FixDirectoryOffsets(), LOD::File::GetSubNodeName(), LOD::File::GetSubNodesCount(), LOD::WriteableFile::LoadFile(), LOD::File::LoadRaw(), LOD::FileHeader::LodDescription, LOD::FileHeader::LODSize, LOD::FileHeader::LodVersion, MakeDataPath(), pGames_LOD, pNew_LOD, pParty, pSavegameHeader, SaveGame(), Party::sPrevRotationX, Party::sPrevRotationY, Party::sRotationX, Party::sRotationY, Party::uFallStartY, Party::vPosition и Party::vPrevPosition.

Используется в Application::Game::Loop().

+ Граф вызовов:
+ Граф вызова функции:

Переменные

◆ pSavegameList

struct SavegameList* pSavegameList = new SavegameList

См. определение в файле SaveLoad.cpp строка 41

Используется в GUIWindow_Load::GUIWindow_Load(), GUIWindow_Save::GUIWindow_Save(), SavegameList::Initialize() и LoadGame().

◆ uNumSavegameFiles

unsigned int uNumSavegameFiles

См. определение в файле SaveLoad.cpp строка 42

Используется в GUIWindow_Load::GUIWindow_Load(), SavegameList::Initialize(), LoadGame() и UI_DrawSaveLoad().

◆ pSavegameUsedSlots

std::array<unsigned int, MAX_SAVE_SLOTS> pSavegameUsedSlots

◆ pSavegameThumbnails

std::array<Image *, MAX_SAVE_SLOTS> pSavegameThumbnails

См. определение в файле SaveLoad.cpp строка 44

Используется в DoSavegame(), GUIWindow_Load::GUIWindow_Load(), GUIWindow_Save::GUIWindow_Save(), LoadGame() и UI_DrawSaveLoad().

◆ pSavegameHeader

SpriteObject
Definition: SpriteObject.h:189
Player
Definition: Player.h:401
uNumActors
size_t uNumActors
Definition: Actor.cpp:39
Party::vPosition
Vec3_int_ vPosition
Definition: Party.h:250
face
GLenum GLuint GLint GLenum face
Definition: SDL_opengl_glext.h:3022
pNew_LOD
LOD::WriteableFile * pNew_LOD
Definition: LOD.cpp:24
LOD::WriteableFile::FixDirectoryOffsets
int FixDirectoryOffsets()
Definition: LOD.cpp:452
AudioPlayer::SetMasterVolume
void SetMasterVolume(int level)
Definition: AudioPlayer.cpp:183
Localization::GetString
const char * GetString(unsigned int index) const
Definition: Localization.cpp:13
pLevelDecorations
std::array< LevelDecoration, 3000 > pLevelDecorations
Definition: Decoration.cpp:8
LOD::WriteableFile::LoadFile
bool LoadFile(const String &pFilename, bool bWriting)
Definition: LOD.cpp:686
LOD::File::GetSubNodesCount
size_t GetSubNodesCount() const
Definition: LOD.h:72
SetUserInterface
void SetUserInterface(PartyAlignment align, bool bReplace)
Definition: GUIWindow.cpp:1032
Party::GetPlayingTime
GameTime & GetPlayingTime()
Definition: Party.h:230
AudioPlayer::SetMusicVolume
void SetMusicVolume(int music_level)
Definition: AudioPlayer.cpp:165
OtherOverlayList_Image_MM7::Serialize
void Serialize(struct OtherOverlayList *)
Definition: LegacyImages.cpp:169
LOD::FileHeader::LodDescription
char LodDescription[80]
Definition: LOD.h:36
Timer::Resume
void Resume()
Definition: Time.cpp:27
OutdoorLocation::pBModels
BSPModelList pBModels
Definition: Outdoor.h:119
pSpriteObjects
std::array< SpriteObject, MAX_SPRITE_OBJECTS > pSpriteObjects
Definition: SpriteObject.cpp:34
PCX::Encode16
void Encode16(const void *picture_data, unsigned int width, unsigned int height, void *pcx_data, int max_buff_size, unsigned int *packed_size)
Definition: PCX.cpp:297
Party::sPrevRotationX
int sPrevRotationX
Definition: Party.h:255
OutdoorLocation::uFullyRevealedCellOnMap
unsigned char uFullyRevealedCellOnMap[88][11]
Definition: Outdoor.h:134
Party::sRotationX
int sRotationX
Definition: Party.h:252
pGUIWindow_CurrentMenu
GUIWindow * pGUIWindow_CurrentMenu
Definition: GUIWindow.cpp:54
zlib::Compress
int Compress(void *dest, unsigned int *destLen, void *source, unsigned int sourceLen)
Definition: ZlibWrapper.cpp:11
Actor
Definition: Actor.h:151
AudioPlayer::PlaySound
void PlaySound(SoundID eSoundID, int pid, unsigned int uNumRepeats, int x, int y, int a7)
Definition: AudioPlayer.cpp:195
IndoorLocation::stru1
LocationTime_stru1 stru1
Definition: Indoor.h:649
engine
std::shared_ptr< Engine > engine
Definition: Engine.cpp:130
LOD::WriteableFile::_4621A7
bool _4621A7()
Definition: LOD.cpp:446
SOUND_error
@ SOUND_error
Definition: AudioPlayer.h:19
NPCStats::pGroups_copy
uint16_t pGroups_copy[51]
Definition: NPC.h:177
LOD::File::DoesContainerExist
bool DoesContainerExist(const String &filename)
Definition: LOD.cpp:833
localization
Localization * localization
Definition: Localization.cpp:11
SavegameHeader::pLocationName
char pLocationName[20]
Definition: SaveLoad.h:20
pSavegameUsedSlots
std::array< unsigned int, MAX_SAVE_SLOTS > pSavegameUsedSlots
Definition: SaveLoad.cpp:43
Party::pPlayers
std::array< Player, 4 > pPlayers
Definition: Party.h:310
uNumSavegameFiles
unsigned int uNumSavegameFiles
Definition: SaveLoad.cpp:42
GUIWindow::Release
virtual void Release()
Definition: GUIWindow.cpp:292
LOD::FileHeader::LODSize
uint32_t LODSize
Definition: LOD.h:37
LOD::WriteableFile::CloseWriteFile
void CloseWriteFile()
Definition: LOD.cpp:530
BLVHeader::uDoors_ddata_Size
unsigned int uDoors_ddata_Size
Definition: Indoor.h:333
pIndoor
IndoorLocation * pIndoor
Definition: Indoor.cpp:49
current_screen_type
enum CURRENT_SCREEN current_screen_type
Definition: GUIWindow.cpp:83
OtherOverlayList_Image_MM7
Definition: LegacyImages.h:547
Party_Image_MM7::Serialize
void Serialize(struct Party *)
Definition: LegacyImages.cpp:261
Party::uFallStartY
int uFallStartY
Definition: Party.h:265
ODMHeader::uCompressedSize
uint32_t uCompressedSize
Definition: Outdoor.h:16
OutdoorLocation::uPartiallyRevealedCellOnMap
unsigned char uPartiallyRevealedCellOnMap[88][11]
Definition: Outdoor.h:138
Image::GetWidth
unsigned int GetWidth()
Definition: Image.cpp:217
OtherOverlayList_Image_MM7::Deserialize
void Deserialize(struct OtherOverlayList *)
Definition: LegacyImages.cpp:191
LOD::WriteableFile::CreateNewLod
int CreateNewLod(LOD::FileHeader *pHeader, const String &root_name, const String &Source)
Definition: LOD.cpp:257
pParty
Party * pParty
Definition: Party.cpp:30
Image
Definition: Image.h:19
ODMHeader::pMagic
char pMagic[4]
Definition: Outdoor.h:15
DDM_DLV_Header::uNumFacesInBModels
unsigned int uNumFacesInBModels
Definition: Indoor.h:98
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: SDL_opengl_glext.h:2483
Party::vPrevPosition
Vec3_int_ vPrevPosition
Definition: Party.h:253
LOD::FileHeader::LodVersion
char LodVersion[80]
Definition: LOD.h:35
NPCStats::pNewNPCData
NPCData pNewNPCData[501]
Definition: NPC.h:165
LocationTime_stru1::last_visit
GameTime last_visit
Definition: Indoor.h:274
OutdoorLocation::loc_time
LocationTime_stru1 loc_time
Definition: Outdoor.h:132
viewparams
struct ViewingParams * viewparams
Definition: mm7_data.cpp:22
NPCData_Image_MM7::Deserialize
void Deserialize(struct NPCData *item)
Definition: LegacyImages.cpp:147
MM7Initialization
void MM7Initialization()
Definition: Engine.cpp:1287
BLVDoor
Definition: Indoor.h:378
IndoorLocation::blv
struct BLVHeader blv
Definition: Indoor.h:626
IMAGE_FORMAT_R5G6B5
@ IMAGE_FORMAT_R5G6B5
Definition: Image.h:5
IndoorLocation::dlv
struct DDM_DLV_Header dlv
Definition: Indoor.h:648
Log::Warning
void Warning(const wchar_t *pFormat,...)
Definition: Log.cpp:28
ODMHeader
Definition: Outdoor.h:13
DDM_DLV_Header::uNumDecorations
unsigned int uNumDecorations
Definition: Indoor.h:99
pActors
std::array< Actor, 500 > pActors
Definition: Actor.cpp:38
ChestsSerialize
char * ChestsSerialize(char *pData)
Definition: Chest.cpp:486
pSavegameThumbnails
std::array< Image *, MAX_SAVE_SLOTS > pSavegameThumbnails
Definition: SaveLoad.cpp:44
LOD::FileHeader::dword_0000A8
uint32_t dword_0000A8
Definition: LOD.h:38
LOD::WriteableFile::CreateTempFile
int CreateTempFile()
Definition: LOD.cpp:518
PCX_LOD_File_Loader
Definition: ImageLoader.h:94
uNumLevelDecorations
size_t uNumLevelDecorations
Definition: Decoration.cpp:9
GUI_UpdateWindows
void GUI_UpdateWindows()
Definition: GUIWindow.cpp:956
MapsLongTimers_count
int MapsLongTimers_count
Definition: mm7_data.cpp:630
DDM_DLV_Header
Definition: Indoor.h:82
NPCData_Image_MM7
Definition: LegacyImages.h:87
Timer_Image_MM7
Definition: LegacyImages.h:511
IndoorLocation::uNumFaces
unsigned int uNumFaces
Definition: Indoor.h:629
IndoorLocation::_visible_outlines
char _visible_outlines[875]
Definition: Indoor.h:650
bFlashQuestBook
char bFlashQuestBook
Definition: mm7_data.cpp:549
pGames_LOD
LOD::File * pGames_LOD
Definition: LOD.cpp:25
pCurrentMapName
String pCurrentMapName
Definition: mm7_data.cpp:712
LOD::WriteableFile::Write
unsigned int Write(const String &file_name, const void *pDirData, size_t size, int a4)
Definition: LOD.cpp:544
Party::sPrevRotationY
int sPrevRotationY
Definition: Party.h:254
Party_Image_MM7
Definition: LegacyImages.h:410
NPCStats::_476C60_on_load_game
void _476C60_on_load_game()
Definition: NPC.cpp:273
NPCData_Image_MM7::Serialize
void Serialize(struct NPCData *item)
Definition: LegacyImages.cpp:123
OutdoorLocation::ddm
struct DDM_DLV_Header ddm
Definition: Outdoor.h:131
Timer::StopGameTime
void StopGameTime()
Definition: Time.cpp:45
LEVEL_Indoor
@ LEVEL_Indoor
Definition: Indoor.h:286
s_SavedMapName
std::string s_SavedMapName
Definition: mm7_data.cpp:719
MAX_SAVE_SLOTS
constexpr unsigned int MAX_SAVE_SLOTS
Definition: SaveLoad.h:33
CURRENT_SCREEN::SCREEN_GAME
@ SCREEN_GAME
Timer_Image_MM7::Serialize
void Serialize(struct Timer *)
Definition: LegacyImages.cpp:95
ODMHeader::uDecompressedSize
uint32_t uDecompressedSize
Definition: Outdoor.h:17
Party_Image_MM7::Deserialize
void Deserialize(struct Party *)
Definition: LegacyImages.cpp:428
uNumSpriteObjects
size_t uNumSpriteObjects
Definition: SpriteObject.cpp:33
SavegameHeader::playing_time
GameTime playing_time
Definition: SaveLoad.h:21
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
pOtherOverlayList
struct OtherOverlayList * pOtherOverlayList
Definition: Overlays.cpp:19
name
EGLImageKHR EGLint * name
Definition: SDL_egl.h:1497
IndoorLocation::ptr_0002B4_doors_ddata
uint16_t * ptr_0002B4_doors_ddata
Definition: Indoor.h:644
MakeDataPath
std::string MakeDataPath(const char *file_rel_path)
Definition: Engine.cpp:126
Image::Create
static Image * Create(unsigned int width, unsigned int height, IMAGE_FORMAT format, const void *pixels=nullptr)
Definition: Image.cpp:243
Player::vBeacons
std::vector< LloydBeacon > vBeacons
Definition: Player.h:794
LloydBeacon::image
Image * image
Definition: Player.h:279
SavegameHeader::field_30
char field_30[52]
Definition: SaveLoad.h:22
uint
unsigned int uint
Definition: MM7.h:4
uActiveCharacter
unsigned int uActiveCharacter
Definition: mm7_data.cpp:555
Localization::FormatString
String FormatString(unsigned int index,...) const
Definition: Localization.cpp:17
LOD::WriteableFile::AppendDirectory
bool AppendDirectory(const String &file_name, const void *pData, size_t data_size)
Definition: LOD.cpp:506
__debugbreak
void __cdecl __debugbreak(void)
pNPCStats
struct NPCStats * pNPCStats
Definition: NPC.cpp:29
BSPModel::pFaces
std::vector< ODMFace > pFaces
Definition: BSPModel.h:190
GameUI_StatusBar_OnEvent
void GameUI_StatusBar_OnEvent(const String &str, unsigned int num_seconds)
Definition: UIStatusBar.cpp:33
ODMFace
Definition: BSPModel.h:93
LOD::WriteableFile::ClearSubNodes
void ClearSubNodes()
Definition: LOD.h:112
Image::GetPixels
const void * GetPixels(IMAGE_FORMAT format)
Definition: Image.cpp:270
SavegameHeader::pName
char pName[20]
Definition: SaveLoad.h:19
ViewingParams::bRedrawGameUI
int bRedrawGameUI
Definition: Viewport.h:74
LOD::File::GetSubNodeName
String GetSubNodeName(size_t index) const
Definition: LOD.h:71
dword_6BE364_game_settings_1
int dword_6BE364_game_settings_1
Definition: mm7_data.cpp:714
uCurrentlyLoadedLevelType
LEVEL_TYPE uCurrentlyLoadedLevelType
Definition: Indoor.cpp:52
IndoorLocation::pFaces
struct BLVFace * pFaces
Definition: Indoor.h:630
SavegameHeader
Definition: SaveLoad.h:18
CopyFile
bool CopyFile(const String &from, const String &to)
Definition: SaveLoad.cpp:47
LloydBeacon
Definition: Player.h:254
pAudioPlayer
AudioPlayer * pAudioPlayer
Definition: AudioPlayer.cpp:20
BSPModel
Definition: BSPModel.h:163
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:540
logger
Log * logger
Definition: IocContainer.cpp:47
stru_5E4C90_MapPersistVars
stru123 stru_5E4C90_MapPersistVars
Definition: mm7_data.cpp:23
res
GLuint res
Definition: SDL_opengl_glext.h:7940
pOutdoor
OutdoorLocation * pOutdoor
Definition: Outdoor.cpp:48
DDM_DLV_Header::uNumBModels
unsigned int uNumBModels
Definition: Indoor.h:100
LOD::FileHeader
Definition: LOD.h:22
LloydBeacon::uBeaconTime
GameTime uBeaconTime
Definition: Player.h:271
image
EGLImageKHR image
Definition: SDL_egl.h:953
StringPrintf
String StringPrintf(const char *fmt,...)
Definition: Strings.cpp:9
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
Party::sRotationY
int sRotationY
Definition: Party.h:251
SavegameList::pFileList
std::array< String, 45 > pFileList
Definition: SaveLoad.h:13
LOD::File::LoadRaw
void * LoadRaw(const String &pContainer, size_t *data_size=nullptr)
Definition: LOD.cpp:895
IndoorLocation::pDoors
struct BLVDoor * pDoors
Definition: Indoor.h:638
String
std::string String
Definition: Strings.h:10
pEventTimer
Timer * pEventTimer
Definition: Time.cpp:8
BLVFace::uAttributes
unsigned int uAttributes
Definition: Indoor.h:475
ODMHeader::uVersion
uint32_t uVersion
Definition: Outdoor.h:14
CompactLayingItemsList
void CompactLayingItemsList()
Definition: SpriteObject.cpp:882
SaveGame
void SaveGame(bool IsAutoSAve, bool NotSaveWorld)
Definition: SaveLoad.cpp:238
pSavegameList
struct SavegameList * pSavegameList
Definition: SaveLoad.cpp:41
Party::alignment
PartyAlignment alignment
Definition: Party.h:308
Timer_Image_MM7::Deserialize
void Deserialize(struct Timer *)
Definition: LegacyImages.cpp:110
render
std::shared_ptr< IRender > render
Definition: RenderOpenGL.cpp:52
pSavegameHeader
std::array< SavegameHeader, MAX_SAVE_SLOTS > pSavegameHeader
Definition: SaveLoad.cpp:45