*** Merged Code from Multiplayer Branch Revision 2960 ***

- Virtual File System (VFS) by birdflu. This is needed for Multiplayer and is also used for Single Player. Very neat system :-)
- Multiplayer Version 1.1 + some additional features and bugfixes
* INFO: If you compile a new EXE and want to test, be sure to also use the latest SVN GameDir files in your JA2 install directory *




git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@2961 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2009-06-04 21:01:45 +00:00
parent 17f44f63e8
commit 47db604b50
301 changed files with 76701 additions and 1843 deletions
+44 -11
View File
@@ -12,6 +12,7 @@
#include "music control.h"
#include "Timer Control.h"
#include "sysutil.h"
#include "math.h"
#endif
double rStart, rEnd;
@@ -23,7 +24,6 @@ double rActual;
PROGRESSBAR *pBar[ MAX_PROGRESSBARS ];
BOOLEAN gfUseLoadScreenProgressBar = FALSE;
UINT16 gusLeftmostShaded = 0;
extern BOOLEAN bShowSmallImage;
@@ -31,7 +31,6 @@ extern BOOLEAN bShowSmallImage;
void CreateLoadingScreenProgressBar()
{
gusLeftmostShaded = 162;
gfUseLoadScreenProgressBar = TRUE;
// Special case->show small image centered
if (bShowSmallImage == TRUE)
@@ -56,19 +55,28 @@ void CreateLoadingScreenProgressBar()
CreateProgressBar(0, 259, 683, 767, 708);
}
}
SetProgressBarUseBorder(0, FALSE );
}
void RemoveLoadingScreenProgressBar()
{
gfUseLoadScreenProgressBar = FALSE;
RemoveProgressBar( 0 );
SetFontShadow(DEFAULT_SHADOW);
}
// OJW - 20090422
void CreateProgressBarNoBorder( UINT8 ubProgressBarID, UINT16 usLeft, UINT16 usTop, UINT16 usRight, UINT16 usBottom )
{
CreateProgressBar( ubProgressBarID, usLeft, usTop, usRight, usBottom );
SetProgressBarUseBorder( ubProgressBarID, FALSE );
}
//This creates a single progress bar given the coordinates without a panel (containing a title and background).
//A panel is automatically created if you specify a title using SetProgressBarTitle
BOOLEAN CreateProgressBar( UINT8 ubProgressBarID, UINT16 usLeft, UINT16 usTop, UINT16 usRight, UINT16 usBottom )
{
PROGRESSBAR *pNew;
//Allocate new progress bar
pNew = (PROGRESSBAR*)MemAlloc( sizeof( PROGRESSBAR ) );
@@ -100,6 +108,10 @@ BOOLEAN CreateProgressBar( UINT8 ubProgressBarID, UINT16 usLeft, UINT16 usTop, U
pNew->ubColorFillBlue = 0;
pNew->fDisplayText = FALSE;
//OJW - 20090222
pNew->uiFrameBuffer = FRAME_BUFFER;
pNew->fDrawBorder = TRUE;
return TRUE;
}
@@ -166,6 +178,27 @@ void SetProgressBarMsgAttributes( UINT32 ubID, UINT32 usFont, UINT8 ubForeColor,
pCurr->ubMsgFontShadowColor = ubShadowColor;
}
//OJW - 20090422
void SetProgressBarRenderBuffer( UINT32 ubID , UINT32 uiBufferID )
{
PROGRESSBAR *pCurr;
Assert( ubID < MAX_PROGRESSBARS );
pCurr = pBar[ ubID ];
if( !pCurr )
return;
pCurr->uiFrameBuffer = uiBufferID;
}
void SetProgressBarUseBorder( UINT32 ubID , BOOLEAN bBorder )
{
PROGRESSBAR *pCurr;
Assert( ubID < MAX_PROGRESSBARS );
pCurr = pBar[ ubID ];
if( !pCurr )
return;
pCurr->fDrawBorder = bBorder;
}
//When finished, the progress bar needs to be removed.
void RemoveProgressBar( UINT8 ubID )
@@ -198,8 +231,8 @@ void SetRelativeStartAndEndPercentage( UINT8 ubID, UINT32 uiRelStartPerc, UINT32
if( !pCurr )
return;
pCurr->rStart = uiRelStartPerc*0.01;
pCurr->rEnd = uiRelEndPerc*0.01;
pCurr->rStart = (double)uiRelStartPerc*0.01f;
pCurr->rEnd = (double)uiRelEndPerc*0.01f;
//Render the entire panel now, as it doesn't need update during the normal rendering
if( pCurr->fPanel )
@@ -271,7 +304,7 @@ void RenderProgressBar( UINT8 ubID, UINT32 uiPercentage )
{
rActual = pCurr->rStart+(pCurr->rEnd-pCurr->rStart)*uiPercentage*0.01;
if( rActual - pCurr->rLastActual < 0.01 )
if( fabs(rActual - pCurr->rLastActual) < 0.01 )
{
return;
}
@@ -283,9 +316,9 @@ void RenderProgressBar( UINT8 ubID, UINT32 uiPercentage )
{
return;
}
if( gfUseLoadScreenProgressBar )
if( !pCurr->fDrawBorder )
{
ColorFillVideoSurfaceArea( FRAME_BUFFER,
ColorFillVideoSurfaceArea( pCurr->uiFrameBuffer, //FRAME_BUFFER,
pCurr->usBarLeft, pCurr->usBarTop, end, pCurr->usBarBottom,
Get16BPPColor(FROMRGB( pCurr->ubColorFillRed, pCurr->ubColorFillGreen, pCurr->ubColorFillBlue )) );
//if( pCurr->usBarRight > gusLeftmostShaded )
@@ -297,14 +330,14 @@ void RenderProgressBar( UINT8 ubID, UINT32 uiPercentage )
else
{
//Border edge of the progress bar itself in gray
ColorFillVideoSurfaceArea( FRAME_BUFFER,
ColorFillVideoSurfaceArea( pCurr->uiFrameBuffer,
pCurr->usBarLeft, pCurr->usBarTop, pCurr->usBarRight, pCurr->usBarBottom,
Get16BPPColor(FROMRGB(160, 160, 160)) );
//Interior of progress bar in black
ColorFillVideoSurfaceArea( FRAME_BUFFER,
ColorFillVideoSurfaceArea( pCurr->uiFrameBuffer,
pCurr->usBarLeft+2, pCurr->usBarTop+2, pCurr->usBarRight-2, pCurr->usBarBottom-2,
Get16BPPColor(FROMRGB( 0, 0, 0)) );
ColorFillVideoSurfaceArea(FRAME_BUFFER, pCurr->usBarLeft+2, pCurr->usBarTop+2, end, pCurr->usBarBottom-2, Get16BPPColor(FROMRGB(72 , 155, 24)));
ColorFillVideoSurfaceArea(pCurr->uiFrameBuffer, pCurr->usBarLeft+2, pCurr->usBarTop+2, end, pCurr->usBarBottom-2, Get16BPPColor(FROMRGB(72 , 155, 24)));
}
InvalidateRegion( pCurr->usBarLeft, pCurr->usBarTop, pCurr->usBarRight, pCurr->usBarBottom );
ExecuteBaseDirtyRectQueue();
+11
View File
@@ -25,6 +25,8 @@ typedef struct PROGRESSBAR
BOOLEAN fDisplayText;
BOOLEAN fUseSaveBuffer; //use the save buffer when display the text
double rLastActual;
UINT32 uiFrameBuffer;
BOOLEAN fDrawBorder;
}PROGRESSBAR;
extern PROGRESSBAR *pBar[ MAX_PROGRESSBARS ];
@@ -75,4 +77,13 @@ void SetProgressBarColor( UINT8 ubID, UINT8 ubColorFillRed, UINT8 ubColorFillGre
//Pass in TRUE to display the strings.
void SetProgressBarTextDisplayFlag( UINT8 ubID, BOOLEAN fDisplayText, BOOLEAN fUseSaveBuffer, BOOLEAN fSaveScreenToFrameBuffer );
// OJW - 20090422
// draw the progress bar with a white border, or not
void SetProgressBarUseBorder( UINT32 ubID , BOOLEAN bBorder );
// specify which buffer to render the bar to
void SetProgressBarRenderBuffer( UINT32 ubID , UINT32 uiBufferID );
// create a color bar with no border
void CreateProgressBarNoBorder( UINT8 ubProgressBarID, UINT16 usLeft, UINT16 usTop, UINT16 usRight, UINT16 usBottom );
#endif
+12 -1
View File
@@ -6,7 +6,8 @@
#include "stdio.h"
#endif
#include "vfs.h"
#include "PropertyContainer.h"
#ifdef _ANIMSUBSYSTEM_DEBUG
@@ -59,6 +60,7 @@ void AiDbgMessage( CHAR8 *strMessage)
void LiveMessage( CHAR8 *strMessage)
{
#ifndef USE_VFS
FILE *OutFile;
if ((OutFile = fopen("Log.txt", "a+t")) != NULL)
@@ -66,9 +68,14 @@ void LiveMessage( CHAR8 *strMessage)
fprintf(OutFile, "%s\n", strMessage);
fclose(OutFile);
}
#else
static CLog& liveMsg = *CLog::Create(L"LiveLog.txt",true);
liveMsg << strMessage << CLog::endl;
#endif
}
void MPDebugMsg( CHAR8 *strMessage)
{
#ifndef USE_VFS
FILE *OutFile;
if ((OutFile = fopen("MPDebug.txt", "a+t")) != NULL)
@@ -76,4 +83,8 @@ void MPDebugMsg( CHAR8 *strMessage)
fprintf(OutFile, "%s\n", strMessage);
fclose(OutFile);
}
#else
static CLog& mpMsg = *CLog::Create(L"MPDebug.txt", true);
mpMsg << strMessage << CLog::endl;
#endif
}
+128 -72
View File
@@ -8,15 +8,31 @@
#include <string.h>
#include <sstream>
#include <float.h> //limits for float/double vars ie. DBL_MAX FLT_MAX
// Kaiden: INI reading function definitions:
#include "VFS/vfs.h"
std::stack<std::string> iniErrorMessages;
template<typename ValueType>
void PushErrorMessage(std::string const& filename,
std::string const& section,
std::string const& key,
ValueType value, ValueType used_value,
ValueType minVal, ValueType maxVal)
{
std::stringstream errMessage;
errMessage << "The value [" << section << "][" << key << "] = \"" << value << "\" "
<< "in file [" << filename << "] "
<< "is outside the valid range [" << minVal << " , " << maxVal << "]. "
<< used_value << " will be used.";
iniErrorMessages.push(errMessage.str());
}
CIniReader::CIniReader(const STR8 szFileName)
{
memset(m_szFileName,0,sizeof(m_szFileName));
#ifndef USE_VFS
// Snap: Look for the INI file in the custom Data directory.
// If not there, leave at default location.
if ( gCustomDataCat.FindFile(szFileName) ) {
@@ -25,12 +41,18 @@ CIniReader::CIniReader(const STR8 szFileName)
else {
sprintf(m_szFileName, "%s\\%s", gDefaultDataCat.GetRootDir().c_str(), szFileName);
}
#else
strncpy(m_szFileName,szFileName, std::min<int>(strlen(szFileName), sizeof(m_szFileName)-1));
m_oProps.InitFromIniFile(vfs::Path(szFileName));
#endif
}
CIniReader::CIniReader(const STR8 szFileName, BOOLEAN Force_Custom_Data_Path)
{
memset(m_szFileName,0,sizeof(m_szFileName));
// ary-05/05/2009 : force custom data path for potential non existing file -or- force default data path
// : Also, flag file detection to allow functions to determine course of action for case of file [not found/is found].
#ifndef USE_VFS
if ( Force_Custom_Data_Path )
{
if ( gCustomDataCat.FindFile(szFileName) )
@@ -55,32 +77,50 @@ CIniReader::CIniReader(const STR8 szFileName, BOOLEAN Force_Custom_Data_Path)
}
sprintf(m_szFileName, "%s\\%s", gDefaultDataCat.GetRootDir().c_str(), szFileName);
}
#else
strncpy(m_szFileName,szFileName, std::min<int>(strlen(szFileName), sizeof(m_szFileName)-1));
CIniReader_File_Found = m_oProps.InitFromIniFile(vfs::Path(szFileName));
#endif
}
void CIniReader::Clear()
{
#ifndef USE_VFS
memset(m_szFileName, 0, MAX_PATH);
#else
memset(m_szFileName, 0, MAX_PATH);
m_oProps.ClearContainer();
#endif
}
int CIniReader::ReadInteger(const STR8 szSection, const STR8 szKey, int iDefaultValue)
{
#ifndef USE_VFS
return GetPrivateProfileInt(szSection, szKey, iDefaultValue, m_szFileName);
#else
return m_oProps.GetIntProperty(szSection, szKey, iDefaultValue);
#endif
}
int CIniReader::ReadInteger(const STR8 szSection, const STR8 szKey, int defaultValue, int minValue, int maxValue)
{
#ifndef USE_VFS
int iniValueReadFromFile = GetPrivateProfileInt(szSection, szKey, defaultValue, m_szFileName);
#else
int iniValueReadFromFile = m_oProps.GetIntProperty(szSection, szKey, defaultValue);
#endif
//AssertGE(iniValueReadFromFile, minValue);
//AssertLE(iniValueReadFromFile, maxValue);
if (iniValueReadFromFile < minValue) {
std::stringstream errMessage;
errMessage << "The .ini setting " << szKey << "(" << iniValueReadFromFile
<< ") is outside the valid range of " << minValue << " to " << maxValue
<< ". " << minValue << " will be used.";
iniErrorMessages.push(errMessage.str());
if (iniValueReadFromFile < minValue)
{
PushErrorMessage(this->m_szFileName, szSection, szKey, iniValueReadFromFile, minValue, minValue, maxValue);
return minValue;
} else if (iniValueReadFromFile > maxValue) {
std::stringstream errMessage;
errMessage << "The .ini setting " << szKey << "(" << iniValueReadFromFile
<< ") is outside the valid range of " << minValue << " to " << maxValue
<< ". " << maxValue << " will be used.";
iniErrorMessages.push(errMessage.str());
}
else if (iniValueReadFromFile > maxValue)
{
PushErrorMessage(this->m_szFileName, szSection, szKey, iniValueReadFromFile, maxValue, minValue, maxValue);
return maxValue;
}
return iniValueReadFromFile;
@@ -99,32 +139,28 @@ int CIniReader::ReadInteger(const STR8 szSection, const STR8 szKey, int defaultV
// return fltResult;
//}
DOUBLE CIniReader::ReadDouble(const STR8 szSection, const STR8 szKey, DOUBLE defaultValue, DOUBLE minValue, DOUBLE maxValue)
double CIniReader::ReadDouble(const STR8 szSection, const STR8 szKey, double defaultValue, double minValue, double maxValue)
{
double iniValueReadFromFile;
#ifndef USE_VFS
char szResult[255];
char szDefault[255];
DOUBLE iniValueReadFromFile;
sprintf(szDefault, "%f", defaultValue);
GetPrivateProfileString(szSection, szKey, szDefault, szResult, 255, m_szFileName);
iniValueReadFromFile = strtod(szResult, NULL);
iniValueReadFromFile = (float) atof(szResult);
#else
iniValueReadFromFile = m_oProps.GetFloatProperty(szSection, szKey, defaultValue);
#endif
//AssertGE(iniValueReadFromFile, minValue);
//AssertLE(iniValueReadFromFile, maxValue);
if (iniValueReadFromFile < minValue) {
std::stringstream errMessage;
errMessage << "The .ini setting " << szKey << "(" << iniValueReadFromFile
<< ") is outside the valid range of " << minValue << " to " << maxValue
<< ". " << minValue << " will be used.";
iniErrorMessages.push(errMessage.str());
if (iniValueReadFromFile < minValue)
{
PushErrorMessage(this->m_szFileName, szSection, szKey,iniValueReadFromFile, minValue, minValue, maxValue);
return minValue;
} else if (iniValueReadFromFile > maxValue) {
std::stringstream errMessage;
errMessage << "The .ini setting " << szKey << "(" << iniValueReadFromFile
<< ") is outside the valid range of " << minValue << " to " << maxValue
<< ". " << maxValue << " will be used.";
iniErrorMessages.push(errMessage.str());
}
else if (iniValueReadFromFile > maxValue)
{
PushErrorMessage(this->m_szFileName, szSection, szKey, iniValueReadFromFile, maxValue, minValue, maxValue);
return maxValue;
}
return iniValueReadFromFile;
@@ -132,37 +168,36 @@ DOUBLE CIniReader::ReadDouble(const STR8 szSection, const STR8 szKey, DOUBLE def
FLOAT CIniReader::ReadFloat(const STR8 szSection, const STR8 szKey, FLOAT defaultValue, FLOAT minValue, FLOAT maxValue)
{
FLOAT iniValueReadFromFile;
#ifndef USE_VFS
char szResult[255];
char szDefault[255];
FLOAT iniValueReadFromFile;
sprintf(szDefault, "%f", defaultValue);
GetPrivateProfileString(szSection, szKey, szDefault, szResult, 255, m_szFileName);
iniValueReadFromFile = (FLOAT) atof(szResult);
#else
iniValueReadFromFile = (FLOAT) m_oProps.GetFloatProperty(szSection, szKey, (float)defaultValue);
#endif
//AssertGE(iniValueReadFromFile, minValue);
//AssertLE(iniValueReadFromFile, maxValue);
if (iniValueReadFromFile < minValue) {
std::stringstream errMessage;
errMessage << "The .ini setting " << szKey << "(" << iniValueReadFromFile
<< ") is outside the valid range of " << minValue << " to " << maxValue
<< ". " << minValue << " will be used.";
iniErrorMessages.push(errMessage.str());
if (iniValueReadFromFile < minValue)
{
PushErrorMessage(this->m_szFileName, szSection, szKey, iniValueReadFromFile, minValue, minValue, maxValue);
return minValue;
} else if (iniValueReadFromFile > maxValue) {
std::stringstream errMessage;
errMessage << "The .ini setting " << szKey << "(" << iniValueReadFromFile
<< ") is outside the valid range of " << minValue << " to " << maxValue
<< ". " << maxValue << " will be used.";
iniErrorMessages.push(errMessage.str());
}
else if (iniValueReadFromFile > maxValue)
{
PushErrorMessage(this->m_szFileName, szSection, szKey, iniValueReadFromFile, maxValue, minValue, maxValue);
return maxValue;
}
return iniValueReadFromFile;
}
BOOLEAN CIniReader::ReadBoolean(const STR8 szSection, const STR8 szKey, BOOLEAN defaultValue)
BOOLEAN CIniReader::ReadBoolean(const STR8 szSection, const STR8 szKey, bool defaultValue)
{
#ifndef USE_VFS
char szResult[255];
char szDefault[255];
sprintf(szDefault, "%s", defaultValue? "TRUE" : "FALSE");
@@ -173,15 +208,27 @@ BOOLEAN CIniReader::ReadBoolean(const STR8 szSection, const STR8 szKey, BOOLEAN
return TRUE;
else if (strcmp(szResult, "FALSE") == 0)
return FALSE;
#else
utf8string str = m_oProps.GetStringProperty(szSection, szKey, L"");
if( StrCmp::Equal(str, L"true") )
{
return TRUE;
}
else if( StrCmp::Equal(str, L"false") )
{
return FALSE;
}
std::string szResult = str.utf8();
char szDefault[255];
sprintf(szDefault, "%s", defaultValue? "TRUE" : "FALSE");
#endif
std::stringstream errMessage;
errMessage << "The .ini setting " << szKey << "(" << szResult
<< ") is neither TRUE nor FALSE. The value " << szDefault << " will be used.";
errMessage << "The value [" << szSection << "][" << szKey << "] = \"" << szResult << "\" "
<< "in file [" << this->m_szFileName << "] is neither TRUE nor FALSE. The value " << szDefault << " will be used.";
iniErrorMessages.push(errMessage.str());
return defaultValue;
}
// ary-05/15/2009 : snippet on how to use CIniReader::ReadString
// const STR8 test_ini_string = new char[255];
// memset(test_ini_string, 0x00, 255);
@@ -189,16 +236,36 @@ BOOLEAN CIniReader::ReadBoolean(const STR8 szSection, const STR8 szKey, BOOLEAN
void CIniReader::ReadString(const STR8 szSection, const STR8 szKey, const STR8 szDefaultValue, STR8 input_buffer, size_t buffer_size)
{
#ifndef USE_VFS
GetPrivateProfileString(szSection, szKey, szDefaultValue, input_buffer, buffer_size, m_szFileName);
#else
std::string s = m_oProps.GetStringProperty(szSection, szKey, szDefaultValue).utf8();
int len = std::min<unsigned int>(s.length(),buffer_size-1);
strncpy(input_buffer, s.c_str(), len);
input_buffer[len] = 0;
#endif
}
// WANNE - MP: Old version, currently used by Multiplayer
STR8 CIniReader::ReadString(const STR8 szSection, const STR8 szKey, const STR8 szDefaultValue)
{
// >>>>> Memory Leak <<<<<
STR8 szResult = new char[255];
memset(szResult, 0x00, 255);
#ifndef USE_VFS
GetPrivateProfileString(szSection, szKey, szDefaultValue, szResult, 255, m_szFileName);
#else
std::string s = m_oProps.GetStringProperty(szSection, szKey, szDefaultValue).utf8();
strncpy(szResult, s.c_str(), std::min<int>(s.length(),254));
#endif
return szResult;
}
UINT8 CIniReader::ReadUINT8(const STR8 szSection, const STR8 szKey, UINT8 defaultValue, UINT8 minValue, UINT8 maxValue)
{
UINT8 iniValueReadFromFile;
iniValueReadFromFile = (UINT8) this->ReadUINT( szSection, szKey, (UINT32) defaultValue, (UINT32) minValue, (UINT32) maxValue);
return iniValueReadFromFile;
@@ -207,7 +274,6 @@ UINT8 CIniReader::ReadUINT8(const STR8 szSection, const STR8 szKey, UINT8 defa
UINT16 CIniReader::ReadUINT16(const STR8 szSection, const STR8 szKey, UINT16 defaultValue, UINT16 minValue, UINT16 maxValue)
{
UINT16 iniValueReadFromFile;
iniValueReadFromFile = (UINT16) this->ReadUINT( szSection, szKey, (UINT32) defaultValue, (UINT32) minValue, (UINT32) maxValue);
@@ -218,7 +284,6 @@ UINT16 CIniReader::ReadUINT16(const STR8 szSection, const STR8 szKey, UINT16 def
UINT32 CIniReader::ReadUINT32(const STR8 szSection, const STR8 szKey, UINT32 defaultValue, UINT32 minValue, UINT32 maxValue)
{
UINT32 iniValueReadFromFile;
iniValueReadFromFile = (UINT32) this->ReadUINT( szSection, szKey, (UINT32) defaultValue, (UINT32) minValue, (UINT32) maxValue);
@@ -230,7 +295,7 @@ UINT32 CIniReader::ReadUINT32(const STR8 szSection, const STR8 szKey, UINT32 def
UINT32 CIniReader::ReadUINT(const STR8 szSection, const STR8 szKey, UINT32 defaultValue, UINT32 minValue, UINT32 maxValue )
{
UINT32 iniValueReadFromFile;
#ifndef USE_VFS
STR8 szResult = new char[255];
STR8 szDefault = new char[255];
@@ -241,36 +306,27 @@ UINT32 CIniReader::ReadUINT(const STR8 szSection, const STR8 szKey, UINT32 defau
this->ReadString (szSection , szKey , szDefault, szResult, (size_t) 255 );
iniValueReadFromFile = (UINT32) strtoul(szResult,NULL,0);
#else
iniValueReadFromFile = (UINT32) m_oProps.GetUIntProperty(szSection, szKey, defaultValue);
#endif
//AssertGE(iniValueReadFromFile, minValue);
//AssertLE(iniValueReadFromFile, maxValue);
if (iniValueReadFromFile < minValue)
{
std::stringstream errMessage;
errMessage << "The .ini setting " << szKey << "(" << iniValueReadFromFile
<< ") is outside the valid range of " << minValue << " to " << maxValue
<< ". " << minValue << " will be used.";
iniErrorMessages.push(errMessage.str());
PushErrorMessage(this->m_szFileName, szSection, szKey, iniValueReadFromFile, minValue, minValue, maxValue);
iniValueReadFromFile = minValue;
}
else if (iniValueReadFromFile > maxValue)
{
std::stringstream errMessage;
errMessage << "The .ini setting " << szKey << "(" << iniValueReadFromFile
<< ") is outside the valid range of " << minValue << " to " << maxValue
<< ". " << maxValue << " will be used.";
iniErrorMessages.push(errMessage.str());
PushErrorMessage(this->m_szFileName, szSection, szKey, iniValueReadFromFile, maxValue, minValue, maxValue);
iniValueReadFromFile = maxValue;
}
#ifndef USE_VFS
delete [] szResult ;
delete [] szDefault ;
#endif
return iniValueReadFromFile;
}
+9 -3
View File
@@ -6,6 +6,8 @@
#include <stack>
#include <string>
#include "VFS/PropertyContainer.h"
// Kaiden: This will read any value out of
// an INI file as long as the correct type is specified.
// Methods should be fairly self explainatory
@@ -27,7 +29,7 @@ public:
int ReadInteger(const STR8 szSection, const STR8 szKey, int iDefaultValue);
int ReadInteger(const STR8 szSection, const STR8 szKey, int defaultValue, int minValue, int maxValue);
//void testReadUINT32(void);//various limit tests of UINT and double/float handling
//UINT32 CIniReader::testReadUINT32(void);//various limit tests of UINT and double/float handling
//front end functions that control type interpretation and range control, each calls internal ReadUINT
UINT32 ReadUINT32(const STR8 szSection, const STR8 szKey, UINT32 defaultValue, UINT32 minValue, UINT32 maxValue);
UINT16 ReadUINT16(const STR8 szSection, const STR8 szKey, UINT16 defaultValue, UINT16 minValue, UINT16 maxValue);
@@ -40,13 +42,17 @@ public:
DOUBLE ReadDouble(const STR8 szSection, const STR8 szKey, DOUBLE defaultValue, DOUBLE minValue, DOUBLE maxValue);
FLOAT ReadFloat (const STR8 szSection, const STR8 szKey, FLOAT defaultValue, FLOAT minValue, FLOAT maxValue);
BOOLEAN ReadBoolean(const STR8 szSection, const STR8 szKey, BOOLEAN bolDefaultValue);
BOOLEAN ReadBoolean(const STR8 szSection, const STR8 szKey, bool bolDefaultValue);
void ReadString(const STR8 szSection, const STR8 szKey, const STR8 szDefaultValue, STR8 input_buffer, size_t buffer_size);
// WANNE - MP: Old version, currently used by Multiplayer
STR8 ReadString(const STR8 szSection, const STR8 szKey, const STR8 szDefaultValue);
BOOLEAN Is_CIniReader_File_Found(void) {return (CIniReader_File_Found);}
void Clear();
private:
CPropertyContainer m_oProps;
char m_szFileName[MAX_PATH];
BOOLEAN CIniReader_File_Found;
+12
View File
@@ -126,6 +126,9 @@ BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID )
case MLG_BR:
sprintf( filename, "LAPTOP\\BR.STI" );
return TRUE;
case MLG_MP_GOLDPIECEBUTTONS:
sprintf( filename, "INTERFACE\\MPGOLDPIECEBUTTONS.sti" );
return TRUE;
}
#elif defined( GERMAN )
@@ -245,6 +248,9 @@ BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID )
case MLG_BR:
sprintf( filename, "LAPTOP\\BR.STI" );
return TRUE;
case MLG_MP_GOLDPIECEBUTTONS:
sprintf( filename, "GERMAN\\MPGOLDPIECEBUTTONS_german.sti" );
return TRUE;
}
#else
@@ -398,6 +404,9 @@ BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID )
case MLG_BR:
sprintf( filename, "%s\\BR_%s.STI", zLanguage, zLanguage );
break;
case MLG_MP_GOLDPIECEBUTTONS:
sprintf( filename, "%s\\MPGOLDPIECEBUTTONS_%s.sti", zLanguage, zLanguage );
break
default:
return FALSE;
}
@@ -516,6 +525,9 @@ BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID )
case MLG_BR:
sprintf( filename, "LAPTOP\\BR.STI" );
return TRUE;
case MLG_MP_GOLDPIECEBUTTONS:
sprintf( filename, "INTERFACE\\MPGOLDPIECEBUTTONS.sti" );
return TRUE;
}
#endif
+1
View File
@@ -40,6 +40,7 @@ enum
MLG_TITLETEXT_MP, // ROMAN: Additional multiplayer text
MLG_BOBBYRAYTITLE, //inshy: translation needed for russian version
MLG_BR,
MLG_MP_GOLDPIECEBUTTONS,
};
BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID );
+1
View File
@@ -7,5 +7,6 @@
void WriteSTIFile( INT8 *pData, SGPPaletteEntry *pPalette, INT16 sWidth, INT16 sHeight, STR cOutputName, UINT32 fFlags, UINT32 uiAppDataSize );
UINT32 ETRLECompressSubImage( UINT8 * pDest, UINT32 uiDestLen, UINT8 * p8BPPBuffer, UINT16 usWidth, UINT16 usHeight, STCISubImage * pSubImage );
#endif
+211 -28
View File
@@ -33,6 +33,11 @@ void AddChar( UINT32 uiKey );
void RemoveChar( UINT8 ubArrayIndex );
void DeleteHilitedText();
// OJW - 20090427 - Copy/Paste text to/from the clipboard
UINT32 PasteClipboardText();
void CopyToClipboard( void );
void DoublePercentileCharacterFromStringIntoString( STR16 pSrcString, STR16 pDstString );
//All exclusive input types are handled in this function.
@@ -140,6 +145,8 @@ BOOLEAN gfHiliteMode = FALSE;
UINT8 gubCursorPos = 0;
UINT8 gubStartHilite = 0;
UINT8 gubEndHilite = 0;
// OJW - 20090426
UINT8 gubParkingPos = 0; // start of the visible string we render in the textbox
//allow the user to cut, copy, and paste just like windows.
CHAR16 gszClipboardString[256];
@@ -285,6 +292,7 @@ void AddTextInputField( INT16 sLeft, INT16 sTop, INT16 sWidth, INT16 sHeight, IN
//if this is the first field, then hilight it.
if( gpTextInputHead == pNode )
{
gubParkingPos = 0;
gubStartHilite = 0;
gubEndHilite = pNode->ubStrLen;
gubCursorPos = pNode->ubStrLen;
@@ -443,7 +451,7 @@ void SetInputFieldStringWith8BitString( UINT8 ubField, const STR8 szNewText )
}
//Allows external functions to access the strings within the fields at anytime.
void Get8BitStringFromField( UINT8 ubField, STR8 szString )
void Get8BitStringFromField( UINT8 ubField, STR8 szString, UINT32 uiBufferSize )
{
TEXTINPUTNODE *curr;
curr = gpTextInputHead;
@@ -451,7 +459,12 @@ void Get8BitStringFromField( UINT8 ubField, STR8 szString )
{
if( curr->ubID == ubField )
{
sprintf( szString, "%S", curr->szString );
size_t len = __min(uiBufferSize, wcslen(curr->szString)+1);
#ifdef WIN32
sprintf_s(szString, len, "%S", curr->szString );
#else
snprintf(szString, len, "%S", curr->szString );
#endif
return;
}
curr = curr->next;
@@ -459,7 +472,7 @@ void Get8BitStringFromField( UINT8 ubField, STR8 szString )
szString[0] = '\0';
}
void Get16BitStringFromField( UINT8 ubField, STR16 szString )
void Get16BitStringFromField( UINT8 ubField, STR16 szString, UINT32 uiBufferSize )
{
TEXTINPUTNODE *curr;
curr = gpTextInputHead;
@@ -467,7 +480,8 @@ void Get16BitStringFromField( UINT8 ubField, STR16 szString )
{
if( curr->ubID == ubField )
{
swprintf( szString, curr->szString );
size_t len = __min(uiBufferSize, wcslen(curr->szString)+1);
swprintf( szString, len, curr->szString );
return;
}
curr = curr->next;
@@ -482,7 +496,7 @@ INT32 GetNumericStrictValueFromField( UINT8 ubField )
STR16 ptr;
CHAR16 str[20];
INT32 total;
Get16BitStringFromField( ubField, str );
Get16BitStringFromField( ubField, str, 20 );
//Blank string, so return -1
if( str[0] == '\0' )
return -1;
@@ -544,6 +558,7 @@ void SetActiveField( UINT8 ubField )
gpActive = curr;
if( gpActive->szString )
{
gubParkingPos = 0;
gubStartHilite = 0;
gubEndHilite = gpActive->ubStrLen;
gubCursorPos = gpActive->ubStrLen;
@@ -585,6 +600,7 @@ void SelectNextField()
fDone = TRUE;
if( gpActive->szString )
{
gubParkingPos = 0;
gubStartHilite = 0;
gubEndHilite = gpActive->ubStrLen;
gubCursorPos = gpActive->ubStrLen;
@@ -629,6 +645,7 @@ void SelectPrevField()
fDone = TRUE;
if( gpActive->szString )
{
gubParkingPos = 0;
gubStartHilite = 0;
gubEndHilite = gpActive->ubStrLen;
gubCursorPos = gpActive->ubStrLen;
@@ -738,23 +755,39 @@ BOOLEAN HandleTextInput( InputAtom *Event )
}
//For any number of reasons, these ALT and CTRL combination key presses
//will be processed externally
#if 0
#if 1
if( Event->usKeyState & CTRL_DOWN )
{
if( Event->usParam == 'c' || Event->usParam == 'C' )
{
ExecuteCopyCommand();
return TRUE;
// only swallow key if we did anything
if (szClipboard && wcslen(szClipboard)>0)
return TRUE;
else
return FALSE;
}
else if( Event->usParam == 'x' || Event->usParam == 'X' )
{
ExecuteCutCommand();
return TRUE;
// only swallow key if we did anything
if (szClipboard && wcslen(szClipboard)>0)
return TRUE;
else
return FALSE;
}
else if( Event->usParam == 'v' || Event->usParam == 'V' )
{
PasteClipboardText();
ExecutePasteCommand();
return TRUE;
// only swallow key if we did anything
if (szClipboard && wcslen(szClipboard)>0)
return TRUE;
else
return FALSE;
}
}
#endif
@@ -1161,13 +1194,16 @@ void MouseMovedInTextRegionCallback(MOUSE_REGION *reg, INT32 reason)
//Calculate the cursor position.
iClickX = gusMouseXPos - reg->RegionTopLeftX;
iCurrCharPos = 0;
gubCursorPos = 0;
iNextCharPos = StringPixLengthArg( pColors->usFont, 1, gpActive->szString ) / 2;
gubCursorPos = gubParkingPos;
iNextCharPos = SubstringPixLength(gpActive->szString,gubParkingPos, gubCursorPos, pColors->usFont) / 2;
while( iCurrCharPos + (iNextCharPos-iCurrCharPos)/2 < iClickX && gubCursorPos < gpActive->ubStrLen )
{
gubCursorPos++;
if (gubCursorPos >= gpActive->ubStrLen)
break;
iCurrCharPos = iNextCharPos;
iNextCharPos = StringPixLengthArg( pColors->usFont, gubCursorPos + 1, gpActive->szString );
iNextCharPos = SubstringPixLength(gpActive->szString,gubParkingPos, gubCursorPos, pColors->usFont);
}
gubEndHilite = gubCursorPos;
if( gubEndHilite != gubStartHilite )
@@ -1193,7 +1229,8 @@ void MouseClickedInTextRegionCallback(MOUSE_REGION *reg, INT32 reason)
{
if( curr->ubID == ubNewID )
{
gpActive = curr;
//gpActive = curr;
SetActiveField(ubNewID);
break;
}
curr = curr->next;
@@ -1204,13 +1241,15 @@ void MouseClickedInTextRegionCallback(MOUSE_REGION *reg, INT32 reason)
//Calculate the cursor position.
iClickX = gusMouseXPos - reg->RegionTopLeftX;
iCurrCharPos = 0;
gubCursorPos = 0;
iNextCharPos = StringPixLengthArg( pColors->usFont, 1, gpActive->szString ) / 2;
gubCursorPos = gubParkingPos;
iNextCharPos = SubstringPixLength(gpActive->szString,gubParkingPos, gubCursorPos, pColors->usFont) / 2;//StringPixLengthArg( pColors->usFont, 1, gpActive->szString ) / 2;
while( iCurrCharPos + (iNextCharPos-iCurrCharPos)/2 < iClickX && gubCursorPos < gpActive->ubStrLen )
{
gubCursorPos++;
if (gubCursorPos >= gpActive->ubStrLen)
break;
iCurrCharPos = iNextCharPos;
iNextCharPos = StringPixLengthArg( pColors->usFont, gubCursorPos + 1, gpActive->szString );
iNextCharPos = SubstringPixLength(gpActive->szString,gubParkingPos, gubCursorPos, pColors->usFont);
}
gubStartHilite = gubCursorPos; //This value is the anchor
gubEndHilite = gubCursorPos; //The end will move with the cursor as long as it's down.
@@ -1254,6 +1293,57 @@ void RenderActiveTextField()
SetFont( pColors->usFont );
usOffset = (UINT16)(( gpActive->region.RegionBottomRightY - gpActive->region.RegionTopLeftY - GetFontHeight( pColors->usFont ) ) / 2);
RenderBackgroundField( gpActive );
// OJW - 20090426
// Scroll string if message is larger than the textbox area
UINT16 strPixLen = StringPixLength( gpActive->szString , pColors->usFont );
UINT16 regionXLen = gpActive->region.RegionBottomRightX - gpActive->region.RegionTopLeftX - 6; // 3 pixel gap either side
CHAR16 scrollStr[ 256 ]; // the visible portion of the string based on where we moved with the cursor
UINT16 scrollStrLen = 0; // the length of the new string to render
UINT8 scrollCursorPos = gubCursorPos; // the relative position of the cursor (for drawing only)
memset(scrollStr,0,256*sizeof(CHAR16));
// if string to big to fit in text box...
if ( strPixLen > regionXLen )
{
// if the cursor is left of the visible position
if (gubCursorPos < gubParkingPos)
{
// shift the visible string left
gubParkingPos = gubCursorPos;
}
// if the cursor is right of the visible position
else if (gubCursorPos > gubParkingPos)
{
// if the cursor is outside of the visible area on the right
UINT16 visPixLengthToCursor = SubstringPixLength(gpActive->szString,gubParkingPos,gubCursorPos-1, pColors->usFont);
if (visPixLengthToCursor > regionXLen)
{
// shift the visble string right
// find out how many characters to shift the parked character right by
UINT16 diff = visPixLengthToCursor - regionXLen;
UINT16 j = 0; // the number of characters
for (j = 0; j <= (gubCursorPos - gubParkingPos); j++)
{
if (SubstringPixLength( gpActive->szString, gubParkingPos, gubParkingPos+j, pColors->usFont) >= diff)
break;
}
gubParkingPos += j + 1;
}
}
scrollCursorPos = gubCursorPos - gubParkingPos; // set the relative cursor position (for drawing only)
scrollStrLen = gpActive->ubStrLen - gubParkingPos;
memcpy(scrollStr,&gpActive->szString[gubParkingPos], scrollStrLen*sizeof(CHAR16));
}
else
{
scrollCursorPos = gubCursorPos;
scrollStrLen = gpActive->ubStrLen;
memcpy(scrollStr,gpActive->szString, scrollStrLen*sizeof(CHAR16));
}
// end scroll string code
if( gfHiliteMode && gubStartHilite != gubEndHilite )
{ //Some or all of the text is hilighted, so we will use a different method.
UINT16 i;
@@ -1261,18 +1351,19 @@ void RenderActiveTextField()
//sort the hilite order.
if( gubStartHilite < gubEndHilite )
{
usStart = gubStartHilite;
usEnd = gubEndHilite;
// translate hilite positions into the shifted string
usStart = gubStartHilite - gubParkingPos;
usEnd = gubEndHilite - gubParkingPos;
}
else
{
usStart = gubEndHilite;
usEnd = gubStartHilite;
usStart = gubEndHilite - gubParkingPos;
usEnd = gubStartHilite - gubParkingPos;
}
//Traverse the string one character at a time, and draw the highlited part differently.
for( i = 0; i < gpActive->ubStrLen; i++ )
for( i = 0; i < scrollStrLen; i++ )
{
uiCursorXPos = StringPixLengthArg( pColors->usFont, i, gpActive->szString ) + 3;
uiCursorXPos = StringPixLengthArg( pColors->usFont, i, scrollStr ) + 3;
if( i >= usStart && i < usEnd )
{ //in highlighted part of text
SetFontForeground( pColors->ubHiForeColor );
@@ -1285,9 +1376,9 @@ void RenderActiveTextField()
SetFontShadow( pColors->ubShadowColor );
SetFontBackground( 0 );
}
if( gpActive->szString[i] != '%' )
if( scrollStr[i] != '%' )
{
mprintf( uiCursorXPos + gpActive->region.RegionTopLeftX, gpActive->region.RegionTopLeftY + usOffset, L"%c", gpActive->szString[i] );
mprintf( uiCursorXPos + gpActive->region.RegionTopLeftX, gpActive->region.RegionTopLeftY + usOffset, L"%c", scrollStr[i] );
}
else
{
@@ -1300,14 +1391,14 @@ void RenderActiveTextField()
SetFontForeground( pColors->ubForeColor );
SetFontShadow( pColors->ubShadowColor );
SetFontBackground( 0 );
DoublePercentileCharacterFromStringIntoString( gpActive->szString, str );
DoublePercentileCharacterFromStringIntoString( scrollStr, str );
mprintf( gpActive->region.RegionTopLeftX + 3, gpActive->region.RegionTopLeftY + usOffset, str );
}
//Draw the cursor in the correct position.
if( gfEditingText && gpActive->szString )
if( gfEditingText && scrollStr )
{
DoublePercentileCharacterFromStringIntoString( gpActive->szString, str );
uiCursorXPos = StringPixLengthArg( pColors->usFont, gubCursorPos, str ) + 2;
DoublePercentileCharacterFromStringIntoString( scrollStr, str );
uiCursorXPos = StringPixLengthArg( pColors->usFont, scrollCursorPos, str ) + 2;
if( GetJA2Clock()%1000 < 500 )
{ //draw the blinking ibeam cursor during the on blink period.
ColorFillVideoSurfaceArea(FRAME_BUFFER,
@@ -1590,6 +1681,9 @@ void ExecuteCopyCommand()
szClipboard[ ubCount-ubStart ] = gpActive->szString[ ubCount ];
}
szClipboard[ ubCount-ubStart ] = L'\0';
// also copy this data to the W32 clipboard
CopyToClipboard();
}
}
@@ -1766,3 +1860,92 @@ void DoublePercentileCharacterFromStringIntoString( STR16 pSrcString, STR16 pDst
}
pDstString[ iDstIndex ] = 0;
}
// OJW - 20090427 - Paste clipboard text
UINT32 PasteClipboardText()
{
// get the window handle of the window which currently holds the clipboard
//HWND wndH = GetOpenClipboardWindow();
UINT32 iStrLen = 0;
// open the clipboard
if(OpenClipboard(NULL))
{
if (IsClipboardFormatAvailable(CF_UNICODETEXT))
{
STR16 cbText = (STR16)GetClipboardData(CF_UNICODETEXT);
if (cbText != NULL)
{
iStrLen = wcslen(cbText);
if (iStrLen > 0)
{
szClipboard = (STR16)MemAlloc((iStrLen+1)*sizeof(CHAR16));
wcscpy(szClipboard,cbText);
szClipboard[iStrLen] = L'\0';
// empty clipboard of data as we have copied it into the "local" clipboard
// and we will use that from now on
EmptyClipboard();
}
}
}
if (iStrLen == 0)
{
// no unicode text availble, try and get regular text
char* cbTextA = (char*)GetClipboardData(CF_TEXT);
if (cbTextA != NULL)
{
iStrLen = strlen(cbTextA);
if (iStrLen > 0)
{
szClipboard = (STR16)MemAlloc((iStrLen+1)*sizeof(CHAR16));
MultiByteToWideChar( CP_UTF8, 0, cbTextA, -1, (LPWSTR)szClipboard, iStrLen);//swprintf(szClipboard,L"%S",cbTextA);
szClipboard[iStrLen] = L'\0';
// empty clipboard of data as we have copied it into the "local" clipboard
// and we will use that from now on
EmptyClipboard();
}
}
}
CloseClipboard();
}
// did we copy anything from the windows clipboard?
return iStrLen;
}
// OJW - 20090427 - Copy text to the Win32 Clipboard
void CopyToClipboard( void )
{
if (!szClipboard || wcslen(szClipboard) <=0)
return;
if(OpenClipboard(ghWindow))
{
HGLOBAL clipbuffer;
STR16 writeBuffer;
if (IsClipboardFormatAvailable(CF_UNICODETEXT))
{
// duh
EmptyClipboard();
// create new DDE buffer and get exclusive lock to it
clipbuffer = GlobalAlloc(GMEM_DDESHARE, (wcslen(szClipboard)+1)*sizeof(CHAR16));
writeBuffer = (STR16)GlobalLock(clipbuffer);
// copy the clipboard string
wcscpy(writeBuffer, szClipboard);
// unlock and write data to clipboard
GlobalUnlock(clipbuffer);
SetClipboardData(CF_UNICODETEXT,clipbuffer);
}
// finish up
CloseClipboard();
}
}
+2 -2
View File
@@ -118,8 +118,8 @@ void SetInputFieldStringWith16BitString( UINT8 ubField, const STR16 szNewText );
void SetInputFieldStringWith8BitString( UINT8 ubField, const STR8 szNewText );
//Allows external functions to access the strings within the fields at anytime.
void Get8BitStringFromField( UINT8 ubField, STR8 szString );
void Get16BitStringFromField( UINT8 ubField, STR16 szString );
void Get8BitStringFromField( UINT8 ubField, STR8 szString, UINT32 uiBufferSize );
void Get16BitStringFromField( UINT8 ubField, STR16 szString, UINT32 uiBufferSize );
//Utility functions for the INPUTTYPE_EXCLUSIVE_24HOURCLOCK input type.
UINT16 GetExclusive24HourTimeValueFromField( UINT8 ubField );
+18 -1
View File
@@ -173,7 +173,6 @@ extern STR16 gzIMPColorChoosingText[];
extern STR16 sColorChoiceExplanationTexts[];
extern STR16 gzIMPDisabilityTraitText[];
//****
enum
{
ANTIHACKERSTR_EXITGAME,
@@ -1506,6 +1505,12 @@ enum
MPH_TIMER_INVALID,
MPH_ENABLECIV_TEXT,
MPH_USENIV_TEXT,
MPH_OVERRIDEMAXAI_TEXT,
MPH_SYNC_CLIENT_MP_DIR,
MPH_FILE_TRANSFER_DIR_TEXT,
MPH_FILE_TRANSFER_DIR_INVALID,
MPH_FILE_TRANSFER_DIR_TEXT_ADDITIONAL,
MPH_FILE_TRANSFER_DIR_NOT_EXIST,
};
extern STR16 gzMPHScreenText[];
enum
@@ -1522,8 +1527,20 @@ enum
MPS_ACCURACY_TEXT,
MPS_DMGDONE_TEXT,
MPS_DMGTAKEN_TEXT,
MPS_WAITSERVER_TEXT
};
extern STR16 gzMPSScreenText[];
enum
{
MPC_CANCEL_TEXT,
MPC_CONNECTING_TEXT,
MPC_GETSETTINGS_TEXT,
MPC_DOWNLOADING_TEXT,
MPC_HELP1_TEXT,
MPC_HELP2_TEXT,
MPC_READY_TEXT,
};
extern STR16 gzMPCScreenText[];
// Multiplayer Starting Edges
enum
{
+20 -4
View File
@@ -41,7 +41,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;_CRT_SECURE_NO_DEPRECATE&quot;"
Optimization="0"
AdditionalIncludeDirectories="..\Multiplayer"
AdditionalIncludeDirectories="..\Multiplayer;..\VFS"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -105,7 +105,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;_CRT_SECURE_NO_DEPRECATE&quot;"
AdditionalIncludeDirectories="..\Multiplayer"
AdditionalIncludeDirectories="..\Multiplayer;..\VFS"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
RuntimeTypeInfo="false"
@@ -166,7 +166,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;_CRT_SECURE_NO_DEPRECATE&quot;"
AdditionalIncludeDirectories="..\Multiplayer"
AdditionalIncludeDirectories="..\Multiplayer;..\VFS"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
RuntimeTypeInfo="false"
@@ -228,7 +228,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;_CRT_SECURE_NO_DEPRECATE&quot;"
Optimization="0"
AdditionalIncludeDirectories="..\Multiplayer"
AdditionalIncludeDirectories="..\Multiplayer;..\VFS"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -424,6 +424,14 @@
RelativePath=".\WordWrap.h"
>
</File>
<File
RelativePath=".\XML_Parser.h"
>
</File>
<File
RelativePath=".\XMLWriter.h"
>
</File>
</Filter>
<Filter
Name="Source Files"
@@ -622,6 +630,14 @@
RelativePath=".\XML_Strings.cpp"
>
</File>
<File
RelativePath=".\XMLProperties.cpp"
>
</File>
<File
RelativePath=".\XMLWriter.cpp"
>
</File>
</Filter>
</Files>
<Globals>
+16
View File
@@ -425,6 +425,14 @@
RelativePath="WordWrap.h"
>
</File>
<File
RelativePath=".\XML_Parser.h"
>
</File>
<File
RelativePath=".\XMLWriter.h"
>
</File>
</Filter>
<Filter
Name="Source Files"
@@ -625,6 +633,14 @@
RelativePath="XML_Strings2.cpp"
>
</File>
<File
RelativePath=".\XMLProperties.cpp"
>
</File>
<File
RelativePath=".\XMLWriter.cpp"
>
</File>
</Filter>
</Files>
<Globals>
Binary file not shown.
+224
View File
@@ -0,0 +1,224 @@
#include "XML_Parser.h"
#include "vfs_types.h"
#include "PropertyContainer.h"
#include "XMLWriter.h"
#include "VFS/vfs_file_raii.h"
#include "VFS/File/vfs_file.h"
CPropertyContainer::TagMap::TagMap()
{
// setup default map
_map[L"Container"] = L"Container";
_map[L"Section"] = L"Section";
_map[L"SectionID"] = L"name";
_map[L"Key"] = L"Key";
_map[L"KeyID"] = L"name";
}
utf8string const& CPropertyContainer::TagMap::Container(utf8string::char_t* container)
{
if(container)
{
_map[L"Container"] = container;
}
return _map[L"Container"];
}
utf8string const& CPropertyContainer::TagMap::Section(utf8string::char_t* section)
{
if(section)
{
_map[L"Section"] = section;
}
return _map[L"Section"];
}
utf8string const& CPropertyContainer::TagMap::SectionID(utf8string::char_t* section_id)
{
if(section_id)
{
_map[L"SectionID"] = section_id;
}
return _map[L"SectionID"];
}
utf8string const& CPropertyContainer::TagMap::Key(utf8string::char_t* key)
{
if(key)
{
_map[L"Key"] = key;
}
return _map[L"Key"];
}
utf8string const& CPropertyContainer::TagMap::KeyID(utf8string::char_t* key_id)
{
if(key_id)
{
_map[L"KeyID"] = key_id;
}
return _map[L"KeyID"];
}
bool CPropertyContainer::WriteToXMLFile(vfs::Path const& sFileName, CPropertyContainer::TagMap& tagmap)
{
XMLWriter xmlw;
xmlw.OpenNode(tagmap.Container());
tSections::iterator sit = m_mapProps.begin();
for(; sit != m_mapProps.end(); ++sit)
{
xmlw.AddAttributeToNextValue(tagmap.SectionID(),sit->first.utf8());
xmlw.OpenNode(tagmap.Section());
CPropertyContainer::CSection& section = sit->second;
CPropertyContainer::CSection::tProps::iterator kit = section.mapProps.begin();
for(; kit != section.mapProps.end(); ++kit)
{
xmlw.AddAttributeToNextValue(tagmap.KeyID(), kit->first.utf8());
xmlw.AddValue(tagmap.Key(), kit->second.utf8());
}
xmlw.CloseNode();
}
xmlw.CloseNode();
return xmlw.WriteToFile(sFileName);
}
/*********************************************************************************/
/*********************************************************************************/
class CPropertyXMLParser : public IXMLParser
{
enum DOM_OBJECT
{
DO_ELEMENT_Container,
DO_ELEMENT_Section,
DO_ELEMENT_Key,
DO_ELEMENT_NONE,
};
public:
CPropertyXMLParser(
CPropertyContainer& container,
CPropertyContainer::TagMap& tagmap,
XML_Parser &parser,
IXMLParser* caller = NULL)
: IXMLParser("",parser,caller),
_container(container),
_tagmap(tagmap),
current_state(DO_ELEMENT_NONE) // doesn't matter where we come from, we start fresh
{};
virtual void OnStartElement(const XML_Char* name, const XML_Char** atts);
virtual void OnEndElement(const XML_Char* name);
virtual void OnTextElement(const XML_Char *str, int len);
private:
CPropertyContainer& _container;
CPropertyContainer::TagMap& _tagmap;
DOM_OBJECT current_state;
utf8string current_section;
utf8string current_key;
};
void CPropertyXMLParser::OnStartElement(const XML_Char *name, const XML_Char **atts)
{
utf8string utf8_name(name);
if(current_state == DO_ELEMENT_NONE && StrCmp::Equal(utf8_name,_tagmap.Container()))
{
current_state = DO_ELEMENT_Container;
}
else if(current_state == DO_ELEMENT_Container && StrCmp::Equal(utf8_name, _tagmap.Section()))
{
current_state = DO_ELEMENT_Section;
current_section = this->GetAttribute(_tagmap.SectionID().utf8().c_str(),atts);
}
else if(current_state == DO_ELEMENT_Section && StrCmp::Equal(utf8_name, _tagmap.Key()))
{
current_state = DO_ELEMENT_Key;
current_key = this->GetAttribute(_tagmap.KeyID().utf8().c_str(),atts);
}
sCharData = "";
}
void CPropertyXMLParser::OnEndElement(const XML_Char* name)
{
utf8string utf8_name(name);
if(current_state == DO_ELEMENT_Key && StrCmp::Equal(utf8_name, _tagmap.Key()))
{
_container.SetStringProperty(current_section, current_key, vfs::TrimString(sCharData,0,sCharData.length()));
current_state = DO_ELEMENT_Section;
}
else if(current_state == DO_ELEMENT_Section && StrCmp::Equal(utf8_name, _tagmap.Section()))
{
current_state = DO_ELEMENT_Container;
}
else if(current_state == DO_ELEMENT_Container && StrCmp::Equal(utf8_name, _tagmap.Container()))
{
current_state = DO_ELEMENT_NONE;
}
}
void CPropertyXMLParser::OnTextElement(const XML_Char *str, int len)
{
if(current_state == DO_ELEMENT_Key)
{
sCharData.append(str,len);
}
}
bool CPropertyContainer::InitFromXMLFile(vfs::Path const& sFileName, CPropertyContainer::TagMap& tagmap)
{
vfs::tReadableFile *file = NULL;
bool delete_file = false;
try
{
vfs::COpenReadFile rfile(sFileName);
file = &rfile.file();
rfile.release();
}
catch(CBasicException& ex)
{
vfs::CFile* rfile = new vfs::CFile(sFileName);
delete_file = true;
file = vfs::tReadableFile::Cast(rfile);
if(!file->OpenRead())
{
file->Close();
delete file;
return false;
}
}
if(!file)
{
return false;
}
vfs::UInt32 size = file->GetFileSize();
std::vector<vfs::Byte> buffer(size+1);
vfs::UInt32 has_read;
file->Read(&buffer[0],size,has_read);
buffer[size] = 0;
file->Close();
if(delete_file) delete file;
XML_Parser parser = XML_ParserCreate(NULL);
CPropertyXMLParser pp(*this,tagmap,parser,NULL);
pp.GrabParser();
if(!XML_Parse(parser, &buffer[0], size, TRUE))
{
std::wstringstream wss;
wss << L"XML Parser Error in Groups.xml: "
<< utf8string::as_utf16(XML_ErrorString(XML_GetErrorCode(parser)))
<< L" at line "
<< XML_GetCurrentLineNumber(parser);
THROWEXCEPTION(wss.str().c_str());
//return false;
}
return true;
}
+160
View File
@@ -0,0 +1,160 @@
#include "XMLWriter.h"
#include "VFS/vfs_file_raii.h"
#include "VFS/File/vfs_file.h"
void XMLWriter::AddValue(utf8string const& key)
{
m_ssBuffer << Indent() << "<" << key.utf8();
InsertAttributesIntoBuffer();
m_ssBuffer << " />\n";
}
void XMLWriter::AddComment(utf8string const& comment)
{
m_ssBuffer << Indent() << "<!-- " << comment.utf8() << " -->\n";
}
void XMLWriter::OpenNode(utf8string const& key)
{
std::string utf8key = key.utf8();
m_ssBuffer << Indent() << "<" << utf8key;
InsertAttributesIntoBuffer();
m_ssBuffer << ">\n";
m_iIndentLevel += 1;
m_stOpenNodes.push(utf8key);
}
bool XMLWriter::CloseNode()
{
if(m_iIndentLevel < 1)
{
// there is nothing to close
return false;
}
if(m_stOpenNodes.empty())
{
return false;
}
m_iIndentLevel -= 1;
m_ssBuffer << Indent() << "</" << m_stOpenNodes.top() << ">\n";
m_stOpenNodes.pop();
return true;
}
bool XMLWriter::WriteToFile(vfs::Path const& sFileName)
{
try
{
vfs::COpenWriteFile file(sFileName,true,true);
return WriteToFile( &file.file() );
}
catch(CBasicException& ex)
{
vfs::CFile file(sFileName);
if(file.OpenWrite(true,true))
{
return WriteToFile(vfs::tWriteableFile::Cast(&file));
}
}
return false;
}
bool XMLWriter::WriteToFile(vfs::tWriteableFile* pFile)
{
vfs::COpenWriteFile file(pFile);
vfs::UInt32 written;
std::string &str = m_ssBuffer.str();
if(!pFile->Write(str.c_str(), str.length() * sizeof(std::string::value_type), written))
{
return false;
}
return true;
}
std::string XMLWriter::Indent()
{
std::string indent_string;
for(int i=0; i < m_iIndentLevel; ++i)
{
indent_string += "\t";
}
return indent_string;
}
void XMLWriter::InsertAttributesIntoBuffer()
{
if(!m_stNextValAttributes.empty())
{
std::vector<attribute_type>::iterator it = m_stNextValAttributes.begin();
for(; it != m_stNextValAttributes.end(); ++it)
{
m_ssBuffer << " " << it->first << "=\"" << it->second << "\"";
}
}
m_stNextValAttributes.clear();
}
std::string XMLWriter::HandleSpecialCharacters(std::string const& str)
{
std::stringstream ss;
unsigned int current = 0, old = 0;
while( current < str.length() )
{
char const& c = str.at(current);
if( c == '&' )
{
ss << str.substr(old, current-old) << "&amp;";
old = current + 1;
}
else if( c == '<' )
{
ss << str.substr(old, current-old) << "&lt;";
old = current + 1;
}
else if( c == '>' )
{
ss << str.substr(old, current-old) << "&gt;";
old = current + 1;
}
else if( c == '\"' )
{
ss << str.substr(old, current-old) << "&quot;";
old = current + 1;
}
else if( c == '\'' )
{
ss << str.substr(old, current-old) << "&apos;";
old = current + 1;
}
current++;
}
if(old)
{
ss << str.substr(old, current-old);
return ss.str();
}
return str;
}
void testMXLWriter()
{
//XMLWriter<char> xmlw;
XMLWriter xmlw;
//xmlw.OpenNode(L"root");
xmlw.OpenNode("root");
xmlw.AddAttributeToNextValue("attr1",10);
xmlw.AddAttributeToNextValue("attr2","string");
//xmlw.AddValue(L"val1",10);
xmlw.AddValue("val1",10);
xmlw.AddAttributeToNextValue("node_attr",17);
xmlw.AddComment("bbb -->\n <a> comment</a> <!-- aaa");
xmlw.OpenNode("test");
//xmlw.AddValue(L"val2",10.5);
xmlw.AddValue("val2",10.5);
xmlw.CloseNode();
xmlw.CloseNode();
//xmlw.WriteToFile(WideString("xml_output/test.xml")());
xmlw.WriteToFile("xml_output/test.xml");
}
+75
View File
@@ -0,0 +1,75 @@
#ifndef _XMLWRITER_H_
#define _XMLWRITER_H_
#include "FileMan.h"
#include "VFS/Interface/vfs_file_interface.h"
#include "utf8string.h"
#include <stack>
#include <string>
#include <sstream>
#include <vector>
class XMLWriter
{
public:
typedef std::pair<std::string, std::string> attribute_type;
public:
XMLWriter() : m_iIndentLevel(0)
{
m_ssBuffer << "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" ;
};
~XMLWriter()
{};
template<typename ValueType>
void AddAttributeToNextValue(utf8string const& attribute, ValueType const& value)
{
std::stringstream temp_buffer;
temp_buffer << value;
m_stNextValAttributes.push_back( attribute_type(attribute.utf8(),temp_buffer.str()) );
}
template<typename ValueType>
void AddValue(utf8string const& key, ValueType const& value)
{
std::string utf8key = key.utf8();
m_ssBuffer << Indent() << "<" << utf8key;
InsertAttributesIntoBuffer();
m_ssBuffer << "> " << value << " </" << utf8key << ">\n";
}
template<>
void AddValue<std::string >(utf8string const& key, std::string const& value)
{
std::string utf8key = key.utf8();
m_ssBuffer << Indent() << "<" << utf8key;
InsertAttributesIntoBuffer();
m_ssBuffer << "> " << HandleSpecialCharacters(value) << " </" << utf8key << ">\n";
}
void AddValue(utf8string const& key);
void AddComment(utf8string const& comment);
void OpenNode(utf8string const& key);
bool CloseNode();
bool WriteToFile(vfs::Path const& sFileName);
bool WriteToFile(vfs::tWriteableFile* pFile);
private:
std::string Indent();
std::string HandleSpecialCharacters(std::string const& str);
void InsertAttributesIntoBuffer();
private:
std::stringstream m_ssBuffer;
std::stack<std::string> m_stOpenNodes;
std::vector<attribute_type> m_stNextValAttributes;
int m_iIndentLevel;
};
void testMXLWriter();
#endif // _XMLWRITER_H_
+97
View File
@@ -0,0 +1,97 @@
#ifndef _XML_PARSER_H_
#define _XML_PARSER_H_
#include "expat.h"
#include "XML.h"
class IXMLParser
{
public:
const XML_Char* ElementName;
public:
IXMLParser(const XML_Char *element_name, XML_Parser &parser, IXMLParser* caller=NULL)
: _parser(parser), _caller(caller), ElementName(element_name) {};
~IXMLParser() {};
/**
* Interface
*/
static void OnStartCallback(void *userData, const XML_Char* name, const XML_Char** atts)
{
((IXMLParser*)userData)->OnStartElement(name,atts);
}
static void OnEndCallback(void *userData, const XML_Char* name)
{
((IXMLParser*)userData)->OnEndElement(name);
// test if we are done here
if( ((IXMLParser*)userData)->_caller && (strcmp(name, ((IXMLParser*)userData)->ElementName) == 0) )
{
((IXMLParser*)userData)->_caller->GrabParser();
}
}
static void OnTextCallback(void *userData, const XML_Char *str, int len)
{
((IXMLParser*)userData)->OnTextElement(str,len);
}
void GrabParser()
{
XML_SetUserData(_parser,this);
XML_SetElementHandler(_parser, IXMLParser::OnStartCallback, IXMLParser::OnEndCallback);
XML_SetCharacterDataHandler(_parser, IXMLParser::OnTextCallback);
}
/**
* Override these methods in your parser
*/
virtual void OnStartElement(const XML_Char* name, const XML_Char** atts)
{};
virtual void OnEndElement(const XML_Char* name)
{};
virtual void OnTextElement(const XML_Char *str, int len)
{};
protected:
XML_Char const* GetAttribute(const XML_Char* attr_name, const XML_Char** atts)
{
while(*atts)
{
if(strcmp(*atts++,attr_name) == 0)
{
return *atts;
}
atts++;
}
return "";
}
bool GetAttributeAsInt(const XML_Char* attr_name, const XML_Char** attr, int &value)
{
XML_Char const* result = GetAttribute(attr_name,attr);
if( strcmp(result,"") != 0)
{
value = (int)atol(result);
return true;
}
return false;
}
bool GetAttributeAsFloat(const XML_Char* attr_name, const XML_Char** attr, float &value)
{
XML_Char const* result = GetAttribute(attr_name,attr);
if( strcmp(result,"") != 0)
{
value = (float)atof(result);
return true;
}
return false;
}
int GetCurrentLineNumber()
{
return XML_GetCurrentLineNumber(this->_parser);
}
protected:
std::string sCharData;
XML_Parser& _parser;
IXMLParser* _caller;
};
#endif // _XML_PARSER_H_
+68 -33
View File
@@ -26,6 +26,9 @@
#include "GameSettings.h"
#endif
#include "VFS/vfs.h"
#include "PropertyContainer.h"
typedef struct
{
UINT32 uiFont;
@@ -89,6 +92,9 @@ extern BOOLEAN gfFacePanelActive;
extern BOOLEAN fTextBoxMouseRegionCreated;
extern BOOLEAN fDialogueBoxDueToLastMessage;
// OJW - 20090426
INT16 gTacticalMsgFilterPriority = -1; // filter for writing messages to the tactical log
// prototypes
@@ -118,7 +124,7 @@ void AddStringToMapScreenMessageList( STR16 pString, UINT16 usColor, UINT32 uiFo
// clear up a linked list of wrapped strings
void ClearWrappedStrings( WRAPPED_STRING *pStringWrapperHead );
void WriteMessageToFile( STR16 pString );
void WriteMessageToFile( const STR16 pString );
// tactical screen message
void TacticalScreenMsg( UINT16 usColor, UINT8 ubPriority, STR16 pStringA, ... );
@@ -727,6 +733,12 @@ void TacticalScreenMsg( UINT16 usColor, UINT8 ubPriority, STR16 pStringA, ... )
return;
}
// OJW - 20090426 - Filter tactical messages
if ( gTacticalMsgFilterPriority != -1 && gTacticalMsgFilterPriority != ubPriority )
{
return;
}
if( ubPriority == MSG_BETAVERSION )
{
usColor = BETAVERSION_COLOR;
@@ -735,8 +747,10 @@ void TacticalScreenMsg( UINT16 usColor, UINT8 ubPriority, STR16 pStringA, ... )
return;
#endif
#endif
va_start(argptr, pStringA); // Set up variable argument pointer
vswprintf(DestString, pStringA, argptr); // process gprintf string (get output str)
va_end(argptr);
WriteMessageToFile( DestString );
}
if( ubPriority == MSG_TESTVERSION )
@@ -746,9 +760,10 @@ void TacticalScreenMsg( UINT16 usColor, UINT8 ubPriority, STR16 pStringA, ... )
#ifndef JA2TESTVERSION
return;
#endif
va_start(argptr, pStringA); // Set up variable argument pointer
vswprintf(DestString, pStringA, argptr); // process gprintf string (get output str)
va_end(argptr);
WriteMessageToFile( DestString );
}
@@ -797,51 +812,51 @@ void TacticalScreenMsg( UINT16 usColor, UINT8 ubPriority, STR16 pStringA, ... )
pStringWrapperHead=LineWrap(uiFont, LINE_WIDTH, &usLineWidthIfWordIsWiderThenWidth, DestString);
pStringWrapper=pStringWrapperHead;
if(!pStringWrapper)
return;
return;
fNewString = TRUE;
while(pStringWrapper->pNextWrappedString!=NULL)
{
if(!pStringSt)
{
pStringSt=AddString(pStringWrapper->sString, usColor, uiFont, fNewString, ubPriority );
fNewString = FALSE;
pStringSt->pNext=NULL;
pStringSt->pPrev=NULL;
pStringS=pStringSt;
}
else
{
pTempStringSt=AddString(pStringWrapper->sString, usColor, uiFont, fNewString, ubPriority);
fNewString = FALSE;
pTempStringSt->pPrev=pStringSt;
pStringSt->pNext=pTempStringSt;
pStringSt=pTempStringSt;
pTempStringSt->pNext=NULL;
}
pStringWrapper=pStringWrapper->pNextWrappedString;
if(!pStringSt)
{
pStringSt=AddString(pStringWrapper->sString, usColor, uiFont, fNewString, ubPriority );
fNewString = FALSE;
pStringSt->pNext=NULL;
pStringSt->pPrev=NULL;
pStringS=pStringSt;
}
else
{
pTempStringSt=AddString(pStringWrapper->sString, usColor, uiFont, fNewString, ubPriority);
fNewString = FALSE;
pTempStringSt->pPrev=pStringSt;
pStringSt->pNext=pTempStringSt;
pStringSt=pTempStringSt;
pTempStringSt->pNext=NULL;
}
pStringWrapper=pStringWrapper->pNextWrappedString;
}
pTempStringSt=AddString(pStringWrapper->sString, usColor, uiFont, fNewString, ubPriority );
if(pStringSt)
{
pStringSt->pNext=pTempStringSt;
pTempStringSt->pPrev=pStringSt;
pStringSt=pTempStringSt;
pStringSt->pNext=NULL;
pStringSt->pNext=pTempStringSt;
pTempStringSt->pPrev=pStringSt;
pStringSt=pTempStringSt;
pStringSt->pNext=NULL;
}
else
{
pStringSt=pTempStringSt;
pStringSt->pNext=NULL;
pStringSt->pPrev=NULL;
pStringS=pStringSt;
pStringS=pStringSt;
}
// clear up list of wrapped strings
ClearWrappedStrings( pStringWrapperHead );
//LeaveMutex(SCROLL_MESSAGE_MUTEX, __LINE__, __FILE__);
return;
//LeaveMutex(SCROLL_MESSAGE_MUTEX, __LINE__, __FILE__);
return;
}
@@ -885,12 +900,18 @@ void MapScreenMessage( UINT16 usColor, UINT8 ubPriority, STR16 pStringA, ... )
#endif
#endif
va_start(argptr, pStringA); // Set up variable argument pointer
vswprintf(DestString, pStringA, argptr); // process gprintf string (get output str)
va_end(argptr);
WriteMessageToFile( DestString );
}
if( ubPriority == MSG_TESTVERSION )
{
usColor = TESTVERSION_COLOR;
va_start(argptr, pStringA); // Set up variable argument pointer
vswprintf(DestString, pStringA, argptr); // process gprintf string (get output str)
va_end(argptr);
#ifndef JA2TESTVERSION
return;
@@ -1439,10 +1460,10 @@ void ClearTacticalMessageQueue( void )
return;
}
void WriteMessageToFile( STR16 pString )
void WriteMessageToFile( const STR16 pString )
{
#ifdef JA2BETAVERSION
#ifndef USE_VFS
FILE *fp;
fp = fopen( "DebugMessage.txt", "a" );
@@ -1454,7 +1475,10 @@ void WriteMessageToFile( STR16 pString )
fprintf( fp, "%S\n", pString );
fclose( fp );
#else
static CLog& debugMessage = *CLog::Create(L"DebugMessage.txt", true, CLog::FLUSH_IMMEDIATELY);
debugMessage << pString << CLog::endl;
#endif
#endif
}
@@ -1516,6 +1540,17 @@ UINT8 GetRangeOfMapScreenMessages( void )
return ( ubRange );
}
// OJW - 20090426 - only show certain messages in the tactical / message overlay
void SetTacticalMessageFilter( UINT ubPriority )
{
gTacticalMsgFilterPriority = ubPriority;
}
void RemoveTacticalMessageFilter ( void )
{
gTacticalMsgFilterPriority = -1;
}
/*
+16 -12
View File
@@ -22,18 +22,19 @@ struct stringstruct{
struct stringstruct *pPrev;
};
#define MSG_INTERFACE 0
#define MSG_DIALOG 1
#define MSG_CHAT 2
#define MSG_DEBUG 3
#define MSG_UI_FEEDBACK 4
#define MSG_ERROR 5
#define MSG_BETAVERSION 6
#define MSG_TESTVERSION 7
#define MSG_MAP_UI_POSITION_MIDDLE 8
#define MSG_MAP_UI_POSITION_UPPER 9
#define MSG_MAP_UI_POSITION_LOWER 10
#define MSG_SKULL_UI_FEEDBACK 11
#define MSG_INTERFACE 0
#define MSG_DIALOG 1
#define MSG_MPSYSTEM 2
#define MSG_DEBUG 3
#define MSG_UI_FEEDBACK 4
#define MSG_ERROR 5
#define MSG_BETAVERSION 6
#define MSG_TESTVERSION 7
#define MSG_MAP_UI_POSITION_MIDDLE 8
#define MSG_MAP_UI_POSITION_UPPER 9
#define MSG_MAP_UI_POSITION_LOWER 10
#define MSG_SKULL_UI_FEEDBACK 11
#define MSG_CHAT 12
// These defines correlate to defines in font.h
@@ -80,6 +81,9 @@ ScrollStringStPtr SetStringPrev(ScrollStringStPtr pStringSt, ScrollStringStPtr p
void SetString(ScrollStringStPtr pStringSt, STR16 String);
// will go and clear all displayed strings off the screen
void ClearDisplayedListOfTacticalStrings( void );
// OJW - 20090426
void SetTacticalMessageFilter( UINT ubPriority );
void RemoveTacticalMessageFilter ( void );
// clear ALL strings in the tactical Message Queue
void ClearTacticalMessageQueue( void );