Browse Source

Add detail log info to CompareSaves

pull/5174/head
obligaron 4 years ago committed by Anders Jenbo
parent
commit
2c7e886c85
  1. 2
      Source/engine/demomode.cpp
  2. 285
      Source/pfile.cpp
  3. 3
      Source/pfile.h
  4. 14
      test/Fixtures.cmake
  5. 3
      test/fixtures/memory_map/additionalMissiles.txt
  6. 55
      test/fixtures/memory_map/game.txt
  7. 49
      test/fixtures/memory_map/hero.txt
  8. 75
      test/fixtures/memory_map/item.txt
  9. 10
      test/fixtures/memory_map/itemPack.txt
  10. 19
      test/fixtures/memory_map/level.txt
  11. 2
      test/fixtures/memory_map/levelSeed.txt
  12. 13
      test/fixtures/memory_map/lightning.txt
  13. 45
      test/fixtures/memory_map/missile.txt
  14. 76
      test/fixtures/memory_map/monster.txt
  15. 32
      test/fixtures/memory_map/object.txt
  16. 178
      test/fixtures/memory_map/player.txt
  17. 6
      test/fixtures/memory_map/portal.txt
  18. 21
      test/fixtures/memory_map/quest.txt
  19. 2
      test/timedemo_test.cpp

2
Source/engine/demomode.cpp

@ -279,7 +279,7 @@ void NotifyGameLoopEnd()
gbRunGameResult = false;
gbRunGame = false;
HeroCompareResult compareResult = pfile_compare_hero_demo(DemoNumber);
HeroCompareResult compareResult = pfile_compare_hero_demo(DemoNumber, false);
switch (compareResult.status) {
case HeroCompareResult::ReferenceNotFound:
SDL_Log("Timedemo: No final comparision cause reference is not present.");

285
Source/pfile.cpp

@ -5,12 +5,15 @@
*/
#include "pfile.h"
#include <sstream>
#include <string>
#include <unordered_map>
#include <fmt/compile.h>
#include "codec.h"
#include "engine.h"
#include "engine/load_file.hpp"
#include "init.h"
#include "loadsave.h"
#include "menu.h"
@ -188,55 +191,263 @@ bool ArchiveContainsGame(MpqArchive &hsArchive)
return IsHeaderValid(hdr);
}
HeroCompareResult CompareSaves(const std::string &actualSavePath, const std::string &referenceSavePath)
class MemoryBuffer : public std::basic_streambuf<char> {
public:
MemoryBuffer(char *data, size_t byteCount)
{
setg(data, data, data + byteCount);
setp(data, data + byteCount);
}
};
struct CompareInfo {
std::unique_ptr<byte[]> &data;
size_t currentPosition;
size_t size;
bool isTownLevel;
bool dataExists;
};
struct CompareCounter {
int reference;
int actual;
int max()
{
return std::max(reference, actual);
}
void checkIfDataExists(int count, CompareInfo &compareInfoReference, CompareInfo &compareInfoActual)
{
if (reference == count)
compareInfoReference.dataExists = false;
if (actual == count)
compareInfoActual.dataExists = false;
}
};
inline bool string_ends_with(std::string const &value, std::string const &ending)
{
if (ending.size() > value.size())
return false;
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}
void CreateDetailDiffs(string_view prefix, string_view memoryMapFile, CompareInfo &compareInfoReference, CompareInfo &compareInfoActual, std::unordered_map<std::string, size_t> &foundDiffs)
{
std::vector<std::string> possibleFileNamesToCheck;
possibleFileNamesToCheck.emplace_back("hero");
possibleFileNamesToCheck.emplace_back("game");
possibleFileNamesToCheck.emplace_back("additionalMissiles");
// Note: Detail diffs are currently only supported in unit tests
std::string memoryMapFileAssetName = StrCat(paths::BasePath(), "/test/fixtures/memory_map/", memoryMapFile, ".txt");
SDL_RWops *handle = SDL_RWFromFile(memoryMapFileAssetName.c_str(), "r");
if (handle == nullptr) {
app_fatal(StrCat("MemoryMapFile ", memoryMapFile, " is missing"));
return;
}
size_t readBytes = SDL_RWsize(handle);
std::unique_ptr<byte[]> memoryMapFileData { new byte[readBytes] };
SDL_RWread(handle, memoryMapFileData.get(), readBytes, 1);
MemoryBuffer buffer(reinterpret_cast<char *>(memoryMapFileData.get()), readBytes);
std::istream reader(&buffer);
std::unordered_map<std::string, CompareCounter> counter;
auto getCounter = [&](const std::string &counterAsString) {
auto it = counter.find(counterAsString);
if (it != counter.end())
return it->second;
int countFromMapFile = std::stoi(counterAsString);
return CompareCounter { countFromMapFile, countFromMapFile };
};
auto addDiff = [&](const std::string &diffKey) {
auto it = foundDiffs.find(diffKey);
if (it == foundDiffs.end()) {
foundDiffs.insert_or_assign(diffKey, 1);
} else {
foundDiffs.insert_or_assign(diffKey, it->second + 1);
}
};
auto compareBytes = [&](size_t countBytes) {
if (compareInfoReference.dataExists && compareInfoReference.currentPosition + countBytes > compareInfoReference.size)
app_fatal(StrCat("Comparsion failed. Too less bytes in reference to compare. Location: ", prefix));
if (compareInfoActual.dataExists && compareInfoActual.currentPosition + countBytes > compareInfoActual.size)
app_fatal(StrCat("Comparsion failed. Too less bytes in actual to compare. Location: ", prefix));
bool result = true;
if (compareInfoReference.dataExists && compareInfoActual.dataExists)
result = memcmp(compareInfoReference.data.get() + compareInfoReference.currentPosition, compareInfoActual.data.get() + compareInfoActual.currentPosition, countBytes) == 0;
if (compareInfoReference.dataExists)
compareInfoReference.currentPosition += countBytes;
if (compareInfoActual.dataExists)
compareInfoActual.currentPosition += countBytes;
return result;
};
auto read32BitInt = [&](CompareInfo &compareInfo, bool useLE) {
int32_t value = 0;
if (!compareInfo.dataExists)
return value;
if (compareInfo.currentPosition + sizeof(value) > compareInfo.size)
app_fatal("read32BitInt failed. Too less bytes to read.");
memcpy(&value, compareInfo.data.get() + compareInfo.currentPosition, sizeof(value));
if (useLE)
value = SDL_SwapLE32(value);
else
value = SDL_SwapBE32(value);
return value;
};
std::string line;
while (std::getline(reader, line)) {
if (line.size() > 0 && line[line.size() - 1] == '\r')
line.resize(line.size() - 1);
if (line.size() == 0)
continue;
std::stringstream lineStream(line);
std::string command;
std::getline(lineStream, command, ' ');
bool dataExistsReference = compareInfoReference.dataExists;
bool dataExistsActual = compareInfoActual.dataExists;
if (string_ends_with(command, "_HF")) {
if (!gbIsHellfire)
continue;
command.resize(command.size() - 3);
}
if (string_ends_with(command, "_DA")) {
if (gbIsHellfire)
continue;
command.resize(command.size() - 3);
}
if (string_ends_with(command, "_DL")) {
if (compareInfoReference.isTownLevel && compareInfoActual.isTownLevel)
continue;
if (compareInfoReference.isTownLevel)
compareInfoReference.dataExists = false;
if (compareInfoActual.isTownLevel)
compareInfoActual.dataExists = false;
command.resize(command.size() - 3);
}
if (command == "R" || command == "LT" || command == "LC" || command == "LC_LE") {
std::string bitsAsString;
std::getline(lineStream, bitsAsString, ' ');
std::string comment;
std::getline(lineStream, comment);
size_t bytes = static_cast<size_t>(std::stoi(bitsAsString) / 8);
if (command == "LT") {
int32_t valueReference = read32BitInt(compareInfoReference, false);
int32_t valueActual = read32BitInt(compareInfoActual, false);
assert(sizeof(valueReference) == bytes);
compareInfoReference.isTownLevel = valueReference == 0;
compareInfoActual.isTownLevel = valueActual == 0;
}
if (command == "LC" || command == "LC_LE") {
int32_t valueReference = read32BitInt(compareInfoReference, command == "LC_LE");
int32_t valueActual = read32BitInt(compareInfoActual, command == "LC_LE");
assert(sizeof(valueReference) == bytes);
counter.insert_or_assign(comment, CompareCounter { valueReference, valueActual });
}
if (!compareBytes(bytes)) {
std::string diffKey = StrCat(prefix, ".", comment);
addDiff(diffKey);
}
} else if (command == "M") {
std::string countAsString;
std::getline(lineStream, countAsString, ' ');
std::string bitsAsString;
std::getline(lineStream, bitsAsString, ' ');
std::string comment;
std::getline(lineStream, comment);
CompareCounter count = getCounter(countAsString);
size_t bytes = static_cast<size_t>(std::stoi(bitsAsString) / 8);
for (int i = 0; i < count.max(); i++) {
count.checkIfDataExists(i, compareInfoReference, compareInfoActual);
if (!compareBytes(bytes)) {
std::string diffKey = StrCat(prefix, ".", comment);
addDiff(diffKey);
}
}
} else if (command == "C") {
std::string countAsString;
std::getline(lineStream, countAsString, ' ');
std::string subMemoryMapFile;
std::getline(lineStream, subMemoryMapFile, ' ');
std::string comment;
std::getline(lineStream, comment);
CompareCounter count = getCounter(countAsString);
subMemoryMapFile.erase(std::remove(subMemoryMapFile.begin(), subMemoryMapFile.end(), '\r'), subMemoryMapFile.end());
for (int i = 0; i < count.max(); i++) {
count.checkIfDataExists(i, compareInfoReference, compareInfoActual);
std::string subPrefix = StrCat(prefix, ".", comment);
CreateDetailDiffs(subPrefix, subMemoryMapFile, compareInfoReference, compareInfoActual, foundDiffs);
}
}
compareInfoReference.dataExists = dataExistsReference;
compareInfoActual.dataExists = dataExistsActual;
}
}
struct CompareTargets {
std::string fileName;
std::string memoryMapFileName;
bool isTownLevel;
};
HeroCompareResult CompareSaves(const std::string &actualSavePath, const std::string &referenceSavePath, bool logDetails)
{
std::vector<CompareTargets> possibleFileToCheck;
possibleFileToCheck.push_back({ "hero", "hero", false });
possibleFileToCheck.push_back({ "game", "game", false });
possibleFileToCheck.push_back({ "additionalMissiles", "additionalMissiles", false });
char szPerm[MaxMpqPathSize];
for (int i = 0; GetPermSaveNames(i, szPerm); i++) {
possibleFileNamesToCheck.emplace_back(szPerm);
possibleFileToCheck.push_back({ std::string(szPerm), "level", i == 0 });
}
std::int32_t error;
auto actualArchive = *MpqArchive::Open(actualSavePath.c_str(), error);
auto referenceArchive = *MpqArchive::Open(referenceSavePath.c_str(), error);
for (const auto &fileName : possibleFileNamesToCheck) {
size_t fileSizeActual;
auto fileDataActual = ReadArchive(actualArchive, fileName.c_str(), &fileSizeActual);
size_t fileSizeReference;
auto fileDataReference = ReadArchive(referenceArchive, fileName.c_str(), &fileSizeReference);
bool compareResult = true;
std::string message;
for (const auto &compareTarget : possibleFileToCheck) {
size_t fileSizeActual = 0;
auto fileDataActual = ReadArchive(actualArchive, compareTarget.fileName.c_str(), &fileSizeActual);
size_t fileSizeReference = 0;
auto fileDataReference = ReadArchive(referenceArchive, compareTarget.fileName.c_str(), &fileSizeReference);
if (fileDataActual.get() == nullptr && fileDataReference.get() == nullptr) {
continue;
}
if (fileSizeActual != fileSizeReference) {
return { HeroCompareResult::Difference, StrCat("file \"", fileName, "\" is different size. Expected: ", fileSizeReference, "Actual: ", fileSizeActual) };
}
const byte *reference = fileDataReference.get();
const byte *referenceEnd = reference + fileSizeActual;
const byte *actual = fileDataActual.get();
while (reference != referenceEnd) {
if (*reference != *actual) {
const size_t diffSize = std::min<size_t>(16, referenceEnd - reference);
return {
HeroCompareResult::Difference,
fmt::format(
"file \"{}\" is different at byte {}:\n"
"Expected: ... {:02X} ...\n"
" Actual: ... {:02X} ...",
fileName, reference - fileDataReference.get(),
fmt::join(reference, reference + diffSize, " "),
fmt::join(actual, actual + diffSize, " "))
};
}
++reference;
++actual;
if (fileSizeActual == fileSizeReference && memcmp(fileDataReference.get(), fileDataActual.get(), fileSizeActual) == 0)
continue;
compareResult = false;
if (!message.empty())
message.append("\n");
if (fileSizeActual != fileSizeReference)
StrAppend(message, "file \"", compareTarget.fileName, "\" is different size. Expected: ", fileSizeReference, " Actual: ", fileSizeActual);
else
StrAppend(message, "file \"", compareTarget.fileName, "\" has different content.");
if (!logDetails)
continue;
std::unordered_map<std::string, size_t> foundDiffs;
CompareInfo compareInfoReference = { fileDataReference, 0, fileSizeReference, compareTarget.isTownLevel, fileSizeReference != 0 };
CompareInfo compareInfoActual = { fileDataActual, 0, fileSizeActual, compareTarget.isTownLevel, fileSizeActual != 0 };
CreateDetailDiffs(compareTarget.fileName, compareTarget.memoryMapFileName, compareInfoReference, compareInfoActual, foundDiffs);
if (compareInfoReference.currentPosition != fileSizeReference)
app_fatal(StrCat("Comparsion failed. Uncompared bytes in reference. File: ", compareTarget.fileName));
if (compareInfoActual.currentPosition != fileSizeActual)
app_fatal(StrCat("Comparsion failed. Uncompared bytes in actual. File: ", compareTarget.fileName));
for (auto entry : foundDiffs) {
StrAppend(message, "\nDiff found in ", entry.first, " count: ", entry.second);
}
}
return { HeroCompareResult::Same, {} };
return { compareResult ? HeroCompareResult::Same : HeroCompareResult::Difference, message };
}
void pfile_write_hero(MpqWriter &saveWriter, bool writeGameData)
@ -309,7 +520,7 @@ void pfile_write_hero_demo(int demo)
pfile_write_hero(saveWriter, true);
}
HeroCompareResult pfile_compare_hero_demo(int demo)
HeroCompareResult pfile_compare_hero_demo(int demo, bool logDetails)
{
std::string referenceSavePath = GetSavePath(gSaveNumber, StrCat("demo_", demo, "_reference_"));
@ -322,7 +533,7 @@ HeroCompareResult pfile_compare_hero_demo(int demo)
pfile_write_hero(saveWriter, true);
}
return CompareSaves(actualSavePath, referenceSavePath);
return CompareSaves(actualSavePath, referenceSavePath, logDetails);
}
void sfile_write_stash()

3
Source/pfile.h

@ -40,9 +40,10 @@ void pfile_write_hero_demo(int demo);
/**
* @brief Compares the actual game-state (savegame) with a reference game-state (save game from demo recording)
* @param demo for the comparsion
* @param logDetails in case of a difference log details
* @return The comparsion result.
*/
HeroCompareResult pfile_compare_hero_demo(int demo);
HeroCompareResult pfile_compare_hero_demo(int demo, bool logDetails);
void sfile_write_stash();
bool pfile_ui_set_hero_infos(bool (*uiAddHeroInfo)(_uiheroinfo *));
void pfile_ui_set_class_stats(unsigned int playerClass, _uidefaultstats *classStats);

14
test/Fixtures.cmake

@ -64,6 +64,20 @@ set(devilutionx_fixtures
Levels/L4Data/Vile1.DUN
Levels/L4Data/Warlord.DUN
Levels/L4Data/Warlord2.DUN
memory_map/additionalMissiles.txt
memory_map/game.txt
memory_map/hero.txt
memory_map/item.txt
memory_map/itemPack.txt
memory_map/level.txt
memory_map/levelSeed.txt
memory_map/lightning.txt
memory_map/missile.txt
memory_map/monster.txt
memory_map/object.txt
memory_map/player.txt
memory_map/portal.txt
memory_map/quest.txt
timedemo/WarriorLevel1to2/demo_0.dmo
timedemo/WarriorLevel1to2/demo_0_reference_spawn_0.sv
timedemo/WarriorLevel1to2/spawn_0.sv

3
test/fixtures/memory_map/additionalMissiles.txt vendored

@ -0,0 +1,3 @@
R 32 Version
LC_LE 32 MissileCounter
C MissileCounter missile missiles

55
test/fixtures/memory_map/game.txt vendored

@ -0,0 +1,55 @@
R 32 header
R 8 setlevel
R 32 setlvlnum
R 32 currlevel
LT 32 leveltype
R 32 viewX
R 32 viewY
R 8 invflag
R 8 chrflag
LC 32 NumMonsters
LC 32 ItemCount
LC 32 NumMissiles
LC 32 NumObjects
C_DA 17 levelSeed levelSeeds
C_HF 25 levelSeed levelSeeds
C 1 player player
C_DA 16 quest quests
C_HF 24 quest quests
C 4 portal portals
M 200 32 MonsterKillCounts
M_DL 200 32 ActiveMonsters
C_DL NumMonsters monster monsters
M_DL 125 8 ActiveMissiles
M_DL 125 8 AvailableMissiles
C_DL NumMissiles missile missiles
M_DL 127 8 ActiveObjects
M_DL 127 8 AvailableObjects
C_DL NumObjects object objects
LC_DL 32 ActiveLightCount
M_DL 32 8 ActiveLights
C_DL ActiveLightCount lightning lightning
R_DL 32 VisionId
LC_DL 32 VisionCount
C_DL VisionCount lightning vision
M 127 8 ActiveItems
M 127 8 AvailableItems
C ItemCount item items
M 128 8 UniqueItemFlags
M 12544 8 dLight
M 12544 8 dFlags
M 12544 8 dPlayer
M 12544 8 dItem
M_DL 12544 32 dMonster
M_DL 12544 8 dCorpse
M_DL 12544 8 dObject
M_DL 12544 8 dLight
M_DL 12544 8 dPreLight
M_DL 1600 8 AutomapView
M_DL 12544 8 dMissile
R 32 numpremium
R 32 premiumlevel
C_DA 6 item PremiumItems
C_HF 15 item PremiumItems
R 8 AutomapActive
R 32 AutoMapScale

49
test/fixtures/memory_map/hero.txt vendored

@ -0,0 +1,49 @@
R 32 dwLowDateTime
R 32 dwHighDateTime
R 8 destAction
R 8 destParam1
R 8 destParam2
R 8 plrlevel
R 8 px
R 8 py
R 8 targx
R 8 targy
R 256 _pName
R 8 pClass
R 8 pBaseStr
R 8 pBaseMag
R 8 pBaseDex
R 8 pBaseVit
R 8 pLevel
R 8 pStatPts
R 32 pExperience
R 32 pGold
R 32 pHPBase
R 32 pMaxHPBase
R 32 pManaBase
R 32 pMaxManaBase
M 37 8 pSplLvl
R 64 pMemSpells
C 7 itemPack InvBody
C 40 itemPack InvList
M 40 8 InvGrid
R 8 _pNumInv
C 8 itemPack SpdList
R 8 pTownWarps
R 8 pDungMsgs
R 8 pLvlLoad
R 8 pBattleNet
R 8 pManaShield
R 8 pDungMsgs2
R 8 bIsHellfire
R 8 reserved
R 16 wReflections
R 16 reserved
M 10 8 pSplLvl2
R 16 reserved
R 32 pDiabloKillLevel
R 32 pDifficulty
R 32 pDamAcFlags
R 8 friendlyMode
R 8 isOnSetLevel
M 18 8 reserved

75
test/fixtures/memory_map/item.txt vendored

@ -0,0 +1,75 @@
R 32 _iSeed
R 16 _iCreateInfo
R 16 alignment
R 32 _itype
R 32 positionX
R 32 positionY
R 32 _iAnimFlag
R 32 _iAnimData
R 32 numberOfFrames
R 32 currentFrame
R 32 _iAnimWidth
R 32 _iAnimWidth2
R 32 unused
R 8 _iSelFlag
R 24 alignment
R 32 _iPostDraw
R 32 _iIdentified
R 8 _iMagical
R 512 _iName
R 512 _iIName
R 8 _iLoc
R 8 _iClass
R 8 alignment
R 32 _iCurs
R 32 _ivalue
R 32 _iIvalue
R 32 _iMinDam
R 32 _iMaxDam
R 32 _iAC
R 32 _iFlags
R 32 _iMiscId
R 32 _iSpell
R 32 _iCharges
R 32 _iMaxCharges
R 32 _iDurability
R 32 _iMaxDur
R 32 _iPLDam
R 32 _iPLToHit
R 32 _iPLAC
R 32 _iPLStr
R 32 _iPLMag
R 32 _iPLDex
R 32 _iPLVit
R 32 _iPLFR
R 32 _iPLLR
R 32 _iPLMR
R 32 _iPLMana
R 32 _iPLHP
R 32 _iPLDamMod
R 32 _iPLGetHit
R 32 _iPLLight
R 8 _iSplLvlAdd
R 8 _iRequest
R 16 alignment
R 32 _iUid
R 32 _iFMinDam
R 32 _iFMaxDam
R 32 _iLMinDam
R 32 _iLMaxDam
R 32 _iPLEnAc
R 8 _iPrePower
R 8 _iSufPower
R 16 alignment
R 32 _iVAdd1
R 32 _iVMult1
R 32 _iVAdd2
R 32 _iVMult2
R 8 _iMinStr
R 8 _iMinMag
R 8 _iMinDex
R 8 alignment
R 32 _iStatFlag
R 32 IDidx
R 32 dwBuff
R_HF 32 _iDamAcFlags

10
test/fixtures/memory_map/itemPack.txt vendored

@ -0,0 +1,10 @@
R 32 iSeed
R 16 iCreateInfo
R 16 idx
R 8 bId
R 8 bDur
R 8 bMDur
R 8 bCh
R 8 bMCh
R 16 wValue
R 32 dwBuff

19
test/fixtures/memory_map/level.txt vendored

@ -0,0 +1,19 @@
M_DL 12544 8 dCorpse
LC 32 NumMonsters
LC 32 ItemCount
LC 32 NumObjects
M_DL 200 32 ActiveMonsters
C_DL NumMonsters monster monsters
M_DL 127 8 ActiveObjects
M_DL 127 8 AvailableObjects
C_DL NumObjects object objects
M 127 8 ActiveItems
M 127 8 AvailableItems
C ItemCount item items
M 12544 8 dFlags
M 12544 8 dItem
M_DL 12544 32 dMonster
M_DL 12544 8 dObject
M_DL 12544 8 dLight
M_DL 12544 8 dPreLight
M_DL 1600 8 AutomapView

2
test/fixtures/memory_map/levelSeed.txt vendored

@ -0,0 +1,2 @@
R 32 glSeedTbl
R 32 gnLevelTypeTbl

13
test/fixtures/memory_map/lightning.txt vendored

@ -0,0 +1,13 @@
R 32 positionX
R 32 positionY
R 32 _lradius
R 32 _lid
R 32 _ldel
R 32 _lunflag
R 32 unused
R 32 oldX
R 32 oldY
R 32 oldRadius
R 32 offsetX
R 32 offsetY
R 32 _lflags

45
test/fixtures/memory_map/missile.txt vendored

@ -0,0 +1,45 @@
R 32 _mitype
R 32 tileX
R 32 tileY
R 32 offsetX
R 32 offsetY
R 32 velocityX
R 32 velocityY
R 32 startX
R 32 startY
R 32 traveledX
R 32 traveledY
R 32 _mimfnum
R 32 _mispllvl
R 32 _miDelFlag
R 8 _miAnimType
R 24 alignment
R 32 _miAnimFlags
R 32 _miAnimData
R 32 _miAnimDelay
R 32 _miAnimLen
R 32 _miAnimWidth
R 32 _miAnimWidth2
R 32 _miAnimCnt
R 32 _miAnimAdd
R 32 _miAnimFrame
R 32 _miDrawFlag
R 32 _miLightFlag
R 32 _miPreFlag
R 32 _miUniqTrans
R 32 _mirange
R 32 _misource
R 32 _micaster
R 32 _midam
R 32 _miHitFlag
R 32 _midist
R 32 _mlid
R 32 _mirnd
R 32 var1
R 32 var2
R 32 var3
R 32 var4
R 32 var5
R 32 var6
R 32 var7
R 32 limitReached

76
test/fixtures/memory_map/monster.txt vendored

@ -0,0 +1,76 @@
R 32 levelType
R 32 mode
R 8 goal
R 24 alignment
R 32 goalVar1
R 32 goalVar2
R 32 goalVar3
R 32 unused
R 8 pathcount
R 24 alignment
R 32 tileX
R 32 tileY
R 32 futureX
R 32 futureY
R 32 oldX
R 32 oldY
R 32 offsetX
R 32 offsetY
R 32 velocityX
R 32 velocityY
R 32 direction
R 32 enemy
R 8 enemyPositionX
R 8 enemyPositionY
R 16 unused
R 32 _mAnimData
R 32 ticksPerFrame
R 32 tickCounterOfCurrentFrame
R 32 numberOfFrames
R 32 currentFrame
R 32 _meflag
R 32 isInvalid
R 32 var1
R 32 var2
R 32 var3
R 32 tempPositionX
R 32 tempPositionY
R 32 offset2X
R 32 offset2Y
R 32 actionFrame
R 32 maxHitPoints
R 32 hitPoints
R 8 ai
R 8 intelligence
R 16 alignment
R 32 flags
R 8 activeForTicks
R 24 alignment
R 32 unused
R 32 lastX
R 32 lastY
R 32 rndItemSeed
R 32 aiSeed
R 32 unused
R 8 uniqueType
R 8 uniqTrans
R 8 corpseId
R 8 whoHit
R 8 level
R 8 alignment
R 16 exp
R 8 toHit
R 8 minDamage
R 8 maxDamage
R 8 toHitSpecial
R 8 minDamageSpecial
R 8 maxDamageSpecial
R 8 armorClass
R 8 alignment
R 16 resistance
R 16 alignment
R 32 talkMsg
R 8 leader
R 8 leaderRelation
R 8 packSize
R 8 lightId

32
test/fixtures/memory_map/object.txt vendored

@ -0,0 +1,32 @@
R 32 _otype
R 32 positionX
R 32 positionY
R 32 _oLight
R 32 _oAnimFlag
R 32 _oAnimData
R 32 _oAnimDelay
R 32 _oAnimCnt
R 32 _oAnimLen
R 32 _oAnimFrame
R 32 _oAnimWidth
R 32 _oAnimWidth2
R 32 _oDelFlag
R 8 _oBreak
R 24 alignment
R 32 _oSolidFlag
R 32 _oMissFlag
R 8 _oSelFlag
R 24 alignment
R 32 _oPreFlag
R 32 _oTrapFlag
R 32 _oDoorFlag
R 32 _olid
R 32 _oRndSeed
R 32 _oVar1
R 32 _oVar2
R 32 _oVar3
R 32 _oVar4
R 32 _oVar5
R 32 _oVar6
R 32 bookMessage
R 32 _oVar8

178
test/fixtures/memory_map/player.txt vendored

@ -0,0 +1,178 @@
R 32 _pmode
M 25 8 walkpath
R 8 plractive
R 16 alignment
R 32 destAction
R 32 destParam1
R 32 destParam2
R 32 destParam3
R 32 destParam4
R 32 level
R 32 tileX
R 32 tileY
R 32 futureX
R 32 futureY
R 32 _ptargx
R 32 _ptargy
R 32 lastX
R 32 lastY
R 32 oldX
R 32 oldY
R 32 offsetX
R 32 offsetY
R 32 velocityX
R 32 velocityY
R 32 pdir
R 32 unused
R 32 pfxnum
R 32 pData
R 32 ticksPerFrame
R 32 tickCounterOfCurrentFrame
R 32 numberOfFrames
R 32 currentFrame
R 32 _pAnimWidth
R 32 _pAnimWidth2
R 32 _peflag
R 32 _plid
R 32 _pvid
R 32 _pSpell
R 8 _pSplType
R 8 _pSplFrom
R 16 alignment
R 32 _pTSpell
R 8 _pTSplType
R 24 alignment
R 32 _pRSpell
R 8 _pRSplType
R 24 alignment
R 32 _pSBkSpell
R 8 _pSBkSplType
M 64 8 spellLevel
R 56 alignment
R 64 _pMemSpells
R 64 _pAblSpells
R 64 _pScrlSpells
R 8 _pSpellFlags
R 24 alignment
M 4 32 _pSplHotKey
M 4 8 _pSplTHotKey
R 32 _pwtype
R 8 _pBlockFlag
R 8 _pInvincible
R 8 _pLightRad
R 8 _pLvlChanging
R 256 _pName
R 8 _pClass
R 24 alignment
R 32 _pStrength
R 32 _pBaseStr
R 32 _pMagic
R 32 _pBaseMag
R 32 _pDexterity
R 32 _pBaseDex
R 32 _pVitality
R 32 _pBaseVit
R 32 _pStatPts
R 32 _pDamageMod
R 32 _pBaseToBlk
R 32 _pHPBase
R 32 _pMaxHPBase
R 32 _pHitPoints
R 32 _pMaxHP
R 32 _pHPPer
R 32 _pManaBase
R 32 _pMaxManaBase
R 32 _pMana
R 32 _pMaxMana
R 32 _pManaPer
R 8 _pLevel
R 8 _pMaxLvl
R 16 alignment
R 32 _pExperience
R 32 _pMaxExp
R 32 _pNextExper
R 8 _pArmorClass
R 8 _pMagResist
R 8 _pFireResist
R 8 _pLghtResist
R 32 _pGold
R 32 _pInfraFlag
R 32 tempPositionX
R 32 tempPositionY
R 32 tempDirection
R 32 spellLevel
R 32 _pVar5
R 32 offset2.x
R 32 offset2.y
R 32 actionFrame
M_DA 17 8 _pLvlVisited
M_HF 25 8 _pLvlVisited
M_DA 17 8 _pSLvlVisited
M_HF 25 8 _pSLvlVisited
R 16 alignment
R 32 _pGFXLoad
M 8 32 _pNAnim
R 32 _pNFrames
R 32 _pNWidth
M 8 32 _pWAnim
R 32 _pWWidth
M 8 32 _pAAnim
R 32 _pAFrames
R 32 _pAWidth
R 32 _pAFNum
M 8 32 _pLAnim
M 8 32 _pFAnim
M 8 32 _pTAnim
R 32 _pSFrames
R 32 _pSWidth
R 32 _pSFNum
R 32 _pHFrames
M 8 32 _pHAnim
R 32 _pHFrames
R 32 _pHWidth
M 8 32 _pDAnim
R 32 _pDFrames
R 32 _pDWidth
M 8 32 _pBAnim
R 32 _pBFrames
R 32 _pBWidth
C 7 item
C 40 item
R 32 _pNumInv
M 40 8 InvGrid
C 8 item
C 1 item
R 32 _pIMinDam
R 32 _pIMaxDam
R 32 _pIAC
R 32 _pIBonusDam
R 32 _pIBonusToHit
R 32 _pIBonusAC
R 32 _pIBonusDamMod
R 32 alignment
R 64 _pISpells
R 32 _pIFlags
R 32 _pIGetHit
R 8 _pISplLvlAdd
R 8 unused
R 16 alignment
R 32 _pISplDur
R 32 _pIEnAc
R 32 _pIFMinDam
R 32 _pIFMaxDam
R 32 _pILMinDam
R 32 _pILMaxDam
R 32 _pOilType
R 8 pTownWarps
R 8 pDungMsgs
R 8 pLvlLoad
R 8 pDungMsgs2
R 8 pManaShield
R 8 pOriginalCathedral
R 16 unused
R 16 wReflections
R 112 unused
R 32 pDiabloKillLevel
R 32 pDifficulty
R 32 pDamAcFlags
R 160 unused

6
test/fixtures/memory_map/portal.txt vendored

@ -0,0 +1,6 @@
R 32 open
R 32 positionX
R 32 positionY
R 32 level
R 32 ltype
R 32 setlvl

21
test/fixtures/memory_map/quest.txt vendored

@ -0,0 +1,21 @@
R 8 _qlevel
R 8 _qtype
R 8 _qactive
R 8 _qlvltype
R 32 positionX
R 32 positionY
R 8 _qslvl
R 8 _qidx
R_DA 8 _qmsg
R_HF 16 alignment
R_HF 32 _qmsg
R 8 _qvar1
R 8 _qvar2
R 16 alignment
R_DA 8 alignment
R 32 _qlog
R 32 ReturnLvlPositionX
R 32 ReturnLvlPositionY
R 32 ReturnLevel
R 32 ReturnLevelType
R 32 DoomQuestState

2
test/timedemo_test.cpp

@ -52,7 +52,7 @@ void RunTimedemo(std::string timedemoFolderName)
StartGame(false, true);
HeroCompareResult result = pfile_compare_hero_demo(demoNumber);
HeroCompareResult result = pfile_compare_hero_demo(demoNumber, true);
ASSERT_EQ(result.status, HeroCompareResult::Same) << result.message;
ASSERT_FALSE(gbRunGame);
gbRunGame = false;

Loading…
Cancel
Save