LOBOT code (by Asdow, original code by Bio).

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8755 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Sevenfm
2020-02-15 16:19:35 +00:00
parent 25701acf7b
commit 8e9f9cb8a1
51 changed files with 9659 additions and 1730 deletions
+5
View File
@@ -264,6 +264,7 @@ BOOLEAN LoadGameSettings()
gGameSettings.fOptions[TOPTION_STAT_PROGRESS_BARS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_STAT_PROGRESS_BARS" , TRUE ); // HEADROCK HAM 3.6: Progress Bars
gGameSettings.fOptions[TOPTION_MERCENARY_FORMATIONS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_MERCENARY_FORMATIONS" , TRUE ); // Flugente: mercenary formations
gGameSettings.fOptions[TOPTION_REPORT_MISS_MARGIN] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_REPORT_MISS_MARGIN" , FALSE ); // HEADROCK HAM 4: Shot offset report
gGameSettings.fOptions[TOPTION_USE_LOGICAL_BODYTYPES] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_USE_LOGICAL_BODYTYPES" , FALSE );
gGameSettings.fOptions[TOPTION_ALT_MAP_COLOR] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ALT_MAP_COLOR" , FALSE ); // HEADROCK HAM 4: Strategic Map Colors
gGameSettings.fOptions[TOPTION_ALTERNATE_BULLET_GRAPHICS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ALTERNATE_BULLET_GRAPHICS" , TRUE );
gGameSettings.fOptions[TOPTION_SHOW_MERC_RANKS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_SHOW_MERC_RANKS" , FALSE );
@@ -477,6 +478,7 @@ BOOLEAN SaveGameSettings()
settings << "TOPTION_CHEAT_MODE_OPTIONS_END = " << (gGameSettings.fOptions[TOPTION_CHEAT_MODE_OPTIONS_END] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_DEBUG_MODE_OPTIONS_HEADER = " << (gGameSettings.fOptions[TOPTION_DEBUG_MODE_OPTIONS_HEADER] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_REPORT_MISS_MARGIN = " << (gGameSettings.fOptions[TOPTION_REPORT_MISS_MARGIN] ? "TRUE" : "FALSE" ) << endl; // HEADROCK HAM 4: Shot offset report
settings << "TOPTION_USE_LOGICAL_BODYTYPES = " << (gGameSettings.fOptions[TOPTION_USE_LOGICAL_BODYTYPES] ? "TRUE" : "FALSE" ) << endl; // BIO
settings << "TOPTION_SHOW_RESET_ALL_OPTIONS = " << (gGameSettings.fOptions[TOPTION_SHOW_RESET_ALL_OPTIONS] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_RESET_ALL_OPTIONS = " << (gGameSettings.fOptions[TOPTION_RESET_ALL_OPTIONS] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_RETAIN_DEBUG_OPTIONS_IN_RELEASE = " << (gGameSettings.fOptions[TOPTION_RETAIN_DEBUG_OPTIONS_IN_RELEASE] ? "TRUE" : "FALSE" ) << endl;
@@ -591,6 +593,9 @@ void InitGameSettings()
gGameSettings.fOptions[ TOPTION_REPORT_MISS_MARGIN ] = FALSE;
// BIO
gGameSettings.fOptions[ TOPTION_USE_LOGICAL_BODYTYPES ] = FALSE;
gGameSettings.fOptions[ TOPTION_DISABLE_CURSOR_SWAP ] = FALSE;
gGameSettings.fOptions[ TOPTION_QUIET_TRAINING ] = FALSE;
gGameSettings.fOptions[ TOPTION_QUIET_REPAIRING ] = FALSE;
+3
View File
@@ -75,6 +75,9 @@ enum
// WANNE: Moved alternate bullets graphics (tracers) to options
TOPTION_ALTERNATE_BULLET_GRAPHICS,
// BIO LOBOT:
TOPTION_USE_LOGICAL_BODYTYPES,
// CHRISL: HAM 4: Activate/Deactivate NCTH mode
//TOPTION_USE_NCTH,
//Jenilee's Merc Ranks
+17 -9
View File
@@ -438,6 +438,14 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
strcpy(fileName, directoryName);
strcat(fileName, LBEPOCKETFILENAME);
SGP_THROW_IFFALSE(ReadInLBEPocketStats(fileName,FALSE),LBEPOCKETFILENAME);
{
using namespace LogicalBodyTypes;
SGP_THROW_IFFALSE(Layers::Instance().LoadFromFile(directoryName, LBT_LAYERSFILENAME), LBT_LAYERSFILENAME);
SGP_THROW_IFFALSE(PaletteDB::Instance().LoadFromFile(directoryName, LBT_PALETTESFILENAME), LBT_PALETTESFILENAME);
SGP_THROW_IFFALSE(SurfaceDB::Instance().LoadFromFile(directoryName, LBT_ANIMSURFACESFILENAME), LBT_ANIMSURFACESFILENAME);
SGP_THROW_IFFALSE(FilterDB::Instance().LoadFromFile(directoryName, LBT_FILTERSFILENAME), LBT_FILTERSFILENAME);
SGP_THROW_IFFALSE(BodyTypeDB::Instance().LoadFromFile(directoryName, LBT_BODYTYPESFILENAME), LBT_BODYTYPESFILENAME);
}
#ifndef ENGLISH
AddLanguagePrefix(fileName);
@@ -1396,7 +1404,7 @@ BackupBRandEncyclopedia ( gBriefingRoomData, gBriefingRoomDataBackup, 0);
MusicSoundValues[iloop].SoundTacticalBattleGroup[iloop] = -1;
}
}
CHAR8 zFileName[255];
sprintf( zFileName, "scripts\\Music.lua" );
if (FileExists( zFileName ) )
@@ -1404,12 +1412,12 @@ BackupBRandEncyclopedia ( gBriefingRoomData, gBriefingRoomDataBackup, 0);
LetLuaMusicControl(0);
}
#endif
strcpy(fileName, directoryName);
strcat(fileName, DIFFICULTYFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
SGP_THROW_IFFALSE(ReadInDifficultySettings(fileName,FALSE), DIFFICULTYFILENAME);
#ifndef ENGLISH
AddLanguagePrefix(fileName);
if ( FileExists(fileName) )
@@ -1417,8 +1425,8 @@ BackupBRandEncyclopedia ( gBriefingRoomData, gBriefingRoomDataBackup, 0);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
SGP_THROW_IFFALSE(ReadInDifficultySettings(fileName,TRUE), fileName);
}
#endif
#endif
LuaState::INIT(lua::LUA_STATE_STRATEGIC_MINES_AND_UNDERGROUND, true);
g_luaUnderground.LoadScript(GetLanguagePrefix());
// load Lua for Strategic Mines initialization
@@ -1438,7 +1446,7 @@ UINT32 InitializeJA2(void)
HandleJA2CDCheck( );
gfWorldLoaded = FALSE;
//Load external game mechanic data
//if ( !LoadExternalGameplayData(TABLEDATA_DIRECTORY))
//{
@@ -1455,7 +1463,7 @@ UINT32 InitializeJA2(void)
//dnl ch54 111009
//gsRenderCenterX = 805;
//gsRenderCenterY = 805;
// Init data
InitializeSystemVideoObjects( );
@@ -1530,7 +1538,7 @@ UINT32 InitializeJA2(void)
//ADB When a merc calcs CTGT for a thrown item he uses a GLOCK temp item
//but we don't want to recreate it every single time CTGT is called, so init the GLOCK here
//CreateItem(GLOCK_17, 100, &GLOCK_17_ForUseWithLOS);//dnl ch86 120214 move to LOS.cpp
#ifdef JA2BETAVERSION
#ifdef JA2EDITOR
@@ -1573,7 +1581,7 @@ UINT32 InitializeJA2(void)
#ifdef JA2BETAVERSION
#ifdef JA2EDITOR
// CHECK COMMANDLINE FOR SPECIAL UTILITY
if( !strcmp( gzCommandLine, "-EDITORAUTO" ) )
{
+14
View File
@@ -1,6 +1,20 @@
#ifndef _INIT_H
#define _INIT_H
#ifndef PRECOMPILEDHEADERS
#include "LogicalBodyTypes/BodyTypeDB.h"
#include "LogicalBodyTypes/Layers.h"
#include "LogicalBodyTypes/AbstractXMLLoader.h"
#include "LogicalBodyTypes/SurfaceDB.h"
#include "LogicalBodyTypes/FilterDB.h"
#include "LogicalBodyTypes/EnumeratorDB.h"
#include "LogicalBodyTypes/BodyTypeDB.h"
#include "LogicalBodyTypes/PaletteDB.h"
#endif
#include <iostream>
#include <fstream>
UINT32 InitializeJA2( );
void ShutdownJA2( );
+11 -3
View File
@@ -5,10 +5,10 @@
#include "builddefines.h"
#include <time.h>
#include <time.h>
#include <stdio.h>
#include <stdarg.h>
#include "sgp.h"
#include "sgp.h"
#include "gameloop.h"
#include "himage.h"
#include "vobject.h"
@@ -108,7 +108,7 @@
#include "tile cache.h"
#include "Shade Table Util.h"
#include "Exit Grids.h"
#include "Summary Info.h"
#include "Summary Info.h"
#include <time.h>
#include "font.h"
#include "timer.h"
@@ -160,5 +160,13 @@
#include "Scheduling.h"
#include "_JA25EnglishText.h"
#include "XML.h"
#include "LogicalBodyTypes/BodyTypeDB.h"
#include "LogicalBodyTypes/Layers.h"
#include "LogicalBodyTypes/AbstractXMLLoader.h"
#include "LogicalBodyTypes/PaletteDB.h"
#include "LogicalBodyTypes/SurfaceDB.h"
#include "LogicalBodyTypes/FilterDB.h"
#include "LogicalBodyTypes/EnumeratorDB.h"
#include "LogicalBodyTypes/BodyTypeDB.h"
#endif
File diff suppressed because it is too large Load Diff
+20 -8
View File
@@ -41,6 +41,8 @@ extern SGPRect ClippingRect;
extern UINT32 guiTranslucentMask;
extern UINT16 White16BPPPalette[ 256 ];
unsigned short blendWithAlpha(unsigned int rgb565New, unsigned int rgb565Old, unsigned int alpha);
extern void SetClippingRect(SGPRect *clip);
void GetClippingRect(SGPRect *clip);
@@ -118,15 +120,21 @@ BOOLEAN Blt8BPPDataTo16BPPBufferTransZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES
BOOLEAN Blt8BPPDataTo16BPPBufferTransZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex );
BOOLEAN Blt8BPPDataTo16BPPBufferTransZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
BOOLEAN Blt8BPPDataTo16BPPBufferTransZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette );
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette );
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette );
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZ(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowClipAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNB(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferShadowZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex );
BOOLEAN Blt8BPPDataTo16BPPBufferShadowZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
BOOLEAN Blt8BPPDataTo16BPPBufferShadowZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex );
BOOLEAN Blt8BPPDataTo16BPPBufferShadowZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZClipAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBClipAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
// Next blitters are for blitting mask as intensity
BOOLEAN Blt8BPPDataTo16BPPBufferIntensityZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex );
@@ -140,7 +148,8 @@ BOOLEAN Blt8BPPDataTo16BPPBufferIntensity( UINT16 *pBuffer, UINT32 uiDestPitchBY
BOOLEAN Blt8BPPDataTo16BPPBufferTransparentClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
BOOLEAN Blt8BPPDataTo16BPPBufferTransparent( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex );
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadow( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette );
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadow(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferShadowClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
BOOLEAN DDBlt8BPPDataTo16BPPBufferShadow( HVOBJECT hDestVObject, HVOBJECT hSrcVObject, UINT8 level, COLORVAL maskrgb, UINT16 usX, UINT16 usY, SGPRect *srcRect);
@@ -208,9 +217,12 @@ BOOLEAN Blt8BPPDataTo16BPPBufferOutlineZClip( UINT16 *pBuffer, UINT32 uiDestPitc
// ATE: New blitter for included shadow, but pixellate if obscured by z
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscured( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette );
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscured(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows = FALSE);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredTest(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows = FALSE);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows = FALSE);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette );
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClipAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows);
BOOLEAN Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
BOOLEAN Blt8BPPDataTo16BPPBufferTransZPixelateObscured( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex );
@@ -0,0 +1,212 @@
#include "AbstractXMLLoader.h"
namespace LogicalBodyTypes {
AbstractXMLLoader::AbstractXMLLoader(XML_StartElementHandler startHandler, XML_EndElementHandler endHandler, XML_CharacterDataHandler charHandler, ParseDataFactoryFunc parseDataFactF) {
startElementHandler = startHandler;
endElementHandler = endHandler;
characterDataHandler = charHandler;
parseDataFactFuncPntr = parseDataFactF;
}
AbstractXMLLoader::~AbstractXMLLoader(void) {
}
AbstractXMLLoader::ParseData::ParseData(XML_Parser* parser) {
pParser = parser;
state = E_NONE;
level = 0;
szCharData[0] = '\0';
szErrorTxt[0] = '\0';
}
AbstractXMLLoader::ParseData* AbstractXMLLoader::MakeParseData(XML_Parser* parser) {
return new ParseData(parser);
}
bool AbstractXMLLoader::LoadFromFile(const char* directoryName, const char* fileName) {
HWFILE hFile;
UINT32 uiBytesRead;
UINT32 uiFSize;
CHAR8* lpcBuffer;
char fileNameFull[MAX_PATH + 1];
if (strlen(fileName) + strlen(directoryName) >= MAX_PATH) {
LiveMessage("Can't load file. Concatinated filename too long for buffer!");
return false;
}
SetDirectoryName(directoryName);
SetFileName(fileName);
strcpy(fileNameFull, directoryName);
strcat(fileNameFull, fileName);
XML_Parser parser = XML_ParserCreate(NULL);
AbstractXMLLoader::ParseData* data = parseDataFactFuncPntr(&parser);
std::string msg = "Loading ";
msg += fileName;
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, msg.c_str());
hFile = FileOpen(fileNameFull, FILE_ACCESS_READ, FALSE);
if (!hFile) {
delete data;
return false;
}
uiFSize = FileGetSize(hFile);
lpcBuffer = (CHAR8*)MemAlloc(uiFSize + 1);
if (!FileRead(hFile, lpcBuffer, uiFSize, &uiBytesRead)) {
MemFree(lpcBuffer);
delete data;
return false;
}
lpcBuffer[uiFSize] = 0;
FileClose(hFile);
ExternalEntityArgs eeArgs;
eeArgs.directoryName = directoryName;
eeArgs.fileName = fileName;
eeArgs.pParser = &parser;
XML_SetElementHandler(parser, startElementHandler, endElementHandler);
XML_SetCharacterDataHandler(parser, characterDataHandler);
XML_SetUserData(parser, data);
XML_SetExternalEntityRefHandler(parser, ExternalEntityHandler);
XML_SetExternalEntityRefHandlerArg(parser, (void*)&eeArgs);
try {
if (!XML_Parse(parser, lpcBuffer, uiFSize, TRUE)) {
CHAR8 errorBuf[512];
sprintf(errorBuf, "XML Parser Error in %s[%d]: %s", fileNameFull, XML_GetCurrentLineNumber(parser), XML_ErrorString(XML_GetErrorCode(parser)));
LiveMessage(errorBuf);
MemFree(lpcBuffer);
delete data;
return false;
}
} catch (XMLParseException e) {
CHAR8 errorBuf[512];
sprintf(errorBuf, "XML Parser Exception in %s[%d]: %s", fileNameFull, e._LINE, e.what());
LiveMessage(errorBuf);
MemFree(lpcBuffer);
XML_ParserFree(parser);
delete data;
return false;
}
MemFree(lpcBuffer);
XML_ParserFree(parser);
delete data;
return true;
}
int XMLCALL AbstractXMLLoader::ExternalEntityHandler(XML_Parser args, const XML_Char* context, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId) {
ExternalEntityArgs* eArgs = (ExternalEntityArgs*)args;
char fileNameFull[MAX_PATH + 1];
UINT32 uiBytesRead;
UINT32 uiFSize;
CHAR8* lpcBuffer;
HWFILE hFile;
if (strlen(eArgs->directoryName) + strlen(systemId) >= MAX_PATH) {
LiveMessage("Can't load file specified in external entity. Concatinated filename too long for buffer!");
return XML_STATUS_ERROR;
}
strcpy(fileNameFull, eArgs->directoryName);
strcat(fileNameFull, systemId);
hFile = FileOpen(fileNameFull, FILE_ACCESS_READ, FALSE);
if (!hFile) {
LiveMessage("File specified in external entity can't be opened!");
return XML_STATUS_ERROR;
}
uiFSize = FileGetSize(hFile);
lpcBuffer = (CHAR8*)MemAlloc(uiFSize + 1);
if (!FileRead(hFile, lpcBuffer, uiFSize, &uiBytesRead)) {
LiveMessage("File specified in external entity couldn't be read!");
MemFree(lpcBuffer);
return XML_STATUS_ERROR;
}
lpcBuffer[uiFSize] = 0;
FileClose(hFile);
XML_Parser extParser = XML_ExternalEntityParserCreate(*eArgs->pParser, context, NULL);
ParseData* data = (ParseData*)XML_GetUserData(*eArgs->pParser);
data->pParser = &extParser;
try {
if (!XML_Parse(extParser, lpcBuffer, uiFSize, TRUE)) {
CHAR8 errorBuf[512];
sprintf(errorBuf, "XML Parser Error in external entity %s[%d]: %s", systemId, XML_GetCurrentLineNumber(extParser), XML_ErrorString(XML_GetErrorCode(extParser)));
LiveMessage(errorBuf);
return XML_STATUS_ERROR;
}
} catch (XMLParseException e) {
CHAR8 errorBuf[512];
sprintf(errorBuf, "XML Parser Exception in external entity %s[%d]: %s", systemId, e._LINE, e.what());
LiveMessage(errorBuf);
XML_ParserFree(extParser);
return XML_STATUS_ERROR;
}
data->pParser = eArgs->pParser;
XML_ParserFree(extParser);
return XML_STATUS_OK;
};
const char* AbstractXMLLoader::GetFileName() {
return fileName;
}
const char* AbstractXMLLoader::GetDirectoryName() {
return directoryName;
}
void AbstractXMLLoader::SetFileName(const char* fileName) {
strcpy(this->fileName, fileName);
}
void AbstractXMLLoader::SetDirectoryName(const char* directoryName) {
strcpy(this->directoryName, directoryName);
}
const XML_Char* AbstractXMLLoader::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;
}
bool AbstractXMLLoader::ConvertStringToINT8(const XML_Char* num, INT8* int8) {
long l = strtol(num, NULL, 10);
if (l > 127 || l < -128) return false;
if (l == 0 && strcmp(num, "0") != 0) return false;
*int8 = (INT8)l;
return true;
}
bool AbstractXMLLoader::ConvertStringToUINT8(const XML_Char* num, UINT8* uInt8) {
unsigned long ul = strtoul(num, NULL, 10);
if (ul > 255) return false;
if (ul == 0 && strcmp(num, "0") != 0) return false;
*uInt8 = (UINT8)ul;
return true;
}
bool AbstractXMLLoader::ConvertStringToINT32(const XML_Char* num, INT32* int32) {
long l = strtol(num, NULL, 10);
// TODO: add range checks also for long types (and use the defined macros)
// TODO: string should be trimmed (other convert functions also)
if (l == 0 && strcmp(num, "0") != 0) return false;
*int32 = (INT32)l;
return true;
}
bool AbstractXMLLoader::ConvertStringToUINT32(const XML_Char* num, UINT32* uInt32) {
unsigned long ul = strtoul(num, NULL, 10);
if (ul == 0 && strcmp(num, "0") != 0) return false;
*uInt32 = ul;
return true;
}
bool AbstractXMLLoader::ConvertStringToBOOLEAN(const XML_Char* num, BOOLEAN* fBoolean) {
unsigned long ul = strtoul(num, NULL, 10);
if (ul == 0 && strcmp(num, "0") != 0) return false;
*fBoolean = ul != 0;
return true;
}
}
@@ -0,0 +1,84 @@
#pragma once
#ifndef _LBT_ABSTRACTXMLLOADER__H_
#define _LBT_ABSTRACTXMLLOADER__H_
#include <string>
#include <map>
#include "expat.h"
#include "Types.h"
#include "XML.h"
#include "TopicIDs.h"
#include "TopicOps.h"
#include "DEBUG.H"
#include "FileMan.h"
#include "MemMan.h"
#include "Debug Control.h"
#include "Sys Globals.h"
#include "LogicalBodyTypes/Singleton.h"
#include "LogicalBodyTypes/XMLParseException.h"
namespace LogicalBodyTypes {
class AbstractXMLLoader : public ISingleton<AbstractXMLLoader>
{
protected:
enum ParseState {
E_NONE,
FIRST_SUBCLASS_STATE
};
class ParseData {
public:
ParseData(XML_Parser* parser = NULL);
XML_Parser* pParser;
int state; // we sacrifice type safety for the enumerators so subclasses can define their own states
UINT32 level;
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH + 1];
CHAR8 szErrorTxt[MAX_PATH + 1];
} typedef ParseData;
struct ExternalEntityArgs {
const char* directoryName;
const char* fileName;
XML_Parser* pParser;
} typedef ExternalEntityArgs;
typedef ParseData* (*ParseDataFactoryFunc) (XML_Parser* parser);
private:
XML_StartElementHandler startElementHandler;
XML_EndElementHandler endElementHandler;
XML_CharacterDataHandler characterDataHandler;
ParseDataFactoryFunc parseDataFactFuncPntr;
char directoryName[MAX_PATH + 1];
char fileName[MAX_PATH + 1];
public:
AbstractXMLLoader(XML_StartElementHandler startHandler, XML_EndElementHandler endHandler, XML_CharacterDataHandler charHandler, ParseDataFactoryFunc parseDataFactF = MakeParseData);
~AbstractXMLLoader(void);
bool LoadFromFile(const char* directoryName, const char* fileName);
const char* GetFileName();
const char* GetDirectoryName();
void SetFileName(const char* fileName);
void SetDirectoryName(const char* directoryName);
protected:
static const XML_Char* GetAttribute(const XML_Char* name, const XML_Char** atts);
static bool ConvertStringToINT8(const XML_Char* num, INT8* uInt8);
static bool ConvertStringToUINT8(const XML_Char* num, UINT8* uInt8);
static bool ConvertStringToINT32(const XML_Char* num, INT32* int32);
static bool ConvertStringToUINT32(const XML_Char* num, UINT32* uInt32);
static bool ConvertStringToBOOLEAN(const XML_Char* num, BOOLEAN* fBoolean);
static ParseData* MakeParseData(XML_Parser* parser);
private:
static AbstractXMLLoader& Instance();
static void XMLCALL StartElementHandle(void* userData, const XML_Char* name, const XML_Char** atts);
static void XMLCALL EndElementHandle(void* userData, const XML_Char* name);
static void XMLCALL CharacterDataHandle(void* userData, const XML_Char* str, int len);
static int XMLCALL ExternalEntityHandler(XML_Parser args, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId);
};
}
#endif
+59
View File
@@ -0,0 +1,59 @@
#include "BodyType.h"
namespace LogicalBodyTypes {
BodyType::BodyType(UINT32 cacheSize, Filter* filterP) {
filter = filterP;
hasSurfaces = false;
cache = new SurfaceCache(cacheSize);
animstates.resize(NUMANIMATIONSTATES);
physAnimSurfaces.resize(NUMANIMATIONSURFACETYPES);
for (int i = 0; i < NUMANIMATIONSTATES; i++) {
animstates[i].resize(Layers::Instance().GetCount());
}
for (int i = 0; i < NUMANIMATIONSURFACETYPES; i++) {
physAnimSurfaces[i].resize(Layers::Instance().GetCount());
}
// initialize body type specific layer properties with the layer specific layer properties.
Layers::LayerPropertiesVector::size_type numLayers = Layers::Instance().GetCount();
layerProperties.resize(numLayers);
for (Layers::LayerPropertiesVector::size_type layer = 0; layer < numLayers; layer++) {
layerProperties[layer] = Layers::Instance().GetLayerProperties(layer);
}
}
BodyType::~BodyType(void) {
delete cache;
}
void BodyType::AddSurfaceForAnimState(UINT16 usAnimState, Layers::LayerPropertiesVector::size_type layer, AnimationSurfaceType* animSurfaceType, AnimationSurfaceType* alphaSurfaceType, Filter* filter, PaletteTable* paletteTable) {
STRUCTURE_FILE_REF* pStructFile = SurfaceDB::Instance().GetStructFile(animSurfaceType);
UINT32 idx = cache->AddSurface(animSurfaceType, pStructFile);
UINT32 idxAlpha = 0;
if (alphaSurfaceType != NULL) {
idxAlpha = cache->AddSurface(alphaSurfaceType, pStructFile);
}
animstates[usAnimState][layer].push_back(FilterSurfaceTypePair(filter, FilterSurfaceTypePair::second_type(idx, LogicalSurfaceType(animSurfaceType, alphaSurfaceType, idxAlpha, paletteTable))));
hasSurfaces = true;
}
void BodyType::AddSurfaceForPhysSurface(UINT16 usAnimSurface, Layers::LayerPropertiesVector::size_type layer, AnimationSurfaceType* animSurfaceType, AnimationSurfaceType* alphaSurfaceType, Filter* filter, PaletteTable* paletteTable) {
STRUCTURE_FILE_REF* pStructFile = SurfaceDB::Instance().GetStructFile(animSurfaceType);
UINT32 idx = cache->AddSurface(animSurfaceType, pStructFile);
UINT32 idxAlpha = 0;
if (alphaSurfaceType != NULL) {
idxAlpha = cache->AddSurface(alphaSurfaceType, pStructFile);
}
physAnimSurfaces[usAnimSurface][layer].push_back(FilterSurfaceTypePair(filter, FilterSurfaceTypePair::second_type(idx, LogicalSurfaceType(animSurfaceType, alphaSurfaceType, idxAlpha, paletteTable))));
hasSurfaces = true;
}
void BodyType::SetLayerProperties(Layers::LayerPropertiesVector::size_type index, Layers::LayerProperties properties) {
layerProperties[index] = properties; // TODO range check?
}
const Layers::LayerProperties* BodyType::GetLayerProperties(Layers::LayerPropertiesVector::size_type index) {
return &layerProperties[index]; // TODO range check?
}
}
+107
View File
@@ -0,0 +1,107 @@
#pragma once
#ifndef _LBT_BODYTYPE__H_
#define _LBT_BODYTYPE__H_
#include "LogicalBodyTypes/Layers.h"
#include "LogicalBodyTypes/Filter.h"
#include "LogicalBodyTypes/SurfaceCache.h"
#include "LogicalBodyTypes/SurfaceDB.h"
#include "LogicalBodyTypes/PaletteDB.h"
#include "LogicalBodyTypes/PaletteTable.h"
#include "Animation Data.h"
#include "Animation Control.h"
namespace LogicalBodyTypes {
class BodyType {
public:
struct LogicalSurfaceType {
LogicalSurfaceType(AnimationSurfaceType* physicalSurfaceType, AnimationSurfaceType* alphaSurfaceType, UINT32 alphaSurfaceIdx, PaletteTable* paletteTable)
: paletteTable(paletteTable), physicalSurfaceType(physicalSurfaceType), alphaSurfaceType(alphaSurfaceType), alphaSurfaceIdx(alphaSurfaceIdx) {};
const PaletteTable* paletteTable;
const AnimationSurfaceType* physicalSurfaceType;
const AnimationSurfaceType* alphaSurfaceType;
UINT32 alphaSurfaceIdx;
} typedef LogicalSurfaceType;
private:
typedef std::pair<Filter*, std::pair<UINT32, LogicalSurfaceType> > FilterSurfaceTypePair;
typedef std::list<FilterSurfaceTypePair> FilterSurfaceTypeList;
typedef std::vector<FilterSurfaceTypeList> LayerVector;
typedef std::vector<LayerVector> AnimStateVector;
typedef std::vector<LayerVector> PhysAnimSurfaceVector;
AnimStateVector animstates;
PhysAnimSurfaceVector physAnimSurfaces;
Layers::LayerPropertiesVector layerProperties;
Filter* filter;
bool hasSurfaces;
UINT32 numCacheNodes;
UINT32 maxCacheNodes;
SurfaceCache* cache;
public:
BodyType(UINT32 cacheSize, Filter* filterP = NULL);
~BodyType(void);
void AddSurfaceForAnimState(UINT16 usAnimState, Layers::LayerPropertiesVector::size_type layer, AnimationSurfaceType* animSurfaceType, AnimationSurfaceType* alphaSurfaceType = NULL, Filter* filter = NULL, PaletteTable* paletteTable = NULL);
void AddSurfaceForPhysSurface(UINT16 usAnimSurface, Layers::LayerPropertiesVector::size_type layer, AnimationSurfaceType* animSurfaceType, AnimationSurfaceType* alphaSurfaceType = NULL, Filter* filter = NULL, PaletteTable* paletteTable = NULL);
void SetLayerProperties(Layers::LayerPropertiesVector::size_type index, Layers::LayerProperties properties);
const Layers::LayerProperties* GetLayerProperties(Layers::LayerPropertiesVector::size_type index);
inline bool Match(SOLDIERTYPE* pSoldier) {
if (filter != NULL) return filter->Match(pSoldier);
return false; // no filter specified - matches none
};
inline bool HasSurfaces() {
return hasSurfaces;
}
inline BodyType::LogicalSurfaceType* GetLogicalSurfaceType(Layers::LayerPropertiesVector::size_type layer, SOLDIERTYPE* pSoldier) {
FilterSurfaceTypeList::iterator end = animstates[pSoldier->usAnimState][layer].end();
for (FilterSurfaceTypeList::iterator i = animstates[pSoldier->usAnimState][layer].begin(); i != end; i++) {
Filter* f = (*i).first;
if (f != NULL) {
if (f->Match(pSoldier)) {
bool isLoaded = cache->GetLoadedSurface((*i).second.first) != NULL;
if ((*i).second.second.alphaSurfaceType != NULL) {
isLoaded = isLoaded && (cache->GetLoadedSurface((*i).second.second.alphaSurfaceIdx) != NULL);
}
return (isLoaded) ? &(*i).second.second : NULL;
}
} else { // no filter specified - matches all
bool isLoaded = cache->GetLoadedSurface((*i).second.first) != NULL;
if ((*i).second.second.alphaSurfaceType != NULL) {
isLoaded = isLoaded && (cache->GetLoadedSurface((*i).second.second.alphaSurfaceIdx) != NULL);
}
return (isLoaded) ? &(*i).second.second : NULL;
}
}
end = physAnimSurfaces[pSoldier->usAnimSurface][layer].end();
for (FilterSurfaceTypeList::iterator i = physAnimSurfaces[pSoldier->usAnimSurface][layer].begin(); i != end; i++) {
Filter* f = (*i).first;
if (f != NULL) {
if (f->Match(pSoldier)) {
bool isLoaded = cache->GetLoadedSurface((*i).second.first) != NULL;
if ((*i).second.second.alphaSurfaceType != NULL) {
isLoaded = isLoaded && (cache->GetLoadedSurface((*i).second.second.alphaSurfaceIdx) != NULL);
}
return (isLoaded) ? &(*i).second.second : NULL;
}
} else { // no filter specified - matches all
bool isLoaded = cache->GetLoadedSurface((*i).second.first) != NULL;
if ((*i).second.second.alphaSurfaceType != NULL) {
isLoaded = isLoaded && (cache->GetLoadedSurface((*i).second.second.alphaSurfaceIdx) != NULL);
}
return (isLoaded) ? &(*i).second.second : NULL;
}
}
return NULL;
};
};
}
#endif
File diff suppressed because it is too large Load Diff
+78
View File
@@ -0,0 +1,78 @@
#pragma once
#ifndef _LBT_BODYTYPEDB__H_
#define _LBT_BODYTYPEDB__H_
#include <list>
#include "LogicalBodyTypes/Singleton.h"
#include "LogicalBodyTypes/AbstractXMLLoader.h"
#include "LogicalBodyTypes/BodyType.h"
#include "LogicalBodyTypes/FilterDB.h"
#include "LogicalBodyTypes/SurfaceDB.h"
namespace LogicalBodyTypes {
class BodyTypeDB : public AbstractXMLLoader, public Singleton<BodyTypeDB> {
public:
using Singleton <BodyTypeDB>::Instance;
typedef std::list<BodyType*> BodyTypeList;
//TOTAL_SOLDIERS
private:
enum ParseState {
E_ELEMENT_BODYTYPES = FIRST_SUBCLASS_STATE,
E_ELEMENT_BODYTYPE,
E_ELEMENT_LAYER_CONFIGS,
E_ELEMENT_LAYER_CONFIG,
E_ELEMENT_SURFACES,
E_ELEMENT_LAYER,
E_ELEMENT_PROP,
E_ELEMENT_SURFACE
};
struct ParseData : public AbstractXMLLoader::ParseData { // shadow ParseData type and also extend the ParseData stuct of the base class
ParseData(XML_Parser* parser) : AbstractXMLLoader::ParseData(parser) {
currentBodyType = NULL;
filter = NULL;
paletteTable = NULL;
layer = -1;
layerPropertiesConfig.clear();
};
~ParseData() {
if (currentBodyType != NULL) delete currentBodyType;
};
BodyType* currentBodyType;
Filter* filter;
PaletteTable* paletteTable;
Layers::LayerPropertiesVector::size_type layer;
std::map<Layers::LayerPropertiesVector::size_type, Layers::LayerProperties> layerPropertiesConfig;
} typedef ParseData;
BodyTypeList bodyTypes;
public:
BodyTypeDB(void);
~BodyTypeDB(void);
void Add(BodyType* bodyType);
inline BodyType* Find(SOLDIERTYPE* pSoldier) {
BodyTypeList::iterator end = bodyTypes.end();
for (BodyTypeList::iterator i = bodyTypes.begin(); i != end; i++) {
// if we find a bodytype, but it does not have any surfaces, it is meant to exclude objects
// from being matched against bodytypes so we return NULL in that case.
if ((*i)->Match(pSoldier)) return ((*i)->HasSurfaces()) ? *i : NULL;
}
return NULL;
};
private:
static void RegisterEnumerators();
static void XMLCALL StartElementHandle(void* userData, const XML_Char* name, const XML_Char** atts);
static void XMLCALL CharacterDataHandle(void* userData, const XML_Char* str, int len);
static void XMLCALL EndElementHandle(void* userData, const XML_Char* name);
static void XMLCALL ExternalEntityHandler(XML_Parser parser, const XML_Char* context, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId);
static AbstractXMLLoader::ParseData* MakeParseData(XML_Parser* parser); // shadow factory function for ParseData instances
};
}
#endif
@@ -0,0 +1,64 @@
#include "EnumeratorDB.h"
namespace LogicalBodyTypes {
EnumeratorDB::EnumeratorDB() {
}
EnumeratorDB::~EnumeratorDB(void) {
}
void EnumeratorDB::AddEnum(std::string enumName, int num, char* strEnumerators, ...) {
int strLen = strlen(strEnumerators);
char* str = new char[strLen + 1];
strcpy(str, strEnumerators);
// for detecting synchronization issue between the actual enum declaration and the DB insertion
// assert that the number of provided enumerators matches the expected number
int numSemiColons = 0;
for (int i = 0; i < strLen; i++) if (strEnumerators[i] == ',') numSemiColons++;
// TODO: remove output to cout Log this event somehow not just do the assertion!
if (numSemiColons + 1 != num) {
std::cout << enumName << " expected " << num << " got " << numSemiColons + 1 << std::endl;
}
assert(numSemiColons + 1 == num);
// if enumeration already in DB, delete
EnumerationMap::iterator i = enumerations.find(enumName);
if (i != enumerations.end()) enumerations.erase(enumName);
char* token = strtok(str, ", ");
va_list vl;
va_start(vl, strEnumerators);
for (int i = 0; i < num; i++) {
enumerations[enumName][token] = va_arg(vl, int);
token = strtok(NULL, ", ");
}
va_end(vl);
delete str;
}
bool EnumeratorDB::GetEnumeratorStr(const char* enumeration, int enumerator, std::string& str) {
EnumerationMap::iterator i = enumerations.find(enumeration);
if (i != enumerations.end()) {
for (EnumeratorMap::iterator j = i->second.begin(); j != i->second.end(); j++) {
if (j->second == enumerator) {
str = j->first;
return true;
}
}
}
return false;
}
bool EnumeratorDB::GetEnumeratorByStr(const char* enumeration, const char* enumerationStr, int& enumerator) {
EnumerationMap::iterator i = enumerations.find(enumeration);
if (i == enumerations.end()) return false;
EnumeratorMap::iterator j = i->second.find(enumerationStr);
if (j == i->second.end()) return false;
enumerator = j->second;
return true;
}
}
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#ifndef _LBT_ENUMERATORDB__H_
#define _LBT_ENUMERATORDB__H_
#include "LogicalBodyTypes/Singleton.h"
#include <string>
#include <map>
#include <stdarg.h>
#include <iostream>
#define LOGBT_ENUMDB_ADD(enumName, count, ...) EnumeratorDB::Instance().AddEnum(enumName, count, #__VA_ARGS__, __VA_ARGS__)
namespace LogicalBodyTypes {
class EnumeratorDB : public Singleton<EnumeratorDB> {
public:
typedef std::map<std::string, int> EnumeratorMap;
typedef std::map<std::string, EnumeratorMap> EnumerationMap;
EnumerationMap enumerations;
public:
EnumeratorDB();
~EnumeratorDB();
void AddEnum(std::string enumName, int num, char* strEnumerators, ...);
// Note: this will return the FIRST enumerator of the specified enumeration
// that matches the provided ordinal value!
// Also: it is expected that this will only be called in situations where the efficiency is not relevant
// (like for generating a list of enumerators for testing/documentation)
// otherwise a different mechanism for storing the enumerations should be implemented.
bool GetEnumeratorStr(const char* enumeration, int enumerator, std::string& str);
bool GetEnumeratorByStr(const char* enumeration, const char* enumerationStr, int& enumerator);
};
};
#endif
+303
View File
@@ -0,0 +1,303 @@
#include "Filter.h"
namespace LogicalBodyTypes {
Filter::Filter(void) {
}
Filter::~Filter(void) {
for (CriteriaMap::iterator i = criteria.begin(); i != criteria.end(); i++) {
if (i->first & _TYPE_STRING) {
if (i->first & _TYPE_LIST) delete i->second.stringList;
else delete i->second.string;
}
else if (i->first & _TYPE_INTEGER) {
if (i->first & _TYPE_PAIR) delete i->second.numberPair;
else if (i->first & _TYPE_LIST) delete i->second.numberList;
}
}
}
void Filter::AddCriterion(UINT32 type, std::wstring& value) {
type &= ~_TYPE_INTEGER;
type |= _TYPE_STRING;
std::wstring* str = new std::wstring(value);
criterionVariant val;
val.string = str;
criteria.insert(CriteriaMap::value_type(type, val));
}
void Filter::AddCriterion(UINT32 type, STR16 value) {
type &= ~_TYPE_INTEGER;
type |= _TYPE_STRING;
std::wstring* str = new std::wstring(value);
criterionVariant val;
val.string = str;
criteria.insert(CriteriaMap::value_type(type, val));
}
void Filter::AddCriterion(UINT32 type, StringList& list) {
type &= ~_TYPE_INTEGER;
type |= _TYPE_STRING;
criterionVariant val;
val.stringList = new StringList(list); // I don't trust copy constructors, but oh well...
criteria.insert(CriteriaMap::value_type(type, val));
}
void Filter::AddCriterion(UINT32 type, INT32 value) {
type &= ~_TYPE_STRING;
type |= _TYPE_INTEGER;
criterionVariant val;
val.number = value;
criteria.insert(CriteriaMap::value_type(type, val));
}
void Filter::AddCriterion(UINT32 type, INT32 value1, INT32 value2) {
type &= ~_TYPE_STRING;
type |= _TYPE_INTEGER;
criterionVariant val;
val.numberPair = new NumberPair(value1, value2);
criteria.insert(CriteriaMap::value_type(type, val));
}
void Filter::AddCriterion(UINT32 type, NumberList& list) {
type &= ~_TYPE_STRING;
type |= _TYPE_INTEGER;
criterionVariant val;
val.numberList = new NumberList(list); // I don't trust copy constructors, but oh well...
criteria.insert(CriteriaMap::value_type(type, val));
}
void Filter::AddCriterion(UINT32 type, Filter* filter) {
type |= _TYPE_FILTER;
criterionVariant val;
val.filter = filter;
criteria.insert(CriteriaMap::value_type(type, val));
}
void Filter::Dump(std::wstringstream& stream) {
stream << L"<-------- Filter" << std::endl;
for (CriteriaMap::iterator ii = criteria.begin(); ii != criteria.end(); ii++) {
UINT32 flags = ii->first & _UNSET_FLAGS;
UINT32 cType = ii->first & ~_UNSET_FLAGS;
std::string op = "";
if (flags & _REQ_OR) op += "OR";
if (flags & _REQ_AND) op += "AND";
std::string cmpop = "";
if ((flags & _REQ_NOT) && (flags & _REQ_EQ)) cmpop = "!=";
if (((flags & _REQ_NOT) != _REQ_NOT) && (flags & _REQ_EQ)) cmpop = "==";
if ((flags & _REQ_NOT) && (flags & _REQ_GT)) cmpop = ">";
if (((flags & _REQ_NOT) != _REQ_NOT) && (flags & _REQ_GT)) cmpop = "<=";
if ((flags & _REQ_NOT) && (flags & _REQ_LT)) cmpop = "<";
if (((flags & _REQ_NOT) != _REQ_NOT) && (flags & _REQ_LT)) cmpop = ">=";
if (flags & Filter::_TYPE_STRING) {
std::string enumStr;
EnumeratorDB::Instance().GetEnumeratorStr("StringFilterCriterionTypes", cType, enumStr);
stream << L"criterion: " << op << L" str " << enumStr << L" " << cmpop << L" " << *ii->second.string << std::endl;
}
if (flags & Filter::_TYPE_INTEGER) {
std::string enumStr;
// first try to find the enumerator in the integer criterion type list then in the enum list
bool foundEnumerator = EnumeratorDB::Instance().GetEnumeratorStr("IntegerFilterCriterionTypes", cType, enumStr);
if (!foundEnumerator) EnumeratorDB::Instance().GetEnumeratorStr("EnumFilterCriterionTypes", cType, enumStr);
stream << L"criterion: " << op << L" str " << enumStr << L" " << cmpop << L" " << ii->second.number << std::endl;
}
// TODO: drop method or update to match the additional types that have been added.
}
stream << L"-------->" << std::endl;
}
// quite an ugly implementation. Should be re-done
bool Filter::Match(SOLDIERTYPE* pSoldier) {
bool orReq = false;
bool orRes = false;
UINT32 operation = _REQ_AND;
// TODO: make sure container is a BT, since we need no random access anyways!
for (CriteriaMap::iterator ii = criteria.begin(); ii != criteria.end(); ii++) {
UINT32 r = ii->first;
if ((r & _REQ_AND) == _REQ_AND) {
operation = _REQ_AND;
}
else if ((r & _REQ_OR) == _REQ_OR) {
if (orRes) continue;
orReq = true;
operation = _REQ_OR;
}
char sgn;
if (r & _TYPE_INTEGER) {
INT32 cmp_val;
UINT32 q = r & ~_UNSET_FLAGS;
switch (q) {
case REQ_BODYTYPE:
cmp_val = pSoldier->ubBodyType;
break;
case REQ_TEAM:
cmp_val = pSoldier->bTeam;
break;
case REQ_SOLDIER_CLASS:
cmp_val = pSoldier->ubSoldierClass;
break;
case REQ_CIVILIANGROUP:
cmp_val = pSoldier->ubCivilianGroup;
break;
case REQ_CAMO:
cmp_val = pSoldier->bCamo;
break;
case REQ_URBANCAMO:
cmp_val = pSoldier->urbanCamo;
break;
case REQ_DESERTCAMO:
cmp_val = pSoldier->desertCamo;
break;
case REQ_SNOWCAMO:
cmp_val = pSoldier->snowCamo;
break;
case REQ_EXPLEVEL:
cmp_val = pSoldier->stats.bExpLevel;
break;
case REQ_STRENGTH:
cmp_val = pSoldier->stats.bStrength;
break;
case REQ_LEADERSHIP:
cmp_val = pSoldier->stats.bLeadership;
break;
case REQ_WISDOM:
cmp_val = pSoldier->stats.bWisdom;
break;
/* case REQ_SKILLTRAIT1:
cmp_val = pSoldier->stats.ubSkillTrait1;
break;
case REQ_SKILLTRAIT2:
cmp_val = pSoldier->stats.ubSkillTrait2;
break;*/
case REQ_FACEINDEX:
if (pSoldier->ubProfile == NO_PROFILE
|| pSoldier->ubProfile < 1
|| pSoldier->ubProfile > NUM_PROFILES - 2) return false;
cmp_val = gMercProfiles[pSoldier->ubProfile].ubFaceIndex;
break;
case REQ_WEAPON_IN_HAND:
cmp_val = WeaponInHand(pSoldier);
break;
case REQ_MERC_TYPE:
cmp_val = pSoldier->ubWhatKindOfMercAmI;
break;
case REQ_WEAPON_CLASS:
cmp_val = Weapon[pSoldier->inv[HANDPOS].usItem].ubWeaponClass;
break;
case REQ_WEAPON_TYPE:
cmp_val = Weapon[pSoldier->inv[HANDPOS].usItem].ubWeaponType;
break;
case REQ_CALIBRE:
cmp_val = Weapon[pSoldier->inv[HANDPOS].usItem].ubCalibre;
break;
case REQ_VEST_AMOR_PROTECTION:
cmp_val = Armour[Item[pSoldier->inv[VESTPOS].usItem].ubClassIndex].ubProtection;
break;
case REQ_VEST_AMOR_COVERAGE:
cmp_val = Armour[Item[pSoldier->inv[VESTPOS].usItem].ubClassIndex].ubCoverage;
break;
case REQ_HELMET_AMOR_PROTECTION:
cmp_val = Armour[Item[pSoldier->inv[HELMETPOS].usItem].ubClassIndex].ubProtection;
break;
case REQ_HELMET_AMOR_COVERAGE:
cmp_val = Armour[Item[pSoldier->inv[HELMETPOS].usItem].ubClassIndex].ubCoverage;
break;
default:
if (q < NUM_REQTYPESINV) {
cmp_val = pSoldier->inv[q].usItem;
} else {
// not implemented. We should log this somehow(must be cached).
return false;
}
}
if (r & _TYPE_LIST) {
NumberList* nl = ii->second.numberList;
sgn = -1; // -1 or 1 doesn't matter
for (NumberList::iterator i = nl->begin(); i != nl->end(); i++) {
if (*i == cmp_val) {
sgn = 0;
break;
}
}
} else if (r & _TYPE_PAIR) {
NumberPair* nl = ii->second.numberPair;
// TODO: resolve compiler warning about usigned/signed and the comparison ops?!?
sgn = (nl->second > cmp_val) ? -1 : (nl->first < cmp_val) ? 1 : 0;
} else {
sgn = (ii->second.number > cmp_val) ? -1 : (ii->second.number < cmp_val) ? 1 : 0;
}
} else if (r & _TYPE_STRING) {
// string comparison is quite costly at the moment. should be avoided or reimplemented.
// would probably be much more sensible just to loop and make a wchar for wchar check.
// I wanted to use the signum compare as with the integer values. But since that
// is more like a code gimmick than an actual useful feature, probably better to
// drop the check for > < for strings alltogether.
std::wstring cmp_val;
CHAR16 wStr[31];
switch (r & ~_UNSET_FLAGS) {
case REQ_NAME:
wcscpy(wStr, pSoldier->name);
cmp_val = wStr;
break;
case REQ_PROFILENAME:
if (pSoldier->ubProfile == NO_PROFILE
|| pSoldier->ubProfile < 1
|| pSoldier->ubProfile > NUM_PROFILES - 2) return false;
wcscpy(wStr, gMercProfiles[pSoldier->ubProfile].zName);
cmp_val = wStr;
break;
case REQ_NICKNAME:
if (pSoldier->ubProfile == NO_PROFILE
|| pSoldier->ubProfile < 1
|| pSoldier->ubProfile > NUM_PROFILES - 2) return false;
wcscpy(wStr, gMercProfiles[pSoldier->ubProfile].zNickname);
cmp_val = wStr;
break;
default:
// not implemented. We should log this somehow(must be cached).
return false;
}
if (r & _TYPE_LIST) {
StringList* sl = ii->second.stringList;
sgn = -1; // -1 or 1 doesn't matter
for (StringList::iterator i = sl->begin(); i != sl->end(); i++) {
if (*i == cmp_val) {
sgn = 0;
break;
}
}
}
else {
std::wstring* sp = ii->second.string;
sgn = cmp_val.compare(*sp);
}
} else if (r & _TYPE_FILTER) {
if (ii->second.filter == NULL) {
// TODO: log or exception
return false;
}
sgn = (ii->second.filter->Match(pSoldier)) ? 0 : -1; // -1 or 1 doesn't matter
} else {
// TODO: log or exception
return false;
}
bool res = ((r & _REQ_NOT) == _REQ_NOT) ^ (
(((r & _REQ_EQ) == _REQ_EQ) && sgn == 0)
|| (((r & _REQ_IN) == _REQ_IN) && sgn == 0)
|| (((r & _REQ_BTWN) == _REQ_BTWN) && sgn == 0)
|| (((r & _REQ_GT) == _REQ_GT) && sgn == 1)
|| (((r & _REQ_LT) == _REQ_LT) && sgn == -1)
);
if (operation == _REQ_AND) {
if (!res) return false;
} else if (operation == _REQ_OR) {
orRes |= res;
}
}
return !orReq || orRes;
};
};
+118
View File
@@ -0,0 +1,118 @@
#pragma once
#ifndef _LBT_FILTER__H_
#define _LBT_FILTER__H_
#include <string>
#include <map>
#include "DEBUG.H"
#include "Soldier Control.h"
#include "soldier profile type.h"
#include "Soldier Profile.h"
#include "Weapons.h"
#include "LogicalBodyTypes/EnumeratorDB.h"
namespace LogicalBodyTypes {
class Filter {
public:
enum ConditionTypes
{
// lowest two bytes are reserved for enumerators
REQ_HELMETPOS,
REQ_VESTPOS,
REQ_LEGPOS,
REQ_HEAD1POS,
REQ_HEAD2POS,
REQ_HANDPOS,
REQ_SECONDHANDPOS,
REQ_VESTPOCKPOS,
REQ_LTHIGHPOCKPOS,
REQ_RTHIGHPOCKPOS,
REQ_CPACKPOCKPOS,
REQ_BPACKPOCKPOS,
REQ_GUNSLINGPOCKPOS,
REQ_KNIFEPOCKPOS,
NUM_REQTYPESINV,
REQ_SEX,
REQ_MERC_TYPE,
REQ_NAME,
REQ_SOLDIER_CLASS,
REQ_TEAM,
REQ_CIVILIANGROUP,
REQ_CAMO,
REQ_URBANCAMO,
REQ_DESERTCAMO,
REQ_SNOWCAMO,
REQ_BODYTYPE,
REQ_EXPLEVEL,
REQ_STRENGTH,
REQ_LEADERSHIP,
REQ_WISDOM,
REQ_SKILLTRAIT1,
REQ_SKILLTRAIT2,
REQ_FACEINDEX,
REQ_PROFILENAME,
REQ_NICKNAME,
REQ_WEAPON_IN_HAND,
REQ_WEAPON_CLASS,
REQ_WEAPON_TYPE,
REQ_CALIBRE,
REQ_VEST_AMOR_PROTECTION,
REQ_VEST_AMOR_COVERAGE,
REQ_HELMET_AMOR_PROTECTION,
REQ_HELMET_AMOR_COVERAGE,
NUM_REQTYPES,
// 3rd byte is for operator flags
_REQ_BTWN = 0x20000,
_REQ_NOT = 0x40000,
_REQ_EQ = 0x80000,
_REQ_LT = 0x100000,
_REQ_GT = 0x200000,
_REQ_AND = 0x400000,
_REQ_OR = 0x800000,
_REQ_IN = 0x1000000,
// 4th byte is for type flags
_TYPE_STRING = 0x2000000,
_TYPE_INTEGER = 0x4000000,
_TYPE_ENUM = 0x8000000,
_TYPE_LIST = 0x10000000,
_TYPE_PAIR = 0x20000000,
_TYPE_FILTER = 0x40000000,
// TODO rename enumerator _ALL_FLAGS or somesuch
_UNSET_FLAGS = _TYPE_FILTER | _TYPE_PAIR | _TYPE_LIST | _TYPE_ENUM | _TYPE_STRING | _TYPE_INTEGER | _REQ_IN | _REQ_OR | _REQ_AND | _REQ_BTWN | _REQ_NOT | _REQ_EQ | _REQ_LT | _REQ_GT
};
typedef std::pair <INT32, INT32> NumberPair;
typedef std::list <std::wstring> StringList;
typedef std::list <INT32> NumberList;
union criterionVariant {
INT32 number;
std::wstring* string;
NumberPair* numberPair;
StringList* stringList;
NumberList* numberList;
Filter* filter;
} typedef criterionVariant;
typedef std::multimap <UINT32, criterionVariant> CriteriaMap;
public:
Filter(void);
~Filter(void);
void AddCriterion(UINT32 type, std::wstring& value);
void AddCriterion(UINT32 type, STR16 value);
void AddCriterion(UINT32 type, StringList& list);
void AddCriterion(UINT32 type, INT32 value);
void AddCriterion(UINT32 type, INT32 value1, INT32 value2);
void AddCriterion(UINT32 type, NumberList& list);
void AddCriterion(UINT32 type, Filter* filter);
void Dump(std::wstringstream& stream);
bool Match(SOLDIERTYPE* pSoldier);
private:
CriteriaMap criteria;
};
}
#endif
+689
View File
@@ -0,0 +1,689 @@
#include "FilterDB.h"
namespace LogicalBodyTypes {
FilterDB::FilterDB(void) : AbstractXMLLoader(StartElementHandle, EndElementHandle, CharacterDataHandle, MakeParseData) {
RegisterEnumerators();
}
FilterDB::~FilterDB(void) {
for (FilterMap::iterator i = filters.begin(); i != filters.end(); i++) {
delete i->second;
}
}
bool FilterDB::AddFilter(std::string name, Filter* filter) {
iterator i = filters.find(name);
if (i != filters.end()) {
return false;
}
filters[name] = filter;
return true;
}
Filter* FilterDB::FindFilter(std::string name) {
iterator i = filters.find(name);
return (i != filters.end()) ? i->second : NULL;
}
FilterDB::FilterMap::const_iterator FilterDB::begin() {
return filters.begin();
}
FilterDB::FilterMap::const_iterator FilterDB::end() {
return filters.end();
}
AbstractXMLLoader::ParseData* FilterDB::MakeParseData(XML_Parser* parser) {
return new ParseData(parser);
}
void XMLCALL FilterDB::StartElementHandle(void* userData, const XML_Char* name, const XML_Char** atts) {
ParseData* data = (ParseData*)userData;
switch (data->state) {
case E_NONE:
if (strcmp(name, "Filters") == 0) {
data->state = E_ELEMENT_FILTERS;
break;
}
case E_ELEMENT_FILTERS:
if (strcmp(name, "Filter") == 0) {
data->state = E_ELEMENT_FILTER;
data->currentFilter = new Filter();
XML_Char const* attrName = GetAttribute("name", atts);
if (attrName == NULL) throw XMLParseException("Mandatory attribute missing!", name, data->pParser);
data->filterName = attrName;
break;
}
case E_ELEMENT_FILTER:
if (strcmp(name, "AND") == 0) {
data->state = E_OPERATION;
data->operationFlags = Filter::_REQ_AND;
break;
}
if (strcmp(name, "OR") == 0) {
data->state = E_OPERATION;
data->operationFlags = Filter::_REQ_OR;
break;
}
case E_OPERATION:
{
data->state = E_CRITERION;
data->criterionType = 0;
int ord;
data->criterionName = name;
std::string enumeratorString = "Filter::REQ_";
enumeratorString += name;
if (EnumeratorDB::Instance().GetEnumeratorByStr("IntegerFilterCriterionTypes", enumeratorString.c_str(), ord)) {
data->criterionType = ord;
data->criterionType |= Filter::_TYPE_INTEGER;
}
else if (EnumeratorDB::Instance().GetEnumeratorByStr("StringFilterCriterionTypes", enumeratorString.c_str(), ord)) {
data->criterionType = ord;
data->criterionType |= Filter::_TYPE_STRING;
}
else if (EnumeratorDB::Instance().GetEnumeratorByStr("EnumFilterCriterionTypes", enumeratorString.c_str(), ord)) {
data->criterionType = ord;
data->criterionType |= Filter::_TYPE_ENUM;
}
else if (strcmp(name, "FILTER") == 0) {
data->criterionType = ord;
data->criterionType |= Filter::_TYPE_FILTER;
}
else throw XMLParseException("Unexpected element (unknown criterion)!", name, data->pParser);
XML_Char const* cmpOp = GetAttribute("op", atts);
if (cmpOp != NULL) {
if (strcmp(cmpOp, "gt") == 0) {
if ((data->criterionType & Filter::_TYPE_FILTER) == Filter::_TYPE_FILTER) {
throw XMLParseException("Greater than operator not supported for filter criterion types!", name, data->pParser);
}
data->criterionType |= Filter::_REQ_GT;
}
else if (strcmp(cmpOp, "lt") == 0) {
if ((data->criterionType & Filter::_TYPE_FILTER) == Filter::_TYPE_FILTER) {
throw XMLParseException("Lesser than operator not supported for filter criterion types!", name, data->pParser);
}
data->criterionType |= Filter::_REQ_LT;
}
else if (strcmp(cmpOp, "eq") == 0) data->criterionType |= Filter::_REQ_EQ;
else if (strcmp(cmpOp, "btwn") == 0) {
if ((data->criterionType & Filter::_TYPE_INTEGER) != Filter::_TYPE_INTEGER) {
// TODO: also allow between for enums
throw XMLParseException("Between operator only handles numerical values!", name, data->pParser);
}
data->criterionType |= Filter::_REQ_BTWN | Filter::_TYPE_PAIR;
}
else if (strcmp(cmpOp, "in") == 0) {
if (data->criterionType & (Filter::_TYPE_INTEGER | Filter::_TYPE_STRING)) {
// TODO: also allow in for enums
data->criterionType |= Filter::_REQ_IN | Filter::_TYPE_LIST;
}
else throw XMLParseException("In operator only handles numerical or string values!", name, data->pParser);
}
else throw XMLParseException("Undefined operator!", name, data->pParser);
}
else {
data->criterionType |= Filter::_REQ_EQ;
}
XML_Char const* not = GetAttribute("not", atts);
if (not != NULL) {
if (strcmp(not, "") != 0) throw XMLParseException("Not attribute must not have a value assigned!", name, data->pParser);
data->criterionType |= Filter::_REQ_NOT;
}
break;
}
default:
throw XMLParseException("Unexpected element!", name, data->pParser);
}
}
void XMLCALL FilterDB::EndElementHandle(void* userData, const XML_Char* name) {
ParseData* data = (ParseData*)userData;
switch (data->state) {
case E_CRITERION:
if (strcmp(name, data->criterionName.c_str()) == 0) {
data->state = E_OPERATION;
break;
}
case E_OPERATION:
if (((data->operationFlags & Filter::_REQ_AND) && strcmp(name, "AND") == 0) || ((data->operationFlags & Filter::_REQ_OR) && strcmp(name, "OR") == 0)) {
data->state = E_ELEMENT_FILTER;
break;
}
case E_ELEMENT_FILTER:
if (strcmp(name, "Filter") == 0) {
data->state = E_ELEMENT_FILTERS;
if (!Instance().AddFilter(data->filterName, data->currentFilter)) {
throw XMLParseException("Filter could not be added. Filter already defined!", name, data->pParser);
}
data->currentFilter = NULL; // in case an exception is raised between here and the start of the next filter element
break;
}
case E_ELEMENT_FILTERS:
if (strcmp(name, "Filters") == 0) {
data->state = E_NONE;
break;
}
default:
throw XMLParseException("Unexpected element! Closing tag missing?", name, data->pParser);
return;
}
}
void XMLCALL FilterDB::CharacterDataHandle(void* userData, const XML_Char* str, int len) {
ParseData* data = (ParseData*)userData;
switch (data->state) {
case E_CRITERION:
// TODO: trim character data!
char* text = new char[len + 1];
strncpy(text, str, len);
text[len] = '\0';
if (data->criterionType & Filter::_TYPE_STRING) {
STR16 wStr = NULL;
int len = MultiByteToWideChar(CP_UTF8, 0, text, -1, wStr, 0);
wStr = (STR16)MemAlloc(len * sizeof(CHAR16));
MultiByteToWideChar(CP_UTF8, 0, text, -1, wStr, len);
if (data->criterionType & Filter::_TYPE_LIST) {
Filter::StringList list;
wchar_t* token = wcstok(wStr, L", ");
while (token != NULL) {
list.push_back(token);
token = wcstok(NULL, L", ");
}
data->currentFilter->AddCriterion(data->operationFlags | data->criterionType, list);
}
else {
data->currentFilter->AddCriterion(data->operationFlags | data->criterionType, wStr);
}
MemFree(wStr);
}
else if (data->criterionType & Filter::_TYPE_INTEGER) {
if ((data->criterionType & Filter::_TYPE_LIST) || (data->criterionType & Filter::_TYPE_PAIR)) {
Filter::NumberList list;
char* token = strtok(text, ", ");
while (token != NULL) {
INT32 val;
if (!ConvertStringToINT32(token, &val)) {
delete text;
throw XMLParseException("Invalid value!", data->criterionName.c_str(), data->pParser);
}
list.push_back(val);
token = strtok(NULL, ", ");
}
if (data->criterionType & Filter::_TYPE_PAIR) {
if (list.size() != 2) {
delete text;
throw XMLParseException("Exactly 2 operands must be specified for 'between' operator!", data->criterionName.c_str(), data->pParser);
}
data->currentFilter->AddCriterion(data->operationFlags | data->criterionType, list.front(), list.back());
}
else if (data->criterionType & Filter::_TYPE_LIST) {
data->currentFilter->AddCriterion(data->operationFlags | data->criterionType, list);
}
}
else {
INT32 val;
if (!ConvertStringToINT32(text, &val)) {
delete text;
throw XMLParseException("Invalid value!", data->criterionName.c_str(), data->pParser);
}
data->currentFilter->AddCriterion(data->operationFlags | data->criterionType, val);
}
}
else if (data->criterionType & Filter::_TYPE_ENUM) {
INT32 ord;
if (EnumeratorDB::Instance().GetEnumeratorByStr(data->criterionName.c_str(), text, ord)) {
// For the filter no enum type exists.
// Since we now know the integer value of the enumerator we treat it like any other integer criterion
data->criterionType &= ~Filter::_TYPE_ENUM;
data->criterionType |= Filter::_TYPE_INTEGER;
data->currentFilter->AddCriterion(data->operationFlags | data->criterionType, ord);
}
else {
delete text;
throw XMLParseException("Can't find specified enumerator!", data->criterionName.c_str(), data->pParser);
}
}
else if (data->criterionType & Filter::_TYPE_FILTER) {
Filter* f = Instance().FindFilter(text);
if (f == NULL) {
throw XMLParseException("Can't find specified filter. Make sure it is defined before the filter that references it!", data->criterionName.c_str(), data->pParser);
}
data->currentFilter->AddCriterion(data->operationFlags | data->criterionType, f);
}
delete text;
break;
}
}
void FilterDB::RegisterEnumerators() {
/*****************************************
Filter string criterion types
******************************************/
LOGBT_ENUMDB_ADD("StringFilterCriterionTypes", 3,
Filter::REQ_NAME,
Filter::REQ_PROFILENAME,
Filter::REQ_NICKNAME
);
/*****************************************
Filter enum criterion types
******************************************/
LOGBT_ENUMDB_ADD("IntegerFilterCriterionTypes", 32,
Filter::REQ_HELMETPOS,
Filter::REQ_VESTPOS,
Filter::REQ_LEGPOS,
Filter::REQ_HEAD1POS,
Filter::REQ_HEAD2POS,
Filter::REQ_HANDPOS,
Filter::REQ_SECONDHANDPOS,
Filter::REQ_VESTPOCKPOS,
Filter::REQ_LTHIGHPOCKPOS,
Filter::REQ_RTHIGHPOCKPOS,
Filter::REQ_CPACKPOCKPOS,
Filter::REQ_BPACKPOCKPOS,
Filter::REQ_GUNSLINGPOCKPOS,
Filter::REQ_KNIFEPOCKPOS,
Filter::REQ_TEAM,
Filter::REQ_CAMO,
Filter::REQ_URBANCAMO,
Filter::REQ_DESERTCAMO,
Filter::REQ_SNOWCAMO,
Filter::REQ_EXPLEVEL,
Filter::REQ_STRENGTH,
Filter::REQ_LEADERSHIP,
Filter::REQ_WISDOM,
Filter::REQ_SKILLTRAIT1,
Filter::REQ_SKILLTRAIT2,
Filter::REQ_FACEINDEX,
Filter::REQ_WEAPON_IN_HAND,
Filter::REQ_CALIBRE,
Filter::REQ_VEST_AMOR_PROTECTION,
Filter::REQ_VEST_AMOR_COVERAGE,
Filter::REQ_HELMET_AMOR_PROTECTION,
Filter::REQ_HELMET_AMOR_COVERAGE
);
/*****************************************
Filter enum criterion types
******************************************/
LOGBT_ENUMDB_ADD("EnumFilterCriterionTypes", 7,
Filter::REQ_SEX,
Filter::REQ_MERC_TYPE,
Filter::REQ_SOLDIER_CLASS,
Filter::REQ_CIVILIANGROUP,
Filter::REQ_BODYTYPE,
Filter::REQ_WEAPON_CLASS,
Filter::REQ_WEAPON_TYPE
);
/*****************************************
MERC_TYPE
******************************************/
LOGBT_ENUMDB_ADD("MERC_TYPE", 7,
MERC_TYPE__PLAYER_CHARACTER,
MERC_TYPE__AIM_MERC,
MERC_TYPE__MERC,
MERC_TYPE__NPC,
MERC_TYPE__EPC,
MERC_TYPE__NPC_WITH_UNEXTENDABLE_CONTRACT,
MERC_TYPE__VEHICLE
);
/*****************************************
SOLDIER_CLASS
******************************************/
LOGBT_ENUMDB_ADD("SOLDIER_CLASS", SOLDIER_CLASS_MAX,
SOLDIER_CLASS_NONE,
SOLDIER_CLASS_ADMINISTRATOR,
SOLDIER_CLASS_ELITE,
SOLDIER_CLASS_ARMY,
SOLDIER_CLASS_GREEN_MILITIA,
SOLDIER_CLASS_REG_MILITIA,
SOLDIER_CLASS_ELITE_MILITIA,
SOLDIER_CLASS_CREATURE,
SOLDIER_CLASS_MINER,
SOLDIER_CLASS_ZOMBIE,
SOLDIER_CLASS_TANK,
SOLDIER_CLASS_JEEP,
SOLDIER_CLASS_BANDIT
);
/*****************************************
Filter enum criterion types
******************************************/
LOGBT_ENUMDB_ADD("SEX", 2,
MALE,
FEMALE
);
/*****************************************
SoldierBodyTypes
******************************************/
LOGBT_ENUMDB_ADD("BODYTYPE", TOTALBODYTYPES,
REGMALE,
BIGMALE,
STOCKYMALE,
REGFEMALE,
ADULTFEMALEMONSTER,
AM_MONSTER,
YAF_MONSTER,
YAM_MONSTER,
LARVAE_MONSTER,
INFANT_MONSTER,
QUEENMONSTER,
FATCIV,
MANCIV,
MINICIV,
DRESSCIV,
HATKIDCIV,
KIDCIV,
CRIPPLECIV,
COW,
CROW,
BLOODCAT,
ROBOTNOWEAPON,
HUMVEE,
TANK_NW,
TANK_NE,
ELDORADO,
ICECREAMTRUCK,
JEEP,
COMBAT_JEEP
);
/*****************************************
Civilian Groups
******************************************/
LOGBT_ENUMDB_ADD("CIVILIANGROUP", NUM_CIV_GROUPS,
NON_CIV_GROUP,
REBEL_CIV_GROUP,
KINGPIN_CIV_GROUP,
SANMONA_ARMS_GROUP,
ANGELS_GROUP,
BEGGARS_CIV_GROUP,
TOURISTS_CIV_GROUP,
ALMA_MILITARY_CIV_GROUP,
DOCTORS_CIV_GROUP,
COUPLE1_CIV_GROUP,
HICKS_CIV_GROUP,
WARDEN_CIV_GROUP,
JUNKYARD_CIV_GROUP,
FACTORY_KIDS_GROUP,
QUEENS_CIV_GROUP,
UNNAMED_CIV_GROUP_15,
UNNAMED_CIV_GROUP_16,
UNNAMED_CIV_GROUP_17,
UNNAMED_CIV_GROUP_18,
UNNAMED_CIV_GROUP_19,
ASSASSIN_CIV_GROUP,
POW_PRISON_CIV_GROUP,
UNNAMED_CIV_GROUP_22,
UNNAMED_CIV_GROUP_23,
VOLUNTEER_CIV_GROUP,
BOUNTYHUNTER_CIV_GROUP,
DOWNEDPILOT_CIV_GROUP,
SCIENTIST_GROUP,
RADAR_TECHNICIAN_GROUP,
AIRPORT_STAFF_GROUP,
BARRACK_STAFF_GROUP,
FACTORY_GROUP,
ADMINISTRATIVE_STAFF_GROUP,
LOYAL_CIV_GROUP,
BLACKMARKET_GROUP,
UNNAMED_CIV_GROUP_35,
UNNAMED_CIV_GROUP_36,
UNNAMED_CIV_GROUP_37,
UNNAMED_CIV_GROUP_38,
UNNAMED_CIV_GROUP_39,
UNNAMED_CIV_GROUP_40,
UNNAMED_CIV_GROUP_41,
UNNAMED_CIV_GROUP_42,
UNNAMED_CIV_GROUP_43,
UNNAMED_CIV_GROUP_44,
UNNAMED_CIV_GROUP_45,
UNNAMED_CIV_GROUP_46,
UNNAMED_CIV_GROUP_47,
UNNAMED_CIV_GROUP_48,
UNNAMED_CIV_GROUP_49,
UNNAMED_CIV_GROUP_50,
UNNAMED_CIV_GROUP_51,
UNNAMED_CIV_GROUP_52,
UNNAMED_CIV_GROUP_53,
UNNAMED_CIV_GROUP_54,
UNNAMED_CIV_GROUP_55,
UNNAMED_CIV_GROUP_56,
UNNAMED_CIV_GROUP_57,
UNNAMED_CIV_GROUP_58,
UNNAMED_CIV_GROUP_59,
UNNAMED_CIV_GROUP_60,
UNNAMED_CIV_GROUP_61,
UNNAMED_CIV_GROUP_62,
UNNAMED_CIV_GROUP_63,
UNNAMED_CIV_GROUP_64,
UNNAMED_CIV_GROUP_65,
UNNAMED_CIV_GROUP_66,
UNNAMED_CIV_GROUP_67,
UNNAMED_CIV_GROUP_68,
UNNAMED_CIV_GROUP_69,
UNNAMED_CIV_GROUP_70,
UNNAMED_CIV_GROUP_71,
UNNAMED_CIV_GROUP_72,
UNNAMED_CIV_GROUP_73,
UNNAMED_CIV_GROUP_74,
UNNAMED_CIV_GROUP_75,
UNNAMED_CIV_GROUP_76,
UNNAMED_CIV_GROUP_77,
UNNAMED_CIV_GROUP_78,
UNNAMED_CIV_GROUP_79,
UNNAMED_CIV_GROUP_80,
UNNAMED_CIV_GROUP_81,
UNNAMED_CIV_GROUP_82,
UNNAMED_CIV_GROUP_83,
UNNAMED_CIV_GROUP_84,
UNNAMED_CIV_GROUP_85,
UNNAMED_CIV_GROUP_86,
UNNAMED_CIV_GROUP_87,
UNNAMED_CIV_GROUP_88,
UNNAMED_CIV_GROUP_89,
UNNAMED_CIV_GROUP_90,
UNNAMED_CIV_GROUP_91,
UNNAMED_CIV_GROUP_92,
UNNAMED_CIV_GROUP_93,
UNNAMED_CIV_GROUP_94,
UNNAMED_CIV_GROUP_95,
UNNAMED_CIV_GROUP_96,
UNNAMED_CIV_GROUP_97,
UNNAMED_CIV_GROUP_98,
UNNAMED_CIV_GROUP_99,
UNNAMED_CIV_GROUP_100,
UNNAMED_CIV_GROUP_101,
UNNAMED_CIV_GROUP_102,
UNNAMED_CIV_GROUP_103,
UNNAMED_CIV_GROUP_104,
UNNAMED_CIV_GROUP_105,
UNNAMED_CIV_GROUP_106,
UNNAMED_CIV_GROUP_107,
UNNAMED_CIV_GROUP_108,
UNNAMED_CIV_GROUP_109,
UNNAMED_CIV_GROUP_110,
UNNAMED_CIV_GROUP_111,
UNNAMED_CIV_GROUP_112,
UNNAMED_CIV_GROUP_113,
UNNAMED_CIV_GROUP_114,
UNNAMED_CIV_GROUP_115,
UNNAMED_CIV_GROUP_116,
UNNAMED_CIV_GROUP_117,
UNNAMED_CIV_GROUP_118,
UNNAMED_CIV_GROUP_119,
UNNAMED_CIV_GROUP_120,
UNNAMED_CIV_GROUP_121,
UNNAMED_CIV_GROUP_122,
UNNAMED_CIV_GROUP_123,
UNNAMED_CIV_GROUP_124,
UNNAMED_CIV_GROUP_125,
UNNAMED_CIV_GROUP_126,
UNNAMED_CIV_GROUP_127,
UNNAMED_CIV_GROUP_128,
UNNAMED_CIV_GROUP_129,
UNNAMED_CIV_GROUP_130,
UNNAMED_CIV_GROUP_131,
UNNAMED_CIV_GROUP_132,
UNNAMED_CIV_GROUP_133,
UNNAMED_CIV_GROUP_134,
UNNAMED_CIV_GROUP_135,
UNNAMED_CIV_GROUP_136,
UNNAMED_CIV_GROUP_137,
UNNAMED_CIV_GROUP_138,
UNNAMED_CIV_GROUP_139,
UNNAMED_CIV_GROUP_140,
UNNAMED_CIV_GROUP_141,
UNNAMED_CIV_GROUP_142,
UNNAMED_CIV_GROUP_143,
UNNAMED_CIV_GROUP_144,
UNNAMED_CIV_GROUP_145,
UNNAMED_CIV_GROUP_146,
UNNAMED_CIV_GROUP_147,
UNNAMED_CIV_GROUP_148,
UNNAMED_CIV_GROUP_149,
UNNAMED_CIV_GROUP_150,
UNNAMED_CIV_GROUP_151,
UNNAMED_CIV_GROUP_152,
UNNAMED_CIV_GROUP_153,
UNNAMED_CIV_GROUP_154,
UNNAMED_CIV_GROUP_155,
UNNAMED_CIV_GROUP_156,
UNNAMED_CIV_GROUP_157,
UNNAMED_CIV_GROUP_158,
UNNAMED_CIV_GROUP_159,
UNNAMED_CIV_GROUP_160,
UNNAMED_CIV_GROUP_161,
UNNAMED_CIV_GROUP_162,
UNNAMED_CIV_GROUP_163,
UNNAMED_CIV_GROUP_164,
UNNAMED_CIV_GROUP_165,
UNNAMED_CIV_GROUP_166,
UNNAMED_CIV_GROUP_167,
UNNAMED_CIV_GROUP_168,
UNNAMED_CIV_GROUP_169,
UNNAMED_CIV_GROUP_170,
UNNAMED_CIV_GROUP_171,
UNNAMED_CIV_GROUP_172,
UNNAMED_CIV_GROUP_173,
UNNAMED_CIV_GROUP_174,
UNNAMED_CIV_GROUP_175,
UNNAMED_CIV_GROUP_176,
UNNAMED_CIV_GROUP_177,
UNNAMED_CIV_GROUP_178,
UNNAMED_CIV_GROUP_179,
UNNAMED_CIV_GROUP_180,
UNNAMED_CIV_GROUP_181,
UNNAMED_CIV_GROUP_182,
UNNAMED_CIV_GROUP_183,
UNNAMED_CIV_GROUP_184,
UNNAMED_CIV_GROUP_185,
UNNAMED_CIV_GROUP_186,
UNNAMED_CIV_GROUP_187,
UNNAMED_CIV_GROUP_188,
UNNAMED_CIV_GROUP_189,
UNNAMED_CIV_GROUP_190,
UNNAMED_CIV_GROUP_191,
UNNAMED_CIV_GROUP_192,
UNNAMED_CIV_GROUP_193,
UNNAMED_CIV_GROUP_194,
UNNAMED_CIV_GROUP_195,
UNNAMED_CIV_GROUP_196,
UNNAMED_CIV_GROUP_197,
UNNAMED_CIV_GROUP_198,
UNNAMED_CIV_GROUP_199,
UNNAMED_CIV_GROUP_200,
UNNAMED_CIV_GROUP_201,
UNNAMED_CIV_GROUP_202,
UNNAMED_CIV_GROUP_203,
UNNAMED_CIV_GROUP_204,
UNNAMED_CIV_GROUP_205,
UNNAMED_CIV_GROUP_206,
UNNAMED_CIV_GROUP_207,
UNNAMED_CIV_GROUP_208,
UNNAMED_CIV_GROUP_209,
UNNAMED_CIV_GROUP_210,
UNNAMED_CIV_GROUP_211,
UNNAMED_CIV_GROUP_212,
UNNAMED_CIV_GROUP_213,
UNNAMED_CIV_GROUP_214,
UNNAMED_CIV_GROUP_215,
UNNAMED_CIV_GROUP_216,
UNNAMED_CIV_GROUP_217,
UNNAMED_CIV_GROUP_218,
UNNAMED_CIV_GROUP_219,
UNNAMED_CIV_GROUP_220,
UNNAMED_CIV_GROUP_221,
UNNAMED_CIV_GROUP_222,
UNNAMED_CIV_GROUP_223,
UNNAMED_CIV_GROUP_224,
UNNAMED_CIV_GROUP_225,
UNNAMED_CIV_GROUP_226,
UNNAMED_CIV_GROUP_227,
UNNAMED_CIV_GROUP_228,
UNNAMED_CIV_GROUP_229,
UNNAMED_CIV_GROUP_230,
UNNAMED_CIV_GROUP_231,
UNNAMED_CIV_GROUP_232,
UNNAMED_CIV_GROUP_233,
UNNAMED_CIV_GROUP_234,
UNNAMED_CIV_GROUP_235,
UNNAMED_CIV_GROUP_236,
UNNAMED_CIV_GROUP_237,
UNNAMED_CIV_GROUP_238,
UNNAMED_CIV_GROUP_239,
UNNAMED_CIV_GROUP_240,
UNNAMED_CIV_GROUP_241,
UNNAMED_CIV_GROUP_242,
UNNAMED_CIV_GROUP_243,
UNNAMED_CIV_GROUP_244,
UNNAMED_CIV_GROUP_245,
UNNAMED_CIV_GROUP_246,
UNNAMED_CIV_GROUP_247,
UNNAMED_CIV_GROUP_248,
UNNAMED_CIV_GROUP_249,
UNNAMED_CIV_GROUP_250,
UNNAMED_CIV_GROUP_251,
UNNAMED_CIV_GROUP_252,
UNNAMED_CIV_GROUP_253,
UNNAMED_CIV_GROUP_254
);
/*****************************************
Weapon Class
******************************************/
LOGBT_ENUMDB_ADD("WEAPON_CLASS", NUM_WEAPON_CLASSES,
NOGUNCLASS,
HANDGUNCLASS,
SMGCLASS,
RIFLECLASS,
MGCLASS,
SHOTGUNCLASS,
KNIFECLASS,
MONSTERCLASS
);
/*****************************************
Weapon Type
******************************************/
LOGBT_ENUMDB_ADD("WEAPON_TYPE", GUN_TYPES_MAX,
NOT_GUN,
GUN_PISTOL,
GUN_M_PISTOL,
GUN_SMG,
GUN_RIFLE,
GUN_SN_RIFLE,
GUN_AS_RIFLE,
GUN_LMG,
GUN_SHOTGUN
);
};
}
+68
View File
@@ -0,0 +1,68 @@
#pragma once
#ifndef _LBT_FILTERDB__H_
#define _LBT_FILTERDB__H_
#include "LogicalBodyTypes/AbstractXMLLoader.h"
#include "Animation Data.h"
#include "Weapons.h"
#include "LogicalBodyTypes/EnumeratorDB.h"
#include "LogicalBodyTypes/Filter.h"
#include <map>
namespace LogicalBodyTypes {
class FilterDB : public AbstractXMLLoader, public Singleton<FilterDB> {
public:
using Singleton <FilterDB>::Instance;
typedef std::map<std::string, Filter*> FilterMap;
typedef FilterMap::const_iterator iterator;
private:
enum ParseState {
E_ELEMENT_FILTERS = FIRST_SUBCLASS_STATE,
E_ELEMENT_FILTER,
E_OPERATION,
E_CRITERION
};
struct ParseData : public AbstractXMLLoader::ParseData { // shadow ParseData type and also extend the ParseData stuct of the base class
ParseData(XML_Parser* parser) : AbstractXMLLoader::ParseData(parser) {
currentFilter = NULL;
operationFlags = 0;
criterionName = "";
criterionType = 0;
};
~ParseData() {
// don't like this one bit, but we have to handle this here in case an exception is thrown
// remember to set the pointer to NULL after the filter object has been added to the DB!
if (currentFilter != NULL) delete currentFilter;
};
Filter* currentFilter;
std::string filterName;
UINT32 operationFlags;
std::string criterionName;
UINT32 criterionType;
} typedef ParseData;
FilterMap filters;
public:
FilterDB(void);
~FilterDB(void);
FilterMap::const_iterator begin();
FilterMap::const_iterator end();
Filter* FindFilter(std::string name);
private:
bool AddFilter(std::string name, Filter* filter);
static void RegisterEnumerators();
static void XMLCALL StartElementHandle(void* userData, const XML_Char* name, const XML_Char** atts);
static void XMLCALL EndElementHandle(void* userData, const XML_Char* name);
static void XMLCALL CharacterDataHandle(void* userData, const XML_Char* str, int len);
static void XMLCALL ExternalEntityHandler(XML_Parser parser, const XML_Char* context, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId);
static AbstractXMLLoader::ParseData* MakeParseData(XML_Parser* parser); // shadow factory function for ParseData instances
};
}
#endif
+202
View File
@@ -0,0 +1,202 @@
#include "Layers.h"
#include <iostream>
#include <fstream>
namespace LogicalBodyTypes {
Layers::Layers() : AbstractXMLLoader(StartElementHandle, EndElementHandle, CharacterDataHandle, MakeParseData) {
directionLayerGraphs.resize(NUM_WORLD_DIRECTIONS);
}
Layers::~Layers(void) {
for (LayerPropertiesVector::size_type i = 0; i < layers.size(); i++) {
delete[] layers[i].identifier;
}
}
Layers::LayerGraphIterator Layers::GetIterator(WorldDirections direction) {
return directionLayerGraphs[direction].begin();
}
Layers::LayerGraphIterator Layers::GetIterationEnd(WorldDirections direction) {
return directionLayerGraphs[direction].end();
}
Layers::LayerGraphIterator Layers::GetIterator(INT8 direction) {
return directionLayerGraphs[direction].begin();
}
Layers::LayerGraphIterator Layers::GetIterationEnd(INT8 direction) {
return directionLayerGraphs[direction].end();
}
AbstractXMLLoader::ParseData* Layers::MakeParseData(XML_Parser* parser) {
return new ParseData(parser);
}
void Layers::AddLayerGraphNode(WorldDirections dir, std::string identifier, bool render, bool renderShadows, INT32 zIndex) {
// create layer property object and push it into the layers properties container - if layer not already there
Layers::LayerPropertiesVector::size_type index = GetIndex(identifier);
if (index == -1) {
LayerProperties props;
props.identifier = new char[identifier.size() + 1];
strcpy(props.identifier, identifier.c_str());
props.render = render;
props.renderShadows = renderShadows;
layers.push_back(props);
index = GetIndex(identifier);
}
// create node with zindex and a pointer to the layer properties object
LayerGraphNode node;
node.zIndex = zIndex;
node.index = index;
node.pLayerProperties = NULL; // since the pointers would be invalided once the vector has to be reallocated,
// we set the pointers after the layer configuration is finalized (see UpdateConfiguration)
// add node to direction specific layer graph
LayerGraph::iterator i = directionLayerGraphs[dir].begin();
for (; i != directionLayerGraphs[dir].end(); i++) {
if (i->zIndex > zIndex) break;
}
directionLayerGraphs[dir].insert(i, node);
}
void Layers::UpdateConfiguration() {
for (int d = NORTH; d < NUM_WORLD_DIRECTIONS; ++d) {
WorldDirections dir = static_cast<WorldDirections>(d);
LayerGraph::iterator i = directionLayerGraphs[dir].begin();
for (; i != directionLayerGraphs[dir].end(); i++) {
i->pLayerProperties = &layers[i->index];
}
}
}
Layers::LayerPropertiesVector::size_type Layers::GetCount() {
return layers.size();
}
Layers::LayerPropertiesVector::size_type Layers::GetIndex(std::string& identifier) {
for (LayerPropertiesVector::size_type i = 0; i < layers.size(); i++) {
if (strcmp(layers[i].identifier, identifier.c_str()) == 0) return i;
}
return -1;
}
const Layers::LayerProperties& Layers::GetLayerProperties(LayerPropertiesVector::size_type index) {
return layers[index];
}
void Layers::StartElementHandle(void* userData, const XML_Char* name, const XML_Char** atts) {
ParseData* data = (ParseData*)userData;
switch (data->state) {
case E_NONE:
if (strcmp(name, "Layers") == 0) {
data->level = 0;
data->state = E_ELEMENT_LAYERS;
break;
}
case E_ELEMENT_LAYERS:
case E_ELEMENT_LAYER:
if (strcmp(name, "Layer") == 0) {
data->level++;
data->state = E_ELEMENT_LAYER;
XML_Char const* attrName = GetAttribute("name", atts);
XML_Char const* attrRender = GetAttribute("render", atts);
XML_Char const* attrShadow = GetAttribute("shadow", atts);
XML_Char const* attrDirNorth = GetAttribute("zindex_north", atts);
XML_Char const* attrDirNorthEast = GetAttribute("zindex_northeast", atts);
XML_Char const* attrDirEast = GetAttribute("zindex_east", atts);
XML_Char const* attrDirSouthEast = GetAttribute("zindex_southeast", atts);
XML_Char const* attrDirSouth = GetAttribute("zindex_south", atts);
XML_Char const* attrDirSouthWest = GetAttribute("zindex_southwest", atts);
XML_Char const* attrDirWest = GetAttribute("zindex_west", atts);
XML_Char const* attrDirNorthWest = GetAttribute("zindex_northwest", atts);
if (attrName == NULL || attrRender == NULL || attrShadow == NULL) {
throw XMLParseException("Mandatory attribute missing!", name, data->pParser);
}
BOOLEAN fRender;
if (!ConvertStringToBOOLEAN(attrRender, &fRender)) throw XMLParseException("Attribute 'value' doesn't have a valid value!", name, data->pParser);
BOOLEAN fShadow;
if (!ConvertStringToBOOLEAN(attrShadow, &fShadow)) throw XMLParseException("Attribute 'shadow' doesn't have a valid value!", name, data->pParser);
INT32 value;
if (attrDirNorth != NULL) {
if (!ConvertStringToINT32(attrDirNorth, &value)) throw XMLParseException("Attribute 'zindex_north' doesn't have a valid value!", name, data->pParser);
data->directionZStacks[NORTH].push(ZLevelPair(data->level, value));
}
if (attrDirNorthEast != NULL) {
if (!ConvertStringToINT32(attrDirNorthEast, &value)) throw XMLParseException("Attribute 'zindex_northeast' doesn't have a valid value!", name, data->pParser);
data->directionZStacks[NORTHEAST].push(ZLevelPair(data->level, value));
}
if (attrDirEast != NULL) {
if (!ConvertStringToINT32(attrDirEast, &value)) throw XMLParseException("Attribute 'zindex_east' doesn't have a valid value!", name, data->pParser);
data->directionZStacks[EAST].push(ZLevelPair(data->level, value));
}
if (attrDirSouthEast != NULL) {
if (!ConvertStringToINT32(attrDirSouthEast, &value)) throw XMLParseException("Attribute 'zindex_southeast' doesn't have a valid value!", name, data->pParser);
data->directionZStacks[SOUTHEAST].push(ZLevelPair(data->level, value));
}
if (attrDirSouth != NULL) {
if (!ConvertStringToINT32(attrDirSouth, &value)) throw XMLParseException("Attribute 'zindex_south' doesn't have a valid value!", name, data->pParser);
data->directionZStacks[SOUTH].push(ZLevelPair(data->level, value));
}
if (attrDirSouthWest != NULL) {
if (!ConvertStringToINT32(attrDirSouthWest, &value)) throw XMLParseException("Attribute 'zindex_southwest' doesn't have a valid value!", name, data->pParser);
data->directionZStacks[SOUTHWEST].push(ZLevelPair(data->level, value));
}
if (attrDirWest != NULL) {
if (!ConvertStringToINT32(attrDirWest, &value)) throw XMLParseException("Attribute 'zindex_west' doesn't have a valid value!", name, data->pParser);
data->directionZStacks[WEST].push(ZLevelPair(data->level, value));
}
if (attrDirNorthWest != NULL) {
if (!ConvertStringToINT32(attrDirNorthWest, &value)) throw XMLParseException("Attribute 'zindex_northwest' doesn't have a valid value!", name, data->pParser);
data->directionZStacks[NORTHWEST].push(ZLevelPair(data->level, value));
}
for (int d = NORTH; d < NUM_WORLD_DIRECTIONS; ++d) {
WorldDirections dir = static_cast<WorldDirections>(d);
INT32 value = 0;
if (!data->directionZStacks[dir].empty()) {
value = data->directionZStacks[dir].top().second;
}
Instance().AddLayerGraphNode(dir, attrName, fRender == TRUE, fShadow == TRUE, value);
}
break;
}
default:
throw XMLParseException("Unexpected element!", name, data->pParser);
}
}
void Layers::EndElementHandle(void* userData, const XML_Char* name) {
ParseData* data = (ParseData*)userData;
switch (data->state) {
case E_ELEMENT_LAYER:
if (strcmp(name, "Layer") == 0) {
for (int d = NORTH; d < NUM_WORLD_DIRECTIONS; ++d) {
if (!data->directionZStacks[static_cast<WorldDirections>(d)].empty()) {
if (data->directionZStacks[static_cast<WorldDirections>(d)].top().first == data->level) {
data->directionZStacks[d].pop();
}
}
}
if (--data->level == 0) data->state = E_ELEMENT_LAYERS;
break;
}
case E_ELEMENT_LAYERS:
if (strcmp(name, "Layers") == 0) {
data->state = E_NONE;
Instance().UpdateConfiguration();
break;
}
default:
throw XMLParseException("Unexpected element! Closing tag missing?", name, data->pParser);
return;
}
}
void Layers::CharacterDataHandle(void* userData, const XML_Char* str, int len) {
}
}
+74
View File
@@ -0,0 +1,74 @@
#pragma once
#ifndef _LBT_LAYERS__H_
#define _LBT_LAYERS__H_
#include "LogicalBodyTypes/AbstractXMLLoader.h"
#include <stack>
namespace LogicalBodyTypes {
// Layers configuration implemented as singleton and loadable from XML.
class Layers : public AbstractXMLLoader, public Singleton<Layers> {
public:
using Singleton <Layers>::Instance;
struct LayerProperties {
char* identifier;
bool render;
bool renderShadows;
} typedef LayerProperties;
typedef std::vector <LayerProperties> LayerPropertiesVector;
private:
enum ParseState {
E_ELEMENT_LAYERS = FIRST_SUBCLASS_STATE,
E_ELEMENT_LAYER
};
typedef std::pair <UINT32, INT32> ZLevelPair;
typedef std::stack <ZLevelPair> ZStack;
typedef std::vector <ZStack> ZStackVector;
struct ParseData : public AbstractXMLLoader::ParseData { // shadow ParseData type and also extend the ParseData stuct of the base class
ParseData(XML_Parser* parser) : AbstractXMLLoader::ParseData(parser)
{
directionZStacks.resize(NUM_WORLD_DIRECTIONS);
};
ZStackVector directionZStacks;
} typedef ParseData;
struct LayerGraphNode {
INT32 zIndex;
LayerPropertiesVector::size_type index;
LayerProperties* pLayerProperties;
} typedef LayerGraphNode;
typedef std::list <LayerGraphNode> LayerGraph;
typedef std::vector <LayerGraph> LayerGraphsVector;
LayerPropertiesVector layers;
LayerGraphsVector directionLayerGraphs;
public:
typedef LayerGraph::iterator LayerGraphIterator;
public:
Layers(void);
~Layers(void);
LayerPropertiesVector::size_type GetCount();
// returns -1 if layer doesn't exist
LayerPropertiesVector::size_type GetIndex(std::string& identifier);
const Layers::LayerProperties& GetLayerProperties(LayerPropertiesVector::size_type index);
LayerGraphIterator GetIterator(WorldDirections direction);
LayerGraphIterator GetIterationEnd(WorldDirections direction);
LayerGraphIterator GetIterator(INT8 direction);
LayerGraphIterator GetIterationEnd(INT8 direction);
private:
static void XMLCALL StartElementHandle(void* userData, const XML_Char* name, const XML_Char** atts);
static void XMLCALL CharacterDataHandle(void* userData, const XML_Char* str, int len);
static void XMLCALL EndElementHandle(void* userData, const XML_Char* name);
void AddLayerGraphNode(WorldDirections dir, std::string identifier, bool render, bool renderShadows, INT32 zIndex);
static AbstractXMLLoader::ParseData* MakeParseData(XML_Parser* parser); // shadow factory function for ParseData instances
void UpdateConfiguration();
};
}
#endif
+167
View File
@@ -0,0 +1,167 @@
#include "PaletteDB.h"
namespace LogicalBodyTypes {
PaletteDB::PaletteDB(void) : AbstractXMLLoader(StartElementHandle, EndElementHandle, CharacterDataHandle) {
}
PaletteDB::~PaletteDB(void) {
PaletteTableMap::iterator i = paletteTables.begin();
for (; i != paletteTables.end(); i++) delete i->second;
}
bool PaletteDB::AddPaletteTable(std::string name, PaletteTable* paletteTable) {
PaletteTableMap::iterator i = paletteTables.find(name);
if (i != paletteTables.end()) return false;
paletteTables[name] = paletteTable;
return true;
}
PaletteTable* PaletteDB::FindPaletteTable(std::string name) {
PaletteTableMap::iterator i = paletteTables.find(name);
if (i == paletteTables.end()) return NULL;
return i->second;
}
void XMLCALL PaletteDB::StartElementHandle(void* userData, const XML_Char* name, const XML_Char** atts) {
ParseData* data = (ParseData*)userData;
switch (data->state) {
case E_NONE:
if (strcmp(name, "Palettes") == 0) {
data->state = E_ELEMENT_PALETTES;
break;
}
case E_ELEMENT_PALETTES:
if (strcmp(name, "Palette") == 0) {
data->state = E_ELEMENT_PALETTE;
XML_Char const* aName = GetAttribute("name", atts);
XML_Char const* aFileName = GetAttribute("filename", atts);
if (aFileName == NULL || aName == NULL) throw XMLParseException("Mandatory attribute missing!", name, data->pParser);
PaletteTable* paletteTable = new PaletteTable();
if (!paletteTable->Load(aFileName)) throw XMLParseException("Palette table could not be loaded from the specified file!", name, data->pParser);
Instance().AddPaletteTable(aName, paletteTable);
break;
}
default:
throw XMLParseException("Unexpected element!", name, data->pParser);
}
}
void XMLCALL PaletteDB::EndElementHandle(void* userData, const XML_Char* name) {
ParseData* data = (ParseData*)userData;
switch (data->state) {
case E_ELEMENT_PALETTE:
if (strcmp(name, "Palette") == 0) {
data->state = E_ELEMENT_PALETTES;
break;
}
case E_ELEMENT_PALETTES:
if (strcmp(name, "Palettes") == 0) {
data->state = E_NONE;
break;
}
default:
throw XMLParseException("Unexpected element! Closing tag missing?", name, data->pParser);
return;
}
}
void XMLCALL PaletteDB::CharacterDataHandle(void* userData, const XML_Char* str, int len) {
}
/*
BOOLEAN SOLDIERTYPE::CreateSoldierPalettes( void )
{
CHAR8 zColFilename[100];
INT32 iWhich;
INT32 cnt;
SGPPaletteEntry Temp8BPPPalette[ 256 ];
if (this->p8BPPPalette != NULL) {
MemFree(this->p8BPPPalette);
this->p8BPPPalette = NULL;
}
// Allocate mem for new palette
this->p8BPPPalette = (SGPPaletteEntry *) MemAlloc( sizeof( SGPPaletteEntry ) * 256 );
memset(this->p8BPPPalette, 0, sizeof(SGPPaletteEntry) * 256);
CHECKF(this->p8BPPPalette != NULL);
// Use col file
if (CreateSGPPaletteFromCOLFile(Temp8BPPPalette, zColFilename)) {
// Copy into palette
memcpy(this->p8BPPPalette, Temp8BPPPalette, sizeof( this->p8BPPPalette ) * 256);
} else {
}
if (this->p16BPPPalette != NULL) {
MemFree(this->p16BPPPalette);
this->p16BPPPalette = NULL;
}
// -- BUILD 16BPP Palette from this
this->p16BPPPalette = Create16BPPPalette(this->p8BPPPalette);
for (iWhich = 0; iWhich < NUM_SOLDIER_SHADES; iWhich++) {
if (this->pShades[iWhich] != NULL) {
MemFree(this->pShades[iWhich]);
this->pShades[iWhich] = NULL;
}
}
for (iWhich = 0; iWhich < NUM_SOLDIER_EFFECTSHADES; iWhich++) {
if (this->pEffectShades[iWhich] != NULL) {
MemFree( this->pEffectShades[ iWhich ] );
this->pEffectShades[iWhich] = NULL;
}
}
for (iWhich = 0; iWhich < 20; iWhich++) {
if (this->pGlowShades[iWhich] != NULL) {
MemFree( this->pGlowShades[ iWhich ]);
this->pGlowShades[iWhich] = NULL;
}
}
CreateSoldierPaletteTables( this, HVOBJECT_GLOW_GREEN );
this->pEffectShades[0] = Create16BPPPaletteShaded(this->p8BPPPalette, 100, 100, 100, TRUE);
this->pEffectShades[1] = Create16BPPPaletteShaded(this->p8BPPPalette, 100, 150, 100, TRUE);
// Build shades for glowing visible bad guy
// First do visible guy
this->pGlowShades[0] = Create16BPPPaletteShaded(this->p8BPPPalette, 255, 255, 255, FALSE);
for (cnt = 1; cnt < 10; cnt++) {
this->pGlowShades[cnt] = CreateEnemyGlow16BPPPalette(this->p8BPPPalette, gRedGlowR[cnt], 255, FALSE);
}
// Now for gray guy...
this->pGlowShades[10] = Create16BPPPaletteShaded(this->p8BPPPalette, 100, 100, 100, TRUE);
for (cnt = 11; cnt < 19; cnt++) {
this->pGlowShades[cnt] = CreateEnemyGreyGlow16BPPPalette(this->p8BPPPalette, gRedGlowR[cnt], 0, FALSE);
}
this->pGlowShades[19] = CreateEnemyGreyGlow16BPPPalette(this->p8BPPPalette, gRedGlowR[18], 0, FALSE);
// ATE: OK, piggyback on the shades we are not using for 2 colored lighting....
// ORANGE, VISIBLE GUY
this->pShades[20] = Create16BPPPaletteShaded(this->p8BPPPalette, 255, 255, 255, FALSE);
for (cnt = 21; cnt < 30; cnt++) {
this->pShades[cnt] = CreateEnemyGlow16BPPPalette(this->p8BPPPalette, gOrangeGlowR[( cnt - 20 )], gOrangeGlowG[( cnt - 20 )], TRUE);
}
// ORANGE, GREY GUY
this->pShades[30] = Create16BPPPaletteShaded(this->p8BPPPalette, 100, 100, 100, TRUE);
for (cnt = 31; cnt < 39; cnt++) {
this->pShades[cnt] = CreateEnemyGreyGlow16BPPPalette(this->p8BPPPalette, gOrangeGlowR[(cnt - 20)], gOrangeGlowG[(cnt - 20 )], TRUE);
}
this->pShades[39] = CreateEnemyGreyGlow16BPPPalette(this->p8BPPPalette, gOrangeGlowR[18], gOrangeGlowG[18], TRUE);
return(TRUE);
}
*/
}
+41
View File
@@ -0,0 +1,41 @@
#pragma once
#ifndef _LBT_PALETTEDB__H_
#define _LBT_PALETTEDB__H_
#include <map>
#include "LogicalBodyTypes/Singleton.h"
#include "LogicalBodyTypes/AbstractXMLLoader.h"
#include "LogicalBodyTypes/PaletteTable.h"
namespace LogicalBodyTypes {
class PaletteDB : public AbstractXMLLoader, public Singleton<PaletteDB> {
public:
using Singleton <PaletteDB>::Instance;
typedef std::map<std::string, PaletteTable*> PaletteTableMap;
private:
enum ParseState {
E_ELEMENT_PALETTES = FIRST_SUBCLASS_STATE,
E_ELEMENT_PALETTE
};
PaletteTableMap paletteTables;
public:
PaletteDB(void);
~PaletteDB(void);
bool AddPaletteTable(std::string name, PaletteTable* paletteTable);
PaletteTable* FindPaletteTable(std::string name);
private:
static void XMLCALL StartElementHandle(void* userData, const XML_Char* name, const XML_Char** atts);
static void XMLCALL EndElementHandle(void* userData, const XML_Char* name);
static void XMLCALL CharacterDataHandle(void* userData, const XML_Char* str, int len);
static void XMLCALL ExternalEntityHandler(XML_Parser parser, const XML_Char* context, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId);
};
}
#endif
+102
View File
@@ -0,0 +1,102 @@
#include "PaletteTable.h"
namespace LogicalBodyTypes {
PaletteTable::PaletteTable() {
}
PaletteTable::~PaletteTable() {
}
bool PaletteTable::CreateSGPPaletteFromActFile(SGPPaletteEntry *pPalette, std::string fileName) {
HWFILE hFileHandle;
UINT32 cnt;
char* colFileName = new char[fileName.size() + 1];
strcpy(colFileName, fileName.c_str());
if (!FileExists(colFileName)) {
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Cannot find COL file");
return false;
}
if ((hFileHandle = FileOpen(colFileName, FILE_ACCESS_READ, FALSE)) == 0) {
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Cannot open COL file");
return false;
}
for (cnt = 0; cnt < 256; cnt++) {
FileRead(hFileHandle, &pPalette[cnt].peRed, sizeof(UINT8), NULL);
FileRead(hFileHandle, &pPalette[cnt].peGreen, sizeof(UINT8), NULL);
FileRead(hFileHandle, &pPalette[cnt].peBlue, sizeof(UINT8), NULL);
}
FileClose(hFileHandle);
delete[] colFileName;
return true;
}
bool PaletteTable::Load(std::string fileName) {
INT32 iWhich;
INT32 cnt;
SGPPaletteEntry Temp8BPPPalette[256];
if (this->p8BPPPalette != NULL) {
MemFree(this->p8BPPPalette);
this->p8BPPPalette = NULL;
}
this->p8BPPPalette = (SGPPaletteEntry*)MemAlloc(sizeof(SGPPaletteEntry) * 256);
memset(this->p8BPPPalette, 0, sizeof(SGPPaletteEntry) * 256);
if (CreateSGPPaletteFromActFile(Temp8BPPPalette, (CHAR8*)fileName.c_str())) {
memcpy(this->p8BPPPalette, Temp8BPPPalette, sizeof(this->p8BPPPalette) * 256);
} else {
return false;
}
if (this->p16BPPPalette != NULL ) {
MemFree(this->p16BPPPalette);
this->p16BPPPalette = NULL;
}
this->p16BPPPalette = Create16BPPPalette(this->p8BPPPalette);
for (iWhich = 0; iWhich < NUM_SOLDIER_SHADES; iWhich++) {
if (this->pShades[ iWhich ] != NULL) {
MemFree(this->pShades[iWhich]);
this->pShades[ iWhich ] = NULL;
}
}
for (iWhich = 0; iWhich < NUM_SOLDIER_EFFECTSHADES; iWhich++) {
if (this->pEffectShades[iWhich] != NULL) {
MemFree(this->pEffectShades[iWhich]);
this->pEffectShades[iWhich] = NULL;
}
}
for (iWhich = 0; iWhich < 20; iWhich++) {
if (this->pGlowShades[iWhich] != NULL) {
MemFree(this->pGlowShades[iWhich]);
this->pGlowShades[iWhich] = NULL;
}
}
CreateSoldierPaletteTables(this, HVOBJECT_GLOW_GREEN);
this->pEffectShades[0] = Create16BPPPaletteShaded(this->p8BPPPalette, 100, 100, 100, TRUE);
this->pEffectShades[1] = Create16BPPPaletteShaded(this->p8BPPPalette, 100, 150, 100, TRUE);
this->pGlowShades[0] = Create16BPPPaletteShaded(this->p8BPPPalette, 255, 255, 255, FALSE);
for (cnt = 1; cnt < 10; cnt++) {
this->pGlowShades[cnt] = CreateEnemyGlow16BPPPalette(this->p8BPPPalette, gRedGlowR[cnt], 255, FALSE);
}
this->pGlowShades[10] = Create16BPPPaletteShaded(this->p8BPPPalette, 100, 100, 100, TRUE);
for (cnt = 11; cnt < 19; cnt++) {
this->pGlowShades[cnt] = CreateEnemyGreyGlow16BPPPalette(this->p8BPPPalette, gRedGlowR[cnt], 0, FALSE);
}
this->pGlowShades[19] = CreateEnemyGreyGlow16BPPPalette(this->p8BPPPalette, gRedGlowR[18], 0, FALSE);
this->pShades[20] = Create16BPPPaletteShaded(this->p8BPPPalette, 255, 255, 255, FALSE);
for (cnt = 21; cnt < 30; cnt++) {
this->pShades[cnt] = CreateEnemyGlow16BPPPalette(this->p8BPPPalette, gOrangeGlowR[(cnt - 20)], gOrangeGlowG[(cnt - 20)], TRUE);
}
this->pShades[30] = Create16BPPPaletteShaded(this->p8BPPPalette, 100, 100, 100, TRUE);
for (cnt = 31; cnt < 39; cnt++) {
this->pShades[cnt] = CreateEnemyGreyGlow16BPPPalette(this->p8BPPPalette, gOrangeGlowR[( cnt - 20)], gOrangeGlowG[(cnt - 20)], TRUE);
}
this->pShades[39] = CreateEnemyGreyGlow16BPPPalette(this->p8BPPPalette, gOrangeGlowR[18], gOrangeGlowG[18], TRUE);
return true;
}
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#ifndef _LBT_PALETTETABLE__H_
#define _LBT_PALETTETABLE__H_
#include "soldier control.h"
#include "Utilities.h"
#include "lighting.h"
extern UINT8 gRedGlowR[];
extern UINT8 gOrangeGlowR[];
extern UINT8 gOrangeGlowG[];
extern UINT16* CreateEnemyGlow16BPPPalette(SGPPaletteEntry* pPalette, UINT32 rscale, UINT32 gscale, BOOLEAN fAdjustGreen);
extern UINT16* CreateEnemyGreyGlow16BPPPalette(SGPPaletteEntry* pPalette, UINT32 rscale, UINT32 gscale, BOOLEAN fAdjustGreen);
namespace LogicalBodyTypes {
class PaletteTable : public SOLDIERTYPE {
public:
PaletteTable();
~PaletteTable(void);
bool Load(std::string fileName);
private:
bool CreateSGPPaletteFromActFile(SGPPaletteEntry *pPalette, std::string fileName);
};
}
#endif
+79
View File
@@ -0,0 +1,79 @@
#pragma once
#ifndef _LBT_SINGLETON__H_
#define _LBT_SINGLETON__H_
#include <cassert>
/*
Not thread safe. Copied from the codeproject (Author: Lai Shiaw San Kent)
*/
template<typename T> class ISingleton {
public :
static T& Instance();
};
template<typename T> class Singleton : public ISingleton<T> {
public :
static T& Instance();
static void Destroy();
protected :
inline explicit Singleton() {
assert(Singleton::instance_ == 0);
Singleton::instance_ = static_cast<T*>(this);
}
inline ~Singleton() {
Singleton::instance_ = 0;
}
private :
static T* CreateInstance();
static void ScheduleForDestruction(void (*)());
static void DestroyInstance(T*);
private :
static T* instance_;
private :
inline explicit Singleton(Singleton const&) {}
inline Singleton& operator=(Singleton const&) { return *this; }
};
template<typename T> typename T& Singleton<T>::Instance() {
if (Singleton::instance_ == 0) {
Singleton::instance_ = CreateInstance();
ScheduleForDestruction(Singleton::Destroy);
}
return *(Singleton::instance_);
}
template<typename T>
void Singleton<T>::Destroy() {
if (Singleton::instance_ != 0) {
DestroyInstance(Singleton::instance_);
Singleton::instance_ = 0;
}
}
template<typename T>
inline typename T* Singleton<T>::CreateInstance() {
return new T();
}
template<typename T>
inline void Singleton<T>::ScheduleForDestruction(void (*pFun)()) {
std::atexit(pFun);
}
template<typename T>
inline void Singleton<T>::DestroyInstance(T* p) {
delete p;
}
template<typename T>
typename T* Singleton<T>::instance_ = 0;
#endif
+145
View File
@@ -0,0 +1,145 @@
#include "SurfaceCache.h"
namespace LogicalBodyTypes {
SurfaceCache::SurfaceCache(UINT32 size) {
loadedElementsMax = size;
loadedElements = 0;
oldest = newest = NULL;
};
SurfaceCache::~SurfaceCache() {
for (UINT32 i = 0; i < surfaceVector.size(); i++) {
delete surfaceVector[i];
}
}
AnimationSurfaceType* SurfaceCache::GetLoadedSurface(UINT32 idx) {
if (idx >= surfaceVector.size()) {
// TODO more sensible handling of errors
SET_ERROR("Error: surface index out of range!");
return NULL;
}
CacheEntry* node = surfaceVector[idx];
if (node == newest) {
return node->surface; // nothing to be done here...
}
if (loadedElements < loadedElementsMax) {
if (!oldest) oldest = node;
if (!node->loaded) {
node->loaded = LoadSurface(node->surface, node->structFile);
// TODO more sensible handling of errors
if (!node->loaded) {
SET_ERROR("Error: a surface could not be laoded!");
return NULL;
}
loadedElements++;
} else {
if (node->next) node->next->prev = node->prev;
if (node->prev) node->prev->next = node->next;
}
if (newest) {
newest->next = node;
node->prev = newest;
}
newest = node;
} else {
if (node->loaded) {
if (node == oldest) {
oldest = oldest->next;
}
if (node->next) node->next->prev = node->prev;
if (node->prev) node->prev->next = node->next;
} else {
CacheEntry* oldNext = oldest->next;
while (node == oldNext) {
oldNext = oldNext->next;
}
oldest->prev = NULL;
oldest->next = NULL;
oldest->loaded = !UnloadSurface(oldest->surface);
oldest = oldNext;
node->loaded = LoadSurface(node->surface, node->structFile);
// TODO more sensible handling of errors
if (!node->loaded) {
SET_ERROR("Error: a surface could not be laoded!");
return NULL;
}
}
newest->next = node;
node->prev = newest;
newest = node;
}
return node->surface;
}
UINT32 SurfaceCache::AddSurface(AnimationSurfaceType* surface, STRUCTURE_FILE_REF* pStructFile) {
surface->hVideoObject = NULL;
CacheEntry* node = new CacheEntry(surface, pStructFile);
surfaceVector.push_back(node);
return surfaceVector.size() - 1;
}
bool SurfaceCache::UnloadSurface(AnimationSurfaceType* animSurfaceType) {
if (animSurfaceType->hVideoObject != NULL) {
DeleteVideoObject(animSurfaceType->hVideoObject);
animSurfaceType->hVideoObject = NULL;
}
return true;
}
bool SurfaceCache::LoadSurface(AnimationSurfaceType* animSurfaceType, STRUCTURE_FILE_REF* pStructureFileRef) {
AuxObjectData *pAuxData;
AnimDebugMsg("SurfaceCache::LoadSurface");
// Load into memory
VOBJECT_DESC VObjectDesc;
HVOBJECT hVObject;
HIMAGE hImage;
CHAR8 sFilename[48];
// Create video object
FilenameForBPP(animSurfaceType->Filename, sFilename);
hImage = CreateImage(sFilename, IMAGE_ALLDATA);
if (hImage == NULL) return TRUE == SET_ERROR("Error: Could not load animation file %s", sFilename);
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMHIMAGE;
VObjectDesc.hImage = hImage;
hVObject = CreateVideoObject( &VObjectDesc );
if ( hVObject == NULL ) {
SET_ERROR("Error: Could not load animation file: %s", sFilename);
// Video Object will set error conition.
DestroyImage( hImage );
return false;
}
// Get aux data
if (hImage->uiAppDataSize == hVObject->usNumberOfObjects * sizeof(AuxObjectData)) {
// Valid auxiliary data, so get # od frames from data
pAuxData = (AuxObjectData*) hImage->pAppData;
animSurfaceType->uiNumFramesPerDir = pAuxData->ubNumberOfFrames;
}
else {
SET_ERROR("Invalid # of animations given");
DestroyImage(hImage);
return false;
}
if (pStructureFileRef != NULL) {
INT16 sStartFrame = 0;
// removed exception coding. Do we even need the next block without that? See original global function
if (AddZStripInfoToVObject(hVObject, pStructureFileRef, TRUE, sStartFrame) == FALSE) {
DestroyImage(hImage);
DeleteVideoObject(hVObject);
SET_ERROR("Animation structure ZStrip creation error: %s", sFilename);
return false;
}
}
// the hImage is no longer needed
DestroyImage(hImage);
// Set video object index
animSurfaceType->hVideoObject = hVObject;
// Determine if we have a problem with #frames + directions ( ie mismatch )
if ((animSurfaceType->uiNumDirections * animSurfaceType->uiNumFramesPerDir ) != animSurfaceType->hVideoObject->usNumberOfObjects) {
AnimDebugMsg(String("Surface Database: WARNING!!! Surface %d has #frames mismatch.", usSurfaceIndex));
}
return true;
}
}
+49
View File
@@ -0,0 +1,49 @@
#pragma once
#ifndef _LBT_SURFACECACHE__H_
#define _LBT_SURFACECACHE__H_
#include "Animation Data.h"
#include "Utilities.h"
#include "Sys Globals.h"
#include "Debug Control.h"
namespace LogicalBodyTypes {
class SurfaceCache {
private:
struct CacheEntry {
CacheEntry(AnimationSurfaceType* animSurface, STRUCTURE_FILE_REF* pStructFile) {
surface = animSurface;
structFile = pStructFile;
loaded = false;
prev = next = NULL;
}
bool loaded;
AnimationSurfaceType* surface;
STRUCTURE_FILE_REF* structFile;
CacheEntry* prev;
CacheEntry* next;
} typedef CacheEntry;
typedef std::vector<CacheEntry*> SurfaceVector;
public:
SurfaceCache(UINT32 size);
~SurfaceCache();
AnimationSurfaceType* GetLoadedSurface(UINT32 idx);
UINT32 AddSurface(AnimationSurfaceType* surface, STRUCTURE_FILE_REF* pStructFile);
private:
UINT32 loadedElementsMax;
UINT32 loadedElements;
CacheEntry* newest;
CacheEntry* oldest;
SurfaceVector surfaceVector;
static bool LoadSurface(AnimationSurfaceType* animSurfaceType, STRUCTURE_FILE_REF* pStructureFileRef);
static bool SurfaceCache::UnloadSurface(AnimationSurfaceType* animSurfaceType);
};
}
#endif
Binary file not shown.
+55
View File
@@ -0,0 +1,55 @@
#ifndef _LBT_SURFACE__H_
#define _LBT_SURFACE__H_
#pragma once
#include "LogicalBodyTypes/AbstractXMLLoader.h"
#include "Animation Data.h"
#include "Utilities.h"
#include "Sys Globals.h"
#include "structure.h"
extern void FreeStructureFileRef(STRUCTURE_FILE_REF* pFileRef);
namespace LogicalBodyTypes {
// Singleton serving as container for AnimationSurfaceType instances.
// Implements loading said instances from an XML files.
class SurfaceDB : public AbstractXMLLoader, public Singleton<SurfaceDB> {
public:
using Singleton <SurfaceDB>::Instance;
typedef std::map <std::string, AnimationSurfaceType*> AnimSurfaceTypeMap;
typedef std::map <std::string, STRUCTURE_FILE_REF*> StructTypeFileMap;
typedef std::map <AnimationSurfaceType*, STRUCTURE_FILE_REF*> Surface2StructMap;
typedef AnimSurfaceTypeMap::const_iterator iterator;
private:
enum ParseState {
E_ELEMENT_ANIMSURFACES = FIRST_SUBCLASS_STATE,
E_ELEMENT_ANIMSURFACE
};
AnimSurfaceTypeMap animSurfaceTypes;
StructTypeFileMap structTypeFiles;
Surface2StructMap surfaceStructs;
public:
SurfaceDB(void);
~SurfaceDB(void);
AnimSurfaceTypeMap::const_iterator begin();
AnimSurfaceTypeMap::const_iterator end();
AnimationSurfaceType* GetAnimSurfaceType(std::string name);
STRUCTURE_FILE_REF* GetStructFile(AnimationSurfaceType* animSurfaceType);
private:
static void XMLCALL StartElementHandle(void* userData, const XML_Char* name, const XML_Char** atts);
static void XMLCALL EndElementHandle(void* userData, const XML_Char* name);
static void XMLCALL CharacterDataHandle(void* userData, const XML_Char* str, int len);
static void XMLCALL ExternalEntityHandler(XML_Parser parser, const XML_Char* context, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId);
bool AddAnimSurfaceType(std::string name, AnimationSurfaceType* animSurfaceType, STRUCTURE_FILE_REF* pStructFile);
STRUCTURE_FILE_REF* LoadStructFile(STR fileName);
};
}
#endif
@@ -0,0 +1,18 @@
#include "XMLParseException.h"
XMLParseException::XMLParseException(const char* text, const char* function, int line, const char* file) : std::exception(), message(text), _LINE(line) {
}
XMLParseException::XMLParseException(const char* text, const XML_Char* name, XML_Parser* parser) : std::exception(), message(text), _LINE(0) {
message = text;
if (parser != NULL) {
_LINE = XML_GetCurrentLineNumber(*parser);
}
}
XMLParseException::~XMLParseException(void) {
}
const char* XMLParseException::what() const throw() {
return message.c_str();
}
@@ -0,0 +1,26 @@
#pragma once
#ifndef _LBT_XMLPARSEEXCEPTION__H_
#define _LBT_XMLPARSEEXCEPTION__H_
#include "LogicalBodyTypes/XMLParseException.h"
#include "expat.h"
#include <exception>
#include <string>
class XMLParseException : public std::exception {
public:
XMLParseException(const char* text, const char* function, int line, const char* file);
XMLParseException(const char* text, const XML_Char* name, XML_Parser* parser = NULL);
const char* what() const throw();
~XMLParseException(void);
public:
int _LINE;
std::string message;
std::string _FILE;
std::string _FUNCTION;
std::string _time;
};
#endif
+3 -1
View File
@@ -1526,7 +1526,9 @@ BOOLEAN RenderShopKeeperInterface()
sCenX, sCenY,
pSoldier->usAniFrame,
&rect,
pSoldier->pShades[pSoldier->ubFadeLevel] );
pSoldier->pShades[pSoldier->ubFadeLevel],
TRUE
);
UnLockVideoSurface( FRAME_BUFFER );
}
+26 -1
View File
@@ -66,6 +66,19 @@
<ClInclude Include="Items.h" />
<ClInclude Include="Ja25_Tactical.h" />
<ClInclude Include="Keys.h" />
<ClInclude Include="LogicalBodyTypes\AbstractXMLLoader.h" />
<ClInclude Include="LogicalBodyTypes\BodyType.h" />
<ClInclude Include="LogicalBodyTypes\BodyTypeDB.h" />
<ClInclude Include="LogicalBodyTypes\EnumeratorDB.h" />
<ClInclude Include="LogicalBodyTypes\Filter.h" />
<ClInclude Include="LogicalBodyTypes\FilterDB.h" />
<ClInclude Include="LogicalBodyTypes\Layers.h" />
<ClInclude Include="LogicalBodyTypes\PaletteDB.h" />
<ClInclude Include="LogicalBodyTypes\PaletteTable.h" />
<ClInclude Include="LogicalBodyTypes\Singleton.h" />
<ClInclude Include="LogicalBodyTypes\SurfaceCache.h" />
<ClInclude Include="LogicalBodyTypes\SurfaceDB.h" />
<ClInclude Include="LogicalBodyTypes\XMLParseException.h" />
<ClInclude Include="LOS.h" />
<ClInclude Include="Map Information.h" />
<ClInclude Include="merc entering.h" />
@@ -155,13 +168,25 @@
<ClCompile Include="Items.cpp" />
<ClCompile Include="Ja25_Tactical.cpp" />
<ClCompile Include="Keys.cpp" />
<ClCompile Include="LogicalBodyTypes\AbstractXMLLoader.cpp" />
<ClCompile Include="LogicalBodyTypes\BodyType.cpp" />
<ClCompile Include="LogicalBodyTypes\BodyTypeDB.cpp" />
<ClCompile Include="LogicalBodyTypes\EnumeratorDB.cpp" />
<ClCompile Include="LogicalBodyTypes\Filter.cpp" />
<ClCompile Include="LogicalBodyTypes\FilterDB.cpp" />
<ClCompile Include="LogicalBodyTypes\Layers.cpp" />
<ClCompile Include="LogicalBodyTypes\PaletteDB.cpp" />
<ClCompile Include="LogicalBodyTypes\PaletteTable.cpp" />
<ClCompile Include="LogicalBodyTypes\SurfaceCache.cpp" />
<ClCompile Include="LogicalBodyTypes\SurfaceDB.cpp" />
<ClCompile Include="LogicalBodyTypes\XMLParseException.cpp" />
<ClCompile Include="LOS.cpp" />
<ClCompile Include="Map Information.cpp" />
<ClCompile Include="Merc Entering.cpp" />
<ClCompile Include="Merc Hiring.cpp" />
<ClCompile Include="Militia Control.cpp" />
<ClCompile Include="MiniGame.cpp" />
<ClCompile Include="Morale.cpp" />
<ClCompile Include="Morale.cpp" />
<ClCompile Include="opplist.cpp" />
<ClCompile Include="Overhead.cpp" />
<ClCompile Include="PATHAI.cpp" />
+79 -1
View File
@@ -7,6 +7,9 @@
<Filter Include="Source Files">
<UniqueIdentifier>{c1880088-a976-405e-919e-9f1e97ad6701}</UniqueIdentifier>
</Filter>
<Filter Include="Logical Bodytypes">
<UniqueIdentifier>{7ccf82e9-8713-4351-af1f-218106a69555}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Action Items.h">
@@ -147,7 +150,7 @@
<ClInclude Include="MiniGame.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Morale.h">
<ClInclude Include="Morale.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="opplist.h">
@@ -276,6 +279,45 @@
<ClInclude Include="DynamicDialogue.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\AbstractXMLLoader.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\BodyType.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\BodyTypeDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\EnumeratorDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\Filter.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\FilterDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\Layers.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\PaletteDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\PaletteTable.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\Singleton.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\SurfaceCache.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\SurfaceDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\XMLParseException.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Air Raid.cpp">
@@ -704,5 +746,41 @@
<ClCompile Include="XML_StructureConstruct.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\AbstractXMLLoader.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\BodyType.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\BodyTypeDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\EnumeratorDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\Filter.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\FilterDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\Layers.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\PaletteDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\PaletteTable.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\SurfaceCache.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\SurfaceDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\XMLParseException.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
</ItemGroup>
</Project>
+25
View File
@@ -66,6 +66,19 @@
<ClInclude Include="Items.h" />
<ClInclude Include="Ja25_Tactical.h" />
<ClInclude Include="Keys.h" />
<ClInclude Include="LogicalBodyTypes\AbstractXMLLoader.h" />
<ClInclude Include="LogicalBodyTypes\BodyType.h" />
<ClInclude Include="LogicalBodyTypes\BodyTypeDB.h" />
<ClInclude Include="LogicalBodyTypes\EnumeratorDB.h" />
<ClInclude Include="LogicalBodyTypes\Filter.h" />
<ClInclude Include="LogicalBodyTypes\FilterDB.h" />
<ClInclude Include="LogicalBodyTypes\Layers.h" />
<ClInclude Include="LogicalBodyTypes\PaletteDB.h" />
<ClInclude Include="LogicalBodyTypes\PaletteTable.h" />
<ClInclude Include="LogicalBodyTypes\Singleton.h" />
<ClInclude Include="LogicalBodyTypes\SurfaceCache.h" />
<ClInclude Include="LogicalBodyTypes\SurfaceDB.h" />
<ClInclude Include="LogicalBodyTypes\XMLParseException.h" />
<ClInclude Include="LOS.h" />
<ClInclude Include="Map Information.h" />
<ClInclude Include="merc entering.h" />
@@ -156,6 +169,18 @@
<ClCompile Include="Items.cpp" />
<ClCompile Include="Ja25_Tactical.cpp" />
<ClCompile Include="Keys.cpp" />
<ClCompile Include="LogicalBodyTypes\AbstractXMLLoader.cpp" />
<ClCompile Include="LogicalBodyTypes\BodyType.cpp" />
<ClCompile Include="LogicalBodyTypes\BodyTypeDB.cpp" />
<ClCompile Include="LogicalBodyTypes\EnumeratorDB.cpp" />
<ClCompile Include="LogicalBodyTypes\Filter.cpp" />
<ClCompile Include="LogicalBodyTypes\FilterDB.cpp" />
<ClCompile Include="LogicalBodyTypes\Layers.cpp" />
<ClCompile Include="LogicalBodyTypes\PaletteDB.cpp" />
<ClCompile Include="LogicalBodyTypes\PaletteTable.cpp" />
<ClCompile Include="LogicalBodyTypes\SurfaceCache.cpp" />
<ClCompile Include="LogicalBodyTypes\SurfaceDB.cpp" />
<ClCompile Include="LogicalBodyTypes\XMLParseException.cpp" />
<ClCompile Include="LOS.cpp" />
<ClCompile Include="Map Information.cpp" />
<ClCompile Include="Merc Entering.cpp" />
+78
View File
@@ -7,6 +7,9 @@
<Filter Include="Source Files">
<UniqueIdentifier>{c1880088-a976-405e-919e-9f1e97ad6701}</UniqueIdentifier>
</Filter>
<Filter Include="Logical Bodytypes">
<UniqueIdentifier>{7ccf82e9-8713-4351-af1f-218106a69555}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Action Items.h">
@@ -279,6 +282,45 @@
<ClInclude Include="MiniGame.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\AbstractXMLLoader.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\BodyType.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\BodyTypeDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\EnumeratorDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\Filter.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\FilterDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\Layers.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\PaletteDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\PaletteTable.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\Singleton.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\SurfaceCache.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\SurfaceDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\XMLParseException.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Air Raid.cpp">
@@ -707,5 +749,41 @@
<ClCompile Include="Minigame.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\AbstractXMLLoader.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\BodyType.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\BodyTypeDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\EnumeratorDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\Filter.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\FilterDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\Layers.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\PaletteDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\PaletteTable.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\SurfaceCache.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\SurfaceDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\XMLParseException.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
</ItemGroup>
</Project>
+25
View File
@@ -66,6 +66,19 @@
<ClInclude Include="Items.h" />
<ClInclude Include="Ja25_Tactical.h" />
<ClInclude Include="Keys.h" />
<ClInclude Include="LogicalBodyTypes\AbstractXMLLoader.h" />
<ClInclude Include="LogicalBodyTypes\BodyType.h" />
<ClInclude Include="LogicalBodyTypes\BodyTypeDB.h" />
<ClInclude Include="LogicalBodyTypes\EnumeratorDB.h" />
<ClInclude Include="LogicalBodyTypes\Filter.h" />
<ClInclude Include="LogicalBodyTypes\FilterDB.h" />
<ClInclude Include="LogicalBodyTypes\Layers.h" />
<ClInclude Include="LogicalBodyTypes\PaletteDB.h" />
<ClInclude Include="LogicalBodyTypes\PaletteTable.h" />
<ClInclude Include="LogicalBodyTypes\Singleton.h" />
<ClInclude Include="LogicalBodyTypes\SurfaceCache.h" />
<ClInclude Include="LogicalBodyTypes\SurfaceDB.h" />
<ClInclude Include="LogicalBodyTypes\XMLParseException.h" />
<ClInclude Include="LOS.h" />
<ClInclude Include="Map Information.h" />
<ClInclude Include="merc entering.h" />
@@ -156,6 +169,18 @@
<ClCompile Include="Items.cpp" />
<ClCompile Include="Ja25_Tactical.cpp" />
<ClCompile Include="Keys.cpp" />
<ClCompile Include="LogicalBodyTypes\AbstractXMLLoader.cpp" />
<ClCompile Include="LogicalBodyTypes\BodyType.cpp" />
<ClCompile Include="LogicalBodyTypes\BodyTypeDB.cpp" />
<ClCompile Include="LogicalBodyTypes\EnumeratorDB.cpp" />
<ClCompile Include="LogicalBodyTypes\Filter.cpp" />
<ClCompile Include="LogicalBodyTypes\FilterDB.cpp" />
<ClCompile Include="LogicalBodyTypes\Layers.cpp" />
<ClCompile Include="LogicalBodyTypes\PaletteDB.cpp" />
<ClCompile Include="LogicalBodyTypes\PaletteTable.cpp" />
<ClCompile Include="LogicalBodyTypes\SurfaceCache.cpp" />
<ClCompile Include="LogicalBodyTypes\SurfaceDB.cpp" />
<ClCompile Include="LogicalBodyTypes\XMLParseException.cpp" />
<ClCompile Include="LOS.cpp" />
<ClCompile Include="Map Information.cpp" />
<ClCompile Include="Merc Entering.cpp" />
+78
View File
@@ -7,6 +7,9 @@
<Filter Include="Source Files">
<UniqueIdentifier>{c1880088-a976-405e-919e-9f1e97ad6701}</UniqueIdentifier>
</Filter>
<Filter Include="Logical Bodytypes">
<UniqueIdentifier>{7ccf82e9-8713-4351-af1f-218106a69555}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Action Items.h">
@@ -279,6 +282,45 @@
<ClInclude Include="MiniGame.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\AbstractXMLLoader.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\BodyType.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\BodyTypeDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\EnumeratorDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\Filter.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\FilterDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\Layers.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\PaletteDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\PaletteTable.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\Singleton.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\SurfaceCache.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\SurfaceDB.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
<ClInclude Include="LogicalBodyTypes\XMLParseException.h">
<Filter>Logical Bodytypes</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Air Raid.cpp">
@@ -707,5 +749,41 @@
<ClCompile Include="Minigame.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\AbstractXMLLoader.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\BodyType.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\BodyTypeDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\EnumeratorDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\Filter.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\FilterDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\Layers.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\PaletteDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\PaletteTable.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\SurfaceCache.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\SurfaceDB.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
<ClCompile Include="LogicalBodyTypes\XMLParseException.cpp">
<Filter>Logical Bodytypes</Filter>
</ClCompile>
</ItemGroup>
</Project>
+6
View File
@@ -256,6 +256,12 @@ typedef PARSE_STAGE;
#define DIFFICULTYFILENAME "DifficultySettings.xml"
#define LBT_LAYERSFILENAME "LogicalBodyTypes/Layers.xml"
#define LBT_PALETTESFILENAME "LogicalBodyTypes/Palettes.xml"
#define LBT_ANIMSURFACESFILENAME "LogicalBodyTypes/AnimationSurfaces.xml"
#define LBT_FILTERSFILENAME "LogicalBodyTypes/Filters.xml"
#define LBT_BODYTYPESFILENAME "LogicalBodyTypes/LogicalBodyTypes.xml"
extern BOOLEAN ReadInItemStats(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN WriteItemStats();
+2411 -1160
View File
File diff suppressed because it is too large Load Diff
+7 -3
View File
@@ -2,6 +2,8 @@
#define __RENDERWORLD_H
#include "worlddef.h"
#include "LogicalBodyTypes/Layers.h"
#include "LogicalBodyTypes/BodyTypeDB.h"
// TEMP SELECT STUFF
#define NO_SELECT 0
@@ -221,8 +223,10 @@ BOOLEAN Zero8BPPDataTo16BPPBufferTransparent( UINT16 *pBuffer, UINT32 uiDestPitc
BOOLEAN Blt8BPPDataTo16BPPBufferTransZIncClipZSameZBurnsThrough( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZStripIndex );
BOOLEAN Blt8BPPDataTo16BPPBufferTransInvZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex );
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTransShadowIncClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZIndex, UINT16 *p16BPPPalette );
BOOLEAN Blt8BPPDataTo16BPPBufferTransZIncObscureClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTransShadowIncObscureClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZIndex, UINT16 *p16BPPPalette );
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTransShadowIncClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows = FALSE);
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTransShadowIncClipAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows = FALSE);
BOOLEAN Blt8BPPDataTo16BPPBufferTransZIncObscureClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion);
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTransShadowIncObscureClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows = FALSE);
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTransShadowIncObscureClipAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, INT16 sZIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows = FALSE);
#endif
+60 -46
View File
@@ -2249,20 +2249,20 @@ BOOLEAN AddZStripInfoToVObject( HVOBJECT hVObject, STRUCTURE_FILE_REF * pStructu
sNext = sSTIStartIndex + sSTIStep;
fFirstTime = TRUE;
for (uiLoop = (UINT8)sSTIStartIndex; uiLoop < hVObject->usNumberOfObjects; uiLoop++ )
for (uiLoop = (UINT8)sSTIStartIndex; uiLoop < hVObject->usNumberOfObjects; uiLoop++)
{
// Defualt to true
fCopyIntoVo = TRUE;
// Increment struct index....
if ( uiLoop == (UINT32)sNext )
if (uiLoop == (UINT32)sNext)
{
sNext = (UINT16)( uiLoop + sSTIStep );
sNext = (UINT16)(uiLoop + sSTIStep);
sStructIndex++;
}
else
{
if ( fFirstTime )
if (fFirstTime)
{
fFirstTime = FALSE;
}
@@ -2272,7 +2272,7 @@ BOOLEAN AddZStripInfoToVObject( HVOBJECT hVObject, STRUCTURE_FILE_REF * pStructu
}
}
if ( fFromAnimation )
if (fFromAnimation)
{
uiDestVoIndex = sStructIndex;
}
@@ -2282,17 +2282,17 @@ BOOLEAN AddZStripInfoToVObject( HVOBJECT hVObject, STRUCTURE_FILE_REF * pStructu
}
if ( fCopyIntoVo && sStructIndex < pStructureFileRef->usNumberOfStructures )
if (fCopyIntoVo && sStructIndex < pStructureFileRef->usNumberOfStructures)
{
pDBStructure = pStructureFileRef->pDBStructureRef[ sStructIndex ].pDBStructure;
if (pDBStructure != NULL && ( pDBStructure->ubNumberOfTiles > 1 || ( pDBStructure->fFlags & STRUCTURE_CORPSE ) ) )
//if (pDBStructure != NULL && pDBStructure->ubNumberOfTiles > 1 )
pDBStructure = pStructureFileRef->pDBStructureRef[sStructIndex].pDBStructure;
if (pDBStructure != NULL && (pDBStructure->ubNumberOfTiles > 1 || (pDBStructure->fFlags & STRUCTURE_CORPSE)))
//if (pDBStructure != NULL && pDBStructure->ubNumberOfTiles > 1 )
{
// ATE: We allow SLIDING DOORS of 2 tile sizes...
if ( !(pDBStructure->fFlags & STRUCTURE_ANYDOOR) || ( (pDBStructure->fFlags & ( STRUCTURE_ANYDOOR ) ) && ( pDBStructure->fFlags & STRUCTURE_SLIDINGDOOR ) ) )
if (!(pDBStructure->fFlags & STRUCTURE_ANYDOOR) || ((pDBStructure->fFlags & (STRUCTURE_ANYDOOR)) && (pDBStructure->fFlags & STRUCTURE_SLIDINGDOOR)))
{
hVObject->ppZStripInfo[ uiDestVoIndex ] = (ZStripInfo *) MemAlloc( sizeof( ZStripInfo ) );
if (hVObject->ppZStripInfo[ uiDestVoIndex ] == NULL)
hVObject->ppZStripInfo[uiDestVoIndex] = (ZStripInfo *)MemAlloc(sizeof(ZStripInfo));
if (hVObject->ppZStripInfo[uiDestVoIndex] == NULL)
{
// augh!! out of memory! free everything allocated and abort
for (ubLoop2 = 0; ubLoop2 < uiLoop; ubLoop2++)
@@ -2302,13 +2302,13 @@ BOOLEAN AddZStripInfoToVObject( HVOBJECT hVObject, STRUCTURE_FILE_REF * pStructu
MemFree(hVObject->ppZStripInfo[uiLoop]);
}
}
MemFree( hVObject->ppZStripInfo );
MemFree(hVObject->ppZStripInfo);
hVObject->ppZStripInfo = NULL;
return( FALSE );
return(FALSE);
}
else
{
pCurr = hVObject->ppZStripInfo[ uiDestVoIndex ];
pCurr = hVObject->ppZStripInfo[uiDestVoIndex];
ubNumIncreasing = 0;
ubNumStable = 0;
@@ -2319,7 +2319,7 @@ BOOLEAN AddZStripInfoToVObject( HVOBJECT hVObject, STRUCTURE_FILE_REF * pStructu
sOffsetY = hVObject->pETRLEObject[uiLoop].sOffsetY;
usWidth = hVObject->pETRLEObject[uiLoop].usWidth;
usHeight = hVObject->pETRLEObject[uiLoop].usHeight;
if (pDBStructure->fFlags & (STRUCTURE_MOBILE | STRUCTURE_CORPSE) )
if (pDBStructure->fFlags & (STRUCTURE_MOBILE | STRUCTURE_CORPSE))
{
// adjust for the difference between the animation and structure base tile
@@ -2427,44 +2427,58 @@ BOOLEAN AddZStripInfoToVObject( HVOBJECT hVObject, STRUCTURE_FILE_REF * pStructu
// now create the array!
pCurr->ubNumberOfZChanges = ubNumIncreasing + ubNumStable + ubNumDecreasing;
pCurr->pbZChange = (INT8 *) MemAlloc( pCurr->ubNumberOfZChanges );
if ( pCurr->pbZChange == NULL)
// BIO (LOBOT): had to add a conditional as otherwise function would report a failure
// which then would prompt LOBOT to issue an error when trying to load animation surfaces with
// frames with a certain geometry.
// Only allocate memory and stuff if ubNumberOfZChanges > 0. Otherwise
// MemAlloc returns a NULL pointer which the code would interpret as
// allocation failing because of no memory.
// I hope this is OK, I don't entirely understand what is done here...
if (pCurr->ubNumberOfZChanges > 0)
{
// augh!
for (ubLoop2 = 0; ubLoop2 < uiLoop; ubLoop2++)
pCurr->pbZChange = (INT8 *)MemAlloc(pCurr->ubNumberOfZChanges);
if (pCurr->pbZChange == NULL)
{
if (hVObject->ppZStripInfo[ubLoop2] != NULL)
// augh!
for (ubLoop2 = 0; ubLoop2 < uiLoop; ubLoop2++)
{
MemFree(hVObject->ppZStripInfo[uiLoop]);
if (hVObject->ppZStripInfo[ubLoop2] != NULL)
{
MemFree(hVObject->ppZStripInfo[uiLoop]);
}
}
MemFree(hVObject->ppZStripInfo);
hVObject->ppZStripInfo = NULL;
return(FALSE);
}
for (ubLoop2 = 0; ubLoop2 < ubNumIncreasing; ubLoop2++)
{
pCurr->pbZChange[ubLoop2] = 1;
}
for (; ubLoop2 < ubNumIncreasing + ubNumStable; ubLoop2++)
{
pCurr->pbZChange[ubLoop2] = 0;
}
for (; ubLoop2 < pCurr->ubNumberOfZChanges; ubLoop2++)
{
pCurr->pbZChange[ubLoop2] = -1;
}
if (ubNumIncreasing > 0)
{
pCurr->bInitialZChange = -(ubNumIncreasing);
}
else if (ubNumStable > 0)
{
pCurr->bInitialZChange = 0;
}
else
{
pCurr->bInitialZChange = -(ubNumDecreasing);
}
MemFree( hVObject->ppZStripInfo );
hVObject->ppZStripInfo = NULL;
return( FALSE );
}
for (ubLoop2 = 0; ubLoop2 < ubNumIncreasing; ubLoop2++)
{
pCurr->pbZChange[ubLoop2] = 1;
}
for (; ubLoop2 < ubNumIncreasing + ubNumStable; ubLoop2++)
{
pCurr->pbZChange[ubLoop2] = 0;
}
for (; ubLoop2 < pCurr->ubNumberOfZChanges; ubLoop2++)
{
pCurr->pbZChange[ubLoop2] = -1;
}
if (ubNumIncreasing > 0)
{
pCurr->bInitialZChange = -(ubNumIncreasing);
}
else if (ubNumStable > 0)
{
pCurr->bInitialZChange = 0;
}
else
{
pCurr->bInitialZChange = -(ubNumDecreasing);
pCurr->pbZChange = NULL;
}
}
}
+2
View File
@@ -6352,6 +6352,7 @@ STR16 zOptionsToggleText[] =
L"属性进度条", //L"Stat Progress Bars", // Show progress towards stat increase //ham3.6
L"替代战略地图颜色", // Change color scheme of Strategic Map
L"替代子弹图像", // Show alternate bullet graphics (tracers)
L"Use Logical Bodytypes",
L"显示佣兵军衔", // shows mercs ranks
L"显示脸部装备图",
L"显示脸部装备图标",
@@ -6466,6 +6467,7 @@ STR16 zOptionsScreenHelpText[] =
L"打开时,显示各属性的增长进度。", // L"When ON, shows character progress towards gaining levels.", //ham3.6
L"打开时,战略地图将会根据探索状态显示不同的着色。",
L"打开时,当你射击时会显示间隔子弹图像。",
L"When ON, mercenary body graphic can change along with equipped gear.", // TODO.Translate
L"打开时,在战略界面的佣兵名旁显示军衔。",
L"打开时,显示佣兵脸部装备图。",
L"打开时,佣兵肖像右下角显示脸部装备图标",
+2
View File
@@ -6359,6 +6359,7 @@ STR16 zOptionsToggleText[] =
L"Stat Progress Bars", // Show progress towards stat increase // TODO.Translate
L"Alternate Strategy-Map Colors", // Change color scheme of Strategic Map
L"Alternate bullet graphics", // Show alternate bullet graphics (tracers) // TODO.Translate
L"Use Logical Bodytypes",
L"Show Merc Ranks", // shows mercs ranks // TODO.Translate
L"Show Face gear graphics", // TODO.Translate
L"Show Face gear icons",
@@ -6473,6 +6474,7 @@ STR16 zOptionsScreenHelpText[] =
L"When ON, shows character progress towards gaining levels.", // TODO.Translate
L"When ON, the Strategic Map will be colored differently based on exploration.",
L"When ON, alternate bullet graphics will be shown when you shoot.", // TODO.Translate
L"When ON, mercenary body graphic can change along with equipped gear.", // TODO.Translate
L"When ON, ranks will be displayed before merc names in the strategic view.", // TODO.Translate
L"When ON, you will see the equipped face gear on the merc portraits.", // TODO.Translate
L"When ON, you will see icons for the equipped face gear on the merc portraits in the lower right corner.",
+459 -457
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -6364,6 +6364,7 @@ STR16 zOptionsToggleText[] =
L"Afficher la progression", // Show progress towards stat increase
L"Couleur alternative carte", // Change color scheme of Strategic Map
L"Montrer tirs alternatifs", // Show alternate bullet graphics (tracers)
L"Use Logical Bodytypes",
L"Afficher grade du mercenaire", // shows mercs ranks
L"Afficher équip. sur portrait",
L"Afficher icônes sur portrait",
@@ -6478,6 +6479,7 @@ STR16 zOptionsScreenHelpText[] =
L"Si activé, affiche une barre de progression sur chaque compétence",
L"Si activé, la carte stratégique sera colorée différemment selon l'exploration.",
L"Si activé, le graphisme des tirs alternatifs sera affiché quand vous tirerez.",
L"When ON, mercenary body graphic can change along with equipped gear.", // TODO.Translate
L"Si activée, le grade sera affiché devant le nom du merc. dans la carte stratégique.",
L"Si activé, vous verrez l'équipement du mercenaire à travers son portrait.",
L"Si activé, vous verrez les icônes correspondant à l'équipement porté en bas à droite du portrait.",
+2
View File
@@ -6203,6 +6203,7 @@ STR16 zOptionsToggleText[] =
L"Status Trainingsfortschritt", // Show progress towards stat increase
L"Alternatives Kartenfarbschema", // Change color scheme of Strategic Map
L"Alternative Projektil-Grafik", // Show alternate bullet graphics (tracers)
L"Use Logical Bodytypes",
L"Söldnerrang anzeigen.", // shows mercs ranks
L"Gesichtsequipment-Grafiken",
L"Gesichtsequipment-Icons",
@@ -6317,6 +6318,7 @@ STR16 zOptionsScreenHelpText[] =
L"Wenn diese Funktion aktiviert ist, werden die Söldnerwerte visuell mit ihrem Trainingsfortschritt unterlegt.",
L"Wenn diese Funktion aktiviert ist, wird die Strategische Karte entsprechend Ihres Erkundungsfortschrittes unterschiedlich eingefärbt.",
L"Wenn diese Funktion aktiviert ist, werden geschossene Projektile visuell mit Tracer-Effekten dargestellt.",
L"When ON, mercenary body graphic can change along with equipped gear.", // TODO.Translate
L"Wenn diese Funktion aktiviert ist, werden die Ränge der Söldner in der Strategischen Karte vor dem Namen angezeigt.",
L"Wenn diese Funktion aktiviert ist, sehen sie das Gesichtsequipment Ihrer Söldner direkt auf dem Portrait.",
L"Wenn diese Funktion aktiviert ist, sehen sie Icons für das Gesichtsequipment in der rechten unteren Ecke des Portraits.",
+2
View File
@@ -6342,6 +6342,7 @@ STR16 zOptionsToggleText[] =
L"Stat Progress Bars", // Show progress towards stat increase // TODO.Translate
L"Alternate Strategy-Map Colors", // Change color scheme of Strategic Map
L"Alternate bullet graphics", // Show alternate bullet graphics (tracers) // TODO.Translate
L"Use Logical Bodytypes",
L"Show Merc Ranks", // shows mercs ranks // TODO.Translate
L"Show Face gear graphics", // TODO.Translate
L"Show Face gear icons",
@@ -6456,6 +6457,7 @@ STR16 zOptionsScreenHelpText[] =
L"When ON, shows character progress towards gaining levels.", // TODO.Translate
L"When ON, the Strategic Map will be colored differently based on exploration.",
L"When ON, alternate bullet graphics will be shown when you shoot.", // TODO.Translate
L"When ON, mercenary body graphic can change along with equipped gear.", // TODO.Translate
L"When ON, ranks will be displayed before merc names in the strategic view.", // TODO.Translate
L"When ON, you will see the equipped face gear on the merc portraits.", // TODO.Translate
L"When ON, you will see icons for the equipped face gear on the merc portraits in the lower right corner.",
+2
View File
@@ -6361,6 +6361,7 @@ STR16 zOptionsToggleText[] =
L"Alternate Strategy-Map Colors", // Change color scheme of Strategic Map
L"Alternate bullet graphics", // Show alternate bullet graphics (tracers) // TODO.Translate
L"Show Merc Ranks", // shows mercs ranks // TODO.Translate
L"Use Logical Bodytypes",
L"Show Face gear graphics", // TODO.Translate
L"Show Face gear icons",
L"Disable Cursor Swap", // Disable Cursor Swap // TODO.Translate
@@ -6475,6 +6476,7 @@ STR16 zOptionsScreenHelpText[] =
L"Jeśli WŁĄCZONE, pokazuje postęp w doświadczeniu postaci.",
L"When ON, the Strategic Map will be colored differently based on exploration.",
L"Jeśli WŁĄCZONE, zastępuje starą animację pocisku nową.",
L"When ON, mercenary body graphic can change along with equipped gear.", // TODO.Translate
L"When ON, ranks will be displayed before merc names in the strategic view.", // TODO.Translate
L"When ON, you will see the equipped face gear on the merc portraits.", // TODO.Translate
L"When ON, you will see icons for the equipped face gear on the merc portraits in the lower right corner.",
+2
View File
@@ -6352,6 +6352,7 @@ STR16 zOptionsToggleText[] =
L"Подсветить навык к повышению", //Stat Progress Bars // Show progress towards stat increase
L"Новая расцветка стратег. карты", //Alternate Strategy-Map Colors //Change color scheme of Strategic Map
L"Заметная летящая пуля", // Show alternate bullet graphics (tracers)
L"Использовать LOBOT",
L"Показать ранг бойца", // shows mercs ranks
L"Показать снаряжение на голове", //Show Face gear graphics
L"Показать иконки снаряжения",
@@ -6466,6 +6467,7 @@ STR16 zOptionsScreenHelpText[] =
L"Если включено, навык,\nкоторый вскоре повысится, будет подсвечен.",
L"Если включено, необследованные сектора\nна стратегической карте будут чёрно-белыми.",
L"Если включено, летящая пуля\nбудет более заметной.",
L"Если включено, анимация наемника будет отображать используемое оружие и экипировку.", // TODO.Translate
L"Если включено, на стратегическом экране\nбудет подписан ранг бойца перед его именем.",
L"Если включено, на портрете наёмника\nбудет отображено надетое головное снаряжение.",
L"Если включено, в правом нижнем углу\nна портрете наёмника будут отображены иконки\nнадетого головного снаряжения.",