Files
source/Strategic/XML_Army.cpp
T
00fb898600 Delete builddefines.h
Nothing was left in it but the include of profiler.h, and 132 translation units
were including it for that alone. Fifteen files were leaning on profiler.h to
drag in <set>, <vector> and <ostream> for them; those now include what they use.

This is the commit that moves line numbers. Removing an include line shifts
__LINE__ by one for everything below it, and __LINE__ is an immediate operand in
every Assert() and DebugMsg() call, so the four game executables differ from
their predecessors by roughly a thousand 32-bit constants each. Every one of
those is accounted for: each is a single immediate that moved by -1 where the
builddefines.h include went away, or +1 where a <set>/<vector> include was
added. Nothing else in .text, .rdata or .data moves, no object file's section
sizes change, and symbolize_crash and Ja2Export stay bit-identical.

The one non-immediate difference is that the 24 Editor translation units of the
non-editor apps stop emitting __Avx2WmemEnabledWeakValue, a 4-byte weak COMDAT
they only ever instantiated through profiler.h's <vector>. It is a UCRT weak
default that other translation units still provide.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 01:07:26 -03:00

903 lines
27 KiB
C++

#include <stdio.h>
#include "XML.h"
#include "Strategic AI.h"
#include "expat.h"
#include "Campaign Types.h"
#include "Debug Control.h"
#define MAX_CHAR_DATA_LENGTH 500
extern GARRISON_GROUP gOrigGarrisonGroup[ MAX_GARRISON_GROUPS ];
extern PATROL_GROUP gOrigPatrolGroup[ MAX_PATROL_GROUPS ];
extern ARMY_COMPOSITION gOrigArmyComp[ MAX_ARMY_COMPOSITIONS ];
extern INT32 iOrigGarrisonArraySize;
extern INT32 iOrigPatrolArraySize;
// Garrison externalization
typedef enum
{
GARRISON_ELEMENT_NONE = 0,
GARRISON_ELEMENT_GARRISON_INFO,
GARRISON_ELEMENT_GARRISON,
GARRISON_ELEMENT_SECTOR,
GARRISON_ELEMENT_COMPOSITION
} GARRISON_PARSE_STAGE;
typedef struct
{
UINT8 ubSectorID;
UINT8 ubComposition;
BOOLEAN fValidSector;
} garrisonInfo;
typedef struct
{
GARRISON_PARSE_STAGE curElement;
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
garrisonInfo curGarrisonInfo;
UINT32 uiGarrisonCount;
UINT32 currentDepth;
UINT32 maxReadDepth;
} garrisonParseData;
static void XMLCALL
garrisonStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
{
garrisonParseData * pData = (garrisonParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
{
if(strcmp(name, "GARRISON_INFO") == 0 && pData->curElement == GARRISON_ELEMENT_NONE)
{
pData->curElement = GARRISON_ELEMENT_GARRISON_INFO;
memset( gOrigGarrisonGroup, 0, sizeof(gOrigGarrisonGroup) );
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "GARRISON") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON_INFO)
{
pData->curElement = GARRISON_ELEMENT_GARRISON;
memset( &pData->curGarrisonInfo, 0, sizeof(garrisonInfo) );
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Sector") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON)
{
pData->curElement = GARRISON_ELEMENT_SECTOR;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Composition") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON)
{
pData->curElement = GARRISON_ELEMENT_COMPOSITION;
pData->maxReadDepth++; //we are not skipping this element
}
pData->szCharData[0] = '\0';
}
pData->currentDepth++;
}
static void XMLCALL
garrisonCharacterDataHandle(void *userData, const XML_Char *str, int len)
{
garrisonParseData * pData = (garrisonParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth && strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
}
static void XMLCALL
garrisonEndElementHandle(void *userData, const XML_Char *name)
{
garrisonParseData * pData = (garrisonParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
{
if(strcmp(name, "GARRISON_INFO") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON_INFO)
{
pData->curElement = GARRISON_ELEMENT_NONE;
iOrigGarrisonArraySize = pData->uiGarrisonCount;
}
else if(strcmp(name, "GARRISON") == 0 && pData->curElement == GARRISON_ELEMENT_GARRISON)
{
pData->curElement = GARRISON_ELEMENT_GARRISON_INFO;
if ( pData->curGarrisonInfo.fValidSector && pData->uiGarrisonCount < MAX_GARRISON_GROUPS )
{
gOrigGarrisonGroup[ pData->uiGarrisonCount ].ubSectorID = pData->curGarrisonInfo.ubSectorID;
gOrigGarrisonGroup[ pData->uiGarrisonCount ].ubComposition = pData->curGarrisonInfo.ubComposition;
pData->uiGarrisonCount++;
}
}
else if(strcmp(name, "Sector") == 0 && pData->curElement == GARRISON_ELEMENT_SECTOR)
{
UINT8 x, y;
pData->curElement = GARRISON_ELEMENT_GARRISON;
y = (UINT8)pData->szCharData[0] & 0x1F;
x = (UINT8)atol(&pData->szCharData[1]);
if ( x > 0 && x <= 16 && y > 0 && y <= 16 )
{
pData->curGarrisonInfo.fValidSector = TRUE;
pData->curGarrisonInfo.ubSectorID = SECTOR(x,y);
}
else
{
pData->curGarrisonInfo.fValidSector = FALSE;
}
}
else if(strcmp(name, "Composition") == 0 && pData->curElement == GARRISON_ELEMENT_COMPOSITION)
{
pData->curElement = GARRISON_ELEMENT_GARRISON;
pData->curGarrisonInfo.ubComposition = (UINT8) atol(pData->szCharData);
}
pData->maxReadDepth--;
}
pData->currentDepth--;
}
BOOLEAN ReadInGarrisonInfo(STR fileName)
{
HWFILE hFile;
UINT32 uiBytesRead;
UINT32 uiFSize;
CHAR8 * lpcBuffer;
XML_Parser parser = XML_ParserCreate(NULL);
garrisonParseData pData;
// Open weapons file
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
if ( !hFile )
return( FALSE );
uiFSize = FileGetSize(hFile);
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
//Read in block
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
{
MemFree(lpcBuffer);
return( FALSE );
}
lpcBuffer[uiFSize] = 0; //add a null terminator
FileClose( hFile );
XML_SetElementHandler(parser, garrisonStartElementHandle, garrisonEndElementHandle);
XML_SetCharacterDataHandler(parser, garrisonCharacterDataHandle);
memset(&pData,0,sizeof(pData));
XML_SetUserData(parser, &pData);
iOrigGarrisonArraySize = 0;
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
{
CHAR8 errorBuf[511];
sprintf(errorBuf, "XML Parser Error in GarrisonGroups.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
LiveMessage(errorBuf);
MemFree(lpcBuffer);
return FALSE;
}
MemFree(lpcBuffer);
XML_ParserFree(parser);
return TRUE;
}
BOOLEAN WriteInGarrisonInfo(STR fileName)
{
HWFILE hFile;
hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
if ( !hFile )
return( FALSE );
{
INT8 cnt;
FilePrintf(hFile,"<GARRISON_INFO>\r\n");
for(cnt = 0; cnt < 57; cnt++)
{
FilePrintf(hFile,"\t<GARRISON>\r\n");
FilePrintf(hFile,"\t\t<Sector>%c%d</Sector>\r\n",
(gOrigGarrisonGroup[cnt].ubSectorID / 16 + 0x41),
(gOrigGarrisonGroup[cnt].ubSectorID % 16 + 1));
FilePrintf(hFile,"\t\t<Composition>%d</Composition>\r\n",
gOrigGarrisonGroup[cnt].ubComposition);
FilePrintf(hFile,"\t</GARRISON>\r\n");
}
FilePrintf(hFile,"</GARRISON_INFO>\r\n");
}
FileClose( hFile );
return TRUE;
}
// Patrol externalization
typedef enum
{
PATROL_ELEMENT_NONE = 0,
PATROL_ELEMENT_PATROL_INFO,
PATROL_ELEMENT_PATROL,
PATROL_ELEMENT_SIZE,
PATROL_ELEMENT_PRIORITY,
PATROL_ELEMENT_WAYPOINTS,
PATROL_ELEMENT_SECTOR1,
PATROL_ELEMENT_SECTOR2,
PATROL_ELEMENT_SECTOR3,
PATROL_ELEMENT_SECTOR4
} PATROL_PARSE_STAGE;
typedef struct
{
BOOLEAN fErrorState;
INT8 bSize;
INT8 bPriority;
UINT8 ubSectorID[4];
} patrolInfo;
typedef struct
{
PATROL_PARSE_STAGE curElement;
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
patrolInfo curPatrolInfo;
UINT32 uiPatrolCount;
UINT32 currentDepth;
UINT32 maxReadDepth;
} patrolParseData;
static void XMLCALL
patrolStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
{
patrolParseData * pData = (patrolParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
{
if(strcmp(name, "PATROL_INFO") == 0 && pData->curElement == PATROL_ELEMENT_NONE)
{
pData->curElement = PATROL_ELEMENT_PATROL_INFO;
memset( gOrigPatrolGroup, 0, sizeof(gOrigPatrolGroup) );
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "PATROL") == 0 && pData->curElement == PATROL_ELEMENT_PATROL_INFO)
{
pData->curElement = PATROL_ELEMENT_PATROL;
memset( &pData->curPatrolInfo, 0, sizeof(patrolInfo) );
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Size") == 0 && pData->curElement == PATROL_ELEMENT_PATROL)
{
pData->curElement = PATROL_ELEMENT_SIZE;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Priority") == 0 && pData->curElement == PATROL_ELEMENT_PATROL)
{
pData->curElement = PATROL_ELEMENT_PRIORITY;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Waypoints") == 0 && pData->curElement == PATROL_ELEMENT_PATROL)
{
pData->curElement = PATROL_ELEMENT_WAYPOINTS;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Sector1") == 0 && pData->curElement == PATROL_ELEMENT_WAYPOINTS)
{
pData->curElement = PATROL_ELEMENT_SECTOR1;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Sector2") == 0 && pData->curElement == PATROL_ELEMENT_WAYPOINTS)
{
pData->curElement = PATROL_ELEMENT_SECTOR2;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Sector3") == 0 && pData->curElement == PATROL_ELEMENT_WAYPOINTS)
{
pData->curElement = PATROL_ELEMENT_SECTOR3;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Sector4") == 0 && pData->curElement == PATROL_ELEMENT_WAYPOINTS)
{
pData->curElement = PATROL_ELEMENT_SECTOR4;
pData->maxReadDepth++; //we are not skipping this element
}
pData->szCharData[0] = '\0';
}
pData->currentDepth++;
}
static void XMLCALL
patrolCharacterDataHandle(void *userData, const XML_Char *str, int len)
{
patrolParseData * pData = (patrolParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth && strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
}
static void XMLCALL
patrolEndElementHandle(void *userData, const XML_Char *name)
{
patrolParseData * pData = (patrolParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
{
if(strcmp(name, "PATROL_INFO") == 0 && pData->curElement == PATROL_ELEMENT_PATROL_INFO)
{
pData->curElement = PATROL_ELEMENT_NONE;
iOrigPatrolArraySize = pData->uiPatrolCount;
}
else if(strcmp(name, "PATROL") == 0 && pData->curElement == PATROL_ELEMENT_PATROL)
{
pData->curElement = PATROL_ELEMENT_PATROL_INFO;
if ( !pData->curPatrolInfo.fErrorState && pData->uiPatrolCount < MAX_PATROL_GROUPS )
{
gOrigPatrolGroup[ pData->uiPatrolCount ].bSize = pData->curPatrolInfo.bSize;
gOrigPatrolGroup[ pData->uiPatrolCount ].bPriority = pData->curPatrolInfo.bPriority;
gOrigPatrolGroup[ pData->uiPatrolCount ].ubSectorID[0] = pData->curPatrolInfo.ubSectorID[0];
gOrigPatrolGroup[ pData->uiPatrolCount ].ubSectorID[1] = pData->curPatrolInfo.ubSectorID[1];
gOrigPatrolGroup[ pData->uiPatrolCount ].ubSectorID[2] = pData->curPatrolInfo.ubSectorID[2];
gOrigPatrolGroup[ pData->uiPatrolCount ].ubSectorID[3] = pData->curPatrolInfo.ubSectorID[3];
pData->uiPatrolCount++;
}
}
else if(strcmp(name, "Size") == 0 && pData->curElement == PATROL_ELEMENT_SIZE)
{
pData->curElement = PATROL_ELEMENT_PATROL;
pData->curPatrolInfo.bSize = (INT8) atol(pData->szCharData);
}
else if(strcmp(name, "Priority") == 0 && pData->curElement == PATROL_ELEMENT_PRIORITY)
{
pData->curElement = PATROL_ELEMENT_PATROL;
pData->curPatrolInfo.bPriority = (INT8) atol(pData->szCharData);
if ( pData->curPatrolInfo.bPriority < 0 )
pData->curPatrolInfo.bPriority = 0;
else if ( pData->curPatrolInfo.bPriority > 100 )
pData->curPatrolInfo.bPriority = 100;
}
else if(strcmp(name, "Waypoints") == 0 && pData->curElement == PATROL_ELEMENT_WAYPOINTS)
{
pData->curElement = PATROL_ELEMENT_PATROL;
}
else if(strcmp(name, "Sector1") == 0 && pData->curElement == PATROL_ELEMENT_SECTOR1)
{
pData->curElement = PATROL_ELEMENT_WAYPOINTS;
if ( strcmp(pData->szCharData, "0") == 0 )
{
pData->curPatrolInfo.ubSectorID[0] = 0;
}
else
{
UINT8 x, y;
y = (UINT8)pData->szCharData[0] & 0x1F;
x = (UINT8)atol(&pData->szCharData[1]);
if ( x > 0 && x <= 16 && y > 0 && y <= 16 )
{
pData->curPatrolInfo.ubSectorID[0] = SECTOR(x,y);
}
else
{
pData->curPatrolInfo.fErrorState++;
}
}
}
else if(strcmp(name, "Sector2") == 0 && pData->curElement == PATROL_ELEMENT_SECTOR2)
{
pData->curElement = PATROL_ELEMENT_WAYPOINTS;
if ( strcmp(pData->szCharData, "0") == 0 )
{
pData->curPatrolInfo.ubSectorID[1] = 0;
}
else
{
UINT8 x, y;
y = (UINT8)pData->szCharData[0] & 0x1F;
x = (UINT8)atol(&pData->szCharData[1]);
if ( x > 0 && x <= 16 && y > 0 && y <= 16 )
{
pData->curPatrolInfo.ubSectorID[1] = SECTOR(x,y);
}
else
{
pData->curPatrolInfo.fErrorState++;
}
}
}
else if(strcmp(name, "Sector3") == 0 && pData->curElement == PATROL_ELEMENT_SECTOR3)
{
pData->curElement = PATROL_ELEMENT_WAYPOINTS;
if ( strcmp(pData->szCharData, "0") == 0 )
{
pData->curPatrolInfo.ubSectorID[2] = 0;
}
else
{
UINT8 x, y;
y = (UINT8)pData->szCharData[0] & 0x1F;
x = (UINT8)atol(&pData->szCharData[1]);
if ( x > 0 && x <= 16 && y > 0 && y <= 16 )
{
pData->curPatrolInfo.ubSectorID[2] = SECTOR(x,y);
}
else
{
pData->curPatrolInfo.fErrorState++;
}
}
}
else if(strcmp(name, "Sector4") == 0 && pData->curElement == PATROL_ELEMENT_SECTOR4)
{
pData->curElement = PATROL_ELEMENT_WAYPOINTS;
if ( strcmp(pData->szCharData, "0") == 0 )
{
pData->curPatrolInfo.ubSectorID[3] = 0;
}
else
{
UINT8 x, y;
y = (UINT8)pData->szCharData[0] & 0x1F;
x = (UINT8)atol(&pData->szCharData[1]);
if ( x > 0 && x <= 16 && y > 0 && y <= 16 )
{
pData->curPatrolInfo.ubSectorID[3] = SECTOR(x,y);
}
else
{
pData->curPatrolInfo.fErrorState++;
}
}
}
pData->maxReadDepth--;
}
pData->currentDepth--;
}
BOOLEAN ReadInPatrolInfo(STR fileName)
{
HWFILE hFile;
UINT32 uiBytesRead;
UINT32 uiFSize;
CHAR8 * lpcBuffer;
XML_Parser parser = XML_ParserCreate(NULL);
patrolParseData pData;
// Open weapons file
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
if ( !hFile )
return( FALSE );
uiFSize = FileGetSize(hFile);
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
//Read in block
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
{
MemFree(lpcBuffer);
return( FALSE );
}
lpcBuffer[uiFSize] = 0; //add a null terminator
FileClose( hFile );
XML_SetElementHandler(parser, patrolStartElementHandle, patrolEndElementHandle);
XML_SetCharacterDataHandler(parser, patrolCharacterDataHandle);
memset(&pData,0,sizeof(pData));
XML_SetUserData(parser, &pData);
iOrigPatrolArraySize = 0;
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
{
CHAR8 errorBuf[511];
sprintf(errorBuf, "XML Parser Error in PatrolGroups.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
LiveMessage(errorBuf);
MemFree(lpcBuffer);
return FALSE;
}
MemFree(lpcBuffer);
XML_ParserFree(parser);
return TRUE;
}
BOOLEAN WriteInPatrolInfo(STR fileName)
{
HWFILE hFile;
hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
if ( !hFile )
return( FALSE );
{
INT8 cnt, i;
FilePrintf(hFile,"<PATROL_INFO>\r\n");
for(cnt = 0; cnt < 29; cnt++)
{
FilePrintf(hFile,"\t<PATROL>\r\n");
FilePrintf(hFile,"\t\t<Size>%d</Size>\r\n", gOrigPatrolGroup[cnt].bSize);
FilePrintf(hFile,"\t\t<Priority>%d</Priority>\r\n", gOrigPatrolGroup[cnt].bPriority);
FilePrintf(hFile,"\t\t<Waypoints>\r\n");
for (i=0; i<4; i++)
{
if ( gOrigPatrolGroup[cnt].ubSectorID[i] )
{
FilePrintf(hFile,"\t\t\t<Sector%d>%c%d</Sector%d>\r\n",
i+1,
(gOrigPatrolGroup[cnt].ubSectorID[i] / 16 + 0x41),
(gOrigPatrolGroup[cnt].ubSectorID[i] % 16 + 1),
i+1);
}
else
{
FilePrintf(hFile,"\t\t\t<Sector%d>0</Sector%d>\r\n", i+1, i+1);
}
}
FilePrintf(hFile,"\t\t</Waypoints>\r\n");
FilePrintf(hFile,"\t</PATROL>\r\n");
}
FilePrintf(hFile,"</PATROL_INFO>\r\n");
}
FileClose( hFile );
return TRUE;
}
// Army composition externalization
typedef enum
{
COMPOSITION_ELEMENT_NONE = 0,
COMPOSITION_ELEMENT_COMPOSITION_INFO,
COMPOSITION_ELEMENT_COMPOSITION,
COMPOSITION_ELEMENT_INDEX,
COMPOSITION_ELEMENT_PRIORITY,
COMPOSITION_ELEMENT_ELITE_PERCENTAGE,
COMPOSITION_ELEMENT_TROOP_PERCENTAGE,
COMPOSITION_ELEMENT_ADMIN_PERCENTAGE,
COMPOSITION_ELEMENT_DESIRED_POPULATION,
COMPOSITION_ELEMENT_START_POPULATION
} COMPOSITION_PARSE_STAGE;
typedef struct
{
INT32 iIndex;
INT8 bPriority;
INT8 bElitePercentage;
INT8 bTroopPercentage;
INT8 bAdminPercentage;
INT8 bDesiredPopulation;
INT8 bStartPopulation;
} compositionInfo;
typedef struct
{
COMPOSITION_PARSE_STAGE curElement;
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
compositionInfo curCompositionInfo;
INT32 iHighestIndex;
UINT32 currentDepth;
UINT32 maxReadDepth;
} compositionParseData;
static void XMLCALL
compositionStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
{
compositionParseData * pData = (compositionParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
{
if(strcmp(name, "COMPOSITION_INFO") == 0 && pData->curElement == COMPOSITION_ELEMENT_NONE)
{
pData->curElement = COMPOSITION_ELEMENT_COMPOSITION_INFO;
memset( gOrigArmyComp, 0, sizeof(gOrigArmyComp) );
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "COMPOSITION") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION_INFO)
{
pData->curElement = COMPOSITION_ELEMENT_COMPOSITION;
memset( &pData->curCompositionInfo, 0, sizeof(compositionInfo) );
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Index") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION)
{
pData->curElement = COMPOSITION_ELEMENT_INDEX;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Priority") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION)
{
pData->curElement = COMPOSITION_ELEMENT_PRIORITY;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "ElitePercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION)
{
pData->curElement = COMPOSITION_ELEMENT_ELITE_PERCENTAGE;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "TroopPercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION)
{
pData->curElement = COMPOSITION_ELEMENT_TROOP_PERCENTAGE;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "AdminPercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION)
{
pData->curElement = COMPOSITION_ELEMENT_ADMIN_PERCENTAGE;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "DesiredPopulation") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION)
{
pData->curElement = COMPOSITION_ELEMENT_DESIRED_POPULATION;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "StartPopulation") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION)
{
pData->curElement = COMPOSITION_ELEMENT_START_POPULATION;
pData->maxReadDepth++; //we are not skipping this element
}
pData->szCharData[0] = '\0';
}
pData->currentDepth++;
}
static void XMLCALL
compositionCharacterDataHandle(void *userData, const XML_Char *str, int len)
{
compositionParseData * pData = (compositionParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth && strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
}
static void XMLCALL
compositionEndElementHandle(void *userData, const XML_Char *name)
{
compositionParseData * pData = (compositionParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
{
if(strcmp(name, "COMPOSITION_INFO") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION_INFO)
{
pData->curElement = COMPOSITION_ELEMENT_NONE;
NUM_ARMY_COMPOSITIONS = (UINT8)(pData->iHighestIndex + 1);
}
else if(strcmp(name, "COMPOSITION") == 0 && pData->curElement == COMPOSITION_ELEMENT_COMPOSITION)
{
pData->curElement = COMPOSITION_ELEMENT_COMPOSITION_INFO;
if ( pData->curCompositionInfo.iIndex < MAX_ARMY_COMPOSITIONS )
{
gOrigArmyComp[ pData->curCompositionInfo.iIndex ].iReadability = pData->curCompositionInfo.iIndex;
gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bPriority = pData->curCompositionInfo.bPriority;
gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bElitePercentage = pData->curCompositionInfo.bElitePercentage;
gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bTroopPercentage = pData->curCompositionInfo.bTroopPercentage;
gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bAdminPercentage = pData->curCompositionInfo.bAdminPercentage;
gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bDesiredPopulation = pData->curCompositionInfo.bDesiredPopulation;
gOrigArmyComp[ pData->curCompositionInfo.iIndex ].bStartPopulation = pData->curCompositionInfo.bStartPopulation;
}
}
else if(strcmp(name, "Index") == 0 && pData->curElement == COMPOSITION_ELEMENT_INDEX)
{
pData->curElement = COMPOSITION_ELEMENT_COMPOSITION;
pData->curCompositionInfo.iIndex = (INT32) atol(pData->szCharData);
if ( pData->curCompositionInfo.iIndex < MAX_ARMY_COMPOSITIONS )
{
if ( pData->curCompositionInfo.iIndex > pData->iHighestIndex )
{
pData->iHighestIndex = pData->curCompositionInfo.iIndex;
}
}
}
else if(strcmp(name, "Priority") == 0 && pData->curElement == COMPOSITION_ELEMENT_PRIORITY)
{
pData->curElement = COMPOSITION_ELEMENT_COMPOSITION;
pData->curCompositionInfo.bPriority = (INT8) atol(pData->szCharData);
if ( pData->curCompositionInfo.bPriority < 0 )
pData->curCompositionInfo.bPriority = 0;
else if ( pData->curCompositionInfo.bPriority > 100 )
pData->curCompositionInfo.bPriority = 100;
}
else if(strcmp(name, "ElitePercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_ELITE_PERCENTAGE)
{
pData->curElement = COMPOSITION_ELEMENT_COMPOSITION;
pData->curCompositionInfo.bElitePercentage = (INT8) atol(pData->szCharData);
if ( pData->curCompositionInfo.bElitePercentage < 0 )
pData->curCompositionInfo.bElitePercentage = 0;
else if ( pData->curCompositionInfo.bElitePercentage > 100 )
pData->curCompositionInfo.bElitePercentage = 100;
}
else if(strcmp(name, "TroopPercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_TROOP_PERCENTAGE)
{
pData->curElement = COMPOSITION_ELEMENT_COMPOSITION;
pData->curCompositionInfo.bTroopPercentage = (INT8) atol(pData->szCharData);
if ( pData->curCompositionInfo.bTroopPercentage < 0 )
pData->curCompositionInfo.bTroopPercentage = 0;
else if ( pData->curCompositionInfo.bTroopPercentage > 100 )
pData->curCompositionInfo.bTroopPercentage = 100;
}
else if(strcmp(name, "AdminPercentage") == 0 && pData->curElement == COMPOSITION_ELEMENT_ADMIN_PERCENTAGE)
{
pData->curElement = COMPOSITION_ELEMENT_COMPOSITION;
pData->curCompositionInfo.bAdminPercentage = (INT8) atol(pData->szCharData);
if ( pData->curCompositionInfo.bAdminPercentage < 0 )
pData->curCompositionInfo.bAdminPercentage = 0;
else if ( pData->curCompositionInfo.bAdminPercentage > 100 )
pData->curCompositionInfo.bAdminPercentage = 100;
}
else if(strcmp(name, "DesiredPopulation") == 0 && pData->curElement == COMPOSITION_ELEMENT_DESIRED_POPULATION)
{
pData->curElement = COMPOSITION_ELEMENT_COMPOSITION;
pData->curCompositionInfo.bDesiredPopulation = (INT8) atol(pData->szCharData);
if ( pData->curCompositionInfo.bDesiredPopulation < 0 )
pData->curCompositionInfo.bDesiredPopulation = 1;
}
else if(strcmp(name, "StartPopulation") == 0 && pData->curElement == COMPOSITION_ELEMENT_START_POPULATION)
{
pData->curElement = COMPOSITION_ELEMENT_COMPOSITION;
pData->curCompositionInfo.bStartPopulation = (INT8) atol(pData->szCharData);
if ( pData->curCompositionInfo.bStartPopulation < 0 )
pData->curCompositionInfo.bStartPopulation = 1;
}
pData->maxReadDepth--;
}
pData->currentDepth--;
}
BOOLEAN ReadInArmyCompositionInfo(STR fileName)
{
HWFILE hFile;
UINT32 uiBytesRead;
UINT32 uiFSize;
CHAR8 * lpcBuffer;
XML_Parser parser = XML_ParserCreate(NULL);
compositionParseData pData;
// Open weapons file
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
if ( !hFile )
return( FALSE );
uiFSize = FileGetSize(hFile);
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
//Read in block
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
{
MemFree(lpcBuffer);
return( FALSE );
}
lpcBuffer[uiFSize] = 0; //add a null terminator
FileClose( hFile );
XML_SetElementHandler(parser, compositionStartElementHandle, compositionEndElementHandle);
XML_SetCharacterDataHandler(parser, compositionCharacterDataHandle);
memset(&pData,0,sizeof(pData));
XML_SetUserData(parser, &pData);
NUM_ARMY_COMPOSITIONS = 0;
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
{
CHAR8 errorBuf[511];
sprintf(errorBuf, "XML Parser Error in ArmyComposition.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
LiveMessage(errorBuf);
MemFree(lpcBuffer);
return FALSE;
}
MemFree(lpcBuffer);
XML_ParserFree(parser);
return TRUE;
}
BOOLEAN WriteInArmyCompositionInfo(STR fileName)
{
HWFILE hFile;
hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
if ( !hFile )
return( FALSE );
{
INT8 cnt;
FilePrintf(hFile,"<COMPOSITION_INFO>\r\n");
for(cnt = 0; cnt < NUM_ARMY_COMPOSITIONS; cnt++)
{
FilePrintf(hFile,"\t<COMPOSITION>\r\n");
FilePrintf(hFile,"\t\t<Index>%d</Index>\r\n", gOrigArmyComp[cnt].iReadability );
FilePrintf(hFile,"\t\t<Priority>%d</Priority>\r\n", gOrigArmyComp[cnt].bPriority);
FilePrintf(hFile,"\t\t<ElitePercentage>%d</ElitePercentage>\r\n", gOrigArmyComp[cnt].bElitePercentage);
FilePrintf(hFile,"\t\t<TroopPercentage>%d</TroopPercentage>\r\n", gOrigArmyComp[cnt].bTroopPercentage);
FilePrintf(hFile,"\t\t<AdminPercentage>%d</AdminPercentage>\r\n", gOrigArmyComp[cnt].bAdminPercentage);
FilePrintf(hFile,"\t\t<DesiredPopulation>%d</DesiredPopulation>\r\n", gOrigArmyComp[cnt].bDesiredPopulation);
FilePrintf(hFile,"\t\t<StartPopulation>%d</StartPopulation>\r\n", gOrigArmyComp[cnt].bStartPopulation);
FilePrintf(hFile,"\t</COMPOSITION>\r\n");
}
FilePrintf(hFile,"</COMPOSITION_INFO>\r\n");
}
FileClose( hFile );
return TRUE;
}