# HG changeset patch # User Ritor1 # Date 1390244361 -21600 # Node ID daa61976637daf842129ef30400ee355c220c238 # Parent 56aa61b54785e4bde46d895da78cb9ee36ba9604 savegame and loadgame continue diff -r 56aa61b54785 -r daa61976637d Build/Visual Studio 2012/World of Might and Magic.vcxproj.user --- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj.user Mon Jan 20 17:25:01 2014 +0600 +++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj.user Tue Jan 21 00:59:21 2014 +0600 @@ -4,6 +4,6 @@ $(OutDir)$(TargetName)$(TargetExt) $(OutDir) WindowsLocalDebugger - -novideo -nomarg + -novideo, -nomarg \ No newline at end of file diff -r 56aa61b54785 -r daa61976637d Indoor.cpp --- a/Indoor.cpp Mon Jan 20 17:25:01 2014 +0600 +++ b/Indoor.cpp Tue Jan 21 00:59:21 2014 +0600 @@ -2041,7 +2041,7 @@ pGameLoadingUI_ProgressBar->Progress(); memcpy(&uNumActors, pData, 4); - memcpy(pActors.data(), pData + 4, uNumActors * sizeof(Actor)); + memcpy(&pActors, pData + 4, uNumActors * sizeof(Actor)); pData += 4 + uNumActors * sizeof(Actor); pGameLoadingUI_ProgressBar->Progress(); diff -r 56aa61b54785 -r daa61976637d LOD.cpp --- a/LOD.cpp Mon Jan 20 17:25:01 2014 +0600 +++ b/LOD.cpp Tue Jan 21 00:59:21 2014 +0600 @@ -1648,12 +1648,14 @@ //replace old file by new with added data strcpy(NewFilename, pLODName); fclose(tmp_file); - CloseWriteFile(); + CloseWriteFile(); //isFileOpened == false, current file remove(NewFilename); rename(Filename, NewFilename); CloseWriteFile(); //reload new - LoadFile(pLODName, 0); + LoadFile(pLODName, 0);//isFileOpened == true, next file + if (isFileOpened == false) + __debugbreak(); return 0; } diff -r 56aa61b54785 -r daa61976637d SaveLoad.cpp --- a/SaveLoad.cpp Mon Jan 20 17:25:01 2014 +0600 +++ b/SaveLoad.cpp Tue Jan 21 00:59:21 2014 +0600 @@ -79,7 +79,7 @@ break; } - for (uint j = 0; j < pSoundList->sNumSounds; ++j) + for (uint j = 0; j < pSoundList->sNumSounds; ++j) if (pSoundList->pSL_Sounds[j].uSoundID == 2 * (SoundSetAction[24][0] + 50 * pParty->pPlayers[i].uVoiceID) + 4999) { pSoundList->UnloadSound(j, 1); @@ -94,72 +94,72 @@ int e = GetLastError(); pNew_LOD->LoadFile("data\\new.lod", 0); - FILE *f = pNew_LOD->FindContainer("header.bin", 1); - if (!f) + FILE *file = pNew_LOD->FindContainer("header.bin", 1); + if (!file) { - sprintf(Str, pGlobalTXT_LocalizationStrings[612], 100); + sprintf(Str, pGlobalTXT_LocalizationStrings[612], 100);//Сохраненная игра повреждена! Code=%d Log::Warning(L"%S", Str); MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:549", 0); } Assert(sizeof(SavegameHeader) == 100); - fread(&header, sizeof(SavegameHeader), 1, f); + fread(&header, sizeof(SavegameHeader), 1, file); - f = pNew_LOD->FindContainer("party.bin", 1); - if (!f) + file = pNew_LOD->FindContainer("party.bin", 1); + if (!file) { - sprintf(Str, pGlobalTXT_LocalizationStrings[612], 101); + 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); } if (sizeof(Party) != 0x16238) Log::Warning(L"class Party: deserialization warning"); - fread(pParty, 0x16238u, 1, f); + fread(pParty, sizeof(Party), 1, file); - f = pNew_LOD->FindContainer("clock.bin", 1); - if (!f) + file = pNew_LOD->FindContainer("clock.bin", 1); + if (!file) { - sprintf(Str, pGlobalTXT_LocalizationStrings[612], 102); + 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, 0x28u, 1u, f); + fread(pEventTimer, sizeof(Timer), 1, file); - f = pNew_LOD->FindContainer("overlay.bin", 1); - if (!f) + file = pNew_LOD->FindContainer("overlay.bin", 1); + if (!file) { - sprintf(Str, pGlobalTXT_LocalizationStrings[612], 103); + 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, 0x3F0, 1, f); + fread(pOtherOverlayList, sizeof(OtherOverlayList), 1, file); - f = pNew_LOD->FindContainer("npcdata.bin", 0); - if (!f) + file = pNew_LOD->FindContainer("npcdata.bin", 0); + if (!file) { - sprintf(Str, pGlobalTXT_LocalizationStrings[612], 104); + 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, 0x94BC, 1, f); + fread(pNPCStats->pNewNPCData, sizeof(pNPCStats->pNewNPCData), 1, file); pNPCStats->_476C60(); - f = pNew_LOD->FindContainer("npcgroup.bin", 0); - if (!f) + file = pNew_LOD->FindContainer("npcgroup.bin", 0); + if (!file) { - sprintf(Str, pGlobalTXT_LocalizationStrings[612], 105); + sprintf(Str, pGlobalTXT_LocalizationStrings[612], 105);//Сохраненная игра повреждена! Code=%d Log::Warning(L"%S", Str); MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:600", 0); } if (sizeof(pNPCStats->pGroups_copy) != 0x66) Log::Warning(L"NPCStats: deserialization warning"); - fread(pNPCStats->pGroups_copy, 0x66, 1, f); + fread(pNPCStats->pGroups_copy, sizeof(pNPCStats->pGroups_copy), 1, file); uActiveCharacter = 0; @@ -182,7 +182,7 @@ if (uEquipIdx) { int uItemID = pParty->pPlayers[i].pInventoryItemList[uEquipIdx - 1].uItemID; - if (pItemsTable->pItems[uItemID].uEquipType == 12) + if (pItemsTable->pItems[uItemID].uEquipType == EQUIP_WAND)//жезл { __debugbreak(); // looks like offset in player's inventory and wand_lut much like case in 0042ECB5 v31 = *((int *)&pSpellDatas[66].uNormalLevelRecovery + uItemID); @@ -192,7 +192,6 @@ } } - pGUIWindow_CurrentMenu->Release(); pCurrentScreen = SCREEN_GAME; @@ -254,7 +253,7 @@ unsigned int compressed_block_size; // [sp+260h] [bp-10h]@23 //v66 = a2; - strcpy(byte_6BE3B0.data(), pCurrentMapName); + strcpy(byte_6BE3B0.data(), pCurrentMapName);//byte_6BE3B0 - save_map_name if (!_stricmp(pCurrentMapName, "d05.blv")) // arena return; @@ -414,8 +413,8 @@ } memcpy(data_write_pos, &uNumActors, 4); data_write_pos += 4; - memcpy(data_write_pos, pActors.data(), 836 * uNumActors); - data_write_pos += 836 * uNumActors; + memcpy(data_write_pos, &pActors, uNumActors * sizeof(Actor)); + data_write_pos += uNumActors * sizeof(Actor); memcpy(data_write_pos, &uNumSpriteObjects, 4); data_write_pos += 4; memcpy(data_write_pos, pSpriteObjects.data(), 112 * uNumSpriteObjects); @@ -553,17 +552,17 @@ pGUIWindow_CurrentMenu->Release(); pCurrentScreen = SCREEN_GAME; //v3 = pSavegameThumbnails; - viewparams->bRedrawGameUI = 1; + viewparams->bRedrawGameUI = true; for (uint i = 0; i < 45; i++) pSavegameThumbnails[i].Release(); if ( bNotArena ) pNew_LOD->_4621A7(); else - ShowStatusBarString(pGlobalTXT_LocalizationStrings[583], 2u);// "No saving in the Arena" + ShowStatusBarString(pGlobalTXT_LocalizationStrings[583], 2);// "No saving in the Arena" pIcons_LOD->RemoveTexturesFromTextureList(); pEventTimer->Resume(); - ShowStatusBarString(pGlobalTXT_LocalizationStrings[656], 2u);// "Game Saved!" + ShowStatusBarString(pGlobalTXT_LocalizationStrings[656], 2);// "Game Saved!" viewparams->bRedrawGameUI = true; } // 4E28F8: using guessed type int pCurrentScreen; diff -r 56aa61b54785 -r daa61976637d mm7_2.cpp --- a/mm7_2.cpp Mon Jan 20 17:25:01 2014 +0600 +++ b/mm7_2.cpp Tue Jan 21 00:59:21 2014 +0600 @@ -1060,108 +1060,108 @@ v56 = 1; switch (spawn->uIndex - 1) { - case 0u: - v9 = pMapInfo->uEncounterMonster1AtLeast; - v10 = rand(); - v11 = pMapInfo->uEncounterMonster1AtMost; - pTexture = pMapInfo->pEncounterMonster1Texture; - v12 = v10 % (v11 - v9 + 1); - v13 = pMapInfo->Dif_M1; - v57 = v13; - v56 = v9 + v12; - strcpy(Source, pTexture); + case 0: + //v9 = pMapInfo->uEncounterMonster1AtLeast; + //v10 = rand(); + //v11 = pMapInfo->uEncounterMonster1AtMost; + //pTexture = pMapInfo->pEncounterMonster1Texture; + v12 = rand() % (pMapInfo->uEncounterMonster1AtMost - pMapInfo->uEncounterMonster1AtLeast + 1); + //v13 = pMapInfo->Dif_M1; + v57 = pMapInfo->Dif_M1; + v56 = pMapInfo->uEncounterMonster1AtLeast + v12; + strcpy(Source, pMapInfo->pEncounterMonster1Texture); break; - case 3u: - pTexture = pMapInfo->pEncounterMonster1Texture; - v44 = "%s A"; - sprintf(Source, v44, pTexture); + case 3: + //pTexture = pMapInfo->pEncounterMonster1Texture; + //v44 = "%s A"; + sprintf(Source, "%s A", pMapInfo->pEncounterMonster1Texture); break; - case 4u: - pTexture = pMapInfo->pEncounterMonster2Texture; - v44 = "%s A"; - sprintf(Source, v44, pTexture); + case 4: + //pTexture = pMapInfo->pEncounterMonster2Texture; + //v44 = "%s A"; + sprintf(Source, "%s A", pMapInfo->pEncounterMonster2Texture); break; - case 5u: - pTexture = pMapInfo->pEncounterMonster3Texture; - v44 = "%s A"; - sprintf(Source, v44, pTexture); + case 5: + //pTexture = pMapInfo->pEncounterMonster3Texture; + //v44 = "%s A"; + sprintf(Source, "%s A", pMapInfo->pEncounterMonster3Texture); break; - case 1u: - v9 = pMapInfo->uEncounterMonster2AtLeast; - v14 = rand(); - v15 = pMapInfo->uEncounterMonster2AtMost; - pTexture = pMapInfo->pEncounterMonster2Texture; - v12 = v14 % (v15 - v9 + 1); - v13 = pMapInfo->Dif_M2; - v57 = v13; - v56 = v9 + v12; - strcpy(Source, pTexture); + case 1: + //v9 = pMapInfo->uEncounterMonster2AtLeast; + //v14 = rand(); + //v15 = pMapInfo->uEncounterMonster2AtMost; + //pTexture = pMapInfo->pEncounterMonster2Texture; + v12 = rand() % (pMapInfo->uEncounterMonster2AtMost - pMapInfo->uEncounterMonster2AtLeast + 1); + //v13 = pMapInfo->Dif_M2; + v57 = pMapInfo->Dif_M2; + v56 = pMapInfo->uEncounterMonster2AtLeast + v12; + strcpy(Source, pMapInfo->pEncounterMonster2Texture); break; - case 6u: - pTexture = pMapInfo->pEncounterMonster1Texture; - v44 = "%s B"; - sprintf(Source, v44, pTexture); + case 6: + //pTexture = pMapInfo->pEncounterMonster1Texture; + //v44 = "%s B"; + sprintf(Source, "%s B", pMapInfo->pEncounterMonster1Texture); break; - case 7u: - pTexture = pMapInfo->pEncounterMonster2Texture; - v44 = "%s B"; - sprintf(Source, v44, pTexture); + case 7: + //pTexture = pMapInfo->pEncounterMonster2Texture; + //v44 = "%s B"; + sprintf(Source, "%s B", pMapInfo->pEncounterMonster2Texture); break; - case 8u: - pTexture = pMapInfo->pEncounterMonster3Texture; - v44 = "%s B"; - sprintf(Source, v44, pTexture); + case 8: + //pTexture = pMapInfo->pEncounterMonster3Texture; + //v44 = "%s B"; + sprintf(Source, "%s B", pMapInfo->pEncounterMonster3Texture); break; - case 2u: - v9 = pMapInfo->uEncounterMonster3AtLeast; - v16 = rand(); - v17 = pMapInfo->uEncounterMonster3AtMost; - pTexture = pMapInfo->pEncounterMonster3Texture; - v12 = v16 % (v17 - v9 + 1); - v13 = pMapInfo->Dif_M3; - v57 = v13; - v56 = v9 + v12; - strcpy(Source, pTexture); + case 2: + //v9 = pMapInfo->uEncounterMonster3AtLeast; + //v16 = rand(); + //v17 = pMapInfo->uEncounterMonster3AtMost; + //pTexture = pMapInfo->pEncounterMonster3Texture; + v12 = rand() % (pMapInfo->uEncounterMonster3AtMost - pMapInfo->uEncounterMonster3AtLeast + 1); + //v13 = pMapInfo->Dif_M3; + v57 = pMapInfo->Dif_M3; + v56 = pMapInfo->uEncounterMonster3AtLeast + v12; + strcpy(Source, pMapInfo->pEncounterMonster3Texture); break; - case 9u: - pTexture = pMapInfo->pEncounterMonster1Texture; - v44 = "%s C"; - sprintf(Source, v44, pTexture); + case 9: + //pTexture = pMapInfo->pEncounterMonster1Texture; + //v44 = "%s C"; + sprintf(Source, "%s C", pMapInfo->pEncounterMonster1Texture); break; - case 0xAu: - pTexture = pMapInfo->pEncounterMonster2Texture; - v44 = "%s C"; - sprintf(Source, v44, pTexture); + case 10: + //pTexture = pMapInfo->pEncounterMonster2Texture; + //v44 = "%s C"; + sprintf(Source, "%s C", pMapInfo->pEncounterMonster2Texture); break; - case 0xBu: - pTexture = pMapInfo->pEncounterMonster3Texture; - v44 = "%s C"; - sprintf(Source, v44, pTexture); + case 11: + //pTexture = pMapInfo->pEncounterMonster3Texture; + //v44 = "%s C"; + sprintf(Source, "%s C", pMapInfo->pEncounterMonster3Texture); break; - default: + default: return; } - if (Source[0] == '0') - return; - v57 += a3; - if ( v57 > 4 ) - v57 = 4; - strcpy(Str2, Source); - if ( a4 ) - v56 = a4; - v18 = v56; - if ( (signed int)(v56 + uNumActors) >= 500 ) - return; - pSector = 0; - pPosX = spawn->vPosition.x; - a4 = spawn->vPosition.y; - a3 = spawn->vPosition.z; - if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) - pSector = pIndoor->GetSector(spawn->vPosition.x, spawn->vPosition.y, spawn->vPosition.z); - v53 = 0; - v52 = (((uCurrentlyLoadedLevelType != LEVEL_Outdoor) - 1) & 0x40) + 64; - if ( v18 <= 0 ) - return; + if (Source[0] == '0') + return; + v57 += a3; + if ( v57 > 4 ) + v57 = 4; + strcpy(Str2, Source); + if ( a4 ) + v56 = a4; + v18 = v56; + if ( (signed int)(v56 + uNumActors) >= 500 ) + return; + pSector = 0; + pPosX = spawn->vPosition.x; + a4 = spawn->vPosition.y; + a3 = spawn->vPosition.z; + if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) + pSector = pIndoor->GetSector(spawn->vPosition.x, spawn->vPosition.y, spawn->vPosition.z); + v53 = 0; + v52 = (((uCurrentlyLoadedLevelType != LEVEL_Outdoor) - 1) & 0x40) + 64; + if ( v18 <= 0 ) + return; for (uint i = v53; i < v56; ++i) { pMonster = &pActors[uNumActors]; @@ -1236,16 +1236,10 @@ pMonster->PrepareSprites((char)pTexture); pMonster->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; v32 = rand(); - v33 = v32 % 2048; - v34 = stru_5C6E00->Cos(v32 % 2048); - a4 = v34; - a3 = (unsigned __int64)(v34 * (signed __int64)v52) >> 16; + a3 = fixpoint_mul(stru_5C6E00->Cos(v32 % 2048), v52); pPosX = a3 + spawn->vPosition.x; - v35 = stru_5C6E00->Sin(v33); - a4 = v35; - a3 = (unsigned __int64)(v35 * (signed __int64)v52) >> 16; + a3 = fixpoint_mul(stru_5C6E00->Sin(v32 % 2048), v52); a4 = a3 + spawn->vPosition.y; - v36 = spawn->vPosition.z; a3 = spawn->vPosition.z; if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor ) { @@ -1254,7 +1248,7 @@ ++uNumActors; continue; } - v37 = pIndoor->GetSector(pPosX, a4, v36); + v37 = pIndoor->GetSector(pPosX, a4, spawn->vPosition.z); if ( v37 == pSector ) { v38 = BLV_GetFloorLevel(pPosX, a4, a3, v37, &uFaceID); @@ -4149,7 +4143,7 @@ bool debug_information = false; bool show_picked_face = false; bool draw_debug_line = false; -bool new_speed = false; +bool new_speed = true; int max_flight_height = 4000;