From caa02cd6b7e65254888602bded5a664077ed88c5 Mon Sep 17 00:00:00 2001
From: Asdow <20314541+Asdow@users.noreply.github.com>
Date: Tue, 13 Aug 2024 00:29:48 +0300
Subject: [PATCH] Read new MercOpinions.xml format (#323)
Requires accompanying gameDir change.
MercOpinions.xml now only contains opinions that are not 0. A new tag with fields "id" and "modifier" are used instead of old ones that had 255 $value$ tags for all profiles.
Loading time of MercOpinions.xml went down from ~4.047 s to 0.011 s due to this change with default 1.13 VFS config.
A small cmd utility tool for converting existing MercOpinions.xml data into the new format is available at https://github.com/Asdow/JA2-ConvertXMLData/tree/master
---
Tactical/CMakeLists.txt | 1 +
Tactical/XML.cpp | 9 +++++++
Tactical/XML.h | 3 +++
Tactical/XML_Opinions.cpp | 49 ++++++++++++++-------------------------
4 files changed, 30 insertions(+), 32 deletions(-)
create mode 100644 Tactical/XML.cpp
diff --git a/Tactical/CMakeLists.txt b/Tactical/CMakeLists.txt
index ebecb65da..86810e0df 100644
--- a/Tactical/CMakeLists.txt
+++ b/Tactical/CMakeLists.txt
@@ -93,6 +93,7 @@ set(TacticalSrc
"${CMAKE_CURRENT_SOURCE_DIR}/VehicleMenu.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Weapons.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/World Items.cpp"
+"${CMAKE_CURRENT_SOURCE_DIR}/XML.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/XML_AmmoStrings.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/XML_AmmoTypes.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/XML_Armour.cpp"
diff --git a/Tactical/XML.cpp b/Tactical/XML.cpp
new file mode 100644
index 000000000..4cb460be5
--- /dev/null
+++ b/Tactical/XML.cpp
@@ -0,0 +1,9 @@
+#include "XML.h"
+
+const XML_Char* GetAttribute(const XML_Char* name, const XML_Char** atts) {
+ for (const XML_Char** pIter = atts; *pIter != NULL; pIter++) {
+ const XML_Char* key = *pIter++;
+ if (strcmp(key, name) == 0) return *pIter;
+ }
+ return NULL;
+}
diff --git a/Tactical/XML.h b/Tactical/XML.h
index efa28c25b..963417efc 100644
--- a/Tactical/XML.h
+++ b/Tactical/XML.h
@@ -1,6 +1,7 @@
#ifndef __XML_H
#define __XML_H
+#include "expat.h"
#include "armsdealerinvinit.h"
#include "EnemyItemDrops.h"
#include "Loading Screen.h"
@@ -581,4 +582,6 @@ extern BOOLEAN ReadInAimOldArchive(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN ReadInHistorys(STR fileName, BOOLEAN localizedVersion );
extern BOOLEAN ReadInDifficultySettings(STR fileName, BOOLEAN localizedVersion);
+extern const XML_Char* GetAttribute(const XML_Char* name, const XML_Char** atts);
+
#endif
diff --git a/Tactical/XML_Opinions.cpp b/Tactical/XML_Opinions.cpp
index 5c8084410..a82c5fdac 100644
--- a/Tactical/XML_Opinions.cpp
+++ b/Tactical/XML_Opinions.cpp
@@ -70,21 +70,21 @@ opinionStartElementHandle(void *userData, const XML_Char *name, const XML_Char *
pData->maxReadDepth++; //we are not skipping this element
}
- else if(pData->curElement == ELEMENT)
+ else if (pData->curElement == ELEMENT && strcmp(name, "AnOpinion") == 0)
{
- for(UINT8 i = 0; i < NUMBER_OF_OPINIONS; ++i)
- {
- XML_Char bla[12];
- sprintf(bla, "Opinion%d", i);
-
- if(strcmp(name, bla) == 0)
- {
- pData->curElement = ELEMENT_PROPERTY;
+ pData->curElement = ELEMENT;
+ pData->maxReadDepth++; //we are not skipping this element
- pData->maxReadDepth++; //we are not skipping this element
+ XML_Char const* anID = GetAttribute("id", atts);
+ XML_Char const* modifier = GetAttribute("modifier", atts);
- break;
- }
+ INT32 id, value;
+ id = atoi(anID);
+ value = atoi(modifier);
+
+ if (id >= 0 && id < NUMBER_OF_OPINIONS)
+ {
+ pData->curProfile.bMercOpinion[id] = value;
}
}
@@ -92,9 +92,9 @@ opinionStartElementHandle(void *userData, const XML_Char *name, const XML_Char *
}
pData->currentDepth++;
-
}
+
static void XMLCALL
opinionCharacterDataHandle(void *userData, const XML_Char *str, int len)
{
@@ -149,24 +149,6 @@ opinionEndElementHandle(void *userData, const XML_Char *name)
pData->curIndex = (UINT32) strtoul(pData->szCharData, NULL, 0);
}
- else
- {
- for(UINT8 i = 0; i < NUMBER_OF_OPINIONS; ++i)
- {
- XML_Char bla[12];
- sprintf(bla, "Opinion%d", i);
-
- if(strcmp(name, bla) == 0)
- {
- pData->curElement = ELEMENT;
-
- pData->curProfile.bMercOpinion[i] = (INT8) atol(pData->szCharData);
-
- break;
- }
- }
- }
-
pData->maxReadDepth--;
}
@@ -315,7 +297,10 @@ BOOLEAN WriteMercOpinions()
UINT8 cnt_b = 0;
for (cnt_b = 0; cnt_b < NUMBER_OF_OPINIONS; ++cnt_b)
{
- FilePrintf(hFile,"\t\t%d\r\n", cnt_b, gMercProfiles[ cnt ].bMercOpinion[cnt_b], cnt_b);
+ if (gMercProfiles[cnt].bMercOpinion[cnt_b] != 0)
+ {
+ FilePrintf(hFile, "\t\t\r\n", cnt_b, gMercProfiles[cnt].bMercOpinion[cnt_b]);
+ }
}