First attempt to hand-merge Ryan's Linux and Mac OS X port.

This was a _ton_ of changes, made 15 years ago, so there are probably some
problems to work out still.

Among others: Engine/Base/Stream.* was mostly abandoned and will need to be
re-ported.

Still, this is a pretty good start, and probably holds a world record for
lines of changes or something.  :)
This commit is contained in:
Ryan C. Gordon 2016-03-28 21:03:54 -04:00
parent a7af6eb20b
commit 24cb244d43
497 changed files with 29777 additions and 6544 deletions

View File

@ -77,7 +77,7 @@ void SubMain( int argc, char *argv[])
} }
// initialize engine // initialize engine
SE_InitEngine(""); SE_InitEngine(argv[0], "");
_fnmApplicationPath = CTString(""); _fnmApplicationPath = CTString("");
@ -103,7 +103,7 @@ void SubMain( int argc, char *argv[])
strmSrc.GetLine_t(strLine); strmSrc.GetLine_t(strLine);
// try to find address marker in it // try to find address marker in it
const char *strAdr = strstr(strLine, "$adr:"); char *strAdr = strstr(strLine, "$adr:");
// if there is no marker // if there is no marker
if (strAdr==NULL) { if (strAdr==NULL) {
// just copy the line // just copy the line

View File

@ -1,58 +1,64 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#ifdef PLATFORM_UNIX /* rcg10072001 */
#include <signal.h>
#endif
#include "StdAfx.h" #include "StdAfx.h"
#include <GameMP/Game.h> #include <GameMP/Game.h>
#define DECL_DLL #define DECL_DLL
#if 0 /* rcg10042001 Doesn't seem to exist. */
#include <Entities/Global.h>
#endif
// application state variables // application state variables
extern BOOL _bRunning = TRUE; BOOL _bRunning = TRUE;
static BOOL _bForceRestart = FALSE; static BOOL _bForceRestart = FALSE;
static BOOL _bForceNextMap = FALSE; static BOOL _bForceNextMap = FALSE;
extern CTString _strSamVersion = "no version information"; CTString _strSamVersion = "no version information";
extern INDEX ded_iMaxFPS = 100; INDEX ded_iMaxFPS = 100;
extern CTString ded_strConfig = ""; CTString ded_strConfig = "";
extern CTString ded_strLevel = ""; CTString ded_strLevel = "";
extern INDEX ded_bRestartWhenEmpty = TRUE; INDEX ded_bRestartWhenEmpty = TRUE;
extern FLOAT ded_tmTimeout = -1; FLOAT ded_tmTimeout = -1;
extern CGame *_pGame = NULL; CGame *_pGame = NULL;
extern CTString sam_strFirstLevel = "Levels\\KarnakDemo.wld"; CTString sam_strFirstLevel = "Levels\\KarnakDemo.wld";
extern CTString sam_strIntroLevel = "Levels\\Intro.wld"; CTString sam_strIntroLevel = "Levels\\Intro.wld";
extern CTString sam_strGameName = "serioussam"; CTString sam_strGameName = "serioussam";
CTimerValue _tvLastLevelEnd(-1i64); CTimerValue _tvLastLevelEnd((__int64) -1);
void InitializeGame(void) void InitializeGame(void)
{ {
try { #ifdef STATICALLY_LINKED
#ifndef NDEBUG #define fnmExpanded NULL
#define GAMEDLL _fnmApplicationExe.FileDir()+"Game"+_strModExt+"D.dll" CPrintF(TRANS("Loading game library '%s'...\n"), "(statically linked)");
#else
CTFileName fnmDLL;
#ifndef NDEBUG
fnmDLL = "Bin\\Debug\\Game"+_strModExt+"D.dll";
#else #else
#define GAMEDLL _fnmApplicationExe.FileDir()+"Game"+_strModExt+".dll" fnmDLL = "Bin\\Game"+_strModExt+".dll";
#endif #endif
fnmDLL = CDynamicLoader::ConvertLibNameToPlatform(fnmDLL);
CTFileName fnmExpanded; CTFileName fnmExpanded;
ExpandFilePath(EFP_READ, CTString(GAMEDLL), fnmExpanded); ExpandFilePath(EFP_READ | EFP_NOZIPS,fnmDLL,fnmExpanded);
CPrintF(TRANS("Loading game library '%s'...\n"), (const char *)fnmExpanded); CPrintF(TRANS("Loading game library '%s'...\n"), (const char *)fnmExpanded);
HMODULE hGame = LoadLibraryA(fnmExpanded); #endif
if (hGame==NULL) {
ThrowF_t("%s", GetWindowsError(GetLastError()));
}
CGame* (*GAME_Create)(void) = (CGame* (*)(void))GetProcAddress(hGame, "GAME_Create");
if (GAME_Create==NULL) {
ThrowF_t("%s", GetWindowsError(GetLastError()));
}
_pGame = GAME_Create();
} catch (char *strError) { CDynamicLoader *loader = CDynamicLoader::GetInstance(fnmExpanded);
FatalError("%s", strError); CGame *(*GAME_Create)(void) = NULL;
if (loader->GetError() == NULL) {
GAME_Create = (CGame* (*)(void)) loader->FindSymbol("GAME_Create");
}
if (GAME_Create == NULL) {
FatalError("%s", loader->GetError());
} else {
_pGame = GAME_Create();
// init game - this will load persistent symbols
_pGame->Initialize(CTString("Data\\DedicatedServer.gms"));
} }
// init game - this will load persistent symbols
_pGame->Initialize(CTString("Data\\DedicatedServer.gms"));
} }
static void QuitGame(void) static void QuitGame(void)
@ -84,12 +90,16 @@ void LimitFrameRate(void)
// limit maximum frame rate // limit maximum frame rate
ded_iMaxFPS = ClampDn( ded_iMaxFPS, 1L); ded_iMaxFPS = ClampDn( ded_iMaxFPS, 1L);
TIME tmWantedDelta = 1.0f / ded_iMaxFPS; TIME tmWantedDelta = 1.0f / ded_iMaxFPS;
if( tmCurrentDelta<tmWantedDelta) Sleep( (tmWantedDelta-tmCurrentDelta)*1000.0f); if( tmCurrentDelta<tmWantedDelta)
_pTimer->Sleep( (DWORD) ((tmWantedDelta-tmCurrentDelta)*1000.0f) );
// remember new time // remember new time
tvLast = _pTimer->GetHighPrecisionTimer(); tvLast = _pTimer->GetHighPrecisionTimer();
} }
/* rcg10072001 win32ism. */
#ifdef PLATFORM_WIN32
// break/close handler // break/close handler
BOOL WINAPI HandlerRoutine( BOOL WINAPI HandlerRoutine(
DWORD dwCtrlType // control signal type DWORD dwCtrlType // control signal type
@ -104,13 +114,22 @@ BOOL WINAPI HandlerRoutine(
} }
return TRUE; return TRUE;
} }
#endif
#ifdef PLATFORM_UNIX
void unix_signal_catcher(int signum)
{
_bRunning = FALSE;
}
#endif
#define REFRESHTIME (0.1f) #define REFRESHTIME (0.1f)
static void LoadingHook_t(CProgressHookInfo *pphi) static void LoadingHook_t(CProgressHookInfo *pphi)
{ {
// measure time since last call // measure time since last call
static CTimerValue tvLast(0I64); static CTimerValue tvLast((__int64) 0);
CTimerValue tvNow = _pTimer->GetHighPrecisionTimer(); CTimerValue tvNow = _pTimer->GetHighPrecisionTimer();
if (!_bRunning) { if (!_bRunning) {
@ -126,8 +145,13 @@ static void LoadingHook_t(CProgressHookInfo *pphi)
// print status text // print status text
CTString strRes; CTString strRes;
#ifdef PLATFORM_WIN32
printf("\r "); printf("\r ");
printf("\r%s : %3.0f%%\r", pphi->phi_strDescription, pphi->phi_fCompleted*100); printf("\r%s : %3.0f%%\r", (const char *) pphi->phi_strDescription, pphi->phi_fCompleted*100);
#else
// !!! FIXME: This isn't right, either...
printf("%s : %3.0f%%\n", (const char *) pphi->phi_strDescription, pphi->phi_fCompleted*100);
#endif
} }
// loading hook functions // loading hook functions
@ -158,14 +182,21 @@ BOOL StartGame(CTString &strLevel)
return _pGame->NewGame( _pGame->gam_strSessionName, strLevel, sp); return _pGame->NewGame( _pGame->gam_strSessionName, strLevel, sp);
} }
void ExecScript(const CTString &str) void ExecScript(const CTFileName &fnmScript)
{ {
CPrintF("Executing: '%s'\n", str); CPrintF("Executing: '%s'\n", (const char *) fnmScript);
CTString strCmd; CTString strCmd;
strCmd.PrintF("include \"%s\"", str); strCmd.PrintF("include \"%s\"", (const char *) fnmScript);
_pShell->Execute(strCmd); _pShell->Execute(strCmd);
} }
#ifdef PLATFORM_WIN32
#define DelayBeforeExit() fgetc(stdin);
#else
#define DelayBeforeExit()
#endif
BOOL Init(int argc, char* argv[]) BOOL Init(int argc, char* argv[])
{ {
_bDedicatedServer = TRUE; _bDedicatedServer = TRUE;
@ -174,11 +205,14 @@ BOOL Init(int argc, char* argv[])
// NOTE: this cannot be translated - translations are not loaded yet // NOTE: this cannot be translated - translations are not loaded yet
printf("Usage: DedicatedServer <configname> [<modname>]\n" printf("Usage: DedicatedServer <configname> [<modname>]\n"
"This starts a server reading configs from directory 'Scripts\\Dedicated\\<configname>\\'\n"); "This starts a server reading configs from directory 'Scripts\\Dedicated\\<configname>\\'\n");
getch();
DelayBeforeExit();
exit(0); exit(0);
} }
SetConsoleTitleA(argv[1]); #ifdef PLATFORM_WIN32
SetConsoleTitle(argv[1]);
#endif
ded_strConfig = CTString("Scripts\\Dedicated\\")+argv[1]+"\\"; ded_strConfig = CTString("Scripts\\Dedicated\\")+argv[1]+"\\";
@ -190,7 +224,7 @@ BOOL Init(int argc, char* argv[])
_strLogFile = CTString("Dedicated_")+argv[1]; _strLogFile = CTString("Dedicated_")+argv[1];
// initialize engine // initialize engine
SE_InitEngine(sam_strGameName); SE_InitEngine(argv[0], sam_strGameName);
// ParseCommandLine(strCmdLine); // ParseCommandLine(strCmdLine);
@ -211,32 +245,40 @@ BOOL Init(int argc, char* argv[])
FinishTranslationTable(); FinishTranslationTable();
} catch (char *strError) { } catch (char *strError) {
FatalError("%s %s", CTString(fnmTransTable), strError); CTString str(fnmTransTable);
FatalError("%s %s", (const char *) str, strError);
} }
// always disable all warnings when in serious sam // always disable all warnings when in serious sam
_pShell->Execute( "con_bNoWarnings=1;"); _pShell->Execute( "con_bNoWarnings=1;");
// declare shell symbols // declare shell symbols
_pShell->DeclareSymbol("persistent user INDEX ded_iMaxFPS;", &ded_iMaxFPS); _pShell->DeclareSymbol("persistent user INDEX ded_iMaxFPS;", (void *) &ded_iMaxFPS);
_pShell->DeclareSymbol("user void Quit(void);", &QuitGame); _pShell->DeclareSymbol("user void Quit(void);", (void *) &QuitGame);
_pShell->DeclareSymbol("user CTString ded_strLevel;", &ded_strLevel); _pShell->DeclareSymbol("user CTString ded_strLevel;", (void *) &ded_strLevel);
_pShell->DeclareSymbol("user FLOAT ded_tmTimeout;", &ded_tmTimeout); _pShell->DeclareSymbol("user FLOAT ded_tmTimeout;", (void *) &ded_tmTimeout);
_pShell->DeclareSymbol("user INDEX ded_bRestartWhenEmpty;", &ded_bRestartWhenEmpty); _pShell->DeclareSymbol("user INDEX ded_bRestartWhenEmpty;", (void *) &ded_bRestartWhenEmpty);
_pShell->DeclareSymbol("user void Restart(void);", &RestartGame); _pShell->DeclareSymbol("user void Restart(void);", (void *) &RestartGame);
_pShell->DeclareSymbol("user void NextMap(void);", &NextMap); _pShell->DeclareSymbol("user void NextMap(void);", (void *) &NextMap);
_pShell->DeclareSymbol("persistent user CTString sam_strIntroLevel;", &sam_strIntroLevel); _pShell->DeclareSymbol("persistent user CTString sam_strIntroLevel;", (void *) &sam_strIntroLevel);
_pShell->DeclareSymbol("persistent user CTString sam_strGameName;", &sam_strGameName); _pShell->DeclareSymbol("persistent user CTString sam_strGameName;", (void *) &sam_strGameName);
_pShell->DeclareSymbol("user CTString sam_strFirstLevel;", &sam_strFirstLevel); _pShell->DeclareSymbol("user CTString sam_strFirstLevel;", (void *) &sam_strFirstLevel);
// init game - this will load persistent symbols // init game - this will load persistent symbols
InitializeGame(); InitializeGame();
_pNetwork->md_strGameID = sam_strGameName; _pNetwork->md_strGameID = sam_strGameName;
LoadStringVar(CTString("Data\\Var\\Sam_Version.var"), _strSamVersion); LoadStringVar(CTString("Data\\Var\\Sam_Version.var"), _strSamVersion);
CPrintF(TRANS("Serious Sam version: %s\n"), _strSamVersion); CPrintF(TRANS("Serious Sam version: %s\n"), (const char *) _strSamVersion);
SetConsoleCtrlHandler(HandlerRoutine, TRUE); #if (defined PLATFORM_WIN32)
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#elif (defined PLATFORM_UNIX)
signal(SIGINT, unix_signal_catcher);
signal(SIGHUP, unix_signal_catcher);
signal(SIGQUIT, unix_signal_catcher);
signal(SIGTERM, unix_signal_catcher);
#endif
// if there is a mod // if there is a mod
if (_fnmMod!="") { if (_fnmMod!="") {
@ -269,8 +311,8 @@ void RoundBegin(void)
{ {
// repeat generate script names // repeat generate script names
FOREVER { FOREVER {
strBegScript.PrintF("%s%d_begin.ini", ded_strConfig, iRound); strBegScript.PrintF("%s%d_begin.ini", (const char *) ded_strConfig, iRound);
strEndScript.PrintF("%s%d_end.ini", ded_strConfig, iRound); strEndScript.PrintF("%s%d_end.ini", (const char *) ded_strConfig, iRound);
// if start script exists // if start script exists
if (FileExists(strBegScript)) { if (FileExists(strBegScript)) {
// stop searching // stop searching
@ -303,7 +345,7 @@ void RoundBegin(void)
_bHadPlayers = 0; _bHadPlayers = 0;
_bRestart = 0; _bRestart = 0;
DisableLoadingHook(); DisableLoadingHook();
_tvLastLevelEnd = CTimerValue(-1i64); _tvLastLevelEnd = CTimerValue((__int64) -1);
CPrintF(TRANS("\nALL OK: Dedicated server is now running!\n")); CPrintF(TRANS("\nALL OK: Dedicated server is now running!\n"));
CPrintF(TRANS("Use Ctrl+C to shutdown the server.\n")); CPrintF(TRANS("Use Ctrl+C to shutdown the server.\n"));
CPrintF(TRANS("DO NOT use the 'Close' button, it might leave the port hanging!\n\n")); CPrintF(TRANS("DO NOT use the 'Close' button, it might leave the port hanging!\n\n"));
@ -317,7 +359,7 @@ void ForceNextMap(void)
_bHadPlayers = 0; _bHadPlayers = 0;
_bRestart = 0; _bRestart = 0;
DisableLoadingHook(); DisableLoadingHook();
_tvLastLevelEnd = CTimerValue(-1i64); _tvLastLevelEnd = CTimerValue((__int64) -1);
} }
void RoundEnd(void) void RoundEnd(void)
@ -331,6 +373,10 @@ void RoundEnd(void)
// do the main game loop and render screen // do the main game loop and render screen
void DoGame(void) void DoGame(void)
{ {
#ifdef SINGLE_THREADED
_pTimer->HandleTimerHandlers();
#endif
// do the main game loop // do the main game loop
if( _pGame->gm_bGameOn) { if( _pGame->gm_bGameOn) {
_pGame->GameMainLoop(); _pGame->GameMainLoop();

View File

@ -5,7 +5,7 @@
#include <Engine/Templates/Stock_CModelData.h> #include <Engine/Templates/Stock_CModelData.h>
#include <GameMP/Game.h> #include <GameMP/Game.h>
/* rcg10042001 protect against Visual C-isms. */ // rcg10042001 protect against Visual C-isms.
#ifdef _MSC_VER #ifdef _MSC_VER
#define DECL_DLL _declspec(dllimport) #define DECL_DLL _declspec(dllimport)
#endif #endif
@ -18,6 +18,8 @@
#include <EntitiesMP/Global.h> #include <EntitiesMP/Global.h>
#include <EntitiesMP/Common/Common.h> #include <EntitiesMP/Common/Common.h>
#include <EntitiesMP/Common/GameInterface.h> #include <EntitiesMP/Common/GameInterface.h>
#include <EntitiesMP/WorldLink.h> // rcg10072001 needed enum definition.
#include <EntitiesMP/Player.h> #include <EntitiesMP/Player.h>
#undef DECL_DLL #undef DECL_DLL

View File

@ -427,18 +427,21 @@ void CDependencyList::ExtractTranslations_t( const CTFileName &fnTranslations)
// for each byte in file // for each byte in file
for(INDEX iByte=0; iByte<slSize-4; iByte++) { for(INDEX iByte=0; iByte<slSize-4; iByte++) {
UBYTE *pub = pubFile+iByte; UBYTE *pub = pubFile+iByte;
ULONG *pul = (ULONG*)pub; ULONG ul = *((ULONG*)pub);
BYTESWAP(ul);
// if exe translatable string is here // if exe translatable string is here
if (*pul=='SRTE') { if (ul=='SRTE') {
// get it // get it
CTString str = (char*)(pub+4); CTString str = (char*)(pub+4);
// add it // add it
AddStringForTranslation(str); AddStringForTranslation(str);
// if data translatable string is here // if data translatable string is here
} else if (*pul=='SRTD') { } else if (ul=='SRTD') {
char achr[ 256]; char achr[ 256];
INDEX iStrLen = *(INDEX *)(pub + 4); INDEX iStrLen = *(INDEX *)(pub + 4);
BYTESWAP(iStrLen);
if( iStrLen > 254 || iStrLen<0) { if( iStrLen > 254 || iStrLen<0) {
continue; continue;
} }
@ -449,7 +452,7 @@ void CDependencyList::ExtractTranslations_t( const CTFileName &fnTranslations)
// add it // add it
AddStringForTranslation(str); AddStringForTranslation(str);
// if text translatable string is here // if text translatable string is here
} else if (*pul=='SRTT') { } else if (ul=='SRTT') {
// after describing long and one space we will find file name // after describing long and one space we will find file name
char *pchrStart = (char*)pub + 4 + 1; char *pchrStart = (char*)pub + 4 + 1;

View File

@ -45,7 +45,7 @@ void SubMain( int argc, char *argv[])
} }
// initialize engine // initialize engine
SE_InitEngine(""); SE_InitEngine(argv[0], "");
// get application path from cmd line // get application path from cmd line
_fnmApplicationPath = CTString(ACHR_APP_DIR); _fnmApplicationPath = CTString(ACHR_APP_DIR);
// if not ending with backslash // if not ending with backslash

View File

@ -3,6 +3,13 @@
#include "Ecc/StdH.h" #include "Ecc/StdH.h"
#include "Ecc/Main.h" #include "Ecc/Main.h"
// turn off over-helpful bit of bison... --ryan.
#ifdef __GNUC__
#define __attribute__(x)
#endif
#define YYINITDEPTH 1000
static char *_strCurrentClass; static char *_strCurrentClass;
static int _iCurrentClassID; static int _iCurrentClassID;
static char *_strCurrentBase; static char *_strCurrentBase;
@ -125,7 +132,7 @@ void CreateInternalHandlerFunction(char *strFunctionName, char *strID)
void DeclareFeatureProperties(void) void DeclareFeatureProperties(void)
{ {
if (_bFeature_CanBePredictable) { if (_bFeature_CanBePredictable) {
fprintf(_fTables, " CEntityProperty(CEntityProperty::EPT_ENTITYPTR, NULL, (0x%08x<<8)+%s, offsetof(%s, %s), %s, %s, %s, %s),\n", fprintf(_fTables, " CEntityProperty(CEntityProperty::EPT_ENTITYPTR, NULL, (0x%08x<<8)+%s, _offsetof(%s, %s), %s, %s, %s, %s),\n",
_iCurrentClassID, _iCurrentClassID,
"255", "255",
_strCurrentClass, _strCurrentClass,
@ -142,7 +149,7 @@ void DeclareFeatureProperties(void)
} }
} }
#undef YYERROR_VERBOSE #define YYERROR_VERBOSE 1
%} %}
@ -584,7 +591,7 @@ empty_property_declaration_list
property_declaration property_declaration
: property_id property_type property_identifier property_wed_name_opt property_default_opt property_flags_opt { : property_id property_type property_identifier property_wed_name_opt property_default_opt property_flags_opt {
fprintf(_fTables, " CEntityProperty(%s, %s, (0x%08x<<8)+%s, offsetof(%s, %s), %s, %s, %s, %s),\n", fprintf(_fTables, " CEntityProperty(%s, %s, (0x%08x<<8)+%s, _offsetof(%s, %s), %s, %s, %s, %s),\n",
_strCurrentPropertyPropertyType, _strCurrentPropertyPropertyType,
_strCurrentPropertyEnumType, _strCurrentPropertyEnumType,
_iCurrentClassID, _iCurrentClassID,

View File

@ -4,10 +4,13 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <malloc.h>
#include <stdarg.h> #include <stdarg.h>
#include <math.h> #include <math.h>
#if !PLATFORM_MACOSX
#include <malloc.h>
#endif
#ifdef PLATFORM_UNIX #ifdef PLATFORM_UNIX
#include <errno.h> #include <errno.h>
#include <sys/param.h> #include <sys/param.h>

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include <Engine/StdH.h>
#include <Engine/Base/Anim.h> #include <Engine/Base/Anim.h>
@ -17,7 +17,8 @@
/* /*
* One animation of an animateable object * One animation of an animateable object
*/ */
class COneAnim { class COneAnim
{
public: public:
COneAnim(); COneAnim();
~COneAnim(); ~COneAnim();
@ -61,20 +62,20 @@ CTmpListHead::~CTmpListHead()
{ {
FORDELETELIST(COneAnimNode, coan_Node, *this, it) FORDELETELIST(COneAnimNode, coan_Node, *this, it)
delete &it.Current(); delete &it.Current();
}; }
// Remember ptr to animation and add this node at the end of given animation list // Remember ptr to animation and add this node at the end of given animation list
COneAnimNode::COneAnimNode(COneAnim *AnimToInsert, CListHead *LH) COneAnimNode::COneAnimNode(COneAnim *AnimToInsert, CListHead *LH)
{ {
coan_OneAnim = AnimToInsert; coan_OneAnim = AnimToInsert;
LH->AddTail( coan_Node); LH->AddTail( coan_Node);
}; }
// Constructor sets invalid data // Constructor sets invalid data
COneAnim::COneAnim() COneAnim::COneAnim()
{ {
oa_FrameIndices = NULL; oa_FrameIndices = NULL;
}; }
// Free allocated frame indices array for this animation // Free allocated frame indices array for this animation
COneAnim::~COneAnim() COneAnim::~COneAnim()
@ -82,7 +83,7 @@ COneAnim::~COneAnim()
ASSERT(oa_FrameIndices != NULL); ASSERT(oa_FrameIndices != NULL);
FreeMemory( oa_FrameIndices); FreeMemory( oa_FrameIndices);
oa_FrameIndices = NULL; oa_FrameIndices = NULL;
}; }
/* /*
* Copy constructor. * Copy constructor.
@ -113,18 +114,18 @@ CFileNameNode::CFileNameNode(const char *NewFileName, CListHead *LH)
ASSERT(strlen(NewFileName)>0); ASSERT(strlen(NewFileName)>0);
strcpy( cfnn_FileName, NewFileName); strcpy( cfnn_FileName, NewFileName);
LH->AddTail( cfnn_Node); LH->AddTail( cfnn_Node);
}; }
CAnimData::CAnimData() CAnimData::CAnimData()
{ {
ad_Anims = NULL; ad_Anims = NULL;
ad_NumberOfAnims = 0; ad_NumberOfAnims = 0;
}; }
CAnimData::~CAnimData() CAnimData::~CAnimData()
{ {
Clear(); Clear();
}; }
void CAnimData::Clear() void CAnimData::Clear()
{ {
@ -135,7 +136,7 @@ void CAnimData::Clear()
// clear serial object // clear serial object
CSerial::Clear(); CSerial::Clear();
}; }
// get amount of memory used by this object // get amount of memory used by this object
SLONG CAnimData::GetUsedMemory(void) SLONG CAnimData::GetUsedMemory(void)
@ -157,19 +158,24 @@ BOOL CAnimData::IsAutoFreed(void)
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// Reference counting functions // Reference counting functions
void CAnimData::AddReference(void) { void CAnimData::AddReference(void)
{
if (this!=NULL) { if (this!=NULL) {
MarkUsed(); MarkUsed();
} }
}; }
void CAnimData::RemReference(void) {
void CAnimData::RemReference(void)
{
if (this!=NULL) { if (this!=NULL) {
RemReference_internal(); RemReference_internal();
} }
}; }
void CAnimData::RemReference_internal(void) {
void CAnimData::RemReference_internal(void)
{
_pAnimStock->Release(this); _pAnimStock->Release(this);
}; }
// creates given number of default animations (1 frame, given name and speed) // creates given number of default animations (1 frame, given name and speed)
void CAnimData::CreateAnimations( INDEX ctAnimations, CTString strName/*="None"*/, void CAnimData::CreateAnimations( INDEX ctAnimations, CTString strName/*="None"*/,
@ -228,7 +234,7 @@ void CAnimData::DefaultAnimation()
ad_Anims->oa_NumberOfFrames = 1; ad_Anims->oa_NumberOfFrames = 1;
ad_Anims->oa_FrameIndices = (INDEX *) AllocMemory( sizeof(INDEX)); ad_Anims->oa_FrameIndices = (INDEX *) AllocMemory( sizeof(INDEX));
ad_Anims->oa_FrameIndices[0] = 0; ad_Anims->oa_FrameIndices[0] = 0;
}; }
// Returns index of given frame name in global frame names list. If it is not found // Returns index of given frame name in global frame names list. If it is not found
// new CFileNameObject is added into frames list // new CFileNameObject is added into frames list
@ -243,7 +249,7 @@ INDEX FindFrameIndex( CListHead *pFrameFileList, const char *pFileName)
} }
new CFileNameNode( pFileName, pFrameFileList); new CFileNameNode( pFileName, pFrameFileList);
return( i); return( i);
}; }
CTString GetFrameFileName( CListHead *pFrameFileList, INDEX iMemberInList) CTString GetFrameFileName( CListHead *pFrameFileList, INDEX iMemberInList)
{ {
@ -306,8 +312,11 @@ void CAnimData::LoadFromScript_t( CTStream *File, CListHead *pFrameFileList) //
// if it is not yet there // if it is not yet there
else if( EQUAL_SUB_STR( "DIRECTORY")) else if( EQUAL_SUB_STR( "DIRECTORY"))
{ {
_strupr( ld_line); // !!! FIXME : rcg10092001 You can't uppercase filenames!
sscanf( ld_line, "DIRECTORY %s", base_path); //_strupr( ld_line);
sscanf( ld_line, "DIRECTORY %s", base_path);
// !!! FIXME : rcg10092001 Use CFileSystem::GetDirSeparator().
if( base_path[ strlen( base_path) - 1] != '\\') if( base_path[ strlen( base_path) - 1] != '\\')
strcat( base_path,"\\"); strcat( base_path,"\\");
} }
@ -430,7 +439,7 @@ void CAnimData::LoadFromScript_t( CTStream *File, CListHead *pFrameFileList) //
FORDELETELIST( COneAnimNode, coan_Node, TempAnimationList, litDel) FORDELETELIST( COneAnimNode, coan_Node, TempAnimationList, litDel)
delete &litDel.Current(); delete &litDel.Current();
}; }
void CAnimData::Write_t( CTStream *ostrFile) // throw char * void CAnimData::Write_t( CTStream *ostrFile) // throw char *
{ {
@ -448,7 +457,7 @@ void CAnimData::Write_t( CTStream *ostrFile) // throw char *
ostrFile->Write_t( ad_Anims[i].oa_FrameIndices, ostrFile->Write_t( ad_Anims[i].oa_FrameIndices,
ad_Anims[i].oa_NumberOfFrames * sizeof( INDEX)); ad_Anims[i].oa_NumberOfFrames * sizeof( INDEX));
} }
}; }
// print #define <animation name> lines for all animations into given file // print #define <animation name> lines for all animations into given file
void CAnimData::ExportAnimationNames_t( CTStream *ostrFile, CTString strAnimationPrefix) // throw char * void CAnimData::ExportAnimationNames_t( CTStream *ostrFile, CTString strAnimationPrefix) // throw char *
@ -458,7 +467,7 @@ void CAnimData::ExportAnimationNames_t( CTStream *ostrFile, CTString strAnimatio
for( INDEX iAnimation=0; iAnimation<ad_NumberOfAnims; iAnimation++) for( INDEX iAnimation=0; iAnimation<ad_NumberOfAnims; iAnimation++)
{ {
// prepare one #define line (add prefix) // prepare one #define line (add prefix)
sprintf( chrLine, "#define %s%s %d", strAnimationPrefix, ad_Anims[ iAnimation].oa_Name, sprintf( chrLine, "#define %s%s %d", (const char *) strAnimationPrefix, ad_Anims[ iAnimation].oa_Name,
iAnimation); iAnimation);
// put it into file // put it into file
ostrFile->PutLine_t( chrLine); ostrFile->PutLine_t( chrLine);
@ -500,22 +509,37 @@ void CAnimData::AddAnimation(void)
} }
// replaces requested animation's name with given one // replaces requested animation's name with given one
void CAnimData::SetName( INDEX iAnimation, CTString strNewName){ void CAnimData::SetName( INDEX iAnimation, CTString strNewName)
{
ASSERT(strlen(strNewName)<NAME_SIZE); ASSERT(strlen(strNewName)<NAME_SIZE);
strcpy( ad_Anims[iAnimation].oa_Name, strNewName);}; strcpy( ad_Anims[iAnimation].oa_Name, strNewName);
}
// replaces requested animation's speed with given one // replaces requested animation's speed with given one
void CAnimData::SetSpeed( INDEX iAnimation, TIME tmSpeed){ void CAnimData::SetSpeed( INDEX iAnimation, TIME tmSpeed)
ad_Anims[iAnimation].oa_SecsPerFrame = tmSpeed;}; {
ad_Anims[iAnimation].oa_SecsPerFrame = tmSpeed;
}
// obtains frame index for given place in array representing given animation // obtains frame index for given place in array representing given animation
INDEX CAnimData::GetFrame( INDEX iAnimation, INDEX iFramePlace) { INDEX CAnimData::GetFrame( INDEX iAnimation, INDEX iFramePlace)
{
ASSERT( iFramePlace<ad_Anims[iAnimation].oa_NumberOfFrames); ASSERT( iFramePlace<ad_Anims[iAnimation].oa_NumberOfFrames);
return ad_Anims[iAnimation].oa_FrameIndices[iFramePlace];}; return ad_Anims[iAnimation].oa_FrameIndices[iFramePlace];
}
// sets frame index for given place in array representing given animation // sets frame index for given place in array representing given animation
void CAnimData::SetFrame( INDEX iAnimation, INDEX iFramePlace, INDEX iNewFrame) { void CAnimData::SetFrame( INDEX iAnimation, INDEX iFramePlace, INDEX iNewFrame)
{
ASSERT( iFramePlace<ad_Anims[iAnimation].oa_NumberOfFrames); ASSERT( iFramePlace<ad_Anims[iAnimation].oa_NumberOfFrames);
ad_Anims[iAnimation].oa_FrameIndices[iFramePlace] = iNewFrame;}; ad_Anims[iAnimation].oa_FrameIndices[iFramePlace] = iNewFrame;
}
/* Get number of animations. */ /* Get number of animations. */
INDEX CAnimData::GetAnimsCt(void) const {return ad_NumberOfAnims;}; INDEX CAnimData::GetAnimsCt(void) const
{
return ad_NumberOfAnims;
}
// Delete animation // Delete animation
void CAnimData::DeleteAnimation(INDEX iAnim) void CAnimData::DeleteAnimation(INDEX iAnim)
@ -549,20 +573,20 @@ void CAnimData::Read_t( CTStream *istrFile) // throw char *
// First we recognize main ID // First we recognize main ID
istrFile->ExpectID_t( CChunkID( "ADAT")); istrFile->ExpectID_t( CChunkID( "ADAT"));
// Then we load and create number of animations // Then we load and create number of animations
istrFile->Read_t( &ad_NumberOfAnims, sizeof( INDEX)); (*istrFile)>>ad_NumberOfAnims;
ad_Anims = new COneAnim[ ad_NumberOfAnims]; ad_Anims = new COneAnim[ ad_NumberOfAnims];
for( i=0; i<ad_NumberOfAnims; i++) for( i=0; i<ad_NumberOfAnims; i++)
{ {
// Next block reads and allocates all data for one animation // Next block reads and allocates all data for one animation
istrFile->Read_t( &ad_Anims[i].oa_Name, sizeof( NAME)); istrFile->Read_t(ad_Anims[i].oa_Name, sizeof (ad_Anims[i].oa_Name)); // char[32]
istrFile->Read_t( &ad_Anims[i].oa_SecsPerFrame, sizeof( TIME)); (*istrFile)>>ad_Anims[i].oa_SecsPerFrame;
istrFile->Read_t( &ad_Anims[i].oa_NumberOfFrames, sizeof( INDEX)); (*istrFile)>>ad_Anims[i].oa_NumberOfFrames;
ad_Anims[i].oa_FrameIndices = (INDEX *) ad_Anims[i].oa_FrameIndices = (INDEX *)
AllocMemory( ad_Anims[i].oa_NumberOfFrames * sizeof( INDEX)); AllocMemory( ad_Anims[i].oa_NumberOfFrames * sizeof( INDEX));
istrFile->Read_t( ad_Anims[i].oa_FrameIndices, for (SLONG j = 0; j < ad_Anims[i].oa_NumberOfFrames; j++)
ad_Anims[i].oa_NumberOfFrames * sizeof( INDEX)); (*istrFile)>>ad_Anims[i].oa_FrameIndices[j];
} }
}; }
/* /*
* Default constructor. * Default constructor.
@ -575,13 +599,13 @@ CAnimObject::CAnimObject(void)
ao_iCurrentAnim = -1; ao_iCurrentAnim = -1;
ao_iLastAnim = -1; ao_iLastAnim = -1;
ao_ulFlags = AOF_PAUSED; ao_ulFlags = AOF_PAUSED;
}; }
/* Destructor. */ /* Destructor. */
CAnimObject::~CAnimObject(void) CAnimObject::~CAnimObject(void)
{ {
ao_AnimData->RemReference(); ao_AnimData->RemReference();
}; }
// copy from another object of same class // copy from another object of same class
ENGINE_API void CAnimObject::Copy(CAnimObject &aoOther) ENGINE_API void CAnimObject::Copy(CAnimObject &aoOther)
@ -604,7 +628,7 @@ ENGINE_API void CAnimObject::Synchronize(CAnimObject &aoOther)
} }
/* /*
* Get animation's lenght. * Get animation's length.
*/ */
FLOAT CAnimObject::GetAnimLength(INDEX iAnim) const FLOAT CAnimObject::GetAnimLength(INDEX iAnim) const
{ {
@ -616,7 +640,7 @@ FLOAT CAnimObject::GetAnimLength(INDEX iAnim) const
ASSERT( (iAnim >= 0) && (iAnim < ao_AnimData->ad_NumberOfAnims) ); ASSERT( (iAnim >= 0) && (iAnim < ao_AnimData->ad_NumberOfAnims) );
COneAnim *pCOA = &ao_AnimData->ad_Anims[iAnim]; COneAnim *pCOA = &ao_AnimData->ad_Anims[iAnim];
return pCOA->oa_NumberOfFrames*pCOA->oa_SecsPerFrame; return pCOA->oa_NumberOfFrames*pCOA->oa_SecsPerFrame;
}; }
FLOAT CAnimObject::GetCurrentAnimLength(void) const FLOAT CAnimObject::GetCurrentAnimLength(void) const
{ {
@ -659,7 +683,8 @@ void CAnimObject::PauseAnim(void)
/* /*
* Continues paused animation * Continues paused animation
*/ */
void CAnimObject::ContinueAnim(void){ void CAnimObject::ContinueAnim(void)
{
if( !(ao_ulFlags&AOF_PAUSED)) return; if( !(ao_ulFlags&AOF_PAUSED)) return;
// calculate freezed frame index inside current animation (not in global list of frames!) // calculate freezed frame index inside current animation (not in global list of frames!)
COneAnim *pCOA = &ao_AnimData->ad_Anims[ao_iCurrentAnim]; COneAnim *pCOA = &ao_AnimData->ad_Anims[ao_iCurrentAnim];
@ -677,7 +702,8 @@ void CAnimObject::ContinueAnim(void){
/* /*
* Offsets the animation phase * Offsets the animation phase
*/ */
void CAnimObject::OffsetPhase(TIME tm){ void CAnimObject::OffsetPhase(TIME tm)
{
ao_tmAnimStart += tm; ao_tmAnimStart += tm;
} }
@ -685,19 +711,21 @@ void CAnimObject::OffsetPhase(TIME tm){
/* /*
* Loop anims forward * Loop anims forward
*/ */
void CAnimObject::NextAnim(){ void CAnimObject::NextAnim()
{
ASSERT( ao_iCurrentAnim != -1); ASSERT( ao_iCurrentAnim != -1);
ASSERT( ao_AnimData != NULL); ASSERT( ao_AnimData != NULL);
ao_iCurrentAnim = (ao_iCurrentAnim + 1) % ao_AnimData->ad_NumberOfAnims; ao_iCurrentAnim = (ao_iCurrentAnim + 1) % ao_AnimData->ad_NumberOfAnims;
ao_iLastAnim = ao_iCurrentAnim; ao_iLastAnim = ao_iCurrentAnim;
ao_tmAnimStart = _pTimer->CurrentTick(); ao_tmAnimStart = _pTimer->CurrentTick();
MarkChanged(); MarkChanged();
}; }
/* /*
* Loop anims backward * Loop anims backward
*/ */
void CAnimObject::PrevAnim(){ void CAnimObject::PrevAnim()
{
ASSERT( ao_iCurrentAnim != -1); ASSERT( ao_iCurrentAnim != -1);
ASSERT( ao_AnimData != NULL); ASSERT( ao_AnimData != NULL);
ao_iCurrentAnim = (ao_AnimData->ad_NumberOfAnims + ao_iCurrentAnim - 1) % ao_iCurrentAnim = (ao_AnimData->ad_NumberOfAnims + ao_iCurrentAnim - 1) %
@ -705,7 +733,7 @@ void CAnimObject::PrevAnim(){
ao_iLastAnim = ao_iCurrentAnim; ao_iLastAnim = ao_iCurrentAnim;
ao_tmAnimStart = _pTimer->CurrentTick(); ao_tmAnimStart = _pTimer->CurrentTick();
MarkChanged(); MarkChanged();
}; }
/* /*
* Selects frame for given time offset from animation start (0) * Selects frame for given time offset from animation start (0)
@ -730,31 +758,34 @@ void CAnimObject::LastFrame(void)
/* /*
* Loop frames forward * Loop frames forward
*/ */
void CAnimObject::NextFrame(){ void CAnimObject::NextFrame()
{
ASSERT( ao_iCurrentAnim != -1); ASSERT( ao_iCurrentAnim != -1);
ASSERT( ao_AnimData != NULL); ASSERT( ao_AnimData != NULL);
ASSERT( ao_ulFlags&AOF_PAUSED); ASSERT( ao_ulFlags&AOF_PAUSED);
ao_tmAnimStart += ao_AnimData->ad_Anims[ ao_iCurrentAnim].oa_SecsPerFrame; ao_tmAnimStart += ao_AnimData->ad_Anims[ ao_iCurrentAnim].oa_SecsPerFrame;
MarkChanged(); MarkChanged();
}; }
/* /*
* Loop frames backward * Loop frames backward
*/ */
void CAnimObject::PrevFrame(){ void CAnimObject::PrevFrame()
{
ASSERT( ao_iCurrentAnim != -1); ASSERT( ao_iCurrentAnim != -1);
ASSERT( ao_AnimData != NULL); ASSERT( ao_AnimData != NULL);
ASSERT( ao_ulFlags&AOF_PAUSED); ASSERT( ao_ulFlags&AOF_PAUSED);
ao_tmAnimStart -= ao_AnimData->ad_Anims[ ao_iCurrentAnim].oa_SecsPerFrame; ao_tmAnimStart -= ao_AnimData->ad_Anims[ ao_iCurrentAnim].oa_SecsPerFrame;
MarkChanged(); MarkChanged();
}; }
/* /*
* Retrieves paused flag * Retrieves paused flag
*/ */
BOOL CAnimObject::IsPaused(){ BOOL CAnimObject::IsPaused()
{
return ao_ulFlags&AOF_PAUSED; return ao_ulFlags&AOF_PAUSED;
}; }
/* /*
* Test if some updateable object is up to date with this anim object. * Test if some updateable object is up to date with this anim object.
@ -773,7 +804,8 @@ BOOL CAnimObject::IsUpToDate(const CUpdateable &ud) const
/* /*
* Attach data to this object. * Attach data to this object.
*/ */
void CAnimObject::SetData(CAnimData *pAD) { void CAnimObject::SetData(CAnimData *pAD)
{
// mark new data as referenced once more // mark new data as referenced once more
pAD->AddReference(); pAD->AddReference();
// mark old data as referenced once less // mark old data as referenced once less
@ -809,7 +841,8 @@ void CAnimObject::SetData_t(const CTFileName &fnmAnim) // throw char *
/* /*
* Sets new animation (but doesn't starts it). * Sets new animation (but doesn't starts it).
*/ */
void CAnimObject::SetAnim(INDEX iNew) { void CAnimObject::SetAnim(INDEX iNew)
{
if(ao_AnimData == NULL) return; if(ao_AnimData == NULL) return;
// clamp animation // clamp animation
if( iNew >= GetAnimsCt() ) if( iNew >= GetAnimsCt() )
@ -826,18 +859,19 @@ void CAnimObject::SetAnim(INDEX iNew) {
ao_iLastAnim=iNew; ao_iLastAnim=iNew;
// mark that something has changed // mark that something has changed
MarkChanged(); MarkChanged();
}; }
/* /*
* Start new animation. * Start new animation.
*/ */
void CAnimObject::StartAnim(INDEX iNew) { void CAnimObject::StartAnim(INDEX iNew)
{
if(ao_AnimData == NULL) return; if(ao_AnimData == NULL) return;
// set new animation // set new animation
SetAnim( iNew); SetAnim( iNew);
// set pause off, looping on // set pause off, looping on
ao_ulFlags = AOF_LOOPING; ao_ulFlags = AOF_LOOPING;
}; }
/* Start playing an animation. */ /* Start playing an animation. */
void CAnimObject::PlayAnim(INDEX iNew, ULONG ulFlags) void CAnimObject::PlayAnim(INDEX iNew, ULONG ulFlags)
@ -887,7 +921,7 @@ void CAnimObject::PlayAnim(INDEX iNew, ULONG ulFlags)
// mark that something has changed // mark that something has changed
MarkChanged(); MarkChanged();
}; }
/* Seamlessly continue playing another animation from same point. */ /* Seamlessly continue playing another animation from same point. */
void CAnimObject::SwitchToAnim(INDEX iNew) void CAnimObject::SwitchToAnim(INDEX iNew)
@ -906,13 +940,14 @@ void CAnimObject::SwitchToAnim(INDEX iNew)
/* /*
* Reset anim (restart) * Reset anim (restart)
*/ */
void CAnimObject::ResetAnim() { void CAnimObject::ResetAnim()
{
if(ao_AnimData == NULL) return; if(ao_AnimData == NULL) return;
// remember starting time // remember starting time
ao_tmAnimStart = _pTimer->CurrentTick(); ao_tmAnimStart = _pTimer->CurrentTick();
// mark that something has changed // mark that something has changed
MarkChanged(); MarkChanged();
}; }
// Get info about some animation // Get info about some animation
void CAnimObject::GetAnimInfo(INDEX iAnimNo, CAnimInfo &aiInfo) const void CAnimObject::GetAnimInfo(INDEX iAnimNo, CAnimInfo &aiInfo) const
@ -989,14 +1024,13 @@ INDEX CAnimObject::GetAnimsCt(void) const
if(ao_AnimData == NULL) return 1; if(ao_AnimData == NULL) return 1;
ASSERT( ao_AnimData != NULL); ASSERT( ao_AnimData != NULL);
return( ao_AnimData->ad_NumberOfAnims); return( ao_AnimData->ad_NumberOfAnims);
}; }
// get index of current animation // get index of current animation
INDEX CAnimObject::GetAnim(void) const INDEX CAnimObject::GetAnim(void) const
{ {
return( ao_iCurrentAnim); return( ao_iCurrentAnim);
}; }
/* /*
* Gets the number of current frame. * Gets the number of current frame.
@ -1007,10 +1041,11 @@ INDEX CAnimObject::GetFrame(void) const
} }
/* Gets number of frames in current anim. */ /* Gets number of frames in current anim. */
INDEX CAnimObject::GetFramesInCurrentAnim(void) const { INDEX CAnimObject::GetFramesInCurrentAnim(void) const
{
ASSERT( ao_AnimData != NULL); ASSERT( ao_AnimData != NULL);
return ao_AnimData->ad_Anims[ao_iCurrentAnim].oa_NumberOfFrames; return ao_AnimData->ad_Anims[ao_iCurrentAnim].oa_NumberOfFrames;
}; }
/* /*
* Get information for linear interpolation beetween frames. * Get information for linear interpolation beetween frames.
@ -1070,23 +1105,23 @@ void CAnimObject::GetFrame( INDEX &iFrame0, INDEX &iFrame1, FLOAT &fRatio) const
void CAnimObject::Write_t( CTStream *pstr) // throw char * void CAnimObject::Write_t( CTStream *pstr) // throw char *
{ {
(*pstr).WriteID_t("ANOB"); (*pstr).WriteID_t("ANOB");
(*pstr).WriteRawChunk_t( &ao_tmAnimStart, sizeof( TIME)); (*pstr)<<ao_tmAnimStart;
(*pstr).WriteRawChunk_t( &ao_iCurrentAnim, sizeof( INDEX)); (*pstr)<<ao_iCurrentAnim;
(*pstr).WriteRawChunk_t( &ao_iLastAnim, sizeof( INDEX)); (*pstr)<<ao_iLastAnim;
(*pstr).WriteRawChunk_t( &ao_ulFlags, sizeof( INDEX)); (*pstr)<<ao_ulFlags;
}; }
void CAnimObject::Read_t( CTStream *pstr) // throw char * void CAnimObject::Read_t( CTStream *pstr) // throw char *
{ {
if ((*pstr).PeekID_t()==CChunkID("ANOB")) { if ((*pstr).PeekID_t()==CChunkID("ANOB")) {
(*pstr).ExpectID_t("ANOB"); (*pstr).ExpectID_t("ANOB");
(*pstr).ReadRawChunk_t( &ao_tmAnimStart, sizeof( TIME)); (*pstr)>>ao_tmAnimStart;
(*pstr).ReadRawChunk_t( &ao_iCurrentAnim, sizeof( INDEX)); (*pstr)>>ao_iCurrentAnim;
(*pstr).ReadRawChunk_t( &ao_iLastAnim, sizeof( INDEX)); (*pstr)>>ao_iLastAnim;
(*pstr).ReadRawChunk_t( &ao_ulFlags, sizeof( INDEX)); (*pstr)>>ao_ulFlags;
} else { } else {
(*pstr).ReadRawChunk_t( &ao_tmAnimStart, sizeof( TIME)); (*pstr)>>ao_tmAnimStart;
(*pstr).ReadRawChunk_t( &ao_iCurrentAnim, sizeof( INDEX)); (*pstr)>>ao_iCurrentAnim;
ao_iLastAnim = ao_iCurrentAnim; ao_iLastAnim = ao_iCurrentAnim;
ao_ulFlags = 0; ao_ulFlags = 0;
} }
@ -1101,4 +1136,5 @@ void CAnimObject::Read_t( CTStream *pstr) // throw char *
{ {
ao_iLastAnim = 0; ao_iLastAnim = 0;
} }
}; }

View File

@ -12,7 +12,11 @@
#define NAME_SIZE 32 #define NAME_SIZE 32
typedef char NAME[NAME_SIZE]; typedef char NAME[NAME_SIZE];
#define PATH_MAX 260
#if (!defined PATH_MAX)
#define PATH_MAX 260
#endif
typedef char FILE_NAME[PATH_MAX]; typedef char FILE_NAME[PATH_MAX];
/* /*

View File

@ -1,6 +1,7 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include "Engine/Base/CRC.h"
// Note: this CRC calculation algorithm, although originating from MSDN examples, // Note: this CRC calculation algorithm, although originating from MSDN examples,
// is in fact identical to the Adler32 used in ZIP's CRC calculation. // is in fact identical to the Adler32 used in ZIP's CRC calculation.

View File

@ -17,7 +17,7 @@ inline void CRC_AddBYTE( ULONG &ulCRC, UBYTE ub)
ulCRC = (ulCRC>>8)^crc_aulCRCTable[UBYTE(ulCRC)^ub]; ulCRC = (ulCRC>>8)^crc_aulCRCTable[UBYTE(ulCRC)^ub];
}; };
inline void CRC_AddWORD( ULONG &ulCRC, UBYTE uw) inline void CRC_AddWORD( ULONG &ulCRC, UWORD uw)
{ {
CRC_AddBYTE(ulCRC, UBYTE(uw>> 8)); CRC_AddBYTE(ulCRC, UBYTE(uw>> 8));
CRC_AddBYTE(ulCRC, UBYTE(uw>> 0)); CRC_AddBYTE(ulCRC, UBYTE(uw>> 0));

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "StdH.h" #include "Engine/StdH.h"
#include <Engine/Base/CRCTable.h> #include <Engine/Base/CRCTable.h>
#include <Engine/Base/FileName.h> #include <Engine/Base/FileName.h>
@ -48,7 +48,7 @@ extern BOOL FileMatchesList(CDynamicStackArray<CTFileName> &afnm, const CTFileNa
static CDynamicStackArray<CCRCEntry> _aceEntries; static CDynamicStackArray<CCRCEntry> _aceEntries;
static CNameTable_CCRCEntry _ntEntries; static CNameTable_CCRCEntry _ntEntries;
extern BOOL CRCT_bGatherCRCs = FALSE; // set while gathering CRCs of all loaded files BOOL CRCT_bGatherCRCs = FALSE; // set while gathering CRCs of all loaded files
// init CRC table // init CRC table
void CRCT_Init(void) void CRCT_Init(void)
@ -169,13 +169,14 @@ ULONG CRCT_MakeCRCForFiles_t(CTStream &strmFiles) // throw char *
// read the name // read the name
CTString strName; CTString strName;
strmFiles>>strName; strmFiles>>strName;
CTFileName fname = strName;
// try to find it in table // try to find it in table
CCRCEntry *pce = _ntEntries.Find(strName); CCRCEntry *pce = _ntEntries.Find(fname);
// if not there // if not there
if (pce==NULL) { if (pce==NULL) {
CRCT_AddFile_t(strName); CRCT_AddFile_t(fname);
// add it now // add it now
pce = _ntEntries.Find(strName); pce = _ntEntries.Find(fname);
} }
// add the crc // add the crc
CRC_AddLONG(ulCRC, pce->ce_ulCRC); CRC_AddLONG(ulCRC, pce->ce_ulCRC);

View File

@ -1,12 +1,15 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/CTString.h> #include <Engine/Base/CTString.h>
#include <Engine/Base/Memory.h> #include <Engine/Base/Memory.h>
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>
#include <Engine/Base/Console.h> #include <Engine/Base/Console.h>
#ifndef _MSC_VER
#include <stdio.h> // for vsscanf()
#endif
/* /*
* Equality comparison. * Equality comparison.
@ -456,6 +459,7 @@ INDEX CTString::PrintF(const char *strFormat, ...)
va_list arg; va_list arg;
va_start(arg, strFormat); va_start(arg, strFormat);
return VPrintF(strFormat, arg); return VPrintF(strFormat, arg);
va_end(arg);
} }
@ -491,8 +495,8 @@ INDEX CTString::VPrintF(const char *strFormat, va_list arg)
return iLen; return iLen;
} }
// !!! FIXME: maybe don't do this, and just use the vsscanf() version. --ryan.
#ifdef _MSC_VER
static void *psscanf = &sscanf; static void *psscanf = &sscanf;
// Scan formatted from a string // Scan formatted from a string
__declspec(naked) INDEX CTString::ScanF(const char *strFormat, ...) __declspec(naked) INDEX CTString::ScanF(const char *strFormat, ...)
@ -507,6 +511,20 @@ __declspec(naked) INDEX CTString::ScanF(const char *strFormat, ...)
} }
} }
#else
INDEX CTString::ScanF(const char *strFormat, ...)
{
INDEX retval;
va_list ap;
va_start(ap, strFormat);
retval = (INDEX) vsscanf((const char *) (*this), strFormat, ap);
va_end(ap);
return(retval);
}
#endif
// split string in two strings at specified position (char AT splitting position goes to str2) // split string in two strings at specified position (char AT splitting position goes to str2)
void CTString::Split( INDEX iPos, CTString &str1, CTString &str2) void CTString::Split( INDEX iPos, CTString &str1, CTString &str2)
@ -541,10 +559,10 @@ void CTString::DeleteChar( INDEX iPos)
if (ctChars==0) { if (ctChars==0) {
return; return;
} }
if( iPos>ctChars) iPos=ctChars; if( iPos>ctChars) iPos=ctChars - 1;
else if( iPos<0) iPos=0; else if( iPos<0) iPos=0;
// copy part of string // copy part of string
memmove( &str_String[iPos], &str_String[iPos+1], ctChars-iPos+1); memmove( &str_String[iPos], &str_String[iPos+1], ctChars-iPos);
// shrink memory used by string over deleted char // shrink memory used by string over deleted char
ShrinkMemory( (void**)&str_String, ctChars); ShrinkMemory( (void**)&str_String, ctChars);
} }
@ -630,7 +648,7 @@ void CTString::LoadVar(const class CTFileName &fnmFile)
str.Load_t(fnmFile); str.Load_t(fnmFile);
*this = str; *this = str;
} catch (char *strError) { } catch (char *strError) {
CPrintF(TRANS("Cannot load variable from '%s':\n%s\n"), (CTString&)fnmFile, strError); CPrintF(TRANS("Cannot load variable from '%s':\n%s\n"), (const char *) (CTString&)fnmFile, strError);
} }
} }
@ -639,7 +657,7 @@ void CTString::SaveVar(const class CTFileName &fnmFile)
try { try {
Save_t(fnmFile); Save_t(fnmFile);
} catch (char *strError) { } catch (char *strError) {
CPrintF(TRANS("Cannot save variable to '%s':\n%s\n"), (CTString&)fnmFile, strError); CPrintF(TRANS("Cannot save variable to '%s':\n%s\n"), (const char *) (CTString&)fnmFile, strError);
} }
} }

View File

@ -44,6 +44,7 @@ ENGINE_API CTString::CTString(INDEX iDummy, const char *strFormat, ...)
va_list arg; va_list arg;
va_start(arg, strFormat); va_start(arg, strFormat);
VPrintF(strFormat, arg); VPrintF(strFormat, arg);
va_end(arg);
} }
/* /*

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Changeable.h> #include <Engine/Base/Changeable.h>
#include <Engine/Base/ChangeableRT.h> #include <Engine/Base/ChangeableRT.h>

View File

@ -1,9 +1,9 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Console.h> #include <Engine/Base/Console.h>
#include <Engine/Base/Console_Internal.h> #include <Engine/Base/Console_internal.h>
#include <Engine/Base/Timer.h> #include <Engine/Base/Timer.h>
#include <Engine/Base/ErrorReporting.h> #include <Engine/Base/ErrorReporting.h>
@ -13,11 +13,11 @@
#include <Engine/Math/Functions.h> #include <Engine/Math/Functions.h>
extern CConsole *_pConsole = NULL; CConsole *_pConsole = NULL;
extern INDEX con_iLastLines; extern INDEX con_iLastLines;
extern BOOL con_bCapture = FALSE; BOOL con_bCapture = FALSE;
extern CTString con_strCapture = ""; CTString con_strCapture = "";
// Constructor. // Constructor.
@ -262,7 +262,7 @@ void CConsole::CloseLog(void)
} }
// Print formated text to the main console. // Print formated text to the main console.
extern void CPrintF(const char *strFormat, ...) void CPrintF(const char *strFormat, ...)
{ {
if (_pConsole==NULL) { if (_pConsole==NULL) {
return; return;
@ -272,6 +272,7 @@ extern void CPrintF(const char *strFormat, ...)
va_start(arg, strFormat); va_start(arg, strFormat);
CTString strBuffer; CTString strBuffer;
strBuffer.VPrintF(strFormat, arg); strBuffer.VPrintF(strFormat, arg);
va_end(arg);
// print it to the main console // print it to the main console
_pConsole->PutString(strBuffer); _pConsole->PutString(strBuffer);

View File

@ -1,11 +1,11 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>
#include <Engine/Base/FileName.h> #include <Engine/Base/FileName.h>
#include <Engine/Base/Unzip.h> #include <Engine/Base/Unzip.h>
#include <Engine/Base/FileSystem.h>
#include <Engine/Templates/DynamicStackArray.cpp> #include <Engine/Templates/DynamicStackArray.cpp>
#include <io.h>
extern CDynamicStackArray<CTFileName> _afnmBaseBrowseInc; extern CDynamicStackArray<CTFileName> _afnmBaseBrowseInc;
extern CDynamicStackArray<CTFileName> _afnmBaseBrowseExc; extern CDynamicStackArray<CTFileName> _afnmBaseBrowseExc;
@ -49,32 +49,33 @@ void FillDirList_internal(const CTFileName &fnmBasePath,
continue; continue;
} }
const char *dirsep = CFileSystem::GetDirSeparator();
// start listing the directory // start listing the directory
struct _finddata_t c_file; long hFile; CDynamicArray<CTString> *files;
hFile = _findfirst( (const char *)(fnmBasePath+fnmDir+"*"), &c_file ); files = _pFileSystem->FindFiles(fnmBasePath+fnmDir, "*");
int max = files->Count();
// for each file in the directory // for each file in the directory
for ( for (int i = 0; i < max; i++) {
BOOL bFileExists = hFile!=-1; const char *fname = (*files)[i];
bFileExists;
bFileExists = _findnext( hFile, &c_file )==0) {
// if dummy dir (this dir, parent dir, or any dir starting with '.') // if dummy dir (this dir, parent dir, or any dir starting with '.')
if (c_file.name[0]=='.') { if (_pFileSystem->IsDummyFile(fname)) {
// skip it // skip it
continue; continue;
} }
// get the file's filepath // get the file's filepath
CTFileName fnm = fnmDir+c_file.name; CTFileName fnm = fnmDir + fname;
// if it is a directory // if it is a directory
if (c_file.attrib&_A_SUBDIR) { if (_pFileSystem->IsDirectory(fnm)) {
// if recursive reading // if recursive reading
if (bRecursive) { if (bRecursive) {
// add it to the list of directories to search // add it to the list of directories to search
CDirToRead *pdrNew = new CDirToRead; CDirToRead *pdrNew = new CDirToRead;
pdrNew->dr_strDir = fnm+"\\"; pdrNew->dr_strDir = fnm + dirsep;
lhDirs.AddTail(pdrNew->dr_lnNode); lhDirs.AddTail(pdrNew->dr_lnNode);
} }
// if it matches the pattern // if it matches the pattern
@ -83,13 +84,15 @@ void FillDirList_internal(const CTFileName &fnmBasePath,
afnm.Push() = fnm; afnm.Push() = fnm;
} }
} }
delete files;
} }
} }
// make a list of all files in a directory // make a list of all files in a directory
ENGINE_API void MakeDirList( ENGINE_API void MakeDirList(
CDynamicStackArray<CTFileName> &afnmDir, const CTFileName &fnmDir, const CTString &strPattern, ULONG ulFlags) CDynamicStackArray<CTFileName> &afnmDir, const CTFileName &fnmDir, const CTFileName &fnmPattern, ULONG ulFlags)
{ {
afnmDir.PopAll(); afnmDir.PopAll();
BOOL bRecursive = ulFlags&DLI_RECURSIVE; BOOL bRecursive = ulFlags&DLI_RECURSIVE;
@ -99,17 +102,21 @@ ENGINE_API void MakeDirList(
CDynamicStackArray<CTFileName> afnm; CDynamicStackArray<CTFileName> afnm;
if (_fnmMod!="") { if (_fnmMod!="") {
FillDirList_internal(_fnmApplicationPath, afnm, fnmDir, strPattern, bRecursive, FillDirList_internal(_fnmUserDir, afnm, fnmDir, fnmPattern, bRecursive,
&_afnmBaseBrowseInc, &_afnmBaseBrowseExc);
FillDirList_internal(_fnmApplicationPath, afnm, fnmDir, fnmPattern, bRecursive,
&_afnmBaseBrowseInc, &_afnmBaseBrowseExc); &_afnmBaseBrowseInc, &_afnmBaseBrowseExc);
if (bSearchCD) { if (bSearchCD) {
FillDirList_internal(_fnmCDPath, afnm, fnmDir, strPattern, bRecursive, FillDirList_internal(_fnmCDPath, afnm, fnmDir, fnmPattern, bRecursive,
&_afnmBaseBrowseInc, &_afnmBaseBrowseExc); &_afnmBaseBrowseInc, &_afnmBaseBrowseExc);
} }
FillDirList_internal(_fnmApplicationPath+_fnmMod, afnm, fnmDir, strPattern, bRecursive, NULL, NULL); FillDirList_internal(_fnmUserDir+_fnmMod, afnm, fnmDir, fnmPattern, bRecursive, NULL, NULL);
FillDirList_internal(_fnmApplicationPath+_fnmMod, afnm, fnmDir, fnmPattern, bRecursive, NULL, NULL);
} else { } else {
FillDirList_internal(_fnmApplicationPath, afnm, fnmDir, strPattern, bRecursive, NULL, NULL); FillDirList_internal(_fnmUserDir, afnm, fnmDir, fnmPattern, bRecursive, NULL, NULL);
FillDirList_internal(_fnmApplicationPath, afnm, fnmDir, fnmPattern, bRecursive, NULL, NULL);
if (bSearchCD) { if (bSearchCD) {
FillDirList_internal(_fnmCDPath, afnm, fnmDir, strPattern, bRecursive, NULL, NULL); FillDirList_internal(_fnmCDPath, afnm, fnmDir, fnmPattern, bRecursive, NULL, NULL);
} }
} }
@ -131,7 +138,7 @@ ENGINE_API void MakeDirList(
} }
// if doesn't match pattern // if doesn't match pattern
if (strPattern!="" && !fnm.Matches(strPattern)) { if (fnmPattern!="" && !fnm.Matches(fnmPattern)) {
// skip it // skip it
continue; continue;
} }

View File

@ -0,0 +1,42 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#ifndef SE_INCL_DYNAMICLOADER_H
#define SE_INCL_DYNAMICLOADER_H
#ifdef PRAGMA_ONCE
#pragma once
#endif
/*
* This class handles DLL loading in a platform-abstracted manner.
*/
class ENGINE_API CDynamicLoader {
public:
// Construct a CDynamicLoader to handle symbol lookups in a shared lib.
// (libname) is a platform-independent filename. If you specify "game",
// then you get "Game.dll" on windows, and "libgame.so" on Linux.
// You should ALWAYS use lowercase, unless you know what you're doing.
static CDynamicLoader *GetInstance(const char *libname);
// Convert a win32 DLL path to a platform-specific equivalent.
// ("Bin\\Entities.dll" becomes "Bin/libEntities.so" on Linux, etc.)
static CTFileName ConvertLibNameToPlatform(const char *libname);
virtual ~CDynamicLoader(void) {}
// Lookup (sym) and return a pointer to it.
// Returns NULL on error/symbol not found.
virtual void *FindSymbol(const char *sym) = 0;
// return a human-readable error message. NULL if there's no error.
virtual const char *GetError(void) = 0;
protected:
// use GetInstance(), instead.
CDynamicLoader() {}
};
#endif
// end of DynamicLoader.h ...

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/ErrorReporting.h> #include <Engine/Base/ErrorReporting.h>
#include <Engine/Base/ErrorTable.h> #include <Engine/Base/ErrorTable.h>
@ -34,18 +34,21 @@ void FatalError(const char *strFormat, ...)
// (this is a low overhead and shouldn't allocate memory) // (this is a low overhead and shouldn't allocate memory)
CDS_ResetMode(); CDS_ResetMode();
#ifdef PLATFORM_WIN32
// hide fullscreen window if any // hide fullscreen window if any
if( _bFullScreen) { if( _bFullScreen) {
// must do minimize first - don't know why :( // must do minimize first - don't know why :(
ShowWindow( _hwndMain, SW_MINIMIZE); ShowWindow( _hwndMain, SW_MINIMIZE);
ShowWindow( _hwndMain, SW_HIDE); ShowWindow( _hwndMain, SW_HIDE);
} }
#endif
// format the message in buffer // format the message in buffer
va_list arg; va_list arg;
va_start(arg, strFormat); va_start(arg, strFormat);
CTString strBuffer; CTString strBuffer;
strBuffer.VPrintF(strFormat, arg); strBuffer.VPrintF(strFormat, arg);
va_end(arg);
if (_pConsole!=NULL) { if (_pConsole!=NULL) {
// print the buffer to the console // print the buffer to the console
@ -55,14 +58,20 @@ void FatalError(const char *strFormat, ...)
_pConsole->CloseLog(); _pConsole->CloseLog();
} }
#ifdef PLATFORM_WIN32
// create message box with just OK button // create message box with just OK button
MessageBoxA(NULL, strBuffer, TRANS("Fatal Error"), MessageBoxA(NULL, strBuffer, TRANS("Fatal Error"),
MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL); MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
_bInFatalError = FALSE;
extern void EnableWindowsKeys(void); extern void EnableWindowsKeys(void);
EnableWindowsKeys(); EnableWindowsKeys();
#else
// !!! FIXME : Use SDL2's SDL_ShowSimpleMessageBox().
// !!! FIXME : We should really SDL_Quit() here.
fprintf(stderr, "FATAL ERROR:\n \"%s\"\n\n", (const char *) strBuffer);
#endif
_bInFatalError = FALSE;
// exit program // exit program
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -77,13 +86,18 @@ void WarningMessage(const char *strFormat, ...)
va_start(arg, strFormat); va_start(arg, strFormat);
CTString strBuffer; CTString strBuffer;
strBuffer.VPrintF(strFormat, arg); strBuffer.VPrintF(strFormat, arg);
va_end(arg);
// print it to console // print it to console
CPrintF("%s\n", strBuffer); CPrintF("%s\n", (const char *) strBuffer);
// if warnings are enabled // if warnings are enabled
if( !con_bNoWarnings) { if( !con_bNoWarnings) {
// create message box // create message box
MessageBoxA(NULL, strBuffer, TRANS("Warning"), MB_OK|MB_ICONEXCLAMATION|MB_SETFOREGROUND|MB_TASKMODAL); #ifdef PLATFORM_WIN32
MessageBoxA(NULL, (const char *) strBuffer, TRANS("Warning"), MB_OK|MB_ICONEXCLAMATION|MB_SETFOREGROUND|MB_TASKMODAL);
#else // !!! FIXME: SDL_ShowSimpleMessageBox() in SDL2.
fprintf(stderr, "WARNING: \"%s\"\n", (const char *) strBuffer);
#endif
} }
} }
@ -94,11 +108,17 @@ void InfoMessage(const char *strFormat, ...)
va_start(arg, strFormat); va_start(arg, strFormat);
CTString strBuffer; CTString strBuffer;
strBuffer.VPrintF(strFormat, arg); strBuffer.VPrintF(strFormat, arg);
va_end(arg);
// print it to console // print it to console
CPrintF("%s\n", strBuffer); CPrintF("%s\n", (const char *) strBuffer);
// create message box // create message box
MessageBoxA(NULL, strBuffer, TRANS("Information"), MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND|MB_TASKMODAL); #ifdef PLATFORM_WIN32
MessageBoxA(NULL, (const char *) strBuffer, TRANS("Information"), MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND|MB_TASKMODAL);
#else // !!! FIXME: SDL_ShowSimpleMessageBox() in SDL2.
fprintf(stderr, "INFO: \"%s\"\n", (const char *) strBuffer);
#endif
} }
/* Ask user for yes/no answer(stops program until user responds). */ /* Ask user for yes/no answer(stops program until user responds). */
@ -109,11 +129,27 @@ BOOL YesNoMessage(const char *strFormat, ...)
va_start(arg, strFormat); va_start(arg, strFormat);
CTString strBuffer; CTString strBuffer;
strBuffer.VPrintF(strFormat, arg); strBuffer.VPrintF(strFormat, arg);
va_end(arg);
// print it to console // print it to console
CPrintF("%s\n", strBuffer); CPrintF("%s\n", (const char *) strBuffer);
// create message box // create message box
#ifdef PLATFORM_WIN32
return MessageBoxA(NULL, strBuffer, TRANS("Question"), MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_TASKMODAL)==IDYES; return MessageBoxA(NULL, strBuffer, TRANS("Question"), MB_YESNO|MB_ICONQUESTION|MB_SETFOREGROUND|MB_TASKMODAL)==IDYES;
#else
// !!! FIXME: SDL_messagebox
fprintf(stderr, "QUESTION: \"%s\" [y/n] : ", (const char *) strBuffer);
while (true)
{
int ch = fgetc(stdin);
if (ch == 'y')
return 1;
else if (ch == 'n')
return 0;
}
return 0;
#endif
} }
/* /*
@ -122,11 +158,18 @@ BOOL YesNoMessage(const char *strFormat, ...)
void ThrowF_t(char *strFormat, ...) // throws char * void ThrowF_t(char *strFormat, ...) // throws char *
{ {
const SLONG slBufferSize = 256; const SLONG slBufferSize = 256;
char strBuffer[slBufferSize+1]; //char strBuffer[slBufferSize+1]; // Can't throw from the stack like this!
static char *strBuffer = NULL;
// !!! FIXME: This could be dangerous if you call this in a catch handler...
delete[] strBuffer;
strBuffer = new char[slBufferSize+1];
// format the message in buffer // format the message in buffer
va_list arg; va_list arg;
va_start(arg, strFormat); // variable arguments start after this argument va_start(arg, strFormat); // variable arguments start after this argument
_vsnprintf(strBuffer, slBufferSize, strFormat, arg); _vsnprintf(strBuffer, slBufferSize, strFormat, arg);
va_end(arg);
throw strBuffer; throw strBuffer;
} }
@ -161,7 +204,8 @@ void ThrowF_t(char *strFormat, ...) // throws char *
*/ */
extern const CTString GetWindowsError(DWORD dwWindowsErrorCode) extern const CTString GetWindowsError(DWORD dwWindowsErrorCode)
{ {
// buffer to receive error description #ifdef PLATFORM_WIN32
// buffer to recieve error description
LPVOID lpMsgBuf; LPVOID lpMsgBuf;
// call function that will prepare text abount given windows error code // call function that will prepare text abount given windows error code
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
@ -172,10 +216,23 @@ void ThrowF_t(char *strFormat, ...) // throws char *
// Free the buffer. // Free the buffer.
LocalFree( lpMsgBuf ); LocalFree( lpMsgBuf );
return strResultMessage; return strResultMessage;
#else
CTString retval = "This isn't Windows, so calling this function is probably a portability bug.";
return(retval);
#endif
} }
// must be in separate function to disable stupid optimizer // must be in separate function to disable stupid optimizer
extern void Breakpoint(void) extern void Breakpoint(void)
{ {
#if (defined USE_PORTABLE_C)
raise(SIGTRAP); // This may not work everywhere. Good luck.
#elif (defined __MSVC_INLINE__)
__asm int 0x03; __asm int 0x03;
#elif (defined __GNU_INLINE__)
__asm__ __volatile__ ("int $3\n\t");
#else
#error Please define something for your platform.
#endif
} }

View File

@ -1,18 +1,105 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/FileName.h> #include <Engine/Base/FileName.h>
#include <Engine/Base/ErrorReporting.h> #include <Engine/Base/ErrorReporting.h>
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>
#include <Engine/Base/FileSystem.h>
#include <Engine/Templates/NameTable_CTFileName.h> #include <Engine/Templates/NameTable_CTFileName.h>
#include <Engine/Templates/DynamicStackArray.cpp> #include <Engine/Templates/DynamicStackArray.cpp>
template CDynamicArray<CTFileName>; template class CDynamicArray<CTFileName>;
template CDynamicStackArray<CTFileName>; template class CDynamicStackArray<CTFileName>;
#include <Engine/Templates/StaticStackArray.cpp> #include <Engine/Templates/StaticStackArray.cpp>
template CStaticStackArray<long>; template class CStaticStackArray<long>;
const char *CTFileName::convertFromWin32(const char *src)
{
#if (defined PLATFORM_WIN32)
return(src);
#else
static const char *dirsep = NULL;
static size_t seplen = 0;
static char buf[MAX_PATH]; // This is NOT thread safe, fyi.
char *dest = buf;
if (src == NULL)
{
buf[0] = '\0';
return(buf);
}
if (dirsep == NULL)
{
dirsep = CFileSystem::GetDirSeparator();
seplen = strlen(dirsep);
}
for (dest = buf; *src != '\0'; src++)
{
if (*src == '\\')
{
strcpy(dest, dirsep);
dest += seplen;
}
else
{
*(dest++) = *src;
}
}
*dest = '\0';
return(buf);
#endif
}
const char *CTFileName::convertToWin32(const char *src)
{
#if (defined PLATFORM_WIN32)
return(src);
#else
static const char *dirsep = NULL;
static size_t seplen = 0;
static char buf[MAX_PATH]; // This is NOT thread safe, fyi.
char *dest = buf;
if (src == NULL)
{
buf[0] = '\0';
return(buf);
}
if (dirsep == NULL)
{
dirsep = CFileSystem::GetDirSeparator();
seplen = strlen(dirsep);
}
for (dest = buf; *src != '\0'; src++)
{
if ((*src == *dirsep) && (strncmp(src, dirsep, seplen) == 0))
{
*(dest++) = '\\';
src += (seplen - 1);
}
else
{
*(dest++) = *src;
}
}
*dest = '\0';
return(buf);
#endif
}
#define USE_ABSTRACT_CTFILENAME 1
/* /*
* Get directory part of a filename. * Get directory part of a filename.
@ -24,14 +111,32 @@ CTFileName CTFileName::FileDir() const
// make a temporary copy of string // make a temporary copy of string
CTFileName strPath(*this); CTFileName strPath(*this);
// find last backlash in it // find last backlash in it
char *pPathBackSlash = strrchr( strPath.str_String, '\\');
#ifdef USE_ABSTRACT_CTFILENAME
const char *dirsep = CFileSystem::GetDirSeparator();
char *pPathBackSlash = strstr( strPath.str_String, dirsep);
// if there is no backslash // if there is no backslash
if( pPathBackSlash == NULL) { if( pPathBackSlash == NULL) {
// return emptystring as directory // return emptystring as directory
return( CTFileName("")); return( CTFileName(""));
} }
for (char *p = pPathBackSlash;
(p = strstr(p + 1, dirsep)) != NULL;
pPathBackSlash = p)
{
// (*yawn*).
}
// set end of string after where the backslash was // set end of string after where the backslash was
pPathBackSlash[strlen(dirsep)] = 0;
#else
char *pPathBackSlash = strrchr( strPath.str_String, '\\');
pPathBackSlash[1] = 0; pPathBackSlash[1] = 0;
#endif
// return a copy of temporary string // return a copy of temporary string
return( CTFileName( strPath)); return( CTFileName( strPath));
} }
@ -51,23 +156,50 @@ CTFileName CTFileName::FileName() const
// make a temporary copy of string // make a temporary copy of string
CTFileName strPath(*this); CTFileName strPath(*this);
// find last backlash in what's left
#ifdef USE_ABSTRACT_CTFILENAME
const char *dirsep = CFileSystem::GetDirSeparator();
char *pBackSlash = strstr( strPath.str_String, dirsep);
// if there is no backslash
if( pBackSlash == NULL) {
// return it all as filename
pBackSlash = strPath.str_String;
} else {
for (char *p = pBackSlash;
(p = strstr(p + 1, dirsep)) != NULL;
pBackSlash = p)
{
// (*yawn*).
}
pBackSlash += strlen(dirsep);
}
// find last dot in it // find last dot in it
char *pDot = strrchr( strPath.str_String, '.'); char *pDot = strrchr(pBackSlash, '.');
// if there is a dot // if there is a dot
if( pDot != NULL) { if( pDot != NULL) {
// set end of string there // set end of string there
pDot[0] = 0; *pDot = '\0';
} }
// find last backlash in what's left // return a copy of temporary string, starting after the backslash
return( CTFileName( pBackSlash ));
#else
char *pBackSlash = strrchr( strPath.str_String, '\\'); char *pBackSlash = strrchr( strPath.str_String, '\\');
// if there is no backslash // if there is no backslash
if( pBackSlash == NULL) { if( pBackSlash == NULL) {
// return it all as filename // return it all as filename
return( CTFileName(strPath)); return( CTFileName(strPath));
} }
// return a copy of temporary string, starting after the backslash // return a copy of temporary string, starting after the backslash
return( CTFileName( pBackSlash+1)); return( CTFileName( pBackSlash+1));
#endif
} }
/* /*
@ -93,88 +225,22 @@ CTFileName CTFileName::NoExt() const
return FileDir()+FileName(); return FileDir()+FileName();
} }
static INDEX GetSlashPosition(const CHAR* pszString)
{
for (INDEX iPos = 0; '\0' != *pszString; ++iPos, ++pszString) {
if (('\\' == *pszString) || ('/' == *pszString)) {
return iPos;
}
}
return -1;
}
/* /*
* Set path to the absolute path, taking \.. and /.. into account. * Remove application path from a file name.
*/ */
void CTFileName::SetAbsolutePath(void) void CTFileName::RemoveApplicationPath_t(void) // throws char *
{ {
// Collect path parts
CTString strRemaining(*this);
CStaticStackArray<CTString> astrParts;
INDEX iSlashPos = GetSlashPosition(strRemaining);
if (0 > iSlashPos) {
return; // Invalid path
}
for (;;) {
CTString &strBeforeSlash = astrParts.Push();
CTString strAfterSlash;
strRemaining.Split(iSlashPos, strBeforeSlash, strAfterSlash);
strAfterSlash.TrimLeft(strAfterSlash.Length() - 1);
strRemaining = strAfterSlash;
iSlashPos = GetSlashPosition(strRemaining);
if (0 > iSlashPos) {
astrParts.Push() = strRemaining;
break;
}
}
// Remove certain path parts
for (INDEX iPart = 0; iPart < astrParts.Count(); ++iPart) {
if (CTString("..") != astrParts[iPart]) {
continue;
}
if (0 == iPart) {
return; // Invalid path
}
// Remove ordered
CStaticStackArray<CTString> astrShrinked;
astrShrinked.Push(astrParts.Count() - 2);
astrShrinked.PopAll();
for (INDEX iCopiedPart = 0; iCopiedPart < astrParts.Count(); ++iCopiedPart) {
if ((iCopiedPart != iPart - 1) && (iCopiedPart != iPart)) {
astrShrinked.Push() = astrParts[iCopiedPart];
}
}
astrParts.MoveArray(astrShrinked);
iPart -= 2;
}
// Set new content
strRemaining.Clear();
for (INDEX iPart = 0; iPart < astrParts.Count(); ++iPart) {
strRemaining += astrParts[iPart];
if (iPart < astrParts.Count() - 1) {
#ifdef PLATFORM_WIN32
strRemaining += CTString("\\");
#else
strRemaining += CTString("/");
#endif
}
}
(*this) = strRemaining;
}
/*
* Remove application path from a file name and returns TRUE if it's a relative path.
*/
BOOL CTFileName::RemoveApplicationPath_t(void) // throws char *
{
CTFileName fnmApp = _fnmApplicationPath;
fnmApp.SetAbsolutePath();
// remove the path string from beginning of the string // remove the path string from beginning of the string
BOOL bIsRelative = RemovePrefix(fnmApp); BOOL bHadRightPath = RemovePrefix(_fnmApplicationPath);
if (_fnmMod!="") { if (_fnmMod!="") {
RemovePrefix(_fnmApplicationPath+_fnmMod); RemovePrefix(_fnmApplicationPath+_fnmMod);
} }
return bIsRelative; // if it had wrong path
if (!bHadRightPath) {
// throw error
ThrowF_t(TRANS("File '%s' has got wrong path!\nAll files must reside in directory '%s'."),
str_String, (const char *) (CTString&)_fnmApplicationPath);
}
} }
/* /*
@ -195,8 +261,16 @@ BOOL CTFileName::RemoveApplicationPath_t(void) // throws char *
char strTag[] = "_FNM"; strTag[0] = 'D'; // must create tag at run-time! char strTag[] = "_FNM"; strTag[0] = 'D'; // must create tag at run-time!
// skip dependency catcher header // skip dependency catcher header
strmStream.ExpectID_t(strTag); // data filename strmStream.ExpectID_t(strTag); // data filename
// read the string // read the string
#ifdef PLATFORM_WIN32
strmStream>>(CTString &)fnmFileName; strmStream>>(CTString &)fnmFileName;
#else
CTString ctstr;
strmStream>>ctstr;
fnmFileName = CTString(CTFileName::convertFromWin32(ctstr)); // converts from win32 paths.
#endif
fnmFileName.fnm_pserPreloaded = NULL; fnmFileName.fnm_pserPreloaded = NULL;
} }
@ -228,12 +302,24 @@ BOOL CTFileName::RemoveApplicationPath_t(void) // throws char *
// write dependency catcher header // write dependency catcher header
strmStream.WriteID_t(strTag); // data filename strmStream.WriteID_t(strTag); // data filename
// write the string // write the string
#ifdef PLATFORM_WIN32
strmStream<<(CTString &)fnmFileName; strmStream<<(CTString &)fnmFileName;
#else
strmStream<<CTString(CTFileName::convertToWin32(fnmFileName));
#endif
} }
return strmStream; return strmStream;
} }
// rcg01062002
CTString CTFileName::Win32FmtString(void) const
{
return(CTString(convertToWin32(*this)));
}
void CTFileName::ReadFromText_t(CTStream &strmStream, void CTFileName::ReadFromText_t(CTStream &strmStream,
const CTString &strKeyword) // throw char * const CTString &strKeyword) // throw char *
{ {

View File

@ -13,25 +13,32 @@
*/ */
class ENGINE_API CTFileName : public CTString { class ENGINE_API CTFileName : public CTString {
public: public:
static const char *convertFromWin32(const char *str);
static const char *convertToWin32(const char *src);
class CSerial *fnm_pserPreloaded; // pointer to already loaded object if available class CSerial *fnm_pserPreloaded; // pointer to already loaded object if available
private: private:
/* Constructor from character string. */ /* Constructor from character string. */
inline CTFileName(const char *pString) : CTString(pString), fnm_pserPreloaded(NULL) {}; inline CTFileName(const char *pString) : CTString(convertFromWin32(pString)), fnm_pserPreloaded(NULL) {}
public: public:
/* Default constructor. */ /* Default constructor. */
inline CTFileName(void) : fnm_pserPreloaded(NULL) {}; inline CTFileName(void) : fnm_pserPreloaded(NULL) {};
/* Copy constructor. */ /* Copy constructor. */
inline CTFileName(const CTString &strOriginal) : CTString(strOriginal), fnm_pserPreloaded(NULL) {}; inline CTFileName(const CTString &strOriginal) : CTString(convertFromWin32(strOriginal)), fnm_pserPreloaded(NULL) {}
/* Constructor from character string for insertion in exe-file. */ /* Constructor from character string for insertion in exe-file. */
inline CTFileName(const char *pString, int i) : CTString(pString+i), fnm_pserPreloaded(NULL) {}; inline CTFileName(const char *pString, int i) : CTString(convertFromWin32(pString+i)), fnm_pserPreloaded(NULL) {}
/* Assignment. */ /* Assignment. */
CTFileName &operator=(const char *strCharString); CTFileName &operator=(const char *strCharString);
inline void operator=(const CTString &strOther) { inline void operator=(const CTString &strOther) {
CTString::operator=(strOther); CTString::operator=(convertFromWin32(strOther));
fnm_pserPreloaded = NULL; fnm_pserPreloaded = NULL;
}; };
/* Get CTString with win32-style dir separators for string compares. */
CTString Win32FmtString(void) const;
/* Get directory part of a filename. */ /* Get directory part of a filename. */
CTFileName FileDir(void) const; CTFileName FileDir(void) const;
/* Get name part of a filename. */ /* Get name part of a filename. */
@ -40,10 +47,8 @@ public:
CTFileName FileExt(void) const; CTFileName FileExt(void) const;
/* Get path and file name without extension. */ /* Get path and file name without extension. */
CTFileName NoExt(void) const; CTFileName NoExt(void) const;
/* Set path to the absolute path, taking \.. and /.. into account. */
void SetAbsolutePath(void);
/* Remove application path from a file name. */ /* Remove application path from a file name. */
BOOL RemoveApplicationPath_t(void); // throw char * void RemoveApplicationPath_t(void); // throw char *
// filename is its own name (used for storing in nametable) // filename is its own name (used for storing in nametable)
inline const CTFileName &GetName(void) { return *this; }; inline const CTFileName &GetName(void) { return *this; };

View File

@ -0,0 +1,74 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#ifndef SE_INCL_FILESYSTEM_H
#define SE_INCL_FILESYSTEM_H
#ifdef PRAGMA_ONCE
#pragma once
#endif
#include <Engine/Engine.h>
// !!! FIXME: rcg10142001 This should really be using CTStrings...
/*
* This class handles filesystem differences between platforms.
*/
class ENGINE_API CFileSystem {
public:
// Construct a system-dependent version of CFileSystem.
// (argv0) is argv[0] in your mainline.
// gamename is a simple token that identifies your game.
static CFileSystem *GetInstance(const char *argv0, const char *gamename);
virtual ~CFileSystem(void) {}
// Get the platform-specific directory separator. This could be
// "\\" on win32, "/" on unix, and ":" on MacOS Classic.
// Consider the returned pointer to be READ ONLY, as it points to a
// static, internal literal string on most platforms.
// Some platforms may define a dir separator that is MORE THAN ONE
// CHARACTER LONG. You have been warned.
static const char *GetDirSeparator(void);
// Returns TRUE if (fname) is not a real file ("." and ".." on win32, etc.)
// THIS DOES NOT CHECK IF A SPECIFIC FILE EXISTS IN THE FILESYSTEM!
static BOOL IsDummyFile(const char *fname);
// Returns TRUE if (fname) exists at all. May be a symlink, dir, file, etc.
static BOOL Exists(const char *fname);
// Returns TRUE if (fname) is a directory.
static BOOL IsDirectory(const char *fname);
// Get the path of the binary (.EXE file) being run.
// (buf) is where to store the info, and (bufSize) is the size, in bytes,
// of what's pointed to by (buf). The buffer is always promised to be
// null-terminated.
virtual void GetExecutablePath(char *buf, ULONG bufSize) = 0;
// Get the user directory. This is the user's home directory on systems
// with that concept, and the base (buf) is where to store the info, and
// (bufSize) is the size, in bytes, of what's pointed to by (buf). The
// buffer is always promised to be null-terminated, and, if there's room,
// with have a trailing dir separator. It is likely that you will have
// write permission in the user directory tree, and will NOT have write
// permission in the base directory. You have been warned.
virtual void GetUserDirectory(char *buf, ULONG bufSize) = 0;
// Get an array of CTStrings containing the names of files in (dir) that
// match (wildcard).
virtual CDynamicArray<CTString> *FindFiles(const char *dir,
const char *wildcard) = 0;
protected:
// use GetInstance(), instead.
CFileSystem() {}
};
ENGINE_API extern CFileSystem *_pFileSystem;
#endif
// end of FileSystem.h ...

View File

@ -1,14 +1,20 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/IFeel.h> #include <Engine/Base/IFeel.h>
#include <Engine/Base/FileName.h> #include <Engine/Base/FileName.h>
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>
#include <Engine/Base/Console.h> #include <Engine/Base/Console.h>
#include <Engine/Base/Shell.h> #include <Engine/Base/Shell.h>
#include <Engine/Base/DynamicLoader.h>
// rcg12122001 Moved this over to the CDynamicLoader abstraction, even though
// this is somewhat win32-specific. Hey, you never know; maybe a Linux
// version will show up, so we might as well leave the IFeel interface
// in place...
//Imm_GetProductName //Imm_GetProductName
HINSTANCE _hLib = NULL; CDynamicLoader *_hLib = NULL;
BOOL (*immCreateDevice)(HINSTANCE &hInstance, HWND &hWnd) = NULL; BOOL (*immCreateDevice)(HINSTANCE &hInstance, HWND &hWnd) = NULL;
void (*immDeleteDevice)(void) = NULL; void (*immDeleteDevice)(void) = NULL;
BOOL (*immProductName)(char *strProduct,int iMaxCount) = NULL; BOOL (*immProductName)(char *strProduct,int iMaxCount) = NULL;
@ -86,16 +92,16 @@ CTString IFeel_GetProjectFileName()
if(strProduct == strDeviceName) return strProjectFile; if(strProduct == strDeviceName) return strProjectFile;
} }
// device was not found, return default project file // device was not found, return default project file
CPrintF("No project file specified for device '%s'.\nUsing default project file\n",strProduct); CPrintF("No project file specified for device '%s'.\nUsing default project file\n", (const char *) strProduct);
return strDefaultProjectFile; return strDefaultProjectFile;
} }
// inits imm ifeel device // inits imm ifeel device
BOOL IFeel_InitDevice(HINSTANCE &hInstance, HWND &hWnd) BOOL IFeel_InitDevice(HINSTANCE &hInstance, HWND &hWnd)
{ {
_pShell->DeclareSymbol("void inp_IFeelGainChange(INDEX);", &ifeel_GainChange); _pShell->DeclareSymbol("void inp_IFeelGainChange(INDEX);", (void *) &ifeel_GainChange);
_pShell->DeclareSymbol("persistent user FLOAT inp_fIFeelGain post:inp_IFeelGainChange;", &ifeel_fGain); _pShell->DeclareSymbol("persistent user FLOAT inp_fIFeelGain post:inp_IFeelGainChange;", (void *) &ifeel_fGain);
_pShell->DeclareSymbol("const user INDEX sys_bIFeelEnabled;", &ifeel_bEnabled); _pShell->DeclareSymbol("const user INDEX sys_bIFeelEnabled;", (void *) &ifeel_bEnabled);
IFeel_ChangeGain(ifeel_fGain); IFeel_ChangeGain(ifeel_fGain);
// load iFeel lib // load iFeel lib
@ -103,24 +109,34 @@ BOOL IFeel_InitDevice(HINSTANCE &hInstance, HWND &hWnd)
ExpandFilePath(EFP_READ | EFP_NOZIPS,(CTString)IFEEL_DLL_NAME,fnmExpanded); ExpandFilePath(EFP_READ | EFP_NOZIPS,(CTString)IFEEL_DLL_NAME,fnmExpanded);
if(_hLib!=NULL) return FALSE; if(_hLib!=NULL) return FALSE;
#ifdef PLATFORM_WIN32
UINT iOldErrorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS); UINT iOldErrorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
_hLib = LoadLibraryA(fnmExpanded); #endif
_hLib = CDynamicLoader::GetInstance(fnmExpanded);
#ifdef PLATFORM_WIN32
SetErrorMode(iOldErrorMode); SetErrorMode(iOldErrorMode);
if(_hLib==NULL) #endif
const char *err = _hLib->GetError();
if (err != NULL)
{ {
CPrintF("Error loading ImmWraper.dll.\n\tIFeel disabled\n"); CPrintF("Error loading ImmWraper.dll.\n\tIFeel disabled\nError: %s\n", err);
delete _hLib;
_hLib = NULL;
return FALSE; return FALSE;
} }
// take func pointers // take func pointers
immCreateDevice = (BOOL(*)(HINSTANCE &hInstance, HWND &hWnd)) GetProcAddress(_hLib,"Imm_CreateDevice"); immCreateDevice = (BOOL(*)(HINSTANCE &hInstance, HWND &hWnd)) _hLib->FindSymbol("Imm_CreateDevice");
immDeleteDevice = (void(*)(void)) GetProcAddress(_hLib,"Imm_DeleteDevice"); immDeleteDevice = (void(*)(void)) _hLib->FindSymbol("Imm_DeleteDevice");
immProductName = (BOOL(*)(char *strProduct,int iMaxCount)) GetProcAddress(_hLib,"Imm_GetProductName"); immProductName = (BOOL(*)(char *strProduct,int iMaxCount)) _hLib->FindSymbol("Imm_GetProductName");
immLoadFile = (BOOL(*)(const char *fnFile))GetProcAddress(_hLib,"Imm_LoadFile"); immLoadFile = (BOOL(*)(const char *fnFile))_hLib->FindSymbol("Imm_LoadFile");
immUnloadFile = (void(*)(void))GetProcAddress(_hLib,"immUnloadFile"); immUnloadFile = (void(*)(void))_hLib->FindSymbol("immUnloadFile");
immPlayEffect = (void(*)(const char *pstrEffectName))GetProcAddress(_hLib,"Imm_PlayEffect"); immPlayEffect = (void(*)(const char *pstrEffectName))_hLib->FindSymbol("Imm_PlayEffect");
immStopEffect = (void(*)(const char *pstrEffectName))GetProcAddress(_hLib,"Imm_StopEffect"); immStopEffect = (void(*)(const char *pstrEffectName))_hLib->FindSymbol("Imm_StopEffect");
immChangeGain = (void(*)(const float fGain))GetProcAddress(_hLib,"Imm_ChangeGain"); immChangeGain = (void(*)(const float fGain))_hLib->FindSymbol("Imm_ChangeGain");
// create device // create device
if(immCreateDevice == NULL) if(immCreateDevice == NULL)
@ -151,7 +167,7 @@ void IFeel_DeleteDevice()
immStopEffect = NULL; immStopEffect = NULL;
immChangeGain = NULL; immChangeGain = NULL;
if(_hLib != NULL) FreeLibrary(_hLib); if(_hLib != NULL) delete _hLib;
_hLib = NULL; _hLib = NULL;
} }
// loads project file // loads project file
@ -165,12 +181,12 @@ BOOL IFeel_LoadFile(CTFileName fnFile)
BOOL hr = immLoadFile((const char*)fnmExpanded); BOOL hr = immLoadFile((const char*)fnmExpanded);
if(hr) if(hr)
{ {
CPrintF("IFeel project file '%s' loaded\n", fnFile); CPrintF("IFeel project file '%s' loaded\n", (const char *) fnFile);
return TRUE; return TRUE;
} }
else else
{ {
CPrintF("Error loading IFeel project file '%s'\n", fnFile); CPrintF("Error loading IFeel project file '%s'\n", (const char *) fnFile);
return FALSE; return FALSE;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -117,6 +117,14 @@ public:
// Get given button's current state // Get given button's current state
inline BOOL GetButtonState( INDEX iButtonNo) const { inline BOOL GetButtonState( INDEX iButtonNo) const {
return (inp_ubButtonsBuffer[ iButtonNo] & 128) != 0;}; return (inp_ubButtonsBuffer[ iButtonNo] & 128) != 0;};
// rcg02042003 hack for SDL vs. Win32.
void ClearRelativeMouseMotion(void);
protected:
BOOL PlatformInit(void); /* rcg10072001 platform-specific construction */
BOOL PlatformSetKeyNames(void); /* rcg10072001 platform-specific code */
LONG PlatformGetJoystickCount(void); /* rcg11242001 platform-specific code */
}; };
// pointer to global input object // pointer to global input object

View File

@ -146,79 +146,6 @@
#define KID_2MOUSE2 0xD1 #define KID_2MOUSE2 0xD1
#define KID_2MOUSE3 0xD2 #define KID_2MOUSE3 0xD2
// Mouse device controls
#define CID_MOUSE_AXIS_XP 0
#define CID_MOUSE_AXIS_XN 1
#define CID_MOUSE_AXIS_YP 2
#define CID_MOUSE_AXIS_YN 3
#define CID_MOUSE_WHEEL_UP 4
#define CID_MOUSE_WHEEL_DOWN 5
#define CID_MOUSE_BUTTON1 6
#define CID_MOUSE_BUTTON2 7
#define CID_MOUSE_BUTTON3 8
#define CID_MOUSE_BUTTON4 9
#define CID_MOUSE_BUTTON5 10
// Second mouse device controls
#define CID_MOUSE2_AXIS_XP 0
#define CID_MOUSE2_AXIS_XN 1
#define CID_MOUSE2_AXIS_YP 2
#define CID_MOUSE2_AXIS_YN 3
#define CID_MOUSE2_BUTTON1 4
#define CID_MOUSE2_BUTTON2 5
#define CID_MOUSE2_BUTTON3 6
// Joystick controls
#define CID_JOY_AXIS_XP 0
#define CID_JOY_AXIS_XN 1
#define CID_JOY_AXIS_YP 2
#define CID_JOY_AXIS_YN 3
#define CID_JOY_AXIS_ZP 4
#define CID_JOY_AXIS_ZN 5
#define CID_JOY_AXIS_RP 6
#define CID_JOY_AXIS_RN 7
#define CID_JOY_AXIS_UP 8
#define CID_JOY_AXIS_UN 9
#define CID_JOY_AXIS_VP 10
#define CID_JOY_AXIS_VN 11
#define CID_JOY_BUTTON1 12
#define CID_JOY_BUTTON2 13
#define CID_JOY_BUTTON3 14
#define CID_JOY_BUTTON4 15
#define CID_JOY_BUTTON5 16
#define CID_JOY_BUTTON6 17
#define CID_JOY_BUTTON7 18
#define CID_JOY_BUTTON8 19
#define CID_JOY_BUTTON9 20
#define CID_JOY_BUTTON10 21
#define CID_JOY_BUTTON11 22
#define CID_JOY_BUTTON12 23
#define CID_JOY_BUTTON13 24
#define CID_JOY_BUTTON14 25
#define CID_JOY_BUTTON15 26
#define CID_JOY_BUTTON16 27
#define CID_JOY_BUTTON17 28
#define CID_JOY_BUTTON18 29
#define CID_JOY_BUTTON19 30
#define CID_JOY_BUTTON20 31
#define CID_JOY_BUTTON21 32
#define CID_JOY_BUTTON22 33
#define CID_JOY_BUTTON23 34
#define CID_JOY_BUTTON24 35
#define CID_JOY_BUTTON25 36
#define CID_JOY_BUTTON26 37
#define CID_JOY_BUTTON27 38
#define CID_JOY_BUTTON28 39
#define CID_JOY_BUTTON29 40
#define CID_JOY_BUTTON30 41
#define CID_JOY_BUTTON31 42
#define CID_JOY_BUTTON32 43
#define CID_JOY_POV_N 44
#define CID_JOY_POV_E 45
#define CID_JOY_POV_S 46
#define CID_JOY_POV_W 47
#endif /* include-once check. */ #endif /* include-once check. */

View File

@ -81,17 +81,17 @@ public:
// get the pointer to the first element in the list // get the pointer to the first element in the list
#define LIST_HEAD(listhead, baseclass, member) \ #define LIST_HEAD(listhead, baseclass, member) \
( (baseclass *) ( ((UBYTE *)(&(listhead).Head())) - offsetof(baseclass, member) ) ) ( (baseclass *) ( ((UBYTE *)(&(listhead).Head())) - _offsetof(baseclass, member) ) )
// get the pointer to the last element in the list // get the pointer to the last element in the list
#define LIST_TAIL(listhead, baseclass, member) \ #define LIST_TAIL(listhead, baseclass, member) \
( (baseclass *) ( ((UBYTE *)(&(listhead).Tail())) - offsetof(baseclass, member) ) ) ( (baseclass *) ( ((UBYTE *)(&(listhead).Tail())) - _offsetof(baseclass, member) ) )
// get the pointer to the predecessor of the element // get the pointer to the predecessor of the element
#define LIST_PRED(element, baseclass, member) \ #define LIST_PRED(element, baseclass, member) \
( (baseclass *) ( ((UBYTE *)(&(element).member.Pred())) - offsetof(baseclass, member) ) ) ( (baseclass *) ( ((UBYTE *)(&(element).member.Pred())) - _offsetof(baseclass, member) ) )
// get the pointer to the successor of the element // get the pointer to the successor of the element
#define LIST_SUCC(element, baseclass, member) \ #define LIST_SUCC(element, baseclass, member) \
( (baseclass *) ( ((UBYTE *)(&(element).member.Succ())) - offsetof(baseclass, member) ) ) ( (baseclass *) ( ((UBYTE *)(&(element).member.Succ())) - _offsetof(baseclass, member) ) )

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Lists.h> #include <Engine/Base/Lists.h>

View File

@ -1,15 +1,22 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Memory.h> #include <Engine/Base/Memory.h>
#include <Engine/Base/Translation.h> #include <Engine/Base/Translation.h>
#include <Engine/Base/ErrorReporting.h> #include <Engine/Base/ErrorReporting.h>
/* rcg10282005 "new.h" is deprecated in newer C++ standards... --ryan. */
#ifdef _MSC_VER
#include <new.h> #include <new.h>
#else
#include <new>
#endif
extern FLOAT _bCheckAllAllocations = FALSE; FLOAT _bCheckAllAllocations = FALSE;
#ifdef PLATFORM_WIN32
/* /*
* Declarations for setting up the 'new_handler'. * Declarations for setting up the 'new_handler'.
*/ */
@ -31,14 +38,25 @@ _CRTIMP _PNH __cdecl _set_new_handler( _PNH );*/
// include user32 library (because of message box) // include user32 library (because of message box)
#pragma comment (lib, "user32.lib") #pragma comment (lib, "user32.lib")
#endif
// if not enough memory // if not enough memory
#ifdef _MSC_VER
int NewHandler(size_t size) int NewHandler(size_t size)
{ {
// terminate program // terminate program
FatalError(TRANS("Not enough memory (%d bytes needed)!"), size); FatalError(TRANS("Not enough memory (%d bytes needed)!"), size);
return 0; return 0;
} }
#else
void NewHandler(void)
{
// terminate program
FatalError(TRANS("Not enough memory!"));
}
#define _CrtCheckMemory()
#endif
/* Static class used for initializing memory handlers. */ /* Static class used for initializing memory handlers. */
static class CMemHandlerInit { static class CMemHandlerInit {
@ -52,7 +70,9 @@ CMemHandlerInit::CMemHandlerInit(void)
// set our not-enough-memory handler // set our not-enough-memory handler
_set_new_handler(NewHandler); _set_new_handler(NewHandler);
// make malloc use that handler // make malloc use that handler
#ifdef _MSC_VER
_set_new_mode(1); _set_new_mode(1);
#endif
} }
#undef AllocMemory #undef AllocMemory
@ -73,6 +93,7 @@ void *AllocMemory( SLONG memsize )
return pmem; return pmem;
} }
#ifdef _MSC_VER
#ifndef NDEBUG #ifndef NDEBUG
void *_debug_AllocMemory( SLONG memsize, int iType, const char *strFile, int iLine) void *_debug_AllocMemory( SLONG memsize, int iType, const char *strFile, int iLine)
{ {
@ -91,6 +112,7 @@ void *_debug_AllocMemory( SLONG memsize, int iType, const char *strFile, int iLi
return pmem; return pmem;
} }
#endif #endif
#endif
void *AllocMemoryAligned( SLONG memsize, SLONG slAlignPow2) void *AllocMemoryAligned( SLONG memsize, SLONG slAlignPow2)
{ {

View File

@ -0,0 +1,21 @@
#include "Engine/StdH.h"
#include <Engine/Base/Synchronization.h>
#if (!defined SINGLE_THREADED)
#error you probably want to define SINGLE_THREADED if you compile this.
#endif
CTCriticalSection::CTCriticalSection(void) {}
CTCriticalSection::~CTCriticalSection(void) {}
INDEX CTCriticalSection::Lock(void) { return(1); }
INDEX CTCriticalSection::TryToLock(void) { return(1); }
INDEX CTCriticalSection::Unlock(void) { return(0); }
CTSingleLock::CTSingleLock(CTCriticalSection *pcs, BOOL bLock) : sl_cs(*pcs) {}
CTSingleLock::~CTSingleLock(void) {}
void CTSingleLock::Lock(void) {}
BOOL CTSingleLock::TryToLock(void) { return(TRUE); }
BOOL CTSingleLock::IsLocked(void) { return(TRUE); }
void CTSingleLock::Unlock(void) {}
// end of NullSynchronization.cpp ...

View File

@ -1,5 +1,5 @@
%{ %{
#include "StdH.h" #include <Engine/StdH.h>
#include <Engine/Base/Console.h> #include <Engine/Base/Console.h>
#include <Engine/Base/Shell.h> #include <Engine/Base/Shell.h>
@ -11,6 +11,11 @@
%} %}
%{ %{
// turn off over-helpful bit of bison... --ryan.
#ifdef __GNUC__
#define __attribute__(x)
#endif
#define YYERROR_VERBOSE 1 #define YYERROR_VERBOSE 1
// if error occurs in parsing // if error occurs in parsing
void yyerror(char *str) void yyerror(char *str)
@ -95,7 +100,7 @@ void Declaration(
if (!ShellTypeIsSame(ssNew.ss_istType, istType) || if (!ShellTypeIsSame(ssNew.ss_istType, istType) ||
((ssNew.ss_ulFlags&SSF_CONSTANT)!=(ulQualifiers&SSF_CONSTANT))) { ((ssNew.ss_ulFlags&SSF_CONSTANT)!=(ulQualifiers&SSF_CONSTANT))) {
// error // error
_pShell->ErrorF("Symbol '%s' is already declared diferrently", ssNew.ss_strName); _pShell->ErrorF("Symbol '%s' is already declared diferrently", (const char *) ssNew.ss_strName);
return; return;
} }
@ -112,7 +117,7 @@ void Declaration(
NOTHING; // function values are not retained NOTHING; // function values are not retained
} else { } else {
// error // error
_pShell->ErrorF("'%s': old value couldn't be retained", ssNew.ss_strName); _pShell->ErrorF("'%s': old value couldn't be retained", (const char *) ssNew.ss_strName);
return; return;
} }
} }
@ -331,7 +336,7 @@ pre_func_opt
||_shell_ast[_shell_ast[$3->ss_istType].st_istBaseType].st_sttType!=STT_INDEX ||_shell_ast[_shell_ast[$3->ss_istType].st_istBaseType].st_sttType!=STT_INDEX
||_shell_ast[$3->ss_istType].st_istFirstArgument!=_shell_ast[$3->ss_istType].st_istLastArgument ||_shell_ast[$3->ss_istType].st_istFirstArgument!=_shell_ast[$3->ss_istType].st_istLastArgument
||_shell_ast[_shell_ast[$3->ss_istType].st_istFirstArgument].st_sttType!=STT_INDEX) { ||_shell_ast[_shell_ast[$3->ss_istType].st_istFirstArgument].st_sttType!=STT_INDEX) {
_pShell->ErrorF("'%s' must return 'INDEX' and take 'INDEX' as input", $3->ss_strName); _pShell->ErrorF("'%s' must return 'INDEX' and take 'INDEX' as input", (const char *) $3->ss_strName);
} else { } else {
void *pv = $3->ss_pvValue; void *pv = $3->ss_pvValue;
$$ = (INDEX(*)(INDEX))$3->ss_pvValue; $$ = (INDEX(*)(INDEX))$3->ss_pvValue;
@ -347,7 +352,7 @@ post_func_opt
||_shell_ast[_shell_ast[$3->ss_istType].st_istBaseType].st_sttType!=STT_VOID ||_shell_ast[_shell_ast[$3->ss_istType].st_istBaseType].st_sttType!=STT_VOID
||_shell_ast[$3->ss_istType].st_istFirstArgument!=_shell_ast[$3->ss_istType].st_istLastArgument ||_shell_ast[$3->ss_istType].st_istFirstArgument!=_shell_ast[$3->ss_istType].st_istLastArgument
||_shell_ast[_shell_ast[$3->ss_istType].st_istFirstArgument].st_sttType!=STT_INDEX) { ||_shell_ast[_shell_ast[$3->ss_istType].st_istFirstArgument].st_sttType!=STT_INDEX) {
_pShell->ErrorF("'%s' must return 'void' and take 'INDEX' as input", $3->ss_strName); _pShell->ErrorF("'%s' must return 'void' and take 'INDEX' as input", (const char *) $3->ss_strName);
} else { } else {
$$ = (void(*)(INDEX))$3->ss_pvValue; $$ = (void(*)(INDEX))$3->ss_pvValue;
} }
@ -430,7 +435,7 @@ statement
| lvalue '=' expression ';' { | lvalue '=' expression ';' {
// if it is constant // if it is constant
if ($1.lv_pssSymbol->ss_ulFlags&SSF_CONSTANT) { if ($1.lv_pssSymbol->ss_ulFlags&SSF_CONSTANT) {
_pShell->ErrorF("Symbol '%s' is a constant", $1.lv_pssSymbol->ss_strName); _pShell->ErrorF("Symbol '%s' is a constant", (const char *) $1.lv_pssSymbol->ss_strName);
// if it is not constant // if it is not constant
} else { } else {
// if it can be changed // if it can be changed
@ -473,7 +478,7 @@ statement
// if it is constant // if it is constant
if (ssSymbol.ss_ulFlags&SSF_CONSTANT) { if (ssSymbol.ss_ulFlags&SSF_CONSTANT) {
// error // error
_pShell->ErrorF("Symbol '%s' is a constant", ssSymbol.ss_strName); _pShell->ErrorF("Symbol '%s' is a constant", (const char *) ssSymbol.ss_strName);
} }
// get symbol type // get symbol type
@ -496,7 +501,7 @@ statement
_pShell->ErrorF("Warning: assigning INDEX to FLOAT!"); _pShell->ErrorF("Warning: assigning INDEX to FLOAT!");
*(FLOAT*)ssSymbol.ss_pvValue = $5.iIndex; *(FLOAT*)ssSymbol.ss_pvValue = $5.iIndex;
} else { } else {
_pShell->ErrorF("Symbol '%s' and its initializer have different types", ssSymbol.ss_strName); _pShell->ErrorF("Symbol '%s' and its initializer have different types", (const char *) ssSymbol.ss_strName);
} }
} }
| k_help identifier { | k_help identifier {
@ -566,7 +571,7 @@ lvalue
$$.lv_pssSymbol = &ssSymbol; $$.lv_pssSymbol = &ssSymbol;
if (!ssSymbol.IsDeclared()) { if (!ssSymbol.IsDeclared()) {
// error // error
_pShell->ErrorF("Identifier '%s' is not declared", $1->ss_strName); _pShell->ErrorF("Identifier '%s' is not declared", (const char *) $1->ss_strName);
fDummy = -666; fDummy = -666;
$$.lv_sttType = STT_VOID; $$.lv_sttType = STT_VOID;
$$.lv_pvAddress = &fDummy; $$.lv_pvAddress = &fDummy;
@ -578,7 +583,7 @@ lvalue
// if the identifier is something else // if the identifier is something else
} else { } else {
// error // error
_pShell->ErrorF("'%s' doesn't have a value", $1->ss_strName); _pShell->ErrorF("'%s' doesn't have a value", (const char *) $1->ss_strName);
fDummy = -666.0f; fDummy = -666.0f;
$$.lv_sttType = STT_VOID; $$.lv_sttType = STT_VOID;
$$.lv_pvAddress = &fDummy; $$.lv_pvAddress = &fDummy;
@ -616,7 +621,7 @@ lvalue
} }
} }
} else { } else {
_pShell->ErrorF("'%s[]' doesn't have a value", $1->ss_strName); _pShell->ErrorF("'%s[]' doesn't have a value", (const char *) $1->ss_strName);
fDummy = -666.0f; fDummy = -666.0f;
$$.lv_pvAddress = &fDummy; $$.lv_pvAddress = &fDummy;
} }
@ -673,7 +678,7 @@ expression
} else { } else {
$$.sttType = STT_FLOAT; $$.sttType = STT_FLOAT;
$$.fFloat = -666.0f; $$.fFloat = -666.0f;
_pShell->ErrorF("'%s' is of wrong type", $1.lv_pssSymbol->ss_strName); _pShell->ErrorF("'%s' is of wrong type", (const char *) $1.lv_pssSymbol->ss_strName);
} }
} }
/* shift */ /* shift */
@ -975,7 +980,7 @@ expression
// if the identifier is not declared // if the identifier is not declared
if (!$1->IsDeclared()) { if (!$1->IsDeclared()) {
// error // error
_pShell->ErrorF("Identifier '%s' is not declared", $1->ss_strName); _pShell->ErrorF("Identifier '%s' is not declared", (const char *) $1->ss_strName);
// if the identifier is declared // if the identifier is declared
} else { } else {
// get its type // get its type
@ -989,52 +994,76 @@ expression
_shell_ast[_shell_ast[$3.istType].st_istBaseType].st_sttType = stResult.st_sttType; _shell_ast[_shell_ast[$3.istType].st_istBaseType].st_sttType = stResult.st_sttType;
// if types are same // if types are same
if (ShellTypeIsSame($3.istType, $1->ss_istType)) { if (ShellTypeIsSame($3.istType, $1->ss_istType)) {
bool callfunc = true;
#define PUSHPARAMS \ // !!! FIXME: maybe just dump the win32 codepath here? This will break on Win64, and maybe break on different compilers/compiler versions, etc.
memcpy(_alloca($3.ctBytes), _ubStack+_iStack-$3.ctBytes, $3.ctBytes); #ifdef PLATFORM_WIN32
#define CALLPARAMS
// if void #define FUNCSIG void
if (stResult.st_sttType==STT_VOID) { #define PUSHPARAMS memcpy(_alloca($3.ctBytes), _ubStack+_iStack-$3.ctBytes, $3.ctBytes);
// just call the function #else
$$.sttType = STT_VOID; // This is possibly more portable, but no less scary than the alloca hack.
//PUSHPARAMS; #define MAXSCRIPTFUNCARGS 5
((void (*)(void*))$1->ss_pvValue)(_ubStack+_iStack-$3.ctBytes); void *ARG[MAXSCRIPTFUNCARGS];
// if index if (($3.ctBytes > sizeof (ARG)))
} else if (stResult.st_sttType==STT_INDEX) { {
// call the function and return result _pShell->ErrorF("Function '%s' has too many arguments!", (const char *) $1->ss_strName);
$$.sttType = STT_INDEX; callfunc = false;
PUSHPARAMS; }
$$.iIndex = ((INDEX (*)(void))$1->ss_pvValue)(); else
// if float {
} else if (stResult.st_sttType==STT_FLOAT) { memcpy(ARG, _ubStack+_iStack-$3.ctBytes, $3.ctBytes);
// call the function and return result memset(((char *) ARG) + $3.ctBytes, '\0', sizeof (ARG) - $3.ctBytes);
$$.sttType = STT_FLOAT; }
PUSHPARAMS; #define PUSHPARAMS
$$.fFloat = ((FLOAT (*)(void))$1->ss_pvValue)(); #define FUNCSIG void*, void*, void*, void*, void*
// if string #define CALLPARAMS ARG[0], ARG[1], ARG[2], ARG[3], ARG[4]
} else if (stResult.st_sttType==STT_STRING) { #endif
// call the function and return result
$$.sttType = STT_STRING; if (callfunc) {
CTString &strNew = _shell_astrTempStrings.Push(); // if void
PUSHPARAMS; if (stResult.st_sttType==STT_VOID) {
strNew = ((CTString (*)(void))$1->ss_pvValue)(); // just call the function
$$.strString = (const char*)strNew; $$.sttType = STT_VOID;
} else { PUSHPARAMS;
ASSERT(FALSE); ((void (*)(FUNCSIG))$1->ss_pvValue)(CALLPARAMS);
$$.sttType = STT_FLOAT; // if index
$$.fFloat = -666.0f; } else if (stResult.st_sttType==STT_INDEX) {
// call the function and return result
$$.sttType = STT_INDEX;
PUSHPARAMS;
$$.iIndex = ((INDEX (*)(FUNCSIG))$1->ss_pvValue)(CALLPARAMS);
// if float
} else if (stResult.st_sttType==STT_FLOAT) {
// call the function and return result
$$.sttType = STT_FLOAT;
PUSHPARAMS;
$$.fFloat = ((FLOAT (*)(FUNCSIG))$1->ss_pvValue)(CALLPARAMS);
// if string
} else if (stResult.st_sttType==STT_STRING) {
// call the function and return result
$$.sttType = STT_STRING;
CTString &strNew = _shell_astrTempStrings.Push();
PUSHPARAMS;
strNew = ((CTString (*)(FUNCSIG))$1->ss_pvValue)(CALLPARAMS);
$$.strString = (const char*)strNew;
} else {
ASSERT(FALSE);
$$.sttType = STT_FLOAT;
$$.fFloat = -666.0f;
}
} }
// if types are different // if types are different
} else { } else {
// error // error
$$.sttType = STT_VOID; $$.sttType = STT_VOID;
_pShell->ErrorF("Wrong parameters for '%s'", $1->ss_strName); _pShell->ErrorF("Wrong parameters for '%s'", (const char *) $1->ss_strName);
} }
// if the identifier is something else // if the identifier is something else
} else { } else {
// error // error
$$.sttType = STT_VOID; $$.sttType = STT_VOID;
_pShell->ErrorF("Can't call '%s'", $1->ss_strName); _pShell->ErrorF("Can't call '%s'", (const char *) $1->ss_strName);
} }
} }

View File

@ -4,7 +4,14 @@
#include <Engine/Templates/AllocationArray.h> #include <Engine/Templates/AllocationArray.h>
// needed for parser and scanner // needed for parser and scanner
#ifdef PLATFORM_WIN32
#define alloca _alloca #define alloca _alloca
#endif
// for static linking mojo...
#define yyparse yyparse_engine_base_parser
#define yyerror yyerror_engine_base_parser
extern void yyerror(char *s); extern void yyerror(char *s);
extern int yyparse(void); extern int yyparse(void);

View File

@ -1,5 +1,13 @@
#ifndef SE_INCL_PRIORITY_INL
#define SE_INCL_PRIORITY_INL
#ifdef PRAGMA_ONCE
#pragma once
#endif
class CSetPriority { class CSetPriority {
public: public:
#ifdef PLATFORM_WIN32
DWORD sp_dwProcessOld; DWORD sp_dwProcessOld;
int sp_iThreadOld; int sp_iThreadOld;
HANDLE sp_hThread; HANDLE sp_hThread;
@ -21,4 +29,14 @@ public:
BOOL bSuccessThread = SetThreadPriority(sp_hThread, sp_iThreadOld); BOOL bSuccessThread = SetThreadPriority(sp_hThread, sp_iThreadOld);
ASSERT(bSuccessProcess && bSuccessThread); ASSERT(bSuccessProcess && bSuccessThread);
} }
#else
CSetPriority(DWORD dwProcess, int iThread) { STUBBED(""); }
~CSetPriority(void) { STUBBED(""); }
#endif
}; };
#endif /* include-once blocker. */

View File

@ -1,16 +1,25 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Profiling.h> #include <Engine/Base/Profiling.h>
#include <Engine/Templates/StaticArray.cpp> #include <Engine/Templates/StaticArray.cpp>
template CStaticArray<CProfileCounter>; template class CStaticArray<CProfileCounter>;
template CStaticArray<CProfileTimer>; template class CStaticArray<CProfileTimer>;
#if (defined USE_PORTABLE_C)
#include <sys/time.h>
#endif
static inline __int64 ReadTSC_profile(void) static inline __int64 ReadTSC_profile(void)
{ {
#if (defined USE_PORTABLE_C)
struct timeval tv;
gettimeofday(&tv, NULL);
return( (((__int64) tv.tv_sec) * 1000) + (((__int64) tv.tv_usec) / 1000) );
#elif (defined __MSVC_INLINE__)
__int64 mmRet; __int64 mmRet;
__asm { __asm {
rdtsc rdtsc
@ -18,6 +27,22 @@ static inline __int64 ReadTSC_profile(void)
mov dword ptr [mmRet+4],edx mov dword ptr [mmRet+4],edx
} }
return mmRet; return mmRet;
#elif (defined __GNU_INLINE__)
__int64 mmRet;
__asm__ __volatile__ (
"rdtsc \n\t"
"movl %%eax, 0(%%esi) \n\t"
"movl %%edx, 4(%%esi) \n\t"
:
: "S" (&mmRet)
: "memory", "eax", "edx"
);
return(mmRet);
#else
#error Please implement for your platform/compiler.
#endif
} }
@ -59,7 +84,15 @@ void CProfileForm::CalibrateProfilingTimers(void)
#define REPEATCOUNT 10000 #define REPEATCOUNT 10000
// measure how much it takes to start and stop timer // measure how much it takes to start and stop timer
__int64 llMinStartStopTime(0x7fffffffffffffff);
// rcg10102001 gcc needs the "ll" postfix for numbers this big.
#if (defined __GNUC__)
#define BIGBIGNUMBER 0x7fffffffffffffffll;
#else
#define BIGBIGNUMBER 0x7fffffffffffffff;
#endif
__int64 llMinStartStopTime = BIGBIGNUMBER;
{for (INDEX i=0; i<REPEATCOUNT; i++) { {for (INDEX i=0; i<REPEATCOUNT; i++) {
pfCalibration.Reset(); pfCalibration.Reset();
pfCalibration.StartTimer(ETI_TOTAL); pfCalibration.StartTimer(ETI_TOTAL);
@ -75,7 +108,7 @@ void CProfileForm::CalibrateProfilingTimers(void)
_tvStartStopEpsilon = llMinStartStopTime; _tvStartStopEpsilon = llMinStartStopTime;
// measure how much it takes to start timer // measure how much it takes to start timer
__int64 llMinStartTime(0x7fffffffffffffff); __int64 llMinStartTime = BIGBIGNUMBER;
{for (INDEX i=0; i<REPEATCOUNT; i++) { {for (INDEX i=0; i<REPEATCOUNT; i++) {
pfCalibration.Reset(); pfCalibration.Reset();
pfCalibration.StartTimer(ETI_TOTAL); pfCalibration.StartTimer(ETI_TOTAL);
@ -93,7 +126,8 @@ void CProfileForm::CalibrateProfilingTimers(void)
_tvStartEpsilon = llMinStartTime; _tvStartEpsilon = llMinStartTime;
// measure how much it takes to stop timer // measure how much it takes to stop timer
__int64 llMinStopTime(0x7fffffffffffffff);
__int64 llMinStopTime = BIGBIGNUMBER;
{for (INDEX i=0; i<REPEATCOUNT; i++) { {for (INDEX i=0; i<REPEATCOUNT; i++) {
pfCalibration.Reset(); pfCalibration.Reset();
pfCalibration.StartTimer(ETI_TOTAL); pfCalibration.StartTimer(ETI_TOTAL);
@ -141,7 +175,7 @@ CProfileForm::CProfileForm(
FOREACHINSTATICARRAY(pf_aptTimers, CProfileTimer, itpt) { FOREACHINSTATICARRAY(pf_aptTimers, CProfileTimer, itpt) {
// clear the timer // clear the timer
itpt->pt_tvElapsed.Clear(); itpt->pt_tvElapsed.Clear();
itpt->pt_tvStarted.tv_llValue = -__int64(1); itpt->pt_tvStarted.tv_llValue = (__int64) -1;
itpt->pt_ctAveraging = 0; itpt->pt_ctAveraging = 0;
} }
} }
@ -197,7 +231,7 @@ void CProfileForm::StopTimer_internal(INDEX iTimer)
if (pf_ctRunningTimers==0) { if (pf_ctRunningTimers==0) {
pf_tvOverAllElapsed += tvNow-pf_tvOverAllStarted; pf_tvOverAllElapsed += tvNow-pf_tvOverAllStarted;
} }
IFDEBUG(pt.pt_tvStarted.tv_llValue = -__int64(1)); IFDEBUG(pt.pt_tvStarted.tv_llValue = (__int64) -1);
_tvCurrentProfilingEpsilon += _tvStopEpsilon; _tvCurrentProfilingEpsilon += _tvStopEpsilon;
} }
@ -259,7 +293,7 @@ void CProfileForm::Reset(void)
FOREACHINSTATICARRAY(pf_aptTimers, CProfileTimer, itpt) { FOREACHINSTATICARRAY(pf_aptTimers, CProfileTimer, itpt) {
// clear the timer // clear the timer
itpt->pt_tvElapsed.Clear(); itpt->pt_tvElapsed.Clear();
itpt->pt_tvStarted.tv_llValue = -__int64(1); itpt->pt_tvStarted.tv_llValue = (__int64) -1;
itpt->pt_ctAveraging = 0; itpt->pt_ctAveraging = 0;
} }
} }
@ -271,7 +305,7 @@ void CProfileCounter::Report(char *&strBuffer, INDEX ctAveragingCount)
ctAveragingCount = 1; ctAveragingCount = 1;
} }
strBuffer += sprintf(strBuffer, "%-45s: %7d %7.2f\n", strBuffer += sprintf(strBuffer, "%-45s: %7d %7.2f\n",
pc_strName, pc_ctCount, (double)pc_ctCount/ctAveragingCount); (const char *) pc_strName, pc_ctCount, (double)pc_ctCount/ctAveragingCount);
} }
/* Print one timer in report. */ /* Print one timer in report. */
@ -285,7 +319,7 @@ void CProfileTimer::Report(char *&strBuffer,
if (pt_strAveragingName=="") { if (pt_strAveragingName=="") {
strBuffer += sprintf(strBuffer, "%-45s: %6.2f%% %6.2f%% %6.2f ms\n", strBuffer += sprintf(strBuffer, "%-45s: %6.2f%% %6.2f%% %6.2f ms\n",
pt_strName, (const char *) pt_strName,
pt_tvElapsed.GetSeconds()/tvAppElapsed.GetSeconds()*100, pt_tvElapsed.GetSeconds()/tvAppElapsed.GetSeconds()*100,
pt_tvElapsed.GetSeconds()/tvModElapsed.GetSeconds()*100, pt_tvElapsed.GetSeconds()/tvModElapsed.GetSeconds()*100,
pt_tvElapsed.GetSeconds()/ctAveragingCount*1000 pt_tvElapsed.GetSeconds()/ctAveragingCount*1000
@ -296,12 +330,12 @@ void CProfileTimer::Report(char *&strBuffer,
ctLocalAveraging = 1; ctLocalAveraging = 1;
} }
strBuffer += sprintf(strBuffer, "%-45s: %6.2f%% %6.2f%% %6.2f ms (%4.0fc/%s x%d)\n", strBuffer += sprintf(strBuffer, "%-45s: %6.2f%% %6.2f%% %6.2f ms (%4.0fc/%s x%d)\n",
pt_strName, (const char *) pt_strName,
pt_tvElapsed.GetSeconds()/tvAppElapsed.GetSeconds()*100, pt_tvElapsed.GetSeconds()/tvAppElapsed.GetSeconds()*100,
pt_tvElapsed.GetSeconds()/tvModElapsed.GetSeconds()*100, pt_tvElapsed.GetSeconds()/tvModElapsed.GetSeconds()*100,
pt_tvElapsed.GetSeconds()/ctAveragingCount*1000, pt_tvElapsed.GetSeconds()/ctAveragingCount*1000,
pt_tvElapsed.GetSeconds()/ctLocalAveraging*_pTimer->tm_llCPUSpeedHZ, pt_tvElapsed.GetSeconds()/ctLocalAveraging*_pTimer->tm_llCPUSpeedHZ,
pt_strAveragingName, (const char *) pt_strAveragingName,
pt_ctAveraging/ctAveragingCount pt_ctAveraging/ctAveragingCount
); );
} }
@ -328,7 +362,9 @@ void CProfileForm::Report(CTString &strReport)
CTimerValue tvModuleElapsed = pf_tvOverAllElapsed; CTimerValue tvModuleElapsed = pf_tvOverAllElapsed;
// print the main header // print the main header
strBuffer += sprintf(strBuffer, "%s profile for last %d %s:\n", strBuffer += sprintf(strBuffer, "%s profile for last %d %s:\n",
pf_strTitle, GetAveragingCounter(), pf_strAveragingUnits); (const char *) pf_strTitle,
GetAveragingCounter(),
(const char *) pf_strAveragingUnits);
// print header for timers // print header for timers
strBuffer += sprintf(strBuffer, strBuffer += sprintf(strBuffer,

View File

@ -47,7 +47,7 @@ private:
// this file just defines TIMER_PROFILING as 1 or 0 // this file just defines TIMER_PROFILING as 1 or 0
#include <Engine/Base/ProfilingEnabled.h> #include <Engine/Base/ProfilingEnabled.h>
#endif ENGINE_INTERNAL #endif //ENGINE_INTERNAL
/* /*
* Class for gathering and reporting profiling information. * Class for gathering and reporting profiling information.
@ -153,6 +153,19 @@ public:
/* Get percentage of module time in application time. */ /* Get percentage of module time in application time. */
double GetModulePercentage(void); double GetModulePercentage(void);
#else
// !!! FIXME : rcg10102001 I needed to add these to compile
// !!! FIXME : Engine/Classes/MovableEntity.es. What am I doing wrong?
inline void IncrementCounter(INDEX iCounter, INDEX ctAdd=1) {}
inline void StartTimer(INDEX iTimer) {};
inline void StopTimer(INDEX iTimer) {};
inline void IncrementTimerAveragingCounter(INDEX iTimer, INDEX ctAdd=1) {};
inline void SetCounterName_internal(INDEX iCounter, const CTString &strName) {};
inline void SetTimerName_internal(INDEX iTimer, const CTString &strName, const CTString &strAveragingName) {};
#define SETCOUNTERNAME(a,b) SetCounterName_internal(a,"")
#define SETTIMERNAME(a,b,c) SetTimerName_internal(a,"","")
#endif // ENGINE_INTERNAL #endif // ENGINE_INTERNAL
/* Reset all profiling values. */ /* Reset all profiling values. */

View File

@ -1,3 +1,4 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#define TIMER_PROFILING 0 #define TIMER_PROFILING 0

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "StdH.h" #include <Engine/StdH.h>
#include <Engine/Base/CTString.h> #include <Engine/Base/CTString.h>
#include <Engine/Base/ProgressHook.h> #include <Engine/Base/ProgressHook.h>
#include <Engine/Network/Network.h> #include <Engine/Network/Network.h>

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include <Engine\Base\Protection.h> #include <Engine/Base/Protection.h>
#pragma warning (disable: 4244) #pragma warning (disable: 4244)

View File

@ -5,6 +5,7 @@
#ifdef PRAGMA_ONCE #ifdef PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
#define COPY_PROTECTION 1
typedef struct { typedef struct {
unsigned long P[16 + 2]; unsigned long P[16 + 2];

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/CTString.h> #include <Engine/Base/CTString.h>
#include <Engine/Base/FileName.h> #include <Engine/Base/FileName.h>
#include <Engine/Base/Registry.h> #include <Engine/Base/Registry.h>

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Relations.h> #include <Engine/Base/Relations.h>

View File

@ -62,10 +62,10 @@ void ENGINE_API AddRelationPairHeadHead(CRelationSrc &rsSrc, CRelationDst &rdDst
// get a domain member related to a codomain member through a link // get a domain member related to a codomain member through a link
#define DST(plink, dstclass, dstmember) \ #define DST(plink, dstclass, dstmember) \
( (dstclass *) ( ((UBYTE *)(&(plink->GetDst()))) - offsetof(dstclass, dstmember) ) ) ( (dstclass *) ( ((UBYTE *)(&(plink->GetDst()))) - _offsetof(dstclass, dstmember) ) )
// get a codomain member that a domain member is related to through a link // get a codomain member that a domain member is related to through a link
#define SRC(plink, srcclass, srcmember) \ #define SRC(plink, srcclass, srcmember) \
( (srcclass *) ( ((UBYTE *)(&(plink->GetSrc()))) - offsetof(srcclass, srcmember) ) ) ( (srcclass *) ( ((UBYTE *)(&(plink->GetSrc()))) - _offsetof(srcclass, srcmember) ) )
// make 'for' construct for walking all codomain members related to a domain member // make 'for' construct for walking all codomain members related to a domain member
#define FOREACHDSTOFSRC(srchead, dstclass, dstmember, pdst) \ #define FOREACHDSTOFSRC(srchead, dstclass, dstmember, pdst) \

View File

@ -1,12 +1,11 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/ReplaceFile.h> #include <Engine/Base/ReplaceFile.h>
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>
#include <Engine/Base/ErrorReporting.h> #include <Engine/Base/ErrorReporting.h>
#include <Engine/Base/Anim.h> #include <Engine/Base/Anim.h>
#include <Engine/Base/Shell.h>
#include <Engine/Graphics/Texture.h> #include <Engine/Graphics/Texture.h>
#include <Engine/Models/ModelObject.h> #include <Engine/Models/ModelObject.h>
#include <Engine/Sound/SoundObject.h> #include <Engine/Sound/SoundObject.h>
@ -41,6 +40,7 @@ extern INDEX wed_bUseBaseForReplacement;
static CTFileName CallFileRequester(char *achrTitle, char *achrSelectedFile, char *pFilter) static CTFileName CallFileRequester(char *achrTitle, char *achrSelectedFile, char *pFilter)
{ {
#ifdef PLATFORM_WIN32
typedef CTFileName FileRequester_t( typedef CTFileName FileRequester_t(
char *pchrTitle, char *pchrTitle,
char *pchrFilters, char *pchrFilters,
@ -62,6 +62,13 @@ static CTFileName CallFileRequester(char *achrTitle, char *achrSelectedFile, cha
} }
return pFileRequester( achrTitle, pFilter, "Replace file directory", achrSelectedFile); return pFileRequester( achrTitle, pFilter, "Replace file directory", achrSelectedFile);
#else
STUBBED("wtf?!");
#endif
} }
BOOL GetReplacingFile(CTFileName fnSourceFile, CTFileName &fnReplacingFile, BOOL GetReplacingFile(CTFileName fnSourceFile, CTFileName &fnReplacingFile,
@ -105,7 +112,7 @@ BOOL GetReplacingFile(CTFileName fnSourceFile, CTFileName &fnReplacingFile,
(void) strError; (void) strError;
} }
CTString strTitle; CTString strTitle;
strTitle.PrintF(TRANS("For:\"%s\""), (CTString&)fnSourceFile); strTitle.PrintF(TRANS("For:\"%s\""), (const char *) (CTString&)fnSourceFile);
// call file requester for substituting file // call file requester for substituting file
CTString strDefaultFile; CTString strDefaultFile;
strDefaultFile = fnSourceFile.FileName() + fnSourceFile.FileExt(); strDefaultFile = fnSourceFile.FileName() + fnSourceFile.FileExt();
@ -122,7 +129,7 @@ BOOL GetReplacingFile(CTFileName fnSourceFile, CTFileName &fnReplacingFile,
strBase.Load_t( fnBaseName); strBase.Load_t( fnBaseName);
} }
CTString strNewRemap; CTString strNewRemap;
strNewRemap.PrintF( "\"%s\" \"%s\"\n", (CTString&)fnSourceFile, (CTString&)fnReplacingFile); strNewRemap.PrintF( "\"%s\" \"%s\"\n", (const char *) (CTString&)fnSourceFile, (const char *) (CTString&)fnReplacingFile);
strBase += strNewRemap; strBase += strNewRemap;
strBase.Save_t( fnBaseName); strBase.Save_t( fnBaseName);
} }
@ -162,7 +169,7 @@ void SetTextureWithPossibleReplacing_t(CTextureObject &to, CTFileName &fnmTextur
to.SetData_t(fnmTexture); to.SetData_t(fnmTexture);
} else { } else {
ThrowF_t( TRANS("Unable to load world because texture \"%s\" can't be found."), ThrowF_t( TRANS("Unable to load world because texture \"%s\" can't be found."),
(CTString&)fnmTexture); (const char *) ((CTString&)fnmTexture));
} }
} }
} }
@ -189,7 +196,7 @@ void ReadTextureObject_t(CTStream &strm, CTextureObject &to)
// replacing texture was provided // replacing texture was provided
fnTexture = fnReplacingTexture; fnTexture = fnReplacingTexture;
} else { } else {
ThrowF_t( TRANS("Cannot find substitution for \"%s\""), (CTString&)fnTexture); ThrowF_t( TRANS("Cannot find substitution for \"%s\""), (const char *) (CTString&)fnTexture);
} }
} }
} }
@ -238,7 +245,7 @@ void ReadModelObject_t(CTStream &strm, CModelObject &mo)
// replacing model was provided // replacing model was provided
fnModel = fnReplacingModel; fnModel = fnReplacingModel;
} else { } else {
ThrowF_t( TRANS("Cannot find substitution for \"%s\""), (CTString&)fnModel); ThrowF_t( TRANS("Cannot find substitution for \"%s\""), (const char *) (CTString&)fnModel);
} }
} }
} }
@ -482,7 +489,7 @@ void WriteOffsetAndChildren(CTStream &strm, CModelInstance &mi)
{ {
strm.WriteID_t("MIOF"); // model instance offset strm.WriteID_t("MIOF"); // model instance offset
// write model instance offset and parent bone // write model instance offset and parent bone
strm.Write_t(&mi.mi_qvOffset,sizeof(QVect)); strm<<mi.mi_qvOffset;
CTString strParenBoneID = ska_GetStringFromTable(mi.mi_iParentBoneID); CTString strParenBoneID = ska_GetStringFromTable(mi.mi_iParentBoneID);
strm<<strParenBoneID; strm<<strParenBoneID;
@ -635,7 +642,7 @@ void ReadModelInstanceOld_t(CTStream &strm, CModelInstance &mi)
} }
// read model instance offset and parent bone // read model instance offset and parent bone
strm.Read_t(&mi.mi_qvOffset,sizeof(QVect)); strm>>mi.mi_qvOffset;
CTString strParenBoneID; CTString strParenBoneID;
strm>>strParenBoneID; strm>>strParenBoneID;
mi.mi_iParentBoneID = ska_GetIDFromStringTable(strParenBoneID); mi.mi_iParentBoneID = ska_GetIDFromStringTable(strParenBoneID);
@ -789,7 +796,7 @@ void ReadOffsetAndChildren_t(CTStream &strm, CModelInstance &mi)
INDEX ctcmi = 0; INDEX ctcmi = 0;
strm.ExpectID_t("MIOF"); // model instance offset strm.ExpectID_t("MIOF"); // model instance offset
// read model instance offset and parent bone // read model instance offset and parent bone
strm.Read_t(&mi.mi_qvOffset,sizeof(QVect)); strm>>mi.mi_qvOffset;
CTString strParenBoneID; CTString strParenBoneID;
strm>>strParenBoneID; strm>>strParenBoneID;
mi.mi_iParentBoneID = ska_GetIDFromStringTable(strParenBoneID); mi.mi_iParentBoneID = ska_GetIDFromStringTable(strParenBoneID);
@ -873,7 +880,7 @@ void ReadAnimObject_t(CTStream &strm, CAnimObject &ao)
// replacing anim was provided // replacing anim was provided
fnAnim = fnReplacingAnim; fnAnim = fnReplacingAnim;
} else { } else {
ThrowF_t( TRANS("Cannot find substitution for \"%s\""), (CTString&)fnAnim); ThrowF_t( TRANS("Cannot find substitution for \"%s\""), (const char *) (CTString&)fnAnim);
} }
} }
} }

View File

@ -0,0 +1,174 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include <stdlib.h>
#include <assert.h>
#include <Engine/Base/Types.h>
#include <Engine/Base/SDL/SDLEvents.h>
#include "SDL.h"
static Uint16 next_message_char = 0;
// This keeps the input subsystem in sync with everything else, by
// making sure all SDL events tunnel through one function.
extern int SE_SDL_InputEventPoll(SDL_Event *event);
BOOL PeekMessage(MSG *msg, void *hwnd, UINT wMsgFilterMin,
UINT wMsgFilterMax, UINT wRemoveMsg)
{
assert(msg != NULL);
assert(wRemoveMsg == PM_REMOVE);
assert(wMsgFilterMin == 0);
assert(wMsgFilterMax == 0);
if (next_message_char != 0)
{
msg->message = WM_CHAR;
msg->wParam = next_message_char;
msg->unicode = next_message_char;
next_message_char = 0;
return(TRUE);
} // if
SDL_Event sdlevent;
if (!SE_SDL_InputEventPoll(&sdlevent))
return(FALSE);
assert(sdlevent.type != SDL_NOEVENT);
msg->message = sdlevent.type;
switch (sdlevent.type)
{
case SDL_MOUSEMOTION:
msg->lParam = (
((sdlevent.motion.y << 16) & 0xFFFF0000) |
((sdlevent.motion.x ) & 0x0000FFFF)
);
break;
case SDL_KEYDOWN:
if (sdlevent.key.keysym.mod & KMOD_ALT)
msg->message = WM_SYSKEYDOWN;
// deliberate fall through...
case SDL_KEYUP:
msg->unicode = sdlevent.key.keysym.unicode;
msg->wParam = sdlevent.key.keysym.sym;
break;
case SDL_MOUSEBUTTONDOWN:
if (sdlevent.button.button == 2) // right button...
{
msg->message = WM_RBUTTONDOWN;
} // if
else if (sdlevent.button.button == 4) // wheel up
{
msg->message = WM_MOUSEWHEEL;
msg->wParam = 120 << 16;
} // else if
else if (sdlevent.button.button == 5) // wheel down
{
msg->message = WM_MOUSEWHEEL;
msg->wParam = -120 << 16;
} // else if
break;
case SDL_MOUSEBUTTONUP:
if (sdlevent.button.button == 2) // right button...
{
msg->message = WM_RBUTTONUP;
} // if
break;
} // switch
return(TRUE);
} // PeekMessage
void TranslateMessage(MSG *msg)
{
if (msg->message == WM_KEYDOWN)
{
if (msg->unicode != 0)
next_message_char = msg->unicode;
} // if
} // TranslateMessage
void DispatchMessage(MSG *msg)
{
// do nothing.
} // DispatchMessage
SHORT GetKeyState(int vk)
{
SHORT retval = 0;
switch (vk)
{
case VK_LBUTTON:
if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_LMASK)
retval = 0x8000;
break;
case VK_RBUTTON:
if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_RMASK)
retval = 0x8000;
break;
case VK_MBUTTON:
if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_MMASK)
retval = 0x8000;
break;
default:
if (SDL_GetKeyState(NULL)[vk])
retval = 0x8000;
break;
} // switch
return(retval);
} // GetKeyState
SHORT GetAsyncKeyState(int vk)
{
return(GetKeyState(vk));
} // GetAsyncKeyState
BOOL GetCursorPos(LPPOINT lpPoint)
{
assert(lpPoint != NULL);
int x, y;
SDL_GetMouseState(&x, &y);
lpPoint->x = x;
lpPoint->y = y;
return(TRUE);
} // GetCursorPos
BOOL ScreenToClient(void *hWnd, LPPOINT lpPoint)
{
// do nothing. SDL returns points in client coordinates already.
return(1); // success. :)
} // ScreenToClient
int ShowCursor(BOOL yes)
{
static int count = 0;
count += (yes) ? 1 : -1;
SDL_ShowCursor((count >= 0) ? SDL_ENABLE : SDL_DISABLE);
return(count);
} // ShowCursor
// end of SDLEvents.cpp ...

View File

@ -0,0 +1,132 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#ifndef SE_INCL_SDLEVENTS_H
#define SE_INCL_SDLEVENTS_H
#ifdef PRAGMA_ONCE
#pragma once
#endif
#include <Engine/Base/Types.h>
#include "SDL.h"
#define IsIconic(x) (FALSE)
typedef struct SSAM_SDL_MSG {
UINT message;
WPARAM wParam;
LPARAM lParam;
Uint16 unicode;
} MSG, *PMSG;
#define PM_REMOVE 37337 // super l33t. :)
#define WM_CHAR (SDL_USEREVENT + 0)
#define WM_NULL (SDL_USEREVENT + 1)
#define WM_SYSKEYDOWN (SDL_USEREVENT + 2)
#define WM_LBUTTONDOWN (SDL_MOUSEBUTTONDOWN)
#define WM_LBUTTONUP (SDL_MOUSEBUTTONUP)
#define WM_RBUTTONDOWN (SDL_USEREVENT + 3)
#define WM_RBUTTONUP (SDL_USEREVENT + 4)
#define WM_MOUSEWHEEL (SDL_USEREVENT + 5)
#define WM_KEYDOWN (SDL_KEYDOWN)
#define WM_KEYUP (SDL_KEYUP)
#define WM_MOUSEMOVE (SDL_MOUSEMOTION)
#define WM_PAINT (SDL_VIDEOEXPOSE)
#define WM_QUIT (SDL_QUIT)
#define WM_CLOSE (SDL_NOEVENT)
#define WM_COMMAND (SDL_NOEVENT)
#define WM_ERASEBKGND (SDL_NOEVENT)
#define WM_KILLFOCUS (SDL_NOEVENT)
#define WM_MOUSEFIRST (SDL_NOEVENT)
#define WM_MOUSELAST (SDL_NOEVENT)
#define WM_LBUTTONDBLCLK (SDL_NOEVENT)
#define WM_RBUTTONDBLCLK (SDL_NOEVENT)
#define WM_SYSCOMMAND (SDL_NOEVENT)
#define WM_SETFOCUS (SDL_NOEVENT)
#define WM_ACTIVATE (SDL_NOEVENT)
#define WM_ACTIVATEAPP (SDL_NOEVENT)
#define WM_CANCELMODE (SDL_NOEVENT)
BOOL PeekMessage(MSG *msg, void *hwnd, UINT wMsgFilterMin,
UINT wMsgFilterMax, UINT wRemoveMsg);
void TranslateMessage(MSG *msg);
void DispatchMessage(MSG *msg);
#define VK_ADD SDLK_KP_PLUS
#define VK_BACK SDLK_BACKSPACE
#define VK_CAPITAL SDLK_CAPSLOCK
#define VK_CONTROL SDLK_RCTRL
#define VK_DECIMAL SDLK_KP_PERIOD
#define VK_DELETE SDLK_DELETE
#define VK_DIVIDE SDLK_KP_DIVIDE
#define VK_DOWN SDLK_DOWN
#define VK_END SDLK_END
#define VK_ESCAPE SDLK_ESCAPE
#define VK_F1 SDLK_F1
#define VK_F2 SDLK_F2
#define VK_F3 SDLK_F3
#define VK_F4 SDLK_F4
#define VK_F5 SDLK_F5
#define VK_F6 SDLK_F6
#define VK_F7 SDLK_F7
#define VK_F8 SDLK_F8
#define VK_F9 SDLK_F9
#define VK_F10 SDLK_F10
#define VK_F11 SDLK_F11
#define VK_F12 SDLK_F12
#define VK_HOME SDLK_HOME
#define VK_INSERT SDLK_INSERT
#define VK_LCONTROL SDLK_LCTRL
#define VK_LEFT SDLK_LEFT
#define VK_LMENU SDLK_LALT
#define VK_LSHIFT SDLK_LSHIFT
#define VK_MENU SDLK_LALT
#define VK_MULTIPLY SDLK_KP_MULTIPLY
#define VK_NEXT SDLK_PAGEDOWN
#define VK_NUMLOCK SDLK_NUMLOCK
#define VK_NUMPAD0 SDLK_KP0
#define VK_NUMPAD1 SDLK_KP1
#define VK_NUMPAD2 SDLK_KP2
#define VK_NUMPAD3 SDLK_KP3
#define VK_NUMPAD4 SDLK_KP4
#define VK_NUMPAD5 SDLK_KP5
#define VK_NUMPAD6 SDLK_KP6
#define VK_NUMPAD7 SDLK_KP7
#define VK_NUMPAD8 SDLK_KP8
#define VK_NUMPAD9 SDLK_KP9
#define VK_PAUSE SDLK_PAUSE
#define VK_PRIOR SDLK_PAGEUP
#define VK_RCONTROL SDLK_RCTRL
#define VK_RETURN SDLK_RETURN
#define VK_RIGHT SDLK_RIGHT
#define VK_RMENU SDLK_RALT
#define VK_RSHIFT SDLK_RSHIFT
#define VK_SCROLL SDLK_SCROLLOCK
#define VK_SEPARATOR SDLK_KP_ENTER
#define VK_SHIFT SDLK_LSHIFT
#define VK_SNAPSHOT SDLK_PRINT
#define VK_SPACE SDLK_SPACE
#define VK_SUBTRACT SDLK_KP_MINUS
#define VK_TAB SDLK_TAB
#define VK_UP SDLK_UP
// Pray these never get filled.
#define VK_LBUTTON 1
#define VK_RBUTTON 2
#define VK_MBUTTON 3
SHORT GetKeyState(int vk);
SHORT GetAsyncKeyState(int vk);
BOOL GetCursorPos(LPPOINT lpPoint);
BOOL ScreenToClient(void *hWnd, LPPOINT lpPoint);
int ShowCursor(BOOL yes);
#define LOWORD(x) (x & 0x0000FFFF)
#define HIWORD(x) ((x >> 16) & 0x0000FFFF)
#endif /* include-once blocker. */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,144 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "SDL.h"
#include "SDL_thread.h"
#include "Engine/StdH.h"
#include <Engine/Base/Synchronization.h>
// !!! FIXME: rcg10142001 Most of CTSingleLock is platform-independent.
CTCriticalSection::CTCriticalSection(void)
{
LockCounter = 0;
cs_pvObject = (void *) SDL_CreateMutex();
ASSERT(cs_pvObject != NULL);
}
CTCriticalSection::~CTCriticalSection(void)
{
SDL_DestroyMutex((SDL_mutex *) cs_pvObject);
}
INDEX CTCriticalSection::Lock(void)
{
LockCounter++;
if (LockCounter == 1)
SDL_LockMutex((SDL_mutex *) cs_pvObject);
return(LockCounter);
}
INDEX CTCriticalSection::TryToLock(void)
{
if (LockCounter > 0) // !!! race condition. Ironic, eh?
return(0);
Lock();
return(1);
}
INDEX CTCriticalSection::Unlock(void)
{
if (LockCounter > 0)
{
LockCounter--;
if (LockCounter == 0)
SDL_UnlockMutex((SDL_mutex *) cs_pvObject);
}
return(LockCounter);
}
CTSingleLock::CTSingleLock(CTCriticalSection *pcs, BOOL bLock) : sl_cs(*pcs)
{
// initially not locked
sl_bLocked = FALSE;
sl_iLastLockedIndex = -2;
// critical section must have index assigned
//ASSERT(sl_cs.cs_iIndex>=1||sl_cs.cs_iIndex==-1);
// if should lock immediately
if (bLock) {
Lock();
}
}
CTSingleLock::~CTSingleLock(void)
{
// if locked
if (sl_bLocked) {
// unlock
Unlock();
}
}
void CTSingleLock::Lock(void)
{
// must not be locked
ASSERT(!sl_bLocked);
ASSERT(sl_iLastLockedIndex==-2);
// if not locked
if (!sl_bLocked) {
// lock
INDEX ctLocks = sl_cs.Lock();
// if this mutex was not locked already
// if (ctLocks==1) {
// // check that locking in given order
// if (sl_cs.cs_iIndex!=-1) {
// ASSERT(_iLastLockedMutex<sl_cs.cs_iIndex);
// sl_iLastLockedIndex = _iLastLockedMutex;
// _iLastLockedMutex = sl_cs.cs_iIndex;
// }
// }
}
sl_bLocked = TRUE;
}
BOOL CTSingleLock::TryToLock(void)
{
// must not be locked
ASSERT(!sl_bLocked);
// if not locked
if (!sl_bLocked) {
// if can lock
INDEX ctLocks = sl_cs.TryToLock();
if (ctLocks>=1) {
sl_bLocked = TRUE;
// if this mutex was not locked already
// if (ctLocks==1) {
// // check that locking in given order
// if (sl_cs.cs_iIndex!=-1) {
// ASSERT(_iLastLockedMutex<sl_cs.cs_iIndex);
// sl_iLastLockedIndex = _iLastLockedMutex;
// _iLastLockedMutex = sl_cs.cs_iIndex;
// }
// }
}
}
return sl_bLocked;
}
BOOL CTSingleLock::IsLocked(void)
{
return sl_bLocked;
}
void CTSingleLock::Unlock(void)
{
// must be locked
ASSERT(sl_bLocked);
// if locked
if (sl_bLocked) {
// unlock
INDEX ctLocks = sl_cs.Unlock();
// if unlocked completely
if (ctLocks==0) {
// check that unlocking in exact reverse order
// if (sl_cs.cs_iIndex!=-1) {
// ASSERT(_iLastLockedMutex==sl_cs.cs_iIndex);
// _iLastLockedMutex = sl_iLastLockedIndex;
// sl_iLastLockedIndex = -2;
// }
}
}
sl_bLocked = FALSE;
}

View File

@ -0,0 +1,15 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "SDL.h"
#include "SDL_thread.h"
#include <Engine/Engine.h>
ULONG ThreadLocalGetCurrentTID(void)
{
return(SDL_ThreadID());
} // ThreadLocalGetCurrentTID
// end of SDLThreadLocalStorage.cpp ...

View File

@ -0,0 +1,16 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
/* rcg10072001 Moved stuff into this file. */
#include "SDL.h"
#include <Engine/Engine.h>
#include <Engine/Base/Timer.h>
void CTimer::Sleep(DWORD milliseconds)
{
SDL_Delay(milliseconds);
}
// end of SDLTimer.cpp ...

View File

@ -13,6 +13,10 @@
#define YY_DECL int yylex (YYSTYPE *lvalp) #define YY_DECL int yylex (YYSTYPE *lvalp)
#define yylval (*lvalp) #define yylval (*lvalp)
#ifdef __cplusplus
extern "C" { int yywrap(void); }
#endif
int yywrap(void) int yywrap(void)
{ {
// no more bufers // no more bufers
@ -113,8 +117,8 @@ PARAMCONTENT ([^\ \n\";]|(\\\ ))
if (strParam.FindSubstr(strParamNo)!=-1) { if (strParam.FindSubstr(strParamNo)!=-1) {
_pShell->ErrorF("Parameter substitution recursion detected!"); _pShell->ErrorF("Parameter substitution recursion detected!");
} else { } else {
INDEX ctFound=0; INDEX ctFound;
for(;; ctFound++) { for(ctFound=0;; ctFound++) {
if (!_strCmd.ReplaceSubstr(strParamNo, strParam)) { if (!_strCmd.ReplaceSubstr(strParamNo, strParam)) {
break; break;
} }

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Serial.h> #include <Engine/Base/Serial.h>
@ -81,7 +81,7 @@ void CSerial::Reload(void)
// if there is some error while reloading // if there is some error while reloading
//} catch (char *strError) { //} catch (char *strError) {
// quit the application with error explanation // quit the application with error explanation
//FatalError(TRANS("Cannot reload file '%s':\n%s"), (CTString&)fnmOldName, strError); //FatalError(TRANS("Cannot reload file '%s':\n%s"), (const char *) (CTString&)fnmOldName, strError);
//} //}
// if still here (no exceptions raised) // if still here (no exceptions raised)

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Shell.h> #include <Engine/Base/Shell.h>
#include <Engine/Base/Shell_internal.h> #include <Engine/Base/Shell_internal.h>
@ -14,17 +14,17 @@
#include <Engine/Templates/DynamicArray.cpp> #include <Engine/Templates/DynamicArray.cpp>
#include <Engine/Templates/DynamicStackArray.cpp> #include <Engine/Templates/DynamicStackArray.cpp>
template CDynamicArray<CShellSymbol>; template class CDynamicArray<CShellSymbol>;
// shell type used for undeclared symbols // shell type used for undeclared symbols
extern INDEX _shell_istUndeclared = -1; INDEX _shell_istUndeclared = -1;
// pointer to global shell object // pointer to global shell object
CShell *_pShell = NULL; CShell *_pShell = NULL;
void *_pvNextToDeclare=NULL; // != NULL if declaring external symbol defined in exe code void *_pvNextToDeclare=NULL; // != NULL if declaring external symbol defined in exe code
// define console variable for number of last console lines // define console variable for number of last console lines
extern INDEX con_iLastLines = 5; INDEX con_iLastLines = 5;
extern void yy_switch_to_buffer(YY_BUFFER_STATE); extern void yy_switch_to_buffer(YY_BUFFER_STATE);
@ -99,10 +99,10 @@ CDynamicStackArray<FLOAT> _shell_afExtFloats;
static const char *strCommandLine = ""; static const char *strCommandLine = "";
ENGINE_API extern FLOAT tmp_af[10] = { 0 }; FLOAT tmp_af[10] = { 0 };
ENGINE_API extern INDEX tmp_ai[10] = { 0 }; INDEX tmp_ai[10] = { 0 };
ENGINE_API extern INDEX tmp_fAdd = 0.0f; INDEX tmp_fAdd = 0;
ENGINE_API extern INDEX tmp_i = 0; INDEX tmp_i = 0;
void CShellSymbol::Clear(void) void CShellSymbol::Clear(void)
{ {
@ -175,7 +175,7 @@ void MakeAccessViolation(void* pArgs)
*p=1; *p=1;
} }
extern int _a=123; int _a=123;
void MakeStackOverflow(void* pArgs) void MakeStackOverflow(void* pArgs)
{ {
INDEX bDont = NEXTARGUMENT(INDEX); INDEX bDont = NEXTARGUMENT(INDEX);
@ -196,6 +196,7 @@ void MakeFatalError(void* pArgs)
extern void ReportGlobalMemoryStatus(void) extern void ReportGlobalMemoryStatus(void)
{ {
#ifdef PLATFORM_WIN32
CPrintF(TRANS("Global memory status...\n")); CPrintF(TRANS("Global memory status...\n"));
MEMORYSTATUS ms; MEMORYSTATUS ms;
@ -211,13 +212,15 @@ extern void ReportGlobalMemoryStatus(void)
DWORD dwMax; DWORD dwMax;
GetProcessWorkingSetSize(GetCurrentProcess(), &dwMin, &dwMax); GetProcessWorkingSetSize(GetCurrentProcess(), &dwMin, &dwMax);
CPrintF(TRANS(" Process working set: %dMB-%dMB\n\n"), dwMin/(1024*1024), dwMax/(1024*1024)); CPrintF(TRANS(" Process working set: %dMB-%dMB\n\n"), dwMin/(1024*1024), dwMax/(1024*1024));
#endif
} }
static void MemoryInfo(void) static void MemoryInfo(void)
{ {
ReportGlobalMemoryStatus(); ReportGlobalMemoryStatus();
_HEAPINFO hinfo; #ifdef PLATFORM_WIN32
_HEAPINFO hinfo;
int heapstatus; int heapstatus;
hinfo._pentry = NULL; hinfo._pentry = NULL;
SLONG slTotalUsed = 0; SLONG slTotalUsed = 0;
@ -245,6 +248,7 @@ static void MemoryInfo(void)
} }
CPrintF( "Total used: %d bytes (%.2f MB) in %d blocks\n", slTotalUsed, slTotalUsed/1024.0f/1024.0f, ctUsed); CPrintF( "Total used: %d bytes (%.2f MB) in %d blocks\n", slTotalUsed, slTotalUsed/1024.0f/1024.0f, ctUsed);
CPrintF( "Total free: %d bytes (%.2f MB) in %d blocks\n", slTotalFree, slTotalFree/1024.0f/1024.0f, ctFree); CPrintF( "Total free: %d bytes (%.2f MB) in %d blocks\n", slTotalFree, slTotalFree/1024.0f/1024.0f, ctFree);
#endif
} }
// get help for a shell symbol // get help for a shell symbol
@ -293,14 +297,14 @@ extern void PrintShellSymbolHelp(const CTString &strSymbol)
try { try {
CTString strHelp = GetShellSymbolHelp_t(strSymbol); CTString strHelp = GetShellSymbolHelp_t(strSymbol);
if (strHelp!="") { if (strHelp!="") {
CPrintF("%s\n", strHelp); CPrintF("%s\n", (const char *) strHelp);
} else { } else {
CPrintF( TRANS("No help found for '%s'.\n"), strSymbol); CPrintF( TRANS("No help found for '%s'.\n"), (const char *) strSymbol);
} }
// if failed // if failed
} catch(char *strError) { } catch(char *strError) {
// just print the error // just print the error
CPrintF( TRANS("Cannot print help for '%s': %s\n"), strSymbol, strError); CPrintF( TRANS("Cannot print help for '%s': %s\n"), (const char *) strSymbol, strError);
} }
} }
@ -331,23 +335,23 @@ extern void ListSymbolsByPattern(CTString strPattern)
// print its declaration to the console // print its declaration to the console
if (st.st_sttType == STT_FUNCTION) { if (st.st_sttType == STT_FUNCTION) {
CPrintF("void %s(void)", ss.ss_strName); CPrintF("void %s(void)", (const char *) ss.ss_strName);
} else if (st.st_sttType == STT_STRING) { } else if (st.st_sttType == STT_STRING) {
CPrintF("CTString %s = \"%s\"", ss.ss_strName, *(CTString*)ss.ss_pvValue); CPrintF("CTString %s = \"%s\"", (const char *) ss.ss_strName, (const char *) (*(CTString*)ss.ss_pvValue));
} else if (st.st_sttType == STT_FLOAT) { } else if (st.st_sttType == STT_FLOAT) {
CPrintF("FLOAT %s = %g", ss.ss_strName, *(FLOAT*)ss.ss_pvValue); CPrintF("FLOAT %s = %g", (const char *) ss.ss_strName, *(FLOAT*)ss.ss_pvValue);
} else if (st.st_sttType == STT_INDEX) { } else if (st.st_sttType == STT_INDEX) {
CPrintF("INDEX %s = %d (0x%08x)", ss.ss_strName, *(INDEX*)ss.ss_pvValue, *(INDEX*)ss.ss_pvValue); CPrintF("INDEX %s = %d (0x%08x)", (const char *) ss.ss_strName, *(INDEX*)ss.ss_pvValue, *(INDEX*)ss.ss_pvValue);
} else if (st.st_sttType == STT_ARRAY) { } else if (st.st_sttType == STT_ARRAY) {
// get base type // get base type
ShellType &stBase = _shell_ast[st.st_istBaseType]; ShellType &stBase = _shell_ast[st.st_istBaseType];
if (stBase.st_sttType == STT_FLOAT) { if (stBase.st_sttType == STT_FLOAT) {
CPrintF("FLOAT %s[%d]", ss.ss_strName, st.st_ctArraySize); CPrintF("FLOAT %s[%d]", (const char *) ss.ss_strName, st.st_ctArraySize);
} else if (stBase.st_sttType == STT_INDEX) { } else if (stBase.st_sttType == STT_INDEX) {
CPrintF("INDEX %s[%d]", ss.ss_strName, st.st_ctArraySize); CPrintF("INDEX %s[%d]", (const char *) ss.ss_strName, st.st_ctArraySize);
} else if (stBase.st_sttType == STT_STRING) { } else if (stBase.st_sttType == STT_STRING) {
CPrintF("CTString %s[%d]", ss.ss_strName, st.st_ctArraySize); CPrintF("CTString %s[%d]", (const char *) ss.ss_strName, st.st_ctArraySize);
} else { } else {
ASSERT(FALSE); ASSERT(FALSE);
} }
@ -421,7 +425,7 @@ void LoadCommands(void)
{ {
// list all command files // list all command files
CDynamicStackArray<CTFileName> afnmCmds; CDynamicStackArray<CTFileName> afnmCmds;
MakeDirList( afnmCmds, CTString("Scripts\\Commands\\"), "*.ini", DLI_RECURSIVE); MakeDirList( afnmCmds, CTString("Scripts\\Commands\\"), CTString("*.ini"), DLI_RECURSIVE);
// for each file // for each file
for(INDEX i=0; i<afnmCmds.Count(); i++) { for(INDEX i=0; i<afnmCmds.Count(); i++) {
CTFileName &fnm = afnmCmds[i]; CTFileName &fnm = afnmCmds[i];
@ -452,7 +456,7 @@ void LoadCommands(void)
// assign value // assign value
*(CTString*)ssNew.ss_pvValue = "!command "+strCmd; *(CTString*)ssNew.ss_pvValue = "!command "+strCmd;
} else { } else {
_pShell->ErrorF("Symbol '%s' is not suitable to be a command", ssNew.ss_strName); _pShell->ErrorF("Symbol '%s' is not suitable to be a command", (const char *) ssNew.ss_strName);
} }
} }
} }
@ -527,32 +531,38 @@ void CShell::Initialize(void)
DeclareSymbol("const INDEX YES;", (void*)&_bTRUE); DeclareSymbol("const INDEX YES;", (void*)&_bTRUE);
DeclareSymbol("const INDEX NO;", (void*)&_bFALSE); DeclareSymbol("const INDEX NO;", (void*)&_bFALSE);
DeclareSymbol("user void LoadCommands(void);", &LoadCommands); DeclareSymbol("user void LoadCommands(void);", (void *)&LoadCommands);
DeclareSymbol("user void ListSymbols(void);", &ListSymbols); DeclareSymbol("user void ListSymbols(void);", (void *)&ListSymbols);
DeclareSymbol("user void MemoryInfo(void);", &MemoryInfo); DeclareSymbol("user void MemoryInfo(void);", (void *)&MemoryInfo);
DeclareSymbol("user void MakeAccessViolation(INDEX);", &MakeAccessViolation); DeclareSymbol("user void MakeAccessViolation(INDEX);", (void *)&MakeAccessViolation);
DeclareSymbol("user void MakeStackOverflow(INDEX);", &MakeStackOverflow); DeclareSymbol("user void MakeStackOverflow(INDEX);", (void *)&MakeStackOverflow);
DeclareSymbol("user void MakeFatalError(INDEX);", &MakeFatalError); DeclareSymbol("user void MakeFatalError(INDEX);", (void *)&MakeFatalError);
DeclareSymbol("persistent user INDEX con_iLastLines;", &con_iLastLines); DeclareSymbol("persistent user INDEX con_iLastLines;", (void *)&con_iLastLines);
DeclareSymbol("persistent user FLOAT tmp_af[10];", &tmp_af); DeclareSymbol("persistent user FLOAT tmp_af[10];", (void *)&tmp_af);
DeclareSymbol("persistent user INDEX tmp_ai[10];", &tmp_ai); DeclareSymbol("persistent user INDEX tmp_ai[10];", (void *)&tmp_ai);
DeclareSymbol("persistent user INDEX tmp_i;", &tmp_i); DeclareSymbol("persistent user INDEX tmp_i;", (void *)&tmp_i);
DeclareSymbol("persistent user FLOAT tmp_fAdd;", &tmp_fAdd); DeclareSymbol("persistent user FLOAT tmp_fAdd;", (void *)&tmp_fAdd);
DeclareSymbol("user void Echo(CTString);", &Echo); DeclareSymbol("user void Echo(CTString);", (void *)&Echo);
DeclareSymbol("user CTString UndecorateString(CTString);", &UndecorateString); DeclareSymbol("user CTString UndecorateString(CTString);", (void *)&UndecorateString);
DeclareSymbol("user INDEX Matches(CTString, CTString);", &MatchStrings); DeclareSymbol("user INDEX Matches(CTString, CTString);", (void *)&MatchStrings);
DeclareSymbol("user CTString LoadString(CTString);", &MyLoadString); DeclareSymbol("user CTString LoadString(CTString);", (void *)&MyLoadString);
DeclareSymbol("user void SaveString(CTString, CTString);", &MySaveString); DeclareSymbol("user void SaveString(CTString, CTString);", (void *)&MySaveString);
DeclareSymbol("user CTString RemoveSubstring(CTString, CTString);", &RemoveSubstringCfunc); DeclareSymbol("user CTString RemoveSubstring(CTString, CTString);", (void *)&RemoveSubstringCfunc);
DeclareSymbol("user CTString ToUpper(CTString);", &ToUpperCfunc); DeclareSymbol("user CTString ToUpper(CTString);", (void *)&ToUpperCfunc);
DeclareSymbol("user CTString ToLower(CTString);", &ToLowerCfunc); DeclareSymbol("user CTString ToLower(CTString);", (void *)&ToLowerCfunc);
} }
static BOOL _iParsing = 0; static BOOL _iParsing = 0;
// Declare a symbol in the shell. // Declare a symbol in the shell.
/* rcg10072001 Added second version of DeclareSymbol()... */
void CShell::DeclareSymbol(const CTString &strDeclaration, void *pvValue) void CShell::DeclareSymbol(const CTString &strDeclaration, void *pvValue)
{
DeclareSymbol((const char *) strDeclaration, pvValue);
}
void CShell::DeclareSymbol(const char *strDeclaration, void *pvValue)
{ {
// synchronize access to shell // synchronize access to shell
CTSingleLock slShell(&sh_csShell, TRUE); CTSingleLock slShell(&sh_csShell, TRUE);
@ -578,7 +588,7 @@ void CShell::DeclareSymbol(const CTString &strDeclaration, void *pvValue)
// don't use that value for parsing any more // don't use that value for parsing any more
_pvNextToDeclare = NULL; _pvNextToDeclare = NULL;
}; }
// Execute command(s). // Execute command(s).
void CShell::Execute(const CTString &strCommands) void CShell::Execute(const CTString &strCommands)
@ -813,6 +823,7 @@ void CShell::ErrorF(const char *strFormat, ...)
va_start(arg, strFormat); va_start(arg, strFormat);
CTString strBuffer; CTString strBuffer;
strBuffer.VPrintF(strFormat, arg); strBuffer.VPrintF(strFormat, arg);
va_end(arg);
// print it to the main console // print it to the main console
CPrintF(strBuffer); CPrintF(strBuffer);
@ -843,7 +854,7 @@ void CShell::StorePersistentSymbols(const CTFileName &fnScript)
continue; continue;
} }
char *strUser = (ss.ss_ulFlags & SSF_USER)?"user ":""; const char *strUser = (ss.ss_ulFlags & SSF_USER)?"user ":"";
// get its type // get its type
ShellType &st = _shell_ast[ss.ss_istType]; ShellType &st = _shell_ast[ss.ss_istType];
@ -856,39 +867,39 @@ void CShell::StorePersistentSymbols(const CTFileName &fnScript)
if (stBase.st_sttType==STT_FLOAT) { if (stBase.st_sttType==STT_FLOAT) {
// dump all members as floats // dump all members as floats
for(INDEX i=0; i<st.st_ctArraySize; i++) { for(INDEX i=0; i<st.st_ctArraySize; i++) {
fScript.FPrintF_t("%s[%d]=(FLOAT)%g;\n", ss.ss_strName, i, ((FLOAT*)ss.ss_pvValue)[i]); fScript.FPrintF_t("%s[%d]=(FLOAT)%g;\n", (const char *) ss.ss_strName, i, ((FLOAT*)ss.ss_pvValue)[i]);
} }
// if index // if index
} else if (stBase.st_sttType==STT_INDEX) { } else if (stBase.st_sttType==STT_INDEX) {
// dump all members as indices // dump all members as indices
for(INDEX i=0; i<st.st_ctArraySize; i++) { for(INDEX i=0; i<st.st_ctArraySize; i++) {
fScript.FPrintF_t("%s[%d]=(INDEX)%d;\n", ss.ss_strName, i, ((INDEX*)ss.ss_pvValue)[i]); fScript.FPrintF_t("%s[%d]=(INDEX)%d;\n", (const char *) ss.ss_strName, i, ((INDEX*)ss.ss_pvValue)[i]);
} }
// if string // if string
} else if (stBase.st_sttType==STT_STRING) { } else if (stBase.st_sttType==STT_STRING) {
// dump all members // dump all members
for(INDEX i=0; i<st.st_ctArraySize; i++) { for(INDEX i=0; i<st.st_ctArraySize; i++) {
fScript.FPrintF_t("%s[%d]=\"%s\";\n", ss.ss_strName, i, (const char*)(ScriptEsc(*(CTString*)ss.ss_pvValue)[i]) ); fScript.FPrintF_t("%s[%d]=\"%s\";\n", (const char *) ss.ss_strName, i, (const char*)(ScriptEsc(*(CTString*)ss.ss_pvValue)[i]) );
} }
// otherwise // otherwise
} else { } else {
ThrowF_t("%s is an array of wrong type", ss.ss_strName); ThrowF_t("%s is an array of wrong type", (const char *) ss.ss_strName);
} }
// if float // if float
} else if (st.st_sttType==STT_FLOAT) { } else if (st.st_sttType==STT_FLOAT) {
// dump as float // dump as float
fScript.FPrintF_t("persistent extern %sFLOAT %s=(FLOAT)%g;\n", strUser, ss.ss_strName, *(FLOAT*)ss.ss_pvValue); fScript.FPrintF_t("persistent extern %sFLOAT %s=(FLOAT)%g;\n", strUser, (const char *) ss.ss_strName, *(FLOAT*)ss.ss_pvValue);
// if index // if index
} else if (st.st_sttType==STT_INDEX) { } else if (st.st_sttType==STT_INDEX) {
// dump as index // dump as index
fScript.FPrintF_t("persistent extern %sINDEX %s=(INDEX)%d;\n", strUser, ss.ss_strName, *(INDEX*)ss.ss_pvValue); fScript.FPrintF_t("persistent extern %sINDEX %s=(INDEX)%d;\n", strUser, (const char *) ss.ss_strName, *(INDEX*)ss.ss_pvValue);
// if string // if string
} else if (st.st_sttType==STT_STRING) { } else if (st.st_sttType==STT_STRING) {
// dump as index // dump as index
fScript.FPrintF_t("persistent extern %sCTString %s=\"%s\";\n", strUser, ss.ss_strName, (const char*)ScriptEsc(*(CTString*)ss.ss_pvValue) ); fScript.FPrintF_t("persistent extern %sCTString %s=\"%s\";\n", strUser, (const char *) ss.ss_strName, (const char*)ScriptEsc(*(CTString*)ss.ss_pvValue) );
// otherwise // otherwise
} else { } else {
ThrowF_t("%s of wrong type", ss.ss_strName); ThrowF_t("%s of wrong type", (const char *) ss.ss_strName);
} }
} }
} catch (char *strError) { } catch (char *strError) {

View File

@ -36,6 +36,8 @@ public:
// Declare a symbol in the shell. // Declare a symbol in the shell.
void DeclareSymbol(const CTString &strDeclaration, void *pvValue); void DeclareSymbol(const CTString &strDeclaration, void *pvValue);
/* rcg10072001 Added this version of DeclareSymbol()... */
void DeclareSymbol(const char *strDeclaration, void *pvValue);
// Execute command(s). // Execute command(s).
void Execute(const CTString &strCommands); void Execute(const CTString &strCommands);
// Save shell commands to restore persistent symbols to a script file // Save shell commands to restore persistent symbols to a script file

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Shell.h> #include <Engine/Base/Shell.h>
#include <Engine/Base/Shell_internal.h> #include <Engine/Base/Shell_internal.h>

View File

@ -23,6 +23,17 @@ enum ShellTypeType {
// data type structure // data type structure
struct ShellType { struct ShellType {
ShellType() :
st_sttType(STT_ILLEGAL),
st_ctArraySize(0),
st_istBaseType(0),
st_istFirstArgument(0),
st_istLastArgument(0),
st_istNextInArguments(0),
st_istPrevInArguments(0)
{
}
enum ShellTypeType st_sttType; enum ShellTypeType st_sttType;
INDEX st_ctArraySize; // number of members if an array INDEX st_ctArraySize; // number of members if an array

View File

@ -1,11 +1,15 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Console_Internal.h> #include <Engine/Base/Console_Internal.h>
#include <Engine/Build.h> #include <Engine/Build.h>
#if (!defined PLATFORM_WIN32)
#error You probably should not try to compile this.
#endif
extern ULONG _ulEngineBuildMajor; extern ULONG _ulEngineBuildMajor;
extern ULONG _ulEngineBuildMinor; extern ULONG _ulEngineBuildMinor;

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Statistics.h> #include <Engine/Base/Statistics.h>
#include <Engine/Base/Statistics_Internal.h> #include <Engine/Base/Statistics_Internal.h>
@ -8,9 +8,9 @@
#include <Engine/Templates/DynamicContainer.cpp> #include <Engine/Templates/DynamicContainer.cpp>
#include <Engine/Templates/StaticArray.cpp> #include <Engine/Templates/StaticArray.cpp>
template CStaticArray<CStatCounter>; template class CStaticArray<CStatCounter>;
template CStaticArray<CStatTimer>; template class CStaticArray<CStatTimer>;
template CStaticArray<CStatLabel>; template class CStaticArray<CStatLabel>;
// one globaly used stats report // one globaly used stats report
CStatForm _sfStats; CStatForm _sfStats;

View File

@ -1,14 +1,17 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <sys\types.h> #include <sys/types.h>
#include <sys\stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <io.h>
#include <DbgHelp.h>
#include <Engine/Base/Protection.h>
// !!! FIXME : rcg10162001 Need this anymore, since _findfirst() is abstracted?
#ifdef PLATFORM_WIN32
#include <io.h>
#endif
#include <Engine/Base/Protection.h>
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>
#include <Engine/Base/Memory.h> #include <Engine/Base/Memory.h>
@ -19,6 +22,7 @@
#include <Engine/Base/Unzip.h> #include <Engine/Base/Unzip.h>
#include <Engine/Base/CRC.h> #include <Engine/Base/CRC.h>
#include <Engine/Base/Shell.h> #include <Engine/Base/Shell.h>
#include <Engine/Base/FileSystem.h>
#include <Engine/Templates/NameTable_CTFileName.h> #include <Engine/Templates/NameTable_CTFileName.h>
#include <Engine/Templates/StaticArray.cpp> #include <Engine/Templates/StaticArray.cpp>
#include <Engine/Templates/DynamicStackArray.cpp> #include <Engine/Templates/DynamicStackArray.cpp>
@ -28,22 +32,23 @@
// default size of page used for stream IO operations (4Kb) // default size of page used for stream IO operations (4Kb)
ULONG _ulPageSize = 0; ULONG _ulPageSize = 0;
// maximum lenght of file that can be saved (default: 128Mb) // maximum length of file that can be saved (default: 128Mb)
ULONG _ulMaxLenghtOfSavingFile = (1UL<<20)*128; ULONG _ulMaxLenghtOfSavingFile = (1UL<<20)*128;
extern INDEX fil_bPreferZips = FALSE; INDEX fil_bPreferZips = FALSE;
// set if current thread has currently enabled stream handling // set if current thread has currently enabled stream handling
static _declspec(thread) BOOL _bThreadCanHandleStreams = FALSE; THREADLOCAL(BOOL, _bThreadCanHandleStreams, FALSE);
// list of currently opened streams // list of currently opened streams
static _declspec(thread) CListHead *_plhOpenedStreams = NULL;
ULONG _ulVirtuallyAllocatedSpace = 0; ULONG _ulVirtuallyAllocatedSpace = 0;
ULONG _ulVirtuallyAllocatedSpaceTotal = 0; ULONG _ulVirtuallyAllocatedSpaceTotal = 0;
THREADLOCAL(CListHead *, _plhOpenedStreams, NULL);
// global string with application path // global string with application path
CTFileName _fnmApplicationPath; CTFileName _fnmApplicationPath;
// global string with filename of the started application // global string with filename of the started application
CTFileName _fnmApplicationExe; CTFileName _fnmApplicationExe;
// global string with user-specific writable directory.
CTFileName _fnmUserDir;
// global string with current MOD path // global string with current MOD path
CTFileName _fnmMod; CTFileName _fnmMod;
// global string with current name (the parameter that is passed on cmdline) // global string with current name (the parameter that is passed on cmdline)
@ -104,10 +109,15 @@ static CTFileName _fnmApp;
void InitStreams(void) void InitStreams(void)
{ {
// obtain information about system // obtain information about system
// !!! FIXME: Move this into an abstraction of some sort...
#ifdef PLATFORM_WIN32
SYSTEM_INFO siSystemInfo; SYSTEM_INFO siSystemInfo;
GetSystemInfo( &siSystemInfo); GetSystemInfo( &siSystemInfo);
// and remember page size // and remember page size
_ulPageSize = siSystemInfo.dwPageSize*16; // cca. 64kB on WinNT/Win95 _ulPageSize = siSystemInfo.dwPageSize*16; // cca. 64kB on WinNT/Win95
#else
_ulPageSize = PAGESIZE;
#endif
// keep a copy of path for setting purposes // keep a copy of path for setting purposes
_fnmApp = _fnmApplicationPath; _fnmApp = _fnmApplicationPath;
@ -118,7 +128,9 @@ void InitStreams(void)
LoadStringVar(CTString("DefaultMod.txt"), _fnmMod); LoadStringVar(CTString("DefaultMod.txt"), _fnmMod);
} }
CPrintF(TRANS("Current mod: %s\n"), _fnmMod==""?TRANS("<none>"):(CTString&)_fnmMod); CPrintF(TRANS("Current mod: %s\n"),
(_fnmMod=="") ? TRANS("<none>") :
(const char *) (CTString&)_fnmMod);
// if there is a mod active // if there is a mod active
if (_fnmMod!="") { if (_fnmMod!="") {
// load mod's include/exclude lists // load mod's include/exclude lists
@ -163,54 +175,49 @@ void InitStreams(void)
} }
_findclose( hFile ); _findclose( hFile );
CDynamicArray<CTString> *files;
files = _pFileSystem->FindFiles(_fnmApplicationPath, "*.gro");
int max = files->Count();
int i;
// for each .gro file in the directory
for (i = 0; i < max; i++) {
// add it to active set
UNZIPAddArchive( _fnmApplicationPath+((*files)[i]) );
}
delete files;
// if there is a mod active // if there is a mod active
if (_fnmMod!="") { if (_fnmMod!="") {
// for each group file in mod directory // for each group file in mod directory
struct _finddata_t c_file; files = _pFileSystem->FindFiles(_fnmApplicationPath+_fnmMod, "*.gro");
long hFile; max = files->Count();
hFile = _findfirst(_fnmApplicationPath+_fnmMod+"*.gro", &c_file); for (i = 0; i < max; i++) {
BOOL bOK = (hFile!=-1); UNZIPAddArchive( _fnmApplicationPath + _fnmMod + ((*files)[i]) );
while(bOK) { }
if (CTString(c_file.name).Matches("*.gro")) { delete files;
// add it to active set
UNZIPAddArchive(_fnmApplicationPath+_fnmMod+c_file.name);
}
bOK = _findnext(hFile, &c_file)==0;
}
_findclose( hFile );
} }
// if there is a CD path // if there is a CD path
if (_fnmCDPath!="") { if (_fnmCDPath!="") {
// for each group file on the CD // for each group file on the CD
struct _finddata_t c_file; files = _pFileSystem->FindFiles(_fnmCDPath, "*.gro");
long hFile; max = files->Count();
hFile = _findfirst(_fnmCDPath+"*.gro", &c_file); for (i = 0; i < max; i++) {
BOOL bOK = (hFile!=-1); UNZIPAddArchive( _fnmCDPath + ((*files)[i]) );
while(bOK) {
if (CTString(c_file.name).Matches("*.gro")) {
// add it to active set
UNZIPAddArchive(_fnmCDPath+c_file.name);
}
bOK = _findnext(hFile, &c_file)==0;
} }
_findclose( hFile ); delete files;
// if there is a mod active // if there is a mod active
if (_fnmMod!="") { if (_fnmMod!="") {
// for each group file in mod directory // for each group file in mod directory
struct _finddata_t c_file; files = _pFileSystem->FindFiles(_fnmCDPath+_fnmMod, "*.gro");
long hFile; max = files->Count();
hFile = _findfirst(_fnmCDPath+_fnmMod+"*.gro", &c_file); for (i = 0; i < max; i++) {
BOOL bOK = (hFile!=-1); UNZIPAddArchive( _fnmCDPath + _fnmMod + ((*files)[i]) );
while(bOK) {
if (CTString(c_file.name).Matches("*.gro")) {
// add it to active set
UNZIPAddArchive(_fnmCDPath+_fnmMod+c_file.name);
}
bOK = _findnext(hFile, &c_file)==0;
} }
_findclose( hFile ); delete files;
} }
} }
@ -225,7 +232,8 @@ void InitStreams(void)
} }
CPrintF("\n"); CPrintF("\n");
LoadFileList(_afnmNoCRC, CTFILENAME("Data\\NoCRC.lst")); const char *dirsep = CFileSystem::GetDirSeparator();
LoadFileList(_afnmNoCRC, CTFILENAME("Data" + dirsep + "NoCRC.lst"));
_pShell->SetINDEX(CTString("sys")+"_iCPU"+"Misc", 1); _pShell->SetINDEX(CTString("sys")+"_iCPU"+"Misc", 1);
} }
@ -268,6 +276,7 @@ void CTStream::DisableStreamHandling(void)
_plhOpenedStreams = NULL; _plhOpenedStreams = NULL;
} }
#ifdef PLATFORM_WIN32
int CTStream::ExceptionFilter(DWORD dwCode, _EXCEPTION_POINTERS *pExceptionInfoPtrs) int CTStream::ExceptionFilter(DWORD dwCode, _EXCEPTION_POINTERS *pExceptionInfoPtrs)
{ {
// If the exception is not a page fault, exit. // If the exception is not a page fault, exit.
@ -312,6 +321,7 @@ void CTStream::ExceptionFatalError(void)
{ {
FatalError( GetWindowsError( GetLastError()) ); FatalError( GetWindowsError( GetLastError()) );
} }
#endif
/* /*
* Throw an exception of formatted string. * Throw an exception of formatted string.
@ -320,13 +330,20 @@ void CTStream::Throw_t(char *strFormat, ...) // throws char *
{ {
const SLONG slBufferSize = 256; const SLONG slBufferSize = 256;
char strFormatBuffer[slBufferSize]; char strFormatBuffer[slBufferSize];
char strBuffer[slBufferSize]; static char *strBuffer = NULL;
// ...and yes, you are screwed if you call this in a catch block and
// try to access the previous text again.
delete[] strBuffer;
strBuffer = new char[slBufferSize];
// add the stream description to the format string // add the stream description to the format string
_snprintf(strFormatBuffer, slBufferSize, "%s (%s)", strFormat, strm_strStreamDescription); _snprintf(strFormatBuffer, slBufferSize, "%s (%s)", strFormat, (const char *) strm_strStreamDescription);
// format the message in buffer // format the message in buffer
va_list arg; va_list arg;
va_start(arg, strFormat); // variable arguments start after this argument va_start(arg, strFormat); // variable arguments start after this argument
_vsnprintf(strBuffer, slBufferSize, strFormatBuffer, arg); _vsnprintf(strBuffer, slBufferSize, strFormatBuffer, arg);
va_end(arg);
throw strBuffer; throw strBuffer;
} }
@ -379,7 +396,7 @@ void CTStream::GetLine_t(char *strBuffer, SLONG slBufferSize, char cDelimiter /*
INDEX iLetters = 0; INDEX iLetters = 0;
// test if EOF reached // test if EOF reached
if(AtEOF()) { if(AtEOF()) {
ThrowF_t(TRANS("EOF reached, file %s"), strm_strStreamDescription); ThrowF_t(TRANS("EOF reached, file %s"), (const char *) strm_strStreamDescription);
} }
// get line from istream // get line from istream
FOREVER FOREVER
@ -466,6 +483,7 @@ void CTStream::FPrintF_t(const char *strFormat, ...) // throw char *
va_list arg; va_list arg;
va_start(arg, strFormat); // variable arguments start after this argument va_start(arg, strFormat); // variable arguments start after this argument
_vsnprintf(strBuffer, slBufferSize, strFormat, arg); _vsnprintf(strBuffer, slBufferSize, strFormat, arg);
va_end(arg);
// print the buffer // print the buffer
PutString_t(strBuffer); PutString_t(strBuffer);
} }
@ -504,11 +522,12 @@ void CTStream::ExpectID_t(const CChunkID &cidExpected) // throws char *
void CTStream::ExpectKeyword_t(const CTString &strKeyword) // throw char * void CTStream::ExpectKeyword_t(const CTString &strKeyword) // throw char *
{ {
// check that the keyword is present // check that the keyword is present
for(INDEX iKeywordChar=0; iKeywordChar<(INDEX)strlen(strKeyword); iKeywordChar++) { const INDEX total = (INDEX)strlen(strKeyword);
for(INDEX iKeywordChar=0; iKeywordChar<total; iKeywordChar++) {
SBYTE chKeywordChar; SBYTE chKeywordChar;
(*this)>>chKeywordChar; (*this)>>chKeywordChar;
if (chKeywordChar!=strKeyword[iKeywordChar]) { if (chKeywordChar!=strKeyword[iKeywordChar]) {
ThrowF_t(TRANS("Expected keyword %s not found"), strKeyword); ThrowF_t(TRANS("Expected keyword %s not found"), (const char *) strKeyword);
} }
} }
} }
@ -821,7 +840,7 @@ void CTStream::DictionaryPreload_t(void)
fnm.fnm_pserPreloaded = _pModelStock->Obtain_t(fnm); fnm.fnm_pserPreloaded = _pModelStock->Obtain_t(fnm);
} }
} catch (char *strError) { } catch (char *strError) {
CPrintF( TRANS("Cannot preload %s: %s\n"), (CTString&)fnm, strError); CPrintF( TRANS("Cannot preload %s: %s\n"), (const char *) (CTString&)fnm, strError);
} }
} }
} }
@ -883,9 +902,10 @@ void CTFileStream::Open_t(const CTFileName &fnFileName, CTStream::OpenMode om/*=
if (!_bThreadCanHandleStreams) { if (!_bThreadCanHandleStreams) {
// error // error
::ThrowF_t(TRANS("Cannot open file `%s', stream handling is not enabled for this thread"), ::ThrowF_t(TRANS("Cannot open file `%s', stream handling is not enabled for this thread"),
(CTString&)fnFileName); (const char *) (CTString&)fnFileName);
} }
// check parameters // check parameters
ASSERT(strlen(fnFileName)>0); ASSERT(strlen(fnFileName)>0);
// check that the file is not open // check that the file is not open
@ -972,7 +992,7 @@ void CTFileStream::Create_t(const CTFileName &fnFileName,
if(fstrm_pFile == NULL) if(fstrm_pFile == NULL)
{ {
// throw exception // throw exception
Throw_t(TRANS("Cannot create file `%s' (%s)"), (CTString&)fnmFullFileName, Throw_t(TRANS("Cannot create file `%s' (%s)"), (const char *) (CTString&)fnmFullFileName,
strerror(errno)); strerror(errno));
} }
// if file creation was successfull, set stream description to file name // if file creation was successfull, set stream description to file name
@ -1367,7 +1387,7 @@ SLONG GetFileTimeStamp_t(const CTFileName &fnm)
// try to open file for reading // try to open file for reading
file_handle = _open( fnmExpanded, _O_RDONLY | _O_BINARY); file_handle = _open( fnmExpanded, _O_RDONLY | _O_BINARY);
if(file_handle==-1) { if(file_handle==-1) {
ThrowF_t(TRANS("Cannot open file '%s' for reading"), CTString(fnm)); ThrowF_t(TRANS("Cannot open file '%s' for reading"), (const char *) CTString(fnm));
return -1; return -1;
} }
struct stat statFileStatus; struct stat statFileStatus;
@ -1457,6 +1477,7 @@ static INDEX ExpandFilePath_read(ULONG ulType, const CTFileName &fnmFile, CTFile
{ {
// search for the file in zips // search for the file in zips
INDEX iFileInZip = UNZIPGetFileIndex(fnmFile); INDEX iFileInZip = UNZIPGetFileIndex(fnmFile);
const BOOL userdir_not_basedir = (_fnmUserDir != _fnmApplicationPath);
// if a mod is active // if a mod is active
if (_fnmMod!="") { if (_fnmMod!="") {
@ -1542,6 +1563,44 @@ static INDEX ExpandFilePath_read(ULONG ulType, const CTFileName &fnmFile, CTFile
return EFP_NONE; return EFP_NONE;
} }
// rcg01042002 User dir and children may need to be created on the fly...
static void VerifyDirsExist(const char *_path)
{
char *path = (char *) AllocMemory(strlen(_path) + 1);
strcpy(path, _path);
const char *dirsep = CFileSystem::GetDirSeparator();
// skip first dirsep. This assumes an absolute path and some other
// fundamentals of how a filepath is specified.
char *ptr = strstr(path, dirsep);
ASSERT(ptr != NULL);
if (ptr == NULL)
return;
for (ptr = strstr(ptr+1, dirsep); ptr != NULL; ptr = strstr(ptr+1, dirsep)) {
char ch = *ptr;
*ptr = '\0'; // terminate the path.
if (!_pFileSystem->IsDirectory(path)) {
if (_pFileSystem->Exists(path)) {
CPrintF("Expected %s to be a directory, but it's a file!\n", path);
break;
} else {
CPrintF("Creating directory %s ...\n", path);
_mkdir(path);
if (!_pFileSystem->IsDirectory(path)) {
CPrintF("Creation of directory %s FAILED!\n", path);
break;
}
}
}
*ptr = ch; // put path char back...
}
FreeMemory(path);
}
// Expand a file's filename to full path // Expand a file's filename to full path
INDEX ExpandFilePath(ULONG ulType, const CTFileName &fnmFile, CTFileName &fnmExpanded) INDEX ExpandFilePath(ULONG ulType, const CTFileName &fnmFile, CTFileName &fnmExpanded)
{ {

View File

@ -357,12 +357,14 @@ ENGINE_API INDEX ExpandFilePath(ULONG ulType, const CTFileName &fnmFile, CTFileN
ENGINE_API void MakeDirList( ENGINE_API void MakeDirList(
CDynamicStackArray<CTFileName> &adeDir, CDynamicStackArray<CTFileName> &adeDir,
const CTFileName &fnmDir, // directory to list const CTFileName &fnmDir, // directory to list
const CTString &strPattern, // pattern for each file to match ("" matches all) const CTFileName &fnmPattern, // pattern for each file to match ("" matches all)
ULONG ulFlags // additional flags ULONG ulFlags // additional flags
); );
// global string with application path // global string with application path
ENGINE_API extern CTFileName _fnmApplicationPath; ENGINE_API extern CTFileName _fnmApplicationPath;
// global string with user-specific writable directory.
ENGINE_API extern CTFileName _fnmUserDir;
// global string with current MOD path // global string with current MOD path
ENGINE_API extern CTFileName _fnmMod; ENGINE_API extern CTFileName _fnmMod;
// global string with current name (the parameter that is passed on cmdline) // global string with current name (the parameter that is passed on cmdline)

View File

@ -7,9 +7,10 @@
#endif #endif
// intra-process mutex (only used by thread of same process) // intra-process mutex (only used by thread of same process)
// NOTE: mutex has no interface - it is locked using CTSingleLock
class CTCriticalSection { class CTCriticalSection {
public: public:
// !!! FIXME : rcg10142001 This would be better with a real subclass,
// !!! FIXME : and not void pointers.
void *cs_pvObject; // object is internal to implementation void *cs_pvObject; // object is internal to implementation
INDEX cs_iIndex; // index of mutex used to prevent deadlock with assertions INDEX cs_iIndex; // index of mutex used to prevent deadlock with assertions
// use numbers from 1 and above for deadlock control, or -1 for no deadlock control // use numbers from 1 and above for deadlock control, or -1 for no deadlock control
@ -18,6 +19,10 @@ public:
INDEX Lock(void); INDEX Lock(void);
INDEX TryToLock(void); INDEX TryToLock(void);
INDEX Unlock(void); INDEX Unlock(void);
private:
ULONG LockCounter;
ULONG owner;
}; };
// lock object for locking a mutex with automatic unlocking // lock object for locking a mutex with automatic unlocking
@ -34,6 +39,6 @@ public:
ENGINE_API void Unlock(void); ENGINE_API void Unlock(void);
}; };
#endif /* include-once check. */ #endif /* include-once check. */

View File

@ -0,0 +1,147 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#ifndef SE_INCL_THREADLOCALSTORAGE_H
#define SE_INCL_THREADLOCALSTORAGE_H
#ifdef PRAGMA_ONCE
#pragma once
#endif
#ifdef SINGLE_THREADED
#define THREADLOCAL(type, name, defval) type name = defval
#define EXTERNTHREADLOCAL(type, name) extern type name
#elif (defined _MSC_VER)
#define THREADLOCAL(type, name, defval) type __declspec(thread) name = defval
#define EXTERNTHREADLOCAL(type, name) extern type __declspec(thread) name
#else
#define THREADLOCAL(type, name, defval) CThreadLocalStorage<type> name(defval)
#define EXTERNTHREADLOCAL(type, name) extern CThreadLocalStorage<type> name
#include <Engine/Engine.h>
// !!! FIXME : There is a race condition if a thread is making space for
// !!! FIXME : itself at the same time another thread is touching this class.
// !!! FIXME : Generally, this won't be a problem, if you are careful about
// !!! FIXME : new threads accessing an instance of CThreadLocalStorage for
// !!! FIXME : the first time. I haven't added mutexes, since it would slow
// !!! FIXME : the template class down. If you need it, either do some
// !!! FIXME : external locking, or subclass CThreadLocalStorage to include
// !!! FIXME : a locking mechanism.
// !!! FIXME: 15 years later: why didn't I just use a pthread_key?
ULONG ThreadLocalGetCurrentTID(void);
template <class T>
class CThreadLocalStorage
{
protected:
typedef struct
{
ULONG tid;
T data;
} LocalElements;
size_t FindThreadIndex(void)
{
ULONG tid = ThreadLocalGetCurrentTID();
for (size_t i = 0; i < array_size; i++)
{
if (elements[i].tid == tid)
return(i);
} // for
LocalElements *_elements = new LocalElements[array_size + 1];
for (size_t i = 0; i < array_size; i++)
{
_elements[i].data = elements[i].data;
_elements[i].tid = elements[i].tid;
} // for
delete[] elements;
elements = _elements;
elements[array_size].data = defval;
elements[array_size].tid = tid;
return(array_size++);
} // FindThreadIndex
private:
LocalElements *elements;
size_t array_size;
T defval;
public:
CThreadLocalStorage(T _defval)
: elements(NULL),
array_size(0),
defval(_defval)
{
} // Constructor
~CThreadLocalStorage(void)
{
delete[] elements;
} // Destructor
T &operator =(T val)
{
elements[FindThreadIndex()].data = val;
return(val);
} // operator =
T &operator->(void)
{
return(elements[FindThreadIndex()].data);
} // operator ->
operator T &(void)
{
return(elements[FindThreadIndex()].data);
} // operator T &
};
#if 0
// a test program.
static CThreadLocalStorage<int> tlocal(0);
void *other_thread(void *arg)
{
tlocal = 10;
while (true)
{
printf("2nd thread: %d.\n", (int) tlocal);
sleep(1);
}
return(NULL);
}
int main(int argc, char **argv)
{
pthread_t thread;
tlocal = 5;
pthread_create(&thread, NULL, other_thread, NULL);
while (true)
{
printf("main thread: %d.\n", (int) tlocal);
sleep(1);
}
return(0);
}
#endif
#endif // !defined SINGLE_THREADED
#endif // include-once blocker.
// end of ThreadLocalStorage.h ...

View File

@ -1,10 +1,11 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Timer.h> #include <Engine/Base/Timer.h>
#include <Engine/Base/Console.h> #include <Engine/Base/Console.h>
#include <Engine/Base/Translation.h> #include <Engine/Base/Translation.h>
#include <Engine/Base/ThreadLocalStorage.h> //rcg10242001
#include <Engine/Base/Registry.h> #include <Engine/Base/Registry.h>
#include <Engine/Base/Profiling.h> #include <Engine/Base/Profiling.h>
@ -14,9 +15,23 @@
#include <Engine/Base/ListIterator.inl> #include <Engine/Base/ListIterator.inl>
#include <Engine/Base/Priority.inl> #include <Engine/Base/Priority.inl>
// Read the Pentium TimeStampCounter //#if ( (USE_PORTABLE_C) || (PLATFORM_UNIX) )
//#define USE_GETTIMEOFDAY 1
//#endif
#if USE_GETTIMEOFDAY
#include <sys/time.h>
#endif
// Read the Pentium TimeStampCounter (or something like that).
static inline __int64 ReadTSC(void) static inline __int64 ReadTSC(void)
{ {
#if USE_GETTIMEOFDAY
struct timeval tv;
gettimeofday(&tv, NULL);
return( (((__int64) tv.tv_sec) * 1000000) + ((__int64) tv.tv_usec) );
#elif (defined __MSVC_INLINE__)
__int64 mmRet; __int64 mmRet;
__asm { __asm {
rdtsc rdtsc
@ -24,14 +39,32 @@ static inline __int64 ReadTSC(void)
mov dword ptr [mmRet+4],edx mov dword ptr [mmRet+4],edx
} }
return mmRet; return mmRet;
#elif (defined __GNU_INLINE__)
__int64 mmRet;
__asm__ __volatile__ (
"rdtsc \n\t"
"movl %%eax, 0(%%esi) \n\t"
"movl %%edx, 4(%%esi) \n\t"
:
: "S" (&mmRet)
: "memory", "eax", "edx"
);
return(mmRet);
#else
#error Please implement for your platform/compiler.
#endif
} }
// link with Win-MultiMedia // link with Win-MultiMedia
#ifdef _MSC_VER
#pragma comment(lib, "winmm.lib") #pragma comment(lib, "winmm.lib")
#endif
// current game time always valid for the currently active task // current game time always valid for the currently active task
static _declspec(thread) TIME _CurrentTickTimer = 0.0f; THREADLOCAL(TIME, _CurrentTickTimer, 0.0f);
// CTimer implementation // CTimer implementation
@ -76,9 +109,30 @@ void CTimer_TimerFunc_internal(void)
// streams and to group file before enabling that! // streams and to group file before enabling that!
// CTSTREAM_BEGIN { // CTSTREAM_BEGIN {
#ifdef SINGLE_THREADED
// rcg10272001 experimenting here...
static CTimerValue highResQuantum((double) _pTimer->TickQuantum);
CTimerValue upkeep = _pTimer->GetHighPrecisionTimer() - _pTimer->tm_InitialTimerUpkeep;
TIME t = upkeep.GetSeconds();
if (t < _pTimer->TickQuantum) // not time to do an update, yet.
return;
while (t >= _pTimer->TickQuantum) {
_pTimer->tm_InitialTimerUpkeep += highResQuantum;
_pTimer->tm_RealTimeTimer += _pTimer->TickQuantum;
t -= _pTimer->TickQuantum;
}
#else
// increment the 'real time' timer // increment the 'real time' timer
_pTimer->tm_RealTimeTimer += _pTimer->TickQuantum; _pTimer->tm_RealTimeTimer += _pTimer->TickQuantum;
#endif
// get the current time for real and in ticks // get the current time for real and in ticks
CTimerValue tvTimeNow = _pTimer->GetHighPrecisionTimer(); CTimerValue tvTimeNow = _pTimer->GetHighPrecisionTimer();
TIME tmTickNow = _pTimer->tm_RealTimeTimer; TIME tmTickNow = _pTimer->tm_RealTimeTimer;
@ -104,6 +158,10 @@ void CTimer_TimerFunc_internal(void)
// } CTSTREAM_END; // } CTSTREAM_END;
} }
// !!! FIXME : rcg10192001 Abstract this!
#if (!defined SINGLE_THREADED)
#ifdef PLATFORM_WIN32
void __stdcall CTimer_TimerFunc(UINT uID, UINT uMsg, ULONG dwUser, ULONG dw1, ULONG dw2) void __stdcall CTimer_TimerFunc(UINT uID, UINT uMsg, ULONG dwUser, ULONG dw1, ULONG dw2)
{ {
// access to the list of handlers must be locked // access to the list of handlers must be locked
@ -111,7 +169,18 @@ void __stdcall CTimer_TimerFunc(UINT uID, UINT uMsg, ULONG dwUser, ULONG dw1, UL
// handle all timers // handle all timers
CTimer_TimerFunc_internal(); CTimer_TimerFunc_internal();
} }
#elif (defined PLATFORM_UNIX)
#include "SDL.h"
Uint32 CTimer_TimerFunc_SDL(Uint32 interval)
{
// access to the list of handlers must be locked
CTSingleLock slHooks(&_pTimer->tm_csHooks, TRUE);
// handle all timers
CTimer_TimerFunc_internal();
return(interval);
}
#endif
#endif
#pragma inline_depth() #pragma inline_depth()
@ -121,6 +190,7 @@ static INDEX _aiTries[MAX_MEASURE_TRIES];
// Get processor speed in Hertz // Get processor speed in Hertz
static __int64 GetCPUSpeedHz(void) static __int64 GetCPUSpeedHz(void)
{ {
#ifdef PLATFORM_WIN32
// get the frequency of the 'high' precision timer // get the frequency of the 'high' precision timer
__int64 llTimerFrequency; __int64 llTimerFrequency;
BOOL bPerformanceCounterPresent = QueryPerformanceFrequency((LARGE_INTEGER*)&llTimerFrequency); BOOL bPerformanceCounterPresent = QueryPerformanceFrequency((LARGE_INTEGER*)&llTimerFrequency);
@ -138,8 +208,7 @@ static __int64 GetCPUSpeedHz(void)
__int64 llSpeedMeasured; __int64 llSpeedMeasured;
// try to measure 10 times // try to measure 10 times
INDEX iSet=0; for( INDEX iSet=0; iSet<10; iSet++)
for( ; iSet<10; iSet++)
{ // one time has several tries { // one time has several tries
for( iTry=0; iTry<MAX_MEASURE_TRIES; iTry++) for( iTry=0; iTry<MAX_MEASURE_TRIES; iTry++)
{ // wait the state change on the timer { // wait the state change on the timer
@ -202,20 +271,40 @@ static __int64 GetCPUSpeedHz(void)
// use measured value // use measured value
return (__int64)slSpeedRead*1000000; return (__int64)slSpeedRead*1000000;
} }
#else
STUBBED("I hope this isn't critical...");
return(1);
#endif
} }
#if PLATFORM_MACOSX
extern "C" { signed int GetCPUSpeed(void); } // carbon function, avoid header.
#endif
/* /*
* Constructor. * Constructor.
*/ */
CTimer::CTimer(BOOL bInterrupt /*=TRUE*/) CTimer::CTimer(BOOL bInterrupt /*=TRUE*/)
{ {
#if (defined SINGLE_THREADED)
bInterrupt = FALSE;
#endif
tm_csHooks.cs_iIndex = 1000; tm_csHooks.cs_iIndex = 1000;
// set global pointer // set global pointer
ASSERT(_pTimer == NULL); ASSERT(_pTimer == NULL);
_pTimer = this; _pTimer = this;
tm_bInterrupt = bInterrupt; tm_bInterrupt = bInterrupt;
#if USE_GETTIMEOFDAY
// just use gettimeofday.
tm_llCPUSpeedHZ = tm_llPerformanceCounterFrequency = 1000000;
#elif PLATFORM_WIN32
{ // this part of code must be executed as precisely as possible { // this part of code must be executed as precisely as possible
CSetPriority sp(REALTIME_PRIORITY_CLASS, THREAD_PRIORITY_TIME_CRITICAL); CSetPriority sp(REALTIME_PRIORITY_CLASS, THREAD_PRIORITY_TIME_CRITICAL);
tm_llCPUSpeedHZ = GetCPUSpeedHz(); tm_llCPUSpeedHZ = GetCPUSpeedHz();
@ -225,6 +314,54 @@ CTimer::CTimer(BOOL bInterrupt /*=TRUE*/)
CProfileForm::CalibrateProfilingTimers(); CProfileForm::CalibrateProfilingTimers();
} }
#elif PLATFORM_MACOSX
tm_llPerformanceCounterFrequency = tm_llCPUSpeedHZ = ((__int64) GetCPUSpeed()) * 1000000;
#else
// !!! FIXME : This is an ugly hack.
double mhz = 0.0;
const char *envmhz = getenv("SERIOUS_MHZ");
if (envmhz != NULL)
{
mhz = atof(envmhz);
}
else
{
FILE *fp = fopen("/proc/cpuinfo", "rb");
if (fp != NULL)
{
char *buf = (char *) malloc(10240); // bleh.
if (buf != NULL)
{
fread(buf, 10240, 1, fp);
char *ptr = strstr(buf, "cpu MHz");
if (ptr != NULL)
{
ptr = strchr(ptr, ':');
if (ptr != NULL)
{
do
{
ptr++;
} while ((*ptr == '\t') || (*ptr == ' '));
mhz = atof(ptr);
}
}
free(buf);
}
fclose(fp);
}
}
if (mhz == 0.0) {
FatalError("Can't get CPU speed. Please set SERIOUS_MHZ environment variable.");
}
tm_llPerformanceCounterFrequency = tm_llCPUSpeedHZ = (__int64) (mhz * 1000000.0);
#endif
// clear counters // clear counters
_CurrentTickTimer = TIME(0); _CurrentTickTimer = TIME(0);
tm_RealTimeTimer = TIME(0); tm_RealTimeTimer = TIME(0);
@ -236,8 +373,18 @@ CTimer::CTimer(BOOL bInterrupt /*=TRUE*/)
tm_fLerpFactor2 = 1.0f; tm_fLerpFactor2 = 1.0f;
// start interrupt (eventually) // start interrupt (eventually)
#if (defined SINGLE_THREADED)
tm_InitialTimerUpkeep = GetHighPrecisionTimer();
#else
if( tm_bInterrupt) if( tm_bInterrupt)
{ {
// !!! FIXME : rcg10192001 Abstract this!
#ifdef PLATFORM_WIN32
tm_TimerID = timeSetEvent( tm_TimerID = timeSetEvent(
ULONG(TickQuantum*1000.0f), // period value [ms] ULONG(TickQuantum*1000.0f), // period value [ms]
0, // resolution (0==max. possible) 0, // resolution (0==max. possible)
@ -248,18 +395,27 @@ CTimer::CTimer(BOOL bInterrupt /*=TRUE*/)
// check that interrupt was properly started // check that interrupt was properly started
if( tm_TimerID==NULL) FatalError(TRANS("Cannot initialize multimedia timer!")); if( tm_TimerID==NULL) FatalError(TRANS("Cannot initialize multimedia timer!"));
#else
if (SDL_Init(SDL_INIT_TIMER) == -1) FatalError(TRANS("Cannot initialize multimedia timer!"));
SDL_SetTimer(ULONG(TickQuantum*1000.0f), CTimer_TimerFunc_SDL);
#endif
// make sure that timer interrupt is ticking // make sure that timer interrupt is ticking
INDEX iTry=1; INDEX iTry;
for( ; iTry<=3; iTry++) { for(iTry=1; iTry<=3; iTry++) {
const TIME tmTickBefore = GetRealTimeTick(); const TIME tmTickBefore = GetRealTimeTick();
Sleep(1000* iTry*3 *TickQuantum); Sleep(1000* iTry*3 *TickQuantum);
const TIME tmTickAfter = GetRealTimeTick(); const TIME tmTickAfter = GetRealTimeTick();
ASSERT(tmTickBefore <= tmTickAfter);
if( tmTickBefore!=tmTickAfter) break; if( tmTickBefore!=tmTickAfter) break;
Sleep(1000*iTry); Sleep(1000*iTry);
} }
// report fatal // report fatal
if( iTry>3) FatalError(TRANS("Problem with initializing multimedia timer - please try again.")); if( iTry>3) FatalError(TRANS("Problem with initializing multimedia timer - please try again."));
} }
#endif // !defined SINGLE_THREADED
} }
/* /*
@ -267,19 +423,29 @@ CTimer::CTimer(BOOL bInterrupt /*=TRUE*/)
*/ */
CTimer::~CTimer(void) CTimer::~CTimer(void)
{ {
// !!! FIXME : abstract this.
#if (!defined SINGLE_THREADED)
#ifdef PLATFORM_WIN32
ASSERT(_pTimer == this); ASSERT(_pTimer == this);
// destroy timer // destroy timer
if (tm_bInterrupt) { if (tm_bInterrupt) {
ASSERT(tm_TimerID!=NULL); ASSERT(tm_TimerID);
ULONG rval = timeKillEvent(tm_TimerID); ULONG rval = timeKillEvent(tm_TimerID);
ASSERT(rval == TIMERR_NOERROR); ASSERT(rval == TIMERR_NOERROR);
} }
// check that all handlers have been removed // check that all handlers have been removed
ASSERT(tm_lhHooks.IsEmpty()); ASSERT(tm_lhHooks.IsEmpty());
#else
SDL_SetTimer(0, NULL);
#endif
#endif
// clear global pointer // clear global pointer
_pTimer = NULL; _pTimer = NULL;
} }
/* /*
@ -315,6 +481,13 @@ void CTimer::HandleTimerHandlers(void)
CTimer_TimerFunc_internal(); CTimer_TimerFunc_internal();
} }
/*
* Get current timer value of high precision timer.
*/
CTimerValue CTimer::GetHighPrecisionTimer(void)
{
return ReadTSC();
}
/* /*
* Set the real time tick value. * Set the real time tick value.
@ -377,7 +550,7 @@ void CTimer::DisableLerp(void)
CTString TimeToString(FLOAT fTime) CTString TimeToString(FLOAT fTime)
{ {
CTString strTime; CTString strTime;
int iSec = floor(fTime); int iSec = (int) floor(fTime);
int iMin = iSec/60; int iMin = iSec/60;
iSec = iSec%60; iSec = iSec%60;
int iHou = iMin/60; int iHou = iMin/60;

View File

@ -23,7 +23,7 @@ public:
inline CTimerValue(__int64 llValue) : tv_llValue(llValue) {}; inline CTimerValue(__int64 llValue) : tv_llValue(llValue) {};
public: public:
/* Constructor. */ /* Constructor. */
inline CTimerValue(void) {}; inline CTimerValue(void) : tv_llValue((__int64) -1) {}
/* Constructor from seconds. */ /* Constructor from seconds. */
inline CTimerValue(double dSeconds); inline CTimerValue(double dSeconds);
/* Clear timer value (set it to zero). */ /* Clear timer value (set it to zero). */
@ -118,13 +118,20 @@ public:
inline FLOAT GetLerpFactor2(void) const { return tm_fLerpFactor2; }; inline FLOAT GetLerpFactor2(void) const { return tm_fLerpFactor2; };
/* Get current timer value of high precision timer. */ /* Get current timer value of high precision timer. */
inline CTimerValue GetHighPrecisionTimer(void) { CTimerValue GetHighPrecisionTimer(void);
__int64 mmRet;
_asm rdtsc /*
_asm mov dword ptr [mmRet+0],eax * rcg10072001
_asm mov dword ptr [mmRet+4],edx * put current process to sleep for at least (milliseconds) milliseconds.
return mmRet; * Note that many platforms can't sleep less than 10 milliseconds, and
}; * most will not revive your thread at the exact moment you requested.
* So don't use this on life support machines. :)
*/
void Sleep(DWORD milliseconds);
#ifdef SINGLE_THREADED
CTimerValue tm_InitialTimerUpkeep; // don't touch.
#endif
}; };
// pointer to global timer object // pointer to global timer object

View File

@ -7,7 +7,7 @@
/* Constructor from seconds. */ /* Constructor from seconds. */
inline CTimerValue::CTimerValue(double fSeconds) inline CTimerValue::CTimerValue(double fSeconds)
{ {
tv_llValue = __int64(fSeconds*_pTimer->tm_llPerformanceCounterFrequency); tv_llValue = (__int64) (fSeconds*_pTimer->tm_llPerformanceCounterFrequency);
} }
/* Clear timer value (set it to zero). */ /* Clear timer value (set it to zero). */
inline void CTimerValue::Clear(void) inline void CTimerValue::Clear(void)

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/CTString.h> #include <Engine/Base/CTString.h>
#include <Engine/Base/Translation.h> #include <Engine/Base/Translation.h>

View File

@ -6,12 +6,16 @@
#pragma once #pragma once
#endif #endif
#ifdef _MSC_VER
#define __MSVC_INLINE__
#endif
#include <Engine/Base/Base.h> #include <Engine/Base/Base.h>
#include <Engine/Graphics/gl_types.h> #include <Engine/Graphics/gl_types.h>
typedef signed long int SLONG; typedef signed long int SLONG;
typedef signed short int SWORD; typedef signed short int SWORD;
typedef signed char SBYTE; typedef signed char SBYTE;
typedef signed int SINT; typedef signed int SINT;
typedef unsigned long int ULONG; typedef unsigned long int ULONG;
@ -20,27 +24,194 @@ typedef unsigned char UBYTE;
typedef unsigned int UINT; typedef unsigned int UINT;
#ifdef PLATFORM_UNIX /* rcg10042001 */ #if __POWERPC__ /* rcg03232004 */
#define __forceinline inline #define PLATFORM_BIGENDIAN 1
#define PLATFORM_LITTLEENDIAN 0
#else
#define PLATFORM_BIGENDIAN 0
#define PLATFORM_LITTLEENDIAN 1
#endif
#if (!defined MAX_PATH) // Mac symbols have an underscore prepended...
#define MAX_PATH 256 #if PLATFORM_MACOSX
#define ASMSYM(x) "_" #x
#else
#define ASMSYM(x) #x
#endif
#ifdef PLATFORM_UNIX /* rcg10042001 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <errno.h>
#include <stdarg.h>
#include <ctype.h>
#include <limits.h> // for PAGESIZE...
#include <math.h>
// check for legacy defines...
#if (defined __ICC)
#if (!defined __INTEL_COMPILER)
#define __INTEL_COMPILER __ICC
#endif
#endif #endif
typedef long long __int64; #if ((defined __GNUC__) && (!defined __GNU_INLINE__))
#define __GNU_INLINE__
#endif
#if (defined __INTEL_COMPILER)
#if ((!defined __GNU_INLINE__) && (!defined __MSVC_INLINE__))
#error Please define __GNU_INLINE__ or __MSVC_INLINE__ with Intel C++.
#endif
#if ((defined __GNU_INLINE__) && (defined __MSVC_INLINE__))
#error Define either __GNU_INLINE__ or __MSVC_INLINE__ with Intel C++.
#endif
#endif
#ifndef PAGESIZE
#define PAGESIZE 4096
#endif
#define FAR
#define __forceinline inline
#define __stdcall
#define __cdecl
#define WINAPI
#if (!defined MAX_PATH)
#if (defined MAXPATHLEN)
#define MAX_PATH MAXPATHLEN
#else
#define MAX_PATH 256
#endif
#endif
#define _O_BINARY 0
#define _O_RDONLY O_RDONLY
#define _S_IWRITE S_IWRITE
#define _S_IREAD S_IREAD
#if (!defined __INTEL_COMPILER)
#define _alloca alloca
#endif
#define _CrtCheckMemory() 1
#define _mkdir(x) mkdir(x, S_IRWXU)
#define _open open
#define _close close
#define _strupr strupr
#define stricmp strcasecmp
#define strcmpi strcasecmp
#define strnicmp strncasecmp
#define _vsnprintf vsnprintf
#define _snprintf snprintf
#define _set_new_handler std::set_new_handler
#define _finite finite
inline void _RPT_do(const char *type, const char *fmt, ...)
{
#if 0
#if (!defined NDEBUG)
va_list ap;
fprintf(stderr, "_RPT (%s): ", type);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fflush(stderr);
#endif
#endif
} // _RPT0
#define _CRT_WARN "_CRT_WARN"
#define _CRT_ERROR "_CRT_ERROR"
#define _CRT_ASSER "_CRT_ASSERT"
#define _RPT0(type, fmt) _RPT_do(type, fmt)
#define _RPT1(type, fmt, a1) _RPT_do(type, fmt, a1)
#define _RPT2(type, fmt, a1, a2) _RPT_do(type, fmt, a1, a2)
#define _RPT3(type, fmt, a1, a2, a3) _RPT_do(type, fmt, a1, a2, a3)
#define _RPT4(type, fmt, a1, a2, a3, a4) _RPT_do(type, fmt, a1, a2, a3, a4)
#define STUBBED(txt) fprintf(stderr, "STUB: %s in %s, line %d.\n", txt, __FILE__, __LINE__)
// !!! FIXME : Should inline functions go somewhere else?
inline void _strupr(char *str)
{
if (str != NULL)
{
for (char *ptr = str; *ptr; ptr++)
*ptr = toupper(*ptr);
}
}
inline ULONG _rotl(ULONG ul, int bits)
{
#if (defined USE_PORTABLE_C)
// This is not fast at all, but it works.
for (int i = 0; i < bits; i++)
ul = ( (ul << 1) | ((ul & 0x80000000) >> 31) );
return(ul);
#elif (defined __GNU_INLINE__)
// This, on the other hand, is wicked fast. :)
__asm__ __volatile__ (
"roll %%cl, %%eax \n\t"
: "=a" (ul)
: "a" (ul), "c" (bits)
: "cc"
);
return(ul);
#elif (defined __MSVC_INLINE__)
// MSVC version for Intel C++...
__asm
{
mov eax, dword ptr [ul]
mov ecx, dword ptr [bits]
rol eax, cl
mov dword ptr [ul], eax
}
return(ul);
#else
#error need inline asm for your platform.
#endif
}
typedef unsigned long long __uint64;
#if (!defined __INTEL_COMPILER)
typedef long long __int64;
#endif
typedef UBYTE BYTE;
typedef unsigned short WORD;
typedef unsigned long int DWORD; typedef unsigned long int DWORD;
typedef signed long int LONG; typedef signed long int LONG;
typedef void *LPVOID;
typedef char *LPSTR;
typedef signed long int WPARAM;
typedef signed long int LPARAM;
typedef signed short int SHORT;
typedef void *HWND; /* !!! FIXME this sucks. */ typedef void *HWND; /* !!! FIXME this sucks. */
typedef void *HINSTANCE; /* !!! FIXME this sucks. */ typedef void *HINSTANCE; /* !!! FIXME this sucks. */
typedef void *HGLRC; /* !!! FIXME this sucks. */ typedef void *HGLRC; /* !!! FIXME this sucks. */
typedef void *HGLOBAL; /* !!! FIXME this sucks. */
typedef ULONG COLORREF; /* !!! FIXME this sucks. */ typedef ULONG COLORREF; /* !!! FIXME this sucks. */
typedef struct typedef struct
{ {
LONG x; LONG x;
LONG y; LONG y;
} POINT; } POINT, *LPPOINT;
typedef struct typedef struct
{ {
@ -49,6 +220,20 @@ typedef unsigned int UINT;
LONG right; LONG right;
LONG bottom; LONG bottom;
} RECT; } RECT;
#define WAVE_FORMAT_PCM 0x0001
typedef struct
{
SWORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
WORD wBitsPerSample;
WORD nBlockAlign;
DWORD nAvgBytesPerSec;
WORD cbSize;
} WAVEFORMATEX;
#endif #endif
@ -93,10 +278,18 @@ typedef long int INDEX; // for indexed values and quantities
#define ANGLE_270 (270.0f) #define ANGLE_270 (270.0f)
#define ANGLE_360 (360.0f) #define ANGLE_360 (360.0f)
// you need <stddef.h> for this!
// Stupid GCC bug.
#if (__GNUC__ >= 3)
#define _offsetof(cl, mbr) (((size_t)&(((cl *)0x0004)->mbr)) - 0x0004)
#else
// you need <stddef.h> for this!
#define _offsetof(cl, mbr) offsetof(cl, mbr)
#endif
#define structptr(structure, member, ptr) \ #define structptr(structure, member, ptr) \
( (struct structure *) ( ((UBYTE *)(ptr)) - \ ( (struct structure *) ( ((UBYTE *)(ptr)) - \
offsetof(struct structure, member)) ) _offsetof(struct structure, member)) )
// standard types // standard types
@ -396,6 +589,9 @@ typedef BSPCutter<FLOAT, 3> FLOATbspcutter3D;
template<class cType> template<class cType>
inline void Clear(cType &t) { t.cType::Clear(); }; inline void Clear(cType &t) { t.cType::Clear(); };
template<class cType>
inline void Clear(cType *t) { t->cType::Clear(); };
// specific clearing functions for built-in types // specific clearing functions for built-in types
inline void Clear(signed long int sli) {}; inline void Clear(signed long int sli) {};
inline void Clear(unsigned long int uli) {}; inline void Clear(unsigned long int uli) {};
@ -404,7 +600,101 @@ inline void Clear(float i) {};
inline void Clear(double i) {}; inline void Clear(double i) {};
inline void Clear(void *pv) {}; inline void Clear(void *pv) {};
#define SYMBOLLOCATOR(symbol) // These macros are not safe to use unless data is UNSIGNED!
#define BYTESWAP16_unsigned(x) ((((x)>>8)&0xff)+ (((x)<<8)&0xff00))
#define BYTESWAP32_unsigned(x) (((x)>>24) + (((x)>>8)&0xff00) + (((x)<<8)&0xff0000) + ((x)<<24))
// rcg03242004
#if PLATFORM_LITTLEENDIAN
#define BYTESWAP(x)
#else
static inline void BYTESWAP(UWORD &val)
{
#if __POWERPC__
__asm__ __volatile__ (
"lhbrx %0,0,%1"
: "=r" (val)
: "r" (&val)
);
#else
val = BYTESWAP16_unsigned(val);
#endif
}
static inline void BYTESWAP(SWORD &val)
{
// !!! FIXME: reinterpret_cast ?
UWORD uval = *((UWORD *) &val);
BYTESWAP(uval);
val = *((SWORD *) &uval);
}
static inline void BYTESWAP(ULONG &val)
{
#if __POWERPC__
__asm__ __volatile__ (
"lwbrx %0,0,%1"
: "=r" (val)
: "r" (&val)
);
#else
val = BYTESWAP32_unsigned(val);
#endif
}
static inline void BYTESWAP(SLONG &val)
{
// !!! FIXME: reinterpret_cast ?
ULONG uval = *((ULONG *) &val);
BYTESWAP(uval);
val = *((SLONG *) &uval);
}
static inline void BYTESWAP(BOOL &val)
{
// !!! FIXME: reinterpret_cast ?
ULONG uval = *((ULONG *) &val);
BYTESWAP(uval);
val = *((BOOL *) &uval);
}
static inline void BYTESWAP(FLOAT &val)
{
// !!! FIXME: reinterpret_cast ?
ULONG uval = *((ULONG *) &val);
BYTESWAP(uval);
val = *((FLOAT *) &uval);
}
static inline void BYTESWAP(__uint64 &val)
{
ULONG l = (ULONG) (val & 0xFFFFFFFF);
ULONG h = (ULONG) ((val >> 32) & 0xFFFFFFFF);
BYTESWAP(l);
BYTESWAP(h);
val = ( (((__uint64) (l)) << 32) |
((__uint64) (h)) );
}
static inline void BYTESWAP(__int64 &val)
{
// !!! FIXME: reinterpret_cast ?
__uint64 uval = *((__uint64 *) &val);
BYTESWAP(uval);
val = *((__int64 *) &uval);
}
static inline void BYTESWAP(DOUBLE &val)
{
// !!! FIXME: reinterpret_cast ?
__uint64 uval = *((__uint64 *) &val);
BYTESWAP(uval);
val = *((DOUBLE *) &uval);
}
#endif
#endif /* include-once check. */ #endif /* include-once check. */

View File

@ -0,0 +1,122 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
/* rcg10072001 Implemented. */
#include <dlfcn.h>
#include <Engine/Engine.h>
#include <Engine/Base/DynamicLoader.h>
class CUnixDynamicLoader : public CDynamicLoader
{
public:
CUnixDynamicLoader(const char *libname);
virtual ~CUnixDynamicLoader(void);
virtual void *FindSymbol(const char *sym);
virtual const char *GetError(void);
protected:
void DoOpen(const char *lib);
void SetError(void);
void *module;
CTString *err;
};
CDynamicLoader *CDynamicLoader::GetInstance(const char *libname)
{
return(new CUnixDynamicLoader(libname));
}
void CUnixDynamicLoader::SetError(void)
{
const char *errmsg = ::dlerror();
delete err;
err = NULL;
if (errmsg != NULL)
{
CPrintF("CUnixDynamicLoader error: %s\n", errmsg);
err = new CTString(errmsg);
}
}
const char *CUnixDynamicLoader::GetError(void)
{
return((err) ? (const char *) (*err) : NULL);
}
void *CUnixDynamicLoader::FindSymbol(const char *sym)
{
//printf("Looking for symbol %s\n", sym);
void *retval = NULL;
if (module != NULL) {
retval = ::dlsym(module, sym);
SetError();
}
return(retval);
}
void CUnixDynamicLoader::DoOpen(const char *lib)
{
module = ::dlopen(lib, RTLD_LAZY | RTLD_GLOBAL);
SetError();
}
CTFileName CDynamicLoader::ConvertLibNameToPlatform(const char *libname)
{
#if PLATFORM_MACOSX
const char *DLLEXTSTR = ".dylib";
#else
const char *DLLEXTSTR = ".so";
#endif
CTFileName fnm = CTString(libname);
CTString libstr((strncmp("lib", fnm.FileName(), 3) == 0) ? "" : "lib");
return(fnm.FileDir() + libstr + fnm.FileName() + DLLEXTSTR);
}
CUnixDynamicLoader::CUnixDynamicLoader(const char *libname)
: module(NULL),
err(NULL)
{
if (libname == NULL) {
DoOpen(NULL);
} else {
CTFileName fnm = ConvertLibNameToPlatform(libname);
// Always try to dlopen from inside the game dirs before trying
// system libraries...
if (fnm.FileDir() == "") {
char buf[MAX_PATH];
_pFileSystem->GetExecutablePath(buf, sizeof (buf));
CTFileName fnmDir = CTString(buf);
fnmDir = fnmDir.FileDir() + fnm;
DoOpen(fnmDir);
if (module != NULL) {
return;
}
}
DoOpen(fnm);
}
}
CUnixDynamicLoader::~CUnixDynamicLoader(void)
{
delete err;
if (module != NULL)
::dlclose(module);
}
// end of UnixDynamicLoader.cpp ...

View File

@ -0,0 +1,345 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
/* rcg10142001 Implemented. */
// !!! FIXME: rcg10142001 This should really be using CTStrings...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/param.h>
#include <unistd.h>
#include <Engine/Engine.h>
#include <Engine/Base/FileSystem.h>
ENGINE_API CFileSystem *_pFileSystem = NULL;
class CUnixFileSystem : public CFileSystem
{
public:
CUnixFileSystem(const char *argv0, const char *gamename);
virtual ~CUnixFileSystem(void);
virtual void GetExecutablePath(char *buf, ULONG bufSize);
virtual void GetUserDirectory(char *buf, ULONG bufSize);
virtual CDynamicArray<CTString> *FindFiles(const char *dir,
const char *wildcard);
protected:
char *exePath;
char *userDir;
};
const char *CFileSystem::GetDirSeparator(void)
{
return("/");
}
BOOL CFileSystem::IsDummyFile(const char *fname)
{
return( (strcmp(fname, ".") == 0) || (strcmp(fname, "..") == 0) );
}
BOOL CFileSystem::Exists(const char *fname)
{
struct stat s;
if (stat(fname, &s) == -1)
return(FALSE);
return(TRUE);
}
BOOL CFileSystem::IsDirectory(const char *fname)
{
struct stat s;
if (stat(fname, &s) == -1)
return(FALSE);
return(S_ISDIR(s.st_mode) ? TRUE : FALSE);
}
CFileSystem *CFileSystem::GetInstance(const char *argv0, const char *gamename)
{
return(new CUnixFileSystem(argv0, gamename));
}
static char *copyEnvironmentVariable(const char *varname)
{
const char *envr = getenv(varname);
char *retval = NULL;
if (envr != NULL)
{
retval = new char[strlen(envr) + 1];
strcpy(retval, envr);
}
return(retval);
}
static char *getUserDirByUID(void)
{
uid_t uid = getuid();
struct passwd *pw;
char *retval = NULL;
pw = getpwuid(uid);
if ((pw != NULL) && (pw->pw_dir != NULL))
{
retval = new char[strlen(pw->pw_dir) + 1];
strcpy(retval, pw->pw_dir);
}
return(retval);
}
// !!! FIXME: This could stand to use CTFileNames ...
static char *calcExePath(const char *_argv0)
{
char *ptr;
char *retval = NULL;
char *argv0 = new char[strlen(_argv0) + 1];
strcpy(argv0, _argv0); /* _argv0 may be read-only... */
ptr = strrchr(argv0, '/');
if (ptr != NULL) // explicit path specified? We're done.
{
retval = new char[strlen(argv0) + 1];
strcpy(retval, argv0);
}
// If there isn't a path on argv0, then look through the $PATH for it...
else
{
char *envr;
char *start;
char *exe;
envr = copyEnvironmentVariable("PATH");
if (!envr)
{
delete[] argv0;
return(NULL);
}
start = envr;
do
{
ptr = strchr(start, ':');
if (ptr)
*ptr = '\0';
exe = new char[strlen(start) + strlen(argv0) + 2];
strcpy(exe, start);
if (exe[strlen(exe) - 1] != '/') // make sure there's a dir sep...
strcat(exe, "/");
strcat(exe, argv0); // add on the binary name...
if (access(exe, X_OK) != 0) // Not our binary?
delete[] exe;
else // matching executable file found on path...this is it.
{
retval = new char[strlen(exe) + 1];
strcpy(retval, exe);
delete[] exe;
break;
}
start = ptr + 1;
} while (ptr != NULL);
delete[] envr;
}
delete[] argv0;
if (retval != NULL)
{
char full[MAXPATHLEN];
realpath(retval, full);
delete[] retval;
retval = new char[strlen(full) + 1];
strcpy(retval, full);
}
return(retval);
}
// !!! FIXME: cut and paste from Engine.cpp ! --ryan.
// reverses string
static void StrRev( char *str) {
char ctmp;
char *pch0 = str;
char *pch1 = str+strlen(str)-1;
while( pch1>pch0) {
ctmp = *pch0;
*pch0 = *pch1;
*pch1 = ctmp;
pch0++;
pch1--;
}
}
// FIXME: This is such a lame hack. --ryan.
static void calcModExt(char *full, const char *exePath, const char *gamename)
{
strcat(full, gamename);
// bah...duplication from Engine.cpp ...
char strDirPath[MAX_PATH] = "";
char strTmpPath[MAX_PATH] = "";
strncpy(strTmpPath, exePath, sizeof(strTmpPath)-1);
strDirPath[sizeof(strTmpPath)-1] = 0;
// remove name from application path
StrRev(strTmpPath);
// find last backslash
char *pstr = strchr( strTmpPath, '/');
if( pstr==NULL) {
// not found - path is just "\"
strcpy( strTmpPath, "/");
pstr = strTmpPath;
}
// remove 'debug' from app path if needed
if( strnicmp( pstr, "/gubed", 6)==0) pstr += 6;
if( *pstr == '/') pstr++;
char *pstrFin = strchr( pstr, '/');
if( pstrFin==NULL) {
strcpy( pstr, "/");
pstrFin = pstr;
}
// copy that to the path
StrRev(pstrFin);
strncpy( strDirPath, pstrFin, sizeof(strDirPath)-1);
strDirPath[sizeof(strDirPath)-1] = 0;
strcat(strDirPath, "/ModExt.txt");
if (access(strDirPath, F_OK) == 0)
{
FILE *in = fopen(strDirPath, "rb");
int rc = fread(strTmpPath, 1, 30, in);
if (rc > 0)
{
strTmpPath[rc] = '\0';
strcat(full, strTmpPath);
}
}
strcat(full, "/");
}
CUnixFileSystem::CUnixFileSystem(const char *argv0, const char *gamename)
: exePath(NULL),
userDir(NULL)
{
exePath = calcExePath(argv0);
if (exePath == NULL)
{
exePath = new char[strlen(argv0) + 3];
strcpy(exePath, "./"); // (*shrug*)
strcat(exePath, argv0);
}
userDir = copyEnvironmentVariable("HOME");
if (userDir == NULL)
userDir = getUserDirByUID();
char full[MAXPATHLEN];
realpath(userDir, full);
delete[] userDir;
if (full[strlen(full) - 1] != '/')
strcat(full, "/");
// make sure it ends with a dir separator!
#if PLATFORM_MACOSX
strcat(full, "Library/");
mkdir(full, S_IRWXU); // don't care if this fails. We'll catch it later.
strcat(full, "Application Support/");
mkdir(full, S_IRWXU); // don't care if this fails. We'll catch it later.
strcat(full, "Serious Sam/");
#else
strcat(full, ".serious/");
#endif
if (!Exists(full)) {
if (mkdir(full, S_IRWXU) == -1) {
FatalError("User dir creation failed! (%s)\n", strerror(errno));
}
}
calcModExt(full, exePath, gamename);
if (!Exists(full)) {
if (mkdir(full, S_IRWXU) == -1) {
FatalError("User dir creation failed! (%s)\n", strerror(errno));
}
}
userDir = new char[strlen(full) + 1];
strcpy(userDir, full);
}
CUnixFileSystem::~CUnixFileSystem(void)
{
delete[] exePath;
delete[] userDir;
}
void CUnixFileSystem::GetExecutablePath(char *buf, ULONG bufSize)
{
buf[bufSize - 1] = '\0'; // just in case.
strncpy(buf, exePath, bufSize);
}
void CUnixFileSystem::GetUserDirectory(char *buf, ULONG bufSize)
{
buf[bufSize - 1] = '\0'; // just in case.
strncpy(buf, userDir, bufSize);
}
CDynamicArray<CTString> *CUnixFileSystem::FindFiles(const char *dir,
const char *wildcard)
{
CDynamicArray<CTString> *retval = new CDynamicArray<CTString>;
DIR *d = opendir(dir);
if (d != NULL)
{
struct dirent *dent;
while ((dent = readdir(d)) != NULL)
{
CTString str(dent->d_name);
if (str.Matches(wildcard))
*retval->New() = str;
}
closedir(d);
}
return(retval);
}
// end of UnixFileSystem.cpp ...

View File

@ -0,0 +1,156 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include "Engine/StdH.h"
#include <Engine/Base/Synchronization.h>
CTCriticalSection::CTCriticalSection(void)
{
cs_pvObject = (void *) new pthread_mutex_t;
pthread_mutex_init((pthread_mutex_t *) cs_pvObject, NULL);
LockCounter = 0;
owner = 0;
}
CTCriticalSection::~CTCriticalSection(void)
{
pthread_mutex_destroy((pthread_mutex_t *) cs_pvObject);
delete (pthread_mutex_t *) cs_pvObject;
}
INDEX CTCriticalSection::Lock(void)
{
if (owner == pthread_self())
return(++LockCounter);
pthread_mutex_lock((pthread_mutex_t *) cs_pvObject);
owner = pthread_self();
return(++LockCounter);
}
INDEX CTCriticalSection::TryToLock(void)
{
if (owner == pthread_self())
return(++LockCounter);
if (pthread_mutex_trylock((pthread_mutex_t *) cs_pvObject) == EBUSY)
return(0);
owner = pthread_self();
return(++LockCounter);
}
INDEX CTCriticalSection::Unlock(void)
{
if (owner == pthread_self())
{
if (LockCounter > 0)
{
if (--LockCounter == 0)
{
pthread_mutex_unlock((pthread_mutex_t *) cs_pvObject);
owner = 0;
}
}
}
return(LockCounter);
}
CTSingleLock::CTSingleLock(CTCriticalSection *pcs, BOOL bLock) : sl_cs(*pcs)
{
// initially not locked
sl_bLocked = FALSE;
sl_iLastLockedIndex = -2;
// critical section must have index assigned
//ASSERT(sl_cs.cs_iIndex>=1||sl_cs.cs_iIndex==-1);
// if should lock immediately
if (bLock) {
Lock();
}
}
CTSingleLock::~CTSingleLock(void)
{
// if locked
if (sl_bLocked) {
// unlock
Unlock();
}
}
void CTSingleLock::Lock(void)
{
// must not be locked
ASSERT(!sl_bLocked);
ASSERT(sl_iLastLockedIndex==-2);
// if not locked
if (!sl_bLocked) {
// lock
INDEX ctLocks = sl_cs.Lock();
// if this mutex was not locked already
// if (ctLocks==1) {
// // check that locking in given order
// if (sl_cs.cs_iIndex!=-1) {
// ASSERT(_iLastLockedMutex<sl_cs.cs_iIndex);
// sl_iLastLockedIndex = _iLastLockedMutex;
// _iLastLockedMutex = sl_cs.cs_iIndex;
// }
// }
}
sl_bLocked = TRUE;
}
BOOL CTSingleLock::TryToLock(void)
{
// must not be locked
ASSERT(!sl_bLocked);
// if not locked
if (!sl_bLocked) {
// if can lock
INDEX ctLocks = sl_cs.TryToLock();
if (ctLocks>=1) {
sl_bLocked = TRUE;
// if this mutex was not locked already
// if (ctLocks==1) {
// // check that locking in given order
// if (sl_cs.cs_iIndex!=-1) {
// ASSERT(_iLastLockedMutex<sl_cs.cs_iIndex);
// sl_iLastLockedIndex = _iLastLockedMutex;
// _iLastLockedMutex = sl_cs.cs_iIndex;
// }
// }
}
}
return sl_bLocked;
}
BOOL CTSingleLock::IsLocked(void)
{
return sl_bLocked;
}
void CTSingleLock::Unlock(void)
{
// must be locked
ASSERT(sl_bLocked);
// if locked
if (sl_bLocked) {
// unlock
INDEX ctLocks = sl_cs.Unlock();
// if unlocked completely
if (ctLocks==0) {
// check that unlocking in exact reverse order
// if (sl_cs.cs_iIndex!=-1) {
// ASSERT(_iLastLockedMutex==sl_cs.cs_iIndex);
// _iLastLockedMutex = sl_iLastLockedIndex;
// sl_iLastLockedIndex = -2;
// }
}
}
sl_bLocked = FALSE;
}

View File

@ -3,7 +3,7 @@
// unzip.cpp : Defines the entry point for the console application. // unzip.cpp : Defines the entry point for the console application.
// //
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>
#include <Engine/Base/FileName.h> #include <Engine/Base/FileName.h>
#include <Engine/Base/Translation.h> #include <Engine/Base/Translation.h>
@ -83,7 +83,7 @@ struct EndOfDir {
SWORD eod_swEntriesInDir; SWORD eod_swEntriesInDir;
SLONG eod_slSizeOfDir; SLONG eod_slSizeOfDir;
SLONG eod_slDirOffsetInFile; SLONG eod_slDirOffsetInFile;
SWORD eod_swCommentLenght; SWORD eod_swCommentLength;
// follows: // follows:
// zipfile comment (variable size) // zipfile comment (variable size)
}; };
@ -180,9 +180,11 @@ void CZipHandle::Clear(void)
void CZipHandle::ThrowZLIBError_t(int ierr, const CTString &strDescription) void CZipHandle::ThrowZLIBError_t(int ierr, const CTString &strDescription)
{ {
ThrowF_t(TRANS("(%s/%s) %s - ZLIB error: %s - %s"), ThrowF_t(TRANS("(%s/%s) %s - ZLIB error: %s - %s"),
(const CTString&)*zh_zeEntry.ze_pfnmArchive, (const char *) (const CTString&)*zh_zeEntry.ze_pfnmArchive,
(const CTString&)zh_zeEntry.ze_fnm, (const char *) (const CTString&)zh_zeEntry.ze_fnm,
strDescription, GetZlibError(ierr), zh_zstream.msg); (const char *) strDescription,
(const char *) GetZlibError(ierr),
(const char *) zh_zstream.msg);
} }
// all files in all active zip archives // all files in all active zip archives
@ -203,13 +205,15 @@ void ConvertSlashes(char *p)
} }
} }
#define READ_ZIPFIELD(f, x) { fread(&x, sizeof(x), 1, f); BYTESWAP(x); }
// read directory of a zip archive and add all files in it to active set // read directory of a zip archive and add all files in it to active set
void ReadZIPDirectory_t(CTFileName *pfnmZip) void ReadZIPDirectory_t(CTFileName *pfnmZip)
{ {
FILE *f = fopen(*pfnmZip, "rb"); FILE *f = fopen(*pfnmZip, "rb");
if (f==NULL) { if (f==NULL) {
ThrowF_t(TRANS("%s: Cannot open file (%s)"), (CTString&)*pfnmZip, strerror(errno)); ThrowF_t(TRANS("%s: Cannot open file (%s)"), (const char *) (CTString&)*pfnmZip, strerror(errno));
} }
// start at the end of file, minus expected minimum overhead // start at the end of file, minus expected minimum overhead
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
@ -226,22 +230,30 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
for(; iPos>iMinPos; iPos--) { for(; iPos>iMinPos; iPos--) {
// read signature // read signature
fseek(f, iPos, SEEK_SET); fseek(f, iPos, SEEK_SET);
int slSig; SLONG slSig;
fread(&slSig, sizeof(slSig), 1, f); fread(&slSig, sizeof(slSig), 1, f);
BYTESWAP(slSig);
// if this is the sig // if this is the sig
if (slSig==SIGNATURE_EOD) { if (slSig==SIGNATURE_EOD) {
// read directory end // read directory end
fread(&eod, sizeof(eod), 1, f); READ_ZIPFIELD(f, eod.eod_swDiskNo);
READ_ZIPFIELD(f, eod.eod_swDirStartDiskNo);
READ_ZIPFIELD(f, eod.eod_swEntriesInDirOnThisDisk);
READ_ZIPFIELD(f, eod.eod_swEntriesInDir);
READ_ZIPFIELD(f, eod.eod_slSizeOfDir);
READ_ZIPFIELD(f, eod.eod_slDirOffsetInFile);
READ_ZIPFIELD(f, eod.eod_swCommentLength);
// if multi-volume zip // if multi-volume zip
if (eod.eod_swDiskNo!=0||eod.eod_swDirStartDiskNo!=0 if (eod.eod_swDiskNo!=0||eod.eod_swDirStartDiskNo!=0
||eod.eod_swEntriesInDirOnThisDisk!=eod.eod_swEntriesInDir) { ||eod.eod_swEntriesInDirOnThisDisk!=eod.eod_swEntriesInDir) {
// fail // fail
ThrowF_t(TRANS("%s: Multi-volume zips are not supported"), (CTString&)*pfnmZip); ThrowF_t(TRANS("%s: Multi-volume zips are not supported"), (const char *) (CTString&)*pfnmZip);
} }
// check against empty zips // check against empty zips
if (eod.eod_swEntriesInDir<=0) { if (eod.eod_swEntriesInDir<=0) {
// fail // fail
ThrowF_t(TRANS("%s: Empty zip"), (CTString&)*pfnmZip); ThrowF_t(TRANS("%s: Empty zip"), (const char *) (CTString&)*pfnmZip);
} }
// all ok // all ok
bEODFound = TRUE; bEODFound = TRUE;
@ -251,7 +263,7 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
// if eod not found // if eod not found
if (!bEODFound) { if (!bEODFound) {
// fail // fail
ThrowF_t(TRANS("%s: Cannot find 'end of central directory'"), (CTString&)*pfnmZip); ThrowF_t(TRANS("%s: Cannot find 'end of central directory'"), (const char *) (CTString&)*pfnmZip);
} }
// check if the zip is from a mod // check if the zip is from a mod
@ -265,26 +277,44 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
// for each file // for each file
for (INDEX iFile=0; iFile<eod.eod_swEntriesInDir; iFile++) { for (INDEX iFile=0; iFile<eod.eod_swEntriesInDir; iFile++) {
// read the sig // read the sig
int slSig; SLONG slSig;
fread(&slSig, sizeof(slSig), 1, f); fread(&slSig, sizeof(slSig), 1, f);
BYTESWAP(slSig);
// if this is not the expected sig // if this is not the expected sig
if (slSig!=SIGNATURE_FH) { if (slSig!=SIGNATURE_FH) {
// fail // fail
ThrowF_t(TRANS("%s: Wrong signature for 'file header' number %d'"), ThrowF_t(TRANS("%s: Wrong signature for 'file header' number %d'"),
(CTString&)*pfnmZip, iFile); (const char *) (CTString&)*pfnmZip, iFile);
} }
// read its header // read its header
FileHeader fh; FileHeader fh;
fread(&fh, sizeof(fh), 1, f); READ_ZIPFIELD(f, fh.fh_swVersionMadeBy);
READ_ZIPFIELD(f, fh.fh_swVersionToExtract);
READ_ZIPFIELD(f, fh.fh_swGPBFlag);
READ_ZIPFIELD(f, fh.fh_swCompressionMethod);
READ_ZIPFIELD(f, fh.fh_swModFileTime);
READ_ZIPFIELD(f, fh.fh_swModFileDate);
READ_ZIPFIELD(f, fh.fh_slCRC32);
READ_ZIPFIELD(f, fh.fh_slCompressedSize);
READ_ZIPFIELD(f, fh.fh_slUncompressedSize);
READ_ZIPFIELD(f, fh.fh_swFileNameLen);
READ_ZIPFIELD(f, fh.fh_swExtraFieldLen);
READ_ZIPFIELD(f, fh.fh_swFileCommentLen);
READ_ZIPFIELD(f, fh.fh_swDiskNoStart);
READ_ZIPFIELD(f, fh.fh_swInternalFileAttributes);
READ_ZIPFIELD(f, fh.fh_swExternalFileAttributes);
READ_ZIPFIELD(f, fh.fh_slLocalHeaderOffset);
// read the filename // read the filename
const SLONG slMaxFileName = 512; const SLONG slMaxFileName = 512;
char strBuffer[slMaxFileName+1]; char strBuffer[slMaxFileName+1];
memset(strBuffer, 0, sizeof(strBuffer)); memset(strBuffer, 0, sizeof(strBuffer));
if (fh.fh_swFileNameLen>slMaxFileName) { if (fh.fh_swFileNameLen>slMaxFileName) {
ThrowF_t(TRANS("%s: Too long filepath in zip"), (CTString&)*pfnmZip); ThrowF_t(TRANS("%s: Too long filepath in zip"), (const char *) (CTString&)*pfnmZip);
} }
if (fh.fh_swFileNameLen<=0) { if (fh.fh_swFileNameLen<=0) {
ThrowF_t(TRANS("%s: Invalid filepath length in zip"), (CTString&)*pfnmZip); ThrowF_t(TRANS("%s: Invalid filepath length in zip"), (const char *) (CTString&)*pfnmZip);
} }
fread(strBuffer, fh.fh_swFileNameLen, 1, f); fread(strBuffer, fh.fh_swFileNameLen, 1, f);
@ -299,7 +329,7 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
if (fh.fh_slUncompressedSize!=0 if (fh.fh_slUncompressedSize!=0
||fh.fh_slCompressedSize!=0) { ||fh.fh_slCompressedSize!=0) {
ThrowF_t(TRANS("%s/%s: Invalid directory"), ThrowF_t(TRANS("%s/%s: Invalid directory"),
(CTString&)*pfnmZip, strBuffer); (const char *) (CTString&)*pfnmZip, strBuffer);
} }
// if the file is real file // if the file is real file
@ -324,7 +354,8 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
ze.ze_bStored = FALSE; ze.ze_bStored = FALSE;
} else { } else {
ThrowF_t(TRANS("%s/%s: Only 'deflate' compression is supported"), ThrowF_t(TRANS("%s/%s: Only 'deflate' compression is supported"),
(CTString&)*ze.ze_pfnmArchive, ze.ze_fnm); (const char *) (CTString&)*ze.ze_pfnmArchive,
(const char *) ze.ze_fnm);
} }
} }
} }
@ -332,11 +363,11 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
// if error reading // if error reading
if (ferror(f)) { if (ferror(f)) {
// fail // fail
ThrowF_t(TRANS("%s: Error reading central directory"), (CTString&)*pfnmZip); ThrowF_t(TRANS("%s: Error reading central directory"), (const char *) (CTString&)*pfnmZip);
} }
// report that file was read // report that file was read
CPrintF(TRANS(" %s: %d files\n"), (CTString&)*pfnmZip, ctFiles++); CPrintF(TRANS(" %s: %d files\n"), (const char *) (CTString&)*pfnmZip, ctFiles++);
} }
// add one zip archive to current active set // add one zip archive to current active set
@ -449,7 +480,7 @@ void UNZIPReadDirectoriesReverse_t(void)
// if there were errors // if there were errors
if (strAllErrors!="") { if (strAllErrors!="") {
// report them // report them
ThrowF_t("%s", strAllErrors); ThrowF_t("%s", (const char *) strAllErrors);
} }
} }
@ -537,13 +568,13 @@ INDEX UNZIPOpen_t(const CTFileName &fnm)
// if not found // if not found
if (pze==NULL) { if (pze==NULL) {
// fail // fail
ThrowF_t(TRANS("File not found: %s"), (const CTString&)fnm); ThrowF_t(TRANS("File not found: %s"), (const char *) (const CTString&)fnm);
} }
// for each existing handle // for each existing handle
BOOL bHandleFound = FALSE; BOOL bHandleFound = FALSE;
INDEX iHandle=1; INDEX iHandle;
for (; iHandle<_azhHandles.Count(); iHandle++) { for (iHandle=1; iHandle<_azhHandles.Count(); iHandle++) {
// if unused // if unused
if (!_azhHandles[iHandle].zh_bOpen) { if (!_azhHandles[iHandle].zh_bOpen) {
// use that one // use that one
@ -570,23 +601,34 @@ INDEX UNZIPOpen_t(const CTFileName &fnm)
// clear the handle // clear the handle
zh.Clear(); zh.Clear();
// fail // fail
ThrowF_t(TRANS("Cannot open '%s': %s"), (const CTString&)*pze->ze_pfnmArchive, ThrowF_t(TRANS("Cannot open '%s': %s"), (const char *) (const CTString&)*pze->ze_pfnmArchive,
strerror(errno)); strerror(errno));
} }
// seek to the local header of the entry // seek to the local header of the entry
fseek(zh.zh_fFile, zh.zh_zeEntry.ze_slDataOffset, SEEK_SET); fseek(zh.zh_fFile, zh.zh_zeEntry.ze_slDataOffset, SEEK_SET);
// read the sig // read the sig
int slSig; SLONG slSig;
fread(&slSig, sizeof(slSig), 1, zh.zh_fFile); fread(&slSig, sizeof(slSig), 1, zh.zh_fFile);
BYTESWAP(slSig);
// if this is not the expected sig // if this is not the expected sig
if (slSig!=SIGNATURE_LFH) { if (slSig!=SIGNATURE_LFH) {
// fail // fail
ThrowF_t(TRANS("%s/%s: Wrong signature for 'local file header'"), ThrowF_t(TRANS("%s/%s: Wrong signature for 'local file header'"),
(CTString&)*zh.zh_zeEntry.ze_pfnmArchive, zh.zh_zeEntry.ze_fnm); (const char *) (CTString&)*zh.zh_zeEntry.ze_pfnmArchive, (const char *) zh.zh_zeEntry.ze_fnm);
} }
// read the header // read the header
LocalFileHeader lfh; LocalFileHeader lfh;
fread(&lfh, sizeof(lfh), 1, zh.zh_fFile); READ_ZIPFIELD(zh.zh_fFile, lfh.lfh_swVersionToExtract);
READ_ZIPFIELD(zh.zh_fFile, lfh.lfh_swGPBFlag);
READ_ZIPFIELD(zh.zh_fFile, lfh.lfh_swCompressionMethod);
READ_ZIPFIELD(zh.zh_fFile, lfh.lfh_swModFileTime);
READ_ZIPFIELD(zh.zh_fFile, lfh.lfh_swModFileDate);
READ_ZIPFIELD(zh.zh_fFile, lfh.lfh_slCRC32);
READ_ZIPFIELD(zh.zh_fFile, lfh.lfh_slCompressedSize);
READ_ZIPFIELD(zh.zh_fFile, lfh.lfh_slUncompressedSize);
READ_ZIPFIELD(zh.zh_fFile, lfh.lfh_swFileNameLen);
READ_ZIPFIELD(zh.zh_fFile, lfh.lfh_swExtraFieldLen);
// determine exact compressed data position // determine exact compressed data position
zh.zh_zeEntry.ze_slDataOffset = zh.zh_zeEntry.ze_slDataOffset =
ftell(zh.zh_fFile)+lfh.lfh_swFileNameLen+lfh.lfh_swExtraFieldLen; ftell(zh.zh_fFile)+lfh.lfh_swFileNameLen+lfh.lfh_swExtraFieldLen;

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Updateable.h> #include <Engine/Base/Updateable.h>
#include <Engine/Base/UpdateableRT.h> #include <Engine/Base/UpdateableRT.h>

View File

@ -0,0 +1,89 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
/* rcg10072001 Implemented. */
#include <Engine/Engine.h>
#include <Engine/Base/DynamicLoader.h>
class CWin32DynamicLoader : public CDynamicLoader
{
public:
CWin32DynamicLoader(const char *libname);
virtual ~CWin32DynamicLoader(void);
virtual void *FindSymbol(const char *sym);
virtual const char *GetError(void);
protected:
void SetError(void);
HMODULE module;
CTString *err;
};
CDynamicLoader *CDynamicLoader::GetInstance(const char *libname)
{
return(new CWin32DynamicLoader(libname));
}
void CWin32DynamicLoader::SetError(void)
{
char *errmsg = ::GetWindowsError(::GetLastError());
delete err;
err = NULL;
if (errmsg != NULL)
err = new CTString(errmsg);
}
const char *CWin32DynamicLoader::GetError(void)
{
return((err) ? (const char *) (*err) : NULL);
}
void *CWin32DynamicLoader::FindSymbol(const char *sym)
{
void *retval = NULL;
if (module != NULL) {
retval = ::GetProcAddress(module, sym);
if (retval == NULL)
SetError();
}
return(retval);
}
CTFileName CDynamicLoader::ConvertLibNameToPlatform(const char *libname)
{
return(CTFileName(CTString(libname)));
}
CWin32DynamicLoader::CWin32DynamicLoader(const char *libname)
: module(NULL),
err(NULL)
{
CTFileName fnm(libname);
if (stricmp(fnm.FileExt(), ".dll") != 0)
fnm += ".dll";
module = ::LoadLibrary((const char *) fnm);
if (module == NULL)
SetError();
}
CWin32DynamicLoader::~CWin32DynamicLoader(void)
{
delete err;
if (module != NULL)
::FreeLibrary(module);
}
// end of Win32DynamicLoader.cpp ...

View File

@ -0,0 +1,121 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
/* rcg10072001 Implemented. */
// !!! FIXME: rcg10142001 This should really be using CTStrings...
#include <io.h>
#include <Engine/Engine.h>
#include <Engine/Base/FileSystem.h>
ENGINE_API CFileSystem *_pFileSystem = NULL;
class CWin32FileSystem : public CFileSystem
{
public:
CWin32FileSystem(const char *argv0, const char *gamename);
virtual ~CWin32FileSystem(void);
virtual void GetExecutablePath(char *buf, ULONG bufSize);
virtual void GetUserDirectory(char *buf, ULONG bufSize);
virtual CDynamicArray<CTString> *FindFiles(const char *dir,
const char *wildcard);
protected:
char *exePath;
char *userDir;
};
const char *CFileSystem::GetDirSeparator(void)
{
return("\\");
}
BOOL CFileSystem::IsDummyFile(const char *fname)
{
return( (strcmp(fname, ".") == 0) || (strcmp(fname, "..") == 0) );
}
BOOL CFileSystem::Exists(const char *fname)
{
ASSERTALWAYS("Write me!");
}
BOOL CFileSystem::IsDirectory(const char *fname)
{
ASSERTALWAYS("Write me!");
}
CFileSystem *CFileSystem::GetInstance(const char *argv0, const char *gamename)
{
return(new CWin32FileSystem(argv0, gamename));
}
CWin32FileSystem::CWin32FileSystem(const char *argv0, const char *gamename)
: exePath(NULL),
: userDir(NULL)
{
char buf[MAX_PATH];
memset(buf, '\0', sizeof (buf));
GetModuleFileName(NULL, buf, sizeof (buf) - 1);
exePath = new char[strlen(buf) + 1];
strcpy(exePath, buf);
userDir = new char[strlen(buf) + 1];
strcpy(userDir, buf);
ASSERTALWAYS("We need to chop \\bin\\debug off the string if it's there.\n");
}
CWin32FileSystem::~CWin32FileSystem(void)
{
delete[] exePath;
delete[] userDir;
}
void CWin32FileSystem::GetExecutablePath(char *buf, ULONG bufSize)
{
strncpy(buf, exePath, bufSize);
buf[bufSize - 1] = '\0'; // just in case.
}
void CWin32FileSystem::GetUserDirectory(char *buf, ULONG bufSize)
{
strncpy(buf, userDir, bufSize);
buf[bufSize - 1] = '\0'; // just in case.
}
CDynamicArray<CTString> CWin32FileSystem::FindFiles(const char *dir,
const char *wildcard)
{
CDynamicArray<CTString> *retval = new CDynamicArray<CTString>;
CTString str(dir);
if (dir[strlen(dir) - 1] != '\\')
str += "\\";
struct _finddata_t c_file;
long hFile = _findfirst( (const char *)(str+wildcard), &c_file );
for (BOOL bFileExists = hFile!=-1;
bFileExists;
bFileExists = _findnext( hFile, &c_file )==0)
{
*retval->New() = c_file.name;
}
_findclose(hFile);
return(retval);
}
// end of Win32FileSystem.cpp ...

View File

@ -0,0 +1,986 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
/* rcg10072001 Moved stuff into this file. */
#include <Engine/Base/Timer.h>
#include <Engine/Base/Input.h>
#include <Engine/Base/Translation.h>
#include <Engine/Base/KeyNames.h>
#include <Engine/Math/Functions.h>
#include <Engine/Graphics/Viewport.h>
#include <Engine/Base/Console.h>
#include <Engine/Base/Synchronization.h>
#include <Engine/Base/ErrorReporting.h>
extern INDEX inp_iKeyboardReadingMethod;
extern FLOAT inp_fMouseSensitivity;
extern INDEX inp_bAllowMouseAcceleration;
extern INDEX inp_bMousePrecision;
extern FLOAT inp_fMousePrecisionFactor;
extern FLOAT inp_fMousePrecisionThreshold;
extern FLOAT inp_fMousePrecisionTimeout;
extern FLOAT inp_bInvertMouse;
extern INDEX inp_bFilterMouse;
extern INDEX inp_bAllowPrescan;
extern INDEX inp_i2ndMousePort;
extern FLOAT inp_f2ndMouseSensitivity;
extern INDEX inp_b2ndMousePrecision;
extern FLOAT inp_f2ndMousePrecisionThreshold;
extern FLOAT inp_f2ndMousePrecisionTimeout;
extern FLOAT inp_f2ndMousePrecisionFactor;
extern INDEX inp_bFilter2ndMouse;
extern INDEX inp_bInvert2ndMouse;
extern INDEX inp_ctJoysticksAllowed;
INDEX inp_iMButton4Dn = 0x20040;
INDEX inp_iMButton4Up = 0x20000;
INDEX inp_iMButton5Dn = 0x10020;
INDEX inp_iMButton5Up = 0x10000;
INDEX inp_bMsgDebugger = FALSE;
INDEX inp_bForceJoystickPolling = 0;
INDEX inp_bAutoDisableJoysticks = 0;
/*
NOTE: Three different types of key codes are used here:
1) kid - engine internal type - defined in KeyNames.h
2) scancode - raw PC keyboard scancodes as returned in keydown/keyup messages
3) virtkey - virtual key codes used by windows
*/
// name that is not translated (international)
#define INTNAME(str) str, ""
// name that is translated
#define TRANAME(str) str, "ETRS" str
// basic key conversion table
static struct KeyConversion {
INDEX kc_iKID;
INDEX kc_iVirtKey;
INDEX kc_iScanCode;
char *kc_strName;
char *kc_strNameTrans;
} _akcKeys[] = {
// reserved for 'no-key-pressed'
{ KID_NONE, -1, -1, TRANAME("None")},
// numbers row
{ KID_1 , '1', 2, INTNAME("1")},
{ KID_2 , '2', 3, INTNAME("2")},
{ KID_3 , '3', 4, INTNAME("3")},
{ KID_4 , '4', 5, INTNAME("4")},
{ KID_5 , '5', 6, INTNAME("5")},
{ KID_6 , '6', 7, INTNAME("6")},
{ KID_7 , '7', 8, INTNAME("7")},
{ KID_8 , '8', 9, INTNAME("8")},
{ KID_9 , '9', 10, INTNAME("9")},
{ KID_0 , '0', 11, INTNAME("0")},
{ KID_MINUS , 189, 12, INTNAME("-")},
{ KID_EQUALS , 187, 13, INTNAME("=")},
// 1st alpha row
{ KID_Q , 'Q', 16, INTNAME("Q")},
{ KID_W , 'W', 17, INTNAME("W")},
{ KID_E , 'E', 18, INTNAME("E")},
{ KID_R , 'R', 19, INTNAME("R")},
{ KID_T , 'T', 20, INTNAME("T")},
{ KID_Y , 'Y', 21, INTNAME("Y")},
{ KID_U , 'U', 22, INTNAME("U")},
{ KID_I , 'I', 23, INTNAME("I")},
{ KID_O , 'O', 24, INTNAME("O")},
{ KID_P , 'P', 25, INTNAME("P")},
{ KID_LBRACKET , 219, 26, INTNAME("[")},
{ KID_RBRACKET , 221, 27, INTNAME("]")},
{ KID_BACKSLASH , 220, 43, INTNAME("\\")},
// 2nd alpha row
{ KID_A , 'A', 30, INTNAME("A")},
{ KID_S , 'S', 31, INTNAME("S")},
{ KID_D , 'D', 32, INTNAME("D")},
{ KID_F , 'F', 33, INTNAME("F")},
{ KID_G , 'G', 34, INTNAME("G")},
{ KID_H , 'H', 35, INTNAME("H")},
{ KID_J , 'J', 36, INTNAME("J")},
{ KID_K , 'K', 37, INTNAME("K")},
{ KID_L , 'L', 38, INTNAME("L")},
{ KID_SEMICOLON , 186, 39, INTNAME(";")},
{ KID_APOSTROPHE , 222, 40, INTNAME("'")},
// 3rd alpha row
{ KID_Z , 'Z', 44, INTNAME("Z")},
{ KID_X , 'X', 45, INTNAME("X")},
{ KID_C , 'C', 46, INTNAME("C")},
{ KID_V , 'V', 47, INTNAME("V")},
{ KID_B , 'B', 48, INTNAME("B")},
{ KID_N , 'N', 49, INTNAME("N")},
{ KID_M , 'M', 50, INTNAME("M")},
{ KID_COMMA , 190, 51, INTNAME(",")},
{ KID_PERIOD , 188, 52, INTNAME(".")},
{ KID_SLASH , 191, 53, INTNAME("/")},
// row with F-keys
{ KID_F1 , VK_F1, 59, INTNAME("F1")},
{ KID_F2 , VK_F2, 60, INTNAME("F2")},
{ KID_F3 , VK_F3, 61, INTNAME("F3")},
{ KID_F4 , VK_F4, 62, INTNAME("F4")},
{ KID_F5 , VK_F5, 63, INTNAME("F5")},
{ KID_F6 , VK_F6, 64, INTNAME("F6")},
{ KID_F7 , VK_F7, 65, INTNAME("F7")},
{ KID_F8 , VK_F8, 66, INTNAME("F8")},
{ KID_F9 , VK_F9, 67, INTNAME("F9")},
{ KID_F10 , VK_F10, 68, INTNAME("F10")},
{ KID_F11 , VK_F11, 87, INTNAME("F11")},
{ KID_F12 , VK_F12, 88, INTNAME("F12")},
// extra keys
{ KID_ESCAPE , VK_ESCAPE, 1, TRANAME("Escape")},
{ KID_TILDE , -1, 41, TRANAME("Tilde")},
{ KID_BACKSPACE , VK_BACK, 14, TRANAME("Backspace")},
{ KID_TAB , VK_TAB, 15, TRANAME("Tab")},
{ KID_CAPSLOCK , VK_CAPITAL, 58, TRANAME("Caps Lock")},
{ KID_ENTER , VK_RETURN, 28, TRANAME("Enter")},
{ KID_SPACE , VK_SPACE, 57, TRANAME("Space")},
// modifier keys
{ KID_LSHIFT , VK_LSHIFT , 42, TRANAME("Left Shift")},
{ KID_RSHIFT , VK_RSHIFT , 54, TRANAME("Right Shift")},
{ KID_LCONTROL , VK_LCONTROL, 29, TRANAME("Left Control")},
{ KID_RCONTROL , VK_RCONTROL, 256+29, TRANAME("Right Control")},
{ KID_LALT , VK_LMENU , 56, TRANAME("Left Alt")},
{ KID_RALT , VK_RMENU , 256+56, TRANAME("Right Alt")},
// navigation keys
{ KID_ARROWUP , VK_UP, 256+72, TRANAME("Arrow Up")},
{ KID_ARROWDOWN , VK_DOWN, 256+80, TRANAME("Arrow Down")},
{ KID_ARROWLEFT , VK_LEFT, 256+75, TRANAME("Arrow Left")},
{ KID_ARROWRIGHT , VK_RIGHT, 256+77, TRANAME("Arrow Right")},
{ KID_INSERT , VK_INSERT, 256+82, TRANAME("Insert")},
{ KID_DELETE , VK_DELETE, 256+83, TRANAME("Delete")},
{ KID_HOME , VK_HOME, 256+71, TRANAME("Home")},
{ KID_END , VK_END, 256+79, TRANAME("End")},
{ KID_PAGEUP , VK_PRIOR, 256+73, TRANAME("Page Up")},
{ KID_PAGEDOWN , VK_NEXT, 256+81, TRANAME("Page Down")},
{ KID_PRINTSCR , VK_SNAPSHOT, 256+55, TRANAME("Print Screen")},
{ KID_SCROLLLOCK , VK_SCROLL, 70, TRANAME("Scroll Lock")},
{ KID_PAUSE , VK_PAUSE, 69, TRANAME("Pause")},
// numpad numbers
{ KID_NUM0 , VK_NUMPAD0, 82, INTNAME("Num 0")},
{ KID_NUM1 , VK_NUMPAD1, 79, INTNAME("Num 1")},
{ KID_NUM2 , VK_NUMPAD2, 80, INTNAME("Num 2")},
{ KID_NUM3 , VK_NUMPAD3, 81, INTNAME("Num 3")},
{ KID_NUM4 , VK_NUMPAD4, 75, INTNAME("Num 4")},
{ KID_NUM5 , VK_NUMPAD5, 76, INTNAME("Num 5")},
{ KID_NUM6 , VK_NUMPAD6, 77, INTNAME("Num 6")},
{ KID_NUM7 , VK_NUMPAD7, 71, INTNAME("Num 7")},
{ KID_NUM8 , VK_NUMPAD8, 72, INTNAME("Num 8")},
{ KID_NUM9 , VK_NUMPAD9, 73, INTNAME("Num 9")},
{ KID_NUMDECIMAL , VK_DECIMAL, 83, INTNAME("Num .")},
// numpad gray keys
{ KID_NUMLOCK , VK_NUMLOCK, 256+69, INTNAME("Num Lock")},
{ KID_NUMSLASH , VK_DIVIDE, 256+53, INTNAME("Num /")},
{ KID_NUMMULTIPLY , VK_MULTIPLY, 55, INTNAME("Num *")},
{ KID_NUMMINUS , VK_SUBTRACT, 74, INTNAME("Num -")},
{ KID_NUMPLUS , VK_ADD, 78, INTNAME("Num +")},
{ KID_NUMENTER , VK_SEPARATOR, 256+28, TRANAME("Num Enter")},
// mouse buttons
{ KID_MOUSE1 , VK_LBUTTON, -1, TRANAME("Mouse Button 1")},
{ KID_MOUSE2 , VK_RBUTTON, -1, TRANAME("Mouse Button 2")},
{ KID_MOUSE3 , VK_MBUTTON, -1, TRANAME("Mouse Button 3")},
{ KID_MOUSE4 , -1, -1, TRANAME("Mouse Button 4")},
{ KID_MOUSE5 , -1, -1, TRANAME("Mouse Button 5")},
{ KID_MOUSEWHEELUP , -1, -1, TRANAME("Mouse Wheel Up")},
{ KID_MOUSEWHEELDOWN , -1, -1, TRANAME("Mouse Wheel Down")},
// 2nd mouse buttons
{ KID_2MOUSE1 , -1, -1, TRANAME("2nd Mouse Button 1")},
{ KID_2MOUSE2 , -1, -1, TRANAME("2nd Mouse Button 2")},
{ KID_2MOUSE3 , -1, -1, TRANAME("2nd Mouse Button 3")},
};
// autogenerated fast conversion tables
static INDEX _aiScanToKid[512];
static INDEX _aiVirtToKid[256];
// make fast conversion tables from the general table
static void MakeConversionTables(void)
{
// clear conversion tables
memset(_aiScanToKid, -1, sizeof(_aiScanToKid));
memset(_aiVirtToKid, -1, sizeof(_aiVirtToKid));
// for each Key
for (INDEX iKey=0; iKey<ARRAYCOUNT(_akcKeys); iKey++) {
struct KeyConversion &kc = _akcKeys[iKey];
// get codes
INDEX iKID = kc.kc_iKID;
INDEX iScan = kc.kc_iScanCode;
INDEX iVirt = kc.kc_iVirtKey;
// update the tables
if (iScan>=0) {
_aiScanToKid[iScan] = iKID;
}
if (iVirt>=0) {
_aiVirtToKid[iVirt] = iKID;
}
}
}
// variables for message interception
static HHOOK _hGetMsgHook = NULL;
static HHOOK _hSendMsgHook = NULL;
static int _iMouseZ = 0;
static BOOL _bWheelUp = FALSE;
static BOOL _bWheelDn = FALSE;
CTCriticalSection csInput;
// which keys are pressed, as recorded by message interception (by KIDs)
static UBYTE _abKeysPressed[256];
// set a key according to a keydown/keyup message
static void SetKeyFromMsg(MSG *pMsg, BOOL bDown)
{
INDEX iKID = -1;
// if capturing scan codes
if (inp_iKeyboardReadingMethod==2) {
// get scan code
INDEX iScan = (pMsg->lParam>>16)&0x1FF; // (we use the extended bit too!)
// convert scan code to kid
iKID = _aiScanToKid[iScan];
// if capturing virtual key codes
} else if (inp_iKeyboardReadingMethod==1) {
// get virtualkey
INDEX iVirt = (pMsg->wParam)&0xFF;
if (iVirt == VK_SHIFT) {
iVirt = VK_LSHIFT;
}
if (iVirt == VK_CONTROL) {
iVirt = VK_LCONTROL;
}
if (iVirt == VK_MENU) {
iVirt = VK_LMENU;
}
// convert virtualkey to kid
iKID = _aiVirtToKid[iVirt];
// if not capturing
} else {
// do nothing
return;
}
if (iKID>=0 && iKID<ARRAYCOUNT(_abKeysPressed)) {
// CPrintF("%s: %d\n", _pInput->inp_strButtonNames[iKID], bDown);
_abKeysPressed[iKID] = bDown;
}
}
static void CheckMessage(MSG *pMsg)
{
if ( pMsg->message == WM_LBUTTONUP) {
_abKeysPressed[KID_MOUSE1] = FALSE;
} else if ( pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK) {
_abKeysPressed[KID_MOUSE1] = TRUE;
} else if ( pMsg->message == WM_RBUTTONUP) {
_abKeysPressed[KID_MOUSE2] = FALSE;
} else if ( pMsg->message == WM_RBUTTONDOWN || pMsg->message == WM_RBUTTONDBLCLK) {
_abKeysPressed[KID_MOUSE2] = TRUE;
} else if ( pMsg->message == WM_MBUTTONUP) {
_abKeysPressed[KID_MOUSE3] = FALSE;
} else if ( pMsg->message == WM_MBUTTONDOWN || pMsg->message == WM_MBUTTONDBLCLK) {
_abKeysPressed[KID_MOUSE3] = TRUE;
} else if ( pMsg->message == inp_iMButton4Dn) {
_abKeysPressed[KID_MOUSE4] = TRUE;
} else if ( pMsg->message == inp_iMButton4Up) {
_abKeysPressed[KID_MOUSE4] = FALSE;
} else if ( pMsg->message == inp_iMButton5Dn) {
_abKeysPressed[KID_MOUSE5] = TRUE;
} else if ( pMsg->message == inp_iMButton5Up) {
_abKeysPressed[KID_MOUSE5] = FALSE;
} else if (pMsg->message==WM_KEYUP || pMsg->message==WM_SYSKEYUP) {
SetKeyFromMsg(pMsg, FALSE);
} else if (pMsg->message==WM_KEYDOWN || pMsg->message==WM_SYSKEYDOWN) {
SetKeyFromMsg(pMsg, TRUE);
} else if (inp_bMsgDebugger && pMsg->message >= 0x10000) {
CPrintF("%08x(%d)\n", pMsg->message, pMsg->message);
}
}
// procedure called when message is retreived
LRESULT CALLBACK GetMsgProc(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam) // mouse coordinates
{
MSG *pMsg = (MSG*)lParam;
CheckMessage(pMsg);
LRESULT retValue = 0;
retValue = CallNextHookEx( _hGetMsgHook, nCode, wParam, lParam );
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#endif
if (wParam == PM_NOREMOVE) {
return retValue;
}
if ( pMsg->message == WM_MOUSEWHEEL) {
_iMouseZ += SWORD(UWORD(HIWORD(pMsg->wParam)));
}
return retValue;
}
// procedure called when message is sent
LRESULT CALLBACK SendMsgProc(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam) // mouse coordinates
{
MSG *pMsg = (MSG*)lParam;
CheckMessage(pMsg);
LRESULT retValue = 0;
retValue = CallNextHookEx( _hSendMsgHook, nCode, wParam, lParam );
return retValue;
}
// --------- 2ND MOUSE HANDLING
#define MOUSECOMBUFFERSIZE 256L
static HANDLE _h2ndMouse = NONE;
static BOOL _bIgnoreMouse2 = TRUE;
static INDEX _i2ndMouseX, _i2ndMouseY, _i2ndMouseButtons;
static INDEX _iByteNum = 0;
static UBYTE _aubComBytes[4] = {0,0,0,0};
static INDEX _iLastPort = -1;
static void Poll2ndMouse(void)
{
// reset (mouse reading is relative)
_i2ndMouseX = 0;
_i2ndMouseY = 0;
if( _h2ndMouse==NONE) return;
// check
COMSTAT csComStat;
DWORD dwErrorFlags;
ClearCommError( _h2ndMouse, &dwErrorFlags, &csComStat);
DWORD dwLength = Min( MOUSECOMBUFFERSIZE, (INDEX)csComStat.cbInQue);
if( dwLength<=0) return;
// readout
UBYTE aubMouseBuffer[MOUSECOMBUFFERSIZE];
INDEX iRetries = 999;
while( iRetries>0 && !ReadFile( _h2ndMouse, aubMouseBuffer, dwLength, &dwLength, NULL)) iRetries--;
if( iRetries<=0) return; // what, didn't make it?
// parse the mouse packets
for( INDEX i=0; i<dwLength; i++)
{
// prepare
if( aubMouseBuffer[i] & 64) _iByteNum = 0;
if( _iByteNum<4) _aubComBytes[_iByteNum] = aubMouseBuffer[i];
_iByteNum++;
// buttons ?
if( _iByteNum==1) {
_i2ndMouseButtons &= ~3;
_i2ndMouseButtons |= (_aubComBytes[0] & (32+16)) >>4;
}
// axes ?
else if( _iByteNum==3) {
char iDX = ((_aubComBytes[0] & 3) <<6) + _aubComBytes[1];
char iDY = ((_aubComBytes[0] & 12) <<4) + _aubComBytes[2];
_i2ndMouseX += iDX;
_i2ndMouseY += iDY;
}
// 3rd button?
else if( _iByteNum==4) {
_i2ndMouseButtons &= ~4;
if( aubMouseBuffer[i]&32) _i2ndMouseButtons |= 4;
}
}
// ignore pooling?
if( _bIgnoreMouse2) {
if( _i2ndMouseX!=0 || _i2ndMouseY!=0) _bIgnoreMouse2 = FALSE;
_i2ndMouseX = 0;
_i2ndMouseY = 0;
_i2ndMouseButtons = 0;
return;
}
}
static void Startup2ndMouse(INDEX iPort)
{
// skip if disabled
ASSERT( iPort>=0 && iPort<=4);
if( iPort==0) return;
// determine port string
CTString str2ndMousePort( 0, "COM%d", iPort);
// create COM handle if needed
if( _h2ndMouse==NONE) {
_h2ndMouse = CreateFileA( str2ndMousePort, GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if( _h2ndMouse==INVALID_HANDLE_VALUE) {
// failed! :(
INDEX iError = GetLastError();
/*
if( iError==5) CPrintF( "Cannot open %s (access denied).\n"
"The port is probably already used by another device (mouse, modem...)\n",
str2ndMousePort);
else CPrintF( "Cannot open %s (error %d).\n", str2ndMousePort, iError);
*/
_h2ndMouse = NONE;
return;
}
}
// setup and purge buffers
SetupComm( _h2ndMouse, MOUSECOMBUFFERSIZE, MOUSECOMBUFFERSIZE);
PurgeComm( _h2ndMouse, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
// setup port to 1200 7N1
DCB dcb;
dcb.DCBlength = sizeof(DCB);
GetCommState( _h2ndMouse, &dcb);
dcb.BaudRate = CBR_1200;
dcb.ByteSize = 7;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fBinary = TRUE;
dcb.fParity = TRUE;
SetCommState( _h2ndMouse, &dcb);
// reset
_iByteNum = 0;
_aubComBytes[0] = _aubComBytes[1] = _aubComBytes[2] = _aubComBytes[3] = 0;
_bIgnoreMouse2 = TRUE; // ignore mouse polling until 1 after non-0 readout
_iLastPort = iPort;
//CPrintF( "STARTUP M2!\n");
}
static void Shutdown2ndMouse(void)
{
// skip if already disabled
if( _h2ndMouse==NONE) return;
// disable!
SetCommMask( _h2ndMouse, 0);
EscapeCommFunction( _h2ndMouse, CLRDTR);
EscapeCommFunction( _h2ndMouse, CLRRTS);
PurgeComm( _h2ndMouse, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
// close port if changed
if( _iLastPort != inp_i2ndMousePort) {
CloseHandle( _h2ndMouse);
_h2ndMouse = NONE;
} // over and out
_bIgnoreMouse2 = TRUE;
}
BOOL CInput::PlatformInit(void)
{
_h2ndMouse = NONE;
MakeConversionTables();
return TRUE;
}
// destructor
CInput::~CInput()
{
if( _h2ndMouse!=NONE) CloseHandle( _h2ndMouse);
_h2ndMouse = NONE;
}
BOOL CInput::PlatformSetKeyNames(void)
{
// for each Key
for (INDEX iKey=0; iKey<ARRAYCOUNT(_akcKeys); iKey++) {
struct KeyConversion &kc = _akcKeys[iKey];
// set the name
if (kc.kc_strName!=NULL) {
inp_strButtonNames[kc.kc_iKID] = kc.kc_strName;
if (strlen(kc.kc_strNameTrans)==0) {
inp_strButtonNamesTra[kc.kc_iKID] = kc.kc_strName;
} else {
inp_strButtonNamesTra[kc.kc_iKID] = TranslateConst(kc.kc_strNameTrans, 4);
}
}
}
return TRUE;
}
void CInput::EnableInput(HWND hwnd)
{
// skip if already enabled
if( inp_bInputEnabled) return;
// get window rectangle
RECT rectClient;
GetClientRect(hwnd, &rectClient);
POINT pt;
pt.x=0;
pt.y=0;
ClientToScreen(hwnd, &pt);
OffsetRect(&rectClient, pt.x, pt.y);
// remember mouse pos
GetCursorPos( &inp_ptOldMousePos);
// set mouse clip region
ClipCursor(&rectClient);
// determine screen center position
inp_slScreenCenterX = (rectClient.left + rectClient.right) / 2;
inp_slScreenCenterY = (rectClient.top + rectClient.bottom) / 2;
// clear mouse from screen
while (ShowCursor(FALSE) >= 0);
// save system mouse settings
SystemParametersInfo(SPI_GETMOUSE, 0, &inp_mscMouseSettings, 0);
// set new mouse speed
if (!inp_bAllowMouseAcceleration) {
MouseSpeedControl mscNewSetting = { 0, 0, 0};
SystemParametersInfo(SPI_SETMOUSE, 0, &mscNewSetting, 0);
}
// set cursor position to screen center
SetCursorPos(inp_slScreenCenterX, inp_slScreenCenterY);
_hGetMsgHook = SetWindowsHookEx(WH_GETMESSAGE, &GetMsgProc, NULL, GetCurrentThreadId());
_hSendMsgHook = SetWindowsHookEx(WH_CALLWNDPROC, &SendMsgProc, NULL, GetCurrentThreadId());
// if required, try to enable 2nd mouse
Shutdown2ndMouse();
inp_i2ndMousePort = Clamp( inp_i2ndMousePort, 0L, 4L);
Startup2ndMouse(inp_i2ndMousePort);
// clear button's buffer
memset( _abKeysPressed, 0, sizeof( _abKeysPressed));
// This can be enabled to pre-read the state of currently pressed keys
// for snooping methods, since they only detect transitions.
// That has effect of detecting key presses for keys that were held down before
// enabling.
// the entire thing is disabled because it caused last menu key to re-apply in game.
#if 0
// for each Key
{for (INDEX iKey=0; iKey<ARRAYCOUNT(_akcKeys); iKey++) {
struct KeyConversion &kc = _akcKeys[iKey];
// get codes
INDEX iKID = kc.kc_iKID;
INDEX iScan = kc.kc_iScanCode;
INDEX iVirt = kc.kc_iVirtKey;
// if there is a valid virtkey
if (iVirt>=0) {
// transcribe if modifier
if (iVirt == VK_LSHIFT) {
iVirt = VK_SHIFT;
}
if (iVirt == VK_LCONTROL) {
iVirt = VK_CONTROL;
}
if (iVirt == VK_LMENU) {
iVirt = VK_MENU;
}
// is state is pressed
if (GetAsyncKeyState(iVirt)&0x8000) {
// mark it as pressed
_abKeysPressed[iKID] = 0xFF;
}
}
}}
#endif
// remember current status
inp_bInputEnabled = TRUE;
inp_bPollJoysticks = FALSE;
}
/*
* Disable direct input
*/
void CInput::DisableInput( void)
{
// skip if allready disabled
if( !inp_bInputEnabled) return;
UnhookWindowsHookEx(_hGetMsgHook);
UnhookWindowsHookEx(_hSendMsgHook);
// set mouse clip region to entire screen
ClipCursor(NULL);
// restore mouse pos
SetCursorPos( inp_ptOldMousePos.x, inp_ptOldMousePos.y);
// show mouse on screen
while (ShowCursor(TRUE) < 0);
// set system mouse settings
SystemParametersInfo(SPI_SETMOUSE, 0, &inp_mscMouseSettings, 0);
// eventually disable 2nd mouse
Shutdown2ndMouse();
// remember current status
inp_bInputEnabled = FALSE;
inp_bPollJoysticks = FALSE;
}
// blank any queued mousemove events...SDLInput.cpp needs this when
// returning from the menus/console to game or the viewport will jump... --ryan.
void CInput::ClearRelativeMouseMotion(void)
{
// no-op on win32. --ryan.
}
/*
* Scan states of all available input sources
*/
void CInput::GetInput(BOOL bPreScan)
{
// CTSingleLock sl(&csInput, TRUE);
if (!inp_bInputEnabled) {
return;
}
if (bPreScan && !inp_bAllowPrescan) {
return;
}
// if not pre-scanning
if (!bPreScan) {
// clear button's buffer
memset( inp_ubButtonsBuffer, 0, sizeof( inp_ubButtonsBuffer));
// for each Key
{for (INDEX iKey=0; iKey<ARRAYCOUNT(_akcKeys); iKey++) {
struct KeyConversion &kc = _akcKeys[iKey];
// get codes
INDEX iKID = kc.kc_iKID;
INDEX iScan = kc.kc_iScanCode;
INDEX iVirt = kc.kc_iVirtKey;
// if reading async keystate
if (inp_iKeyboardReadingMethod==0) {
// if there is a valid virtkey
if (iVirt>=0) {
// transcribe if modifier
if (iVirt == VK_LSHIFT) {
iVirt = VK_SHIFT;
}
if (iVirt == VK_LCONTROL) {
iVirt = VK_CONTROL;
}
if (iVirt == VK_LMENU) {
iVirt = VK_MENU;
}
// is state is pressed
if (GetAsyncKeyState(iVirt)&0x8000) {
// mark it as pressed
inp_ubButtonsBuffer[iKID] = 0xFF;
}
}
// if snooping messages
} else {
// if snooped that key is pressed
if (_abKeysPressed[iKID]) {
// mark it as pressed
inp_ubButtonsBuffer[iKID] = 0xFF;
}
}
}}
}
// read mouse position
POINT pntMouse;
if( GetCursorPos( &pntMouse))
{
FLOAT fDX = FLOAT( SLONG(pntMouse.x) - inp_slScreenCenterX);
FLOAT fDY = FLOAT( SLONG(pntMouse.y) - inp_slScreenCenterY);
FLOAT fSensitivity = inp_fMouseSensitivity;
if( inp_bAllowMouseAcceleration) fSensitivity *= 0.25f;
FLOAT fD = Sqrt(fDX*fDX+fDY*fDY);
if (inp_bMousePrecision) {
static FLOAT _tmTime = 0.0f;
if( fD<inp_fMousePrecisionThreshold) _tmTime += 0.05f;
else _tmTime = 0.0f;
if( _tmTime>inp_fMousePrecisionTimeout) fSensitivity /= inp_fMousePrecisionFactor;
}
static FLOAT fDXOld;
static FLOAT fDYOld;
static TIME tmOldDelta;
static CTimerValue tvBefore;
CTimerValue tvNow = _pTimer->GetHighPrecisionTimer();
TIME tmNowDelta = (tvNow-tvBefore).GetSeconds();
if (tmNowDelta<0.001f) {
tmNowDelta = 0.001f;
}
tvBefore = tvNow;
FLOAT fDXSmooth = (fDXOld*tmOldDelta+fDX*tmNowDelta)/(tmOldDelta+tmNowDelta);
FLOAT fDYSmooth = (fDYOld*tmOldDelta+fDY*tmNowDelta)/(tmOldDelta+tmNowDelta);
fDXOld = fDX;
fDYOld = fDY;
tmOldDelta = tmNowDelta;
if (inp_bFilterMouse) {
fDX = fDXSmooth;
fDY = fDYSmooth;
}
// get final mouse values
FLOAT fMouseRelX = +fDX*fSensitivity;
FLOAT fMouseRelY = -fDY*fSensitivity;
if (inp_bInvertMouse) {
fMouseRelY = -fMouseRelY;
}
FLOAT fMouseRelZ = _iMouseZ;
// just interpret values as normal
inp_caiAllAxisInfo[1].cai_fReading = fMouseRelX;
inp_caiAllAxisInfo[2].cai_fReading = fMouseRelY;
inp_caiAllAxisInfo[3].cai_fReading = fMouseRelZ;
// if not pre-scanning
if (!bPreScan) {
// detect wheel up/down movement
_bWheelDn = FALSE;
if (_iMouseZ>0) {
if (_bWheelUp) {
inp_ubButtonsBuffer[KID_MOUSEWHEELUP] = 0x00;
} else {
inp_ubButtonsBuffer[KID_MOUSEWHEELUP] = 0xFF;
_iMouseZ = ClampDn(_iMouseZ-120, 0);
}
}
_bWheelUp = inp_ubButtonsBuffer[KID_MOUSEWHEELUP];
if (_iMouseZ<0) {
if (_bWheelDn) {
inp_ubButtonsBuffer[KID_MOUSEWHEELDOWN] = 0x00;
} else {
inp_ubButtonsBuffer[KID_MOUSEWHEELDOWN] = 0xFF;
_iMouseZ = ClampUp(_iMouseZ+120, 0);
}
}
_bWheelDn = inp_ubButtonsBuffer[KID_MOUSEWHEELDOWN];
}
}
inp_bLastPrescan = bPreScan;
// set cursor position to screen center
if (pntMouse.x!=inp_slScreenCenterX || pntMouse.y!=inp_slScreenCenterY) {
SetCursorPos(inp_slScreenCenterX, inp_slScreenCenterY);
}
// readout 2nd mouse if enabled
if( _h2ndMouse!=NONE)
{
Poll2ndMouse();
//CPrintF( "m2X: %4d, m2Y: %4d, m2B: 0x%02X\n", _i2ndMouseX, _i2ndMouseY, _i2ndMouseButtons);
// handle 2nd mouse buttons
if( _i2ndMouseButtons & 2) inp_ubButtonsBuffer[KID_2MOUSE1] = 0xFF;
if( _i2ndMouseButtons & 1) inp_ubButtonsBuffer[KID_2MOUSE2] = 0xFF;
if( _i2ndMouseButtons & 4) inp_ubButtonsBuffer[KID_2MOUSE3] = 0xFF;
// handle 2nd mouse movement
FLOAT fDX = _i2ndMouseX;
FLOAT fDY = _i2ndMouseY;
FLOAT fSensitivity = inp_f2ndMouseSensitivity;
FLOAT fD = Sqrt(fDX*fDX+fDY*fDY);
if( inp_b2ndMousePrecision) {
static FLOAT _tm2Time = 0.0f;
if( fD<inp_f2ndMousePrecisionThreshold) _tm2Time += 0.05f;
else _tm2Time = 0.0f;
if( _tm2Time>inp_f2ndMousePrecisionTimeout) fSensitivity /= inp_f2ndMousePrecisionFactor;
}
static FLOAT f2DXOld;
static FLOAT f2DYOld;
static TIME tm2OldDelta;
static CTimerValue tv2Before;
CTimerValue tvNow = _pTimer->GetHighPrecisionTimer();
TIME tmNowDelta = (tvNow-tv2Before).GetSeconds();
if( tmNowDelta<0.001f) tmNowDelta = 0.001f;
tv2Before = tvNow;
FLOAT fDXSmooth = (f2DXOld*tm2OldDelta+fDX*tmNowDelta) / (tm2OldDelta+tmNowDelta);
FLOAT fDYSmooth = (f2DYOld*tm2OldDelta+fDY*tmNowDelta) / (tm2OldDelta+tmNowDelta);
f2DXOld = fDX;
f2DYOld = fDY;
tm2OldDelta = tmNowDelta;
if( inp_bFilter2ndMouse) {
fDX = fDXSmooth;
fDY = fDYSmooth;
}
// get final mouse values
FLOAT fMouseRelX = +fDX*fSensitivity;
FLOAT fMouseRelY = -fDY*fSensitivity;
if( inp_bInvert2ndMouse) fMouseRelY = -fMouseRelY;
// just interpret values as normal
inp_caiAllAxisInfo[4].cai_fReading = fMouseRelX;
inp_caiAllAxisInfo[5].cai_fReading = fMouseRelY;
}
// if joystick polling is enabled
if (inp_bPollJoysticks || inp_bForceJoystickPolling) {
// scan all available joysticks
for( INDEX iJoy=0; iJoy<MAX_JOYSTICKS; iJoy++) {
if (inp_abJoystickOn[iJoy] && iJoy<inp_ctJoysticksAllowed) {
// scan joy state
BOOL bSucceeded = ScanJoystick(iJoy, bPreScan);
// if joystick reading failed
if (!bSucceeded && inp_bAutoDisableJoysticks) {
// kill it, so it doesn't slow down CPU
CPrintF(TRANS("Joystick %d failed, disabling it!\n"), iJoy+1);
inp_abJoystickOn[iJoy] = FALSE;
}
}
}
}
}
/*
* Scans axis and buttons for given joystick
*/
BOOL CInput::ScanJoystick(INDEX iJoy, BOOL bPreScan)
{
// read joystick state
JOYINFOEX ji;
ji.dwFlags = JOY_RETURNBUTTONS|JOY_RETURNCENTERED|JOY_RETURNPOV|JOY_RETURNR|
JOY_RETURNX|JOY_RETURNY|JOY_RETURNZ|JOY_RETURNU|JOY_RETURNV;
ji.dwSize = sizeof( JOYINFOEX);
MMRESULT mmResult = joyGetPosEx( JOYSTICKID1+iJoy, &ji);
// if some error
if( mmResult != JOYERR_NOERROR) {
// fail
return FALSE;
}
// for each available axis
for( INDEX iAxis=0; iAxis<MAX_AXES_PER_JOYSTICK; iAxis++) {
ControlAxisInfo &cai = inp_caiAllAxisInfo[ FIRST_JOYAXIS+iJoy*MAX_AXES_PER_JOYSTICK+iAxis];
// if the axis is not present
if (!cai.cai_bExisting) {
// read as zero
cai.cai_fReading = 0.0f;
// skip to next axis
continue;
}
// read its state
SLONG slAxisReading;
switch( iAxis) {
case 0: slAxisReading = ji.dwXpos; break;
case 1: slAxisReading = ji.dwYpos; break;
case 2: slAxisReading = ji.dwZpos; break;
case 3: slAxisReading = ji.dwRpos; break;
case 4: slAxisReading = ji.dwUpos; break;
case 5: slAxisReading = ji.dwVpos; break;
}
// convert from min..max to -1..+1
FLOAT fAxisReading = FLOAT(slAxisReading-cai.cai_slMin)/(cai.cai_slMax-cai.cai_slMin)*2.0f-1.0f;
// set current axis value
cai.cai_fReading = fAxisReading;
}
// if not pre-scanning
if (!bPreScan) {
INDEX iButtonTotal = FIRST_JOYBUTTON+iJoy*MAX_BUTTONS_PER_JOYSTICK;
// for each available button
for( INDEX iButton=0; iButton<32; iButton++) {
// test if the button is pressed
if(ji.dwButtons & (1L<<iButton)) {
inp_ubButtonsBuffer[ iButtonTotal++] = 128;
} else {
inp_ubButtonsBuffer[ iButtonTotal++] = 0;
}
}
// POV hat initially not pressed
// CPrintF("%d\n", ji.dwPOV);
INDEX iStartPOV = iButtonTotal;
inp_ubButtonsBuffer[ iStartPOV+0] = 0;
inp_ubButtonsBuffer[ iStartPOV+1] = 0;
inp_ubButtonsBuffer[ iStartPOV+2] = 0;
inp_ubButtonsBuffer[ iStartPOV+3] = 0;
// if we have POV
if (inp_abJoystickHasPOV[iJoy]) {
// check the four pov directions
if (ji.dwPOV==JOY_POVFORWARD) {
inp_ubButtonsBuffer[ iStartPOV+0] = 128;
} else if (ji.dwPOV==JOY_POVRIGHT) {
inp_ubButtonsBuffer[ iStartPOV+1] = 128;
} else if (ji.dwPOV==JOY_POVBACKWARD) {
inp_ubButtonsBuffer[ iStartPOV+2] = 128;
} else if (ji.dwPOV==JOY_POVLEFT) {
inp_ubButtonsBuffer[ iStartPOV+3] = 128;
// and four mid-positions
} else if (ji.dwPOV==JOY_POVFORWARD+4500) {
inp_ubButtonsBuffer[ iStartPOV+0] = 128;
inp_ubButtonsBuffer[ iStartPOV+1] = 128;
} else if (ji.dwPOV==JOY_POVRIGHT+4500) {
inp_ubButtonsBuffer[ iStartPOV+1] = 128;
inp_ubButtonsBuffer[ iStartPOV+2] = 128;
} else if (ji.dwPOV==JOY_POVBACKWARD+4500) {
inp_ubButtonsBuffer[ iStartPOV+2] = 128;
inp_ubButtonsBuffer[ iStartPOV+3] = 128;
} else if (ji.dwPOV==JOY_POVLEFT+4500) {
inp_ubButtonsBuffer[ iStartPOV+3] = 128;
inp_ubButtonsBuffer[ iStartPOV+0] = 128;
}
}
}
// successful
return TRUE;
}
LONG CInput::PlatformGetJoystickCount(void)
{
return((LONG) joyGetNumDevs());
}
// end of Win32Input.cpp ...

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "StdH.h" #include "Engine/StdH.h"
#include <Engine/Base/Synchronization.h> #include <Engine/Base/Synchronization.h>
@ -303,3 +303,4 @@ void CTSingleLock::Unlock(void)
} }
sl_bLocked = FALSE; sl_bLocked = FALSE;
} }

View File

@ -0,0 +1,15 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
/* rcg10072001 Moved stuff into this file. */
#include <Engine/Engine.h>
#include <Engine/Base/Timer.h>
void CTimer::Sleep(DWORD milliseconds)
{
::Sleep(milliseconds);
}
// end of Win32Timer.cpp ...

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Brushes/Brush.h> #include <Engine/Brushes/Brush.h>
#include <Engine/World/World.h> #include <Engine/World/World.h>

View File

@ -254,16 +254,30 @@ public:
CMappingDefinition bpt_mdMapping; // mapping of texture on polygon CMappingDefinition bpt_mdMapping; // mapping of texture on polygon
union { union {
struct { struct {
UBYTE bpt_ubScroll; // texture scroll UBYTE bpt_ubScroll; // texture scroll
UBYTE bpt_ubBlend; // type of texture blending used UBYTE bpt_ubBlend; // type of texture blending used
UBYTE bpt_ubFlags; // additional flags UBYTE bpt_ubFlags; // additional flags
UBYTE bpt_ubDummy; // unused (alignment) UBYTE bpt_ubDummy; // unused (alignment)
COLOR bpt_colColor; // defines constant color and alpha of polygon COLOR bpt_colColor; // defines constant color and alpha of polygon
} s; } s;
UBYTE bpt_auProperties[8]; UBYTE bpt_auProperties[8];
}; };
// ATTENTION! If you add/edit/remove any data member, PLEASE update the
// operator = method, below! --ryan.
CBrushPolygonTexture& operator =(const CBrushPolygonTexture &src)
{
if (this != &src)
{
bpt_toTexture = src.bpt_toTexture;
bpt_mdMapping = src.bpt_mdMapping;
memcpy(&bpt_auProperties, &src.bpt_auProperties, sizeof (bpt_auProperties));
}
return *this;
}
CBrushPolygonTexture(void) CBrushPolygonTexture(void)
{ {
s.bpt_ubScroll = 0; s.bpt_ubScroll = 0;
@ -347,8 +361,29 @@ struct CBrushPolygonProperties {
UWORD bpp_uwPretenderDistance; // distance for pretender switching [m] UWORD bpp_uwPretenderDistance; // distance for pretender switching [m]
/* Default constructor. */ /* Default constructor. */
CBrushPolygonProperties(void) { memset(this, 0, sizeof(*this)); }; CBrushPolygonProperties(void) { memset(this, 0, sizeof(*this)); };
friend __forceinline CTStream &operator>>(CTStream &strm, CBrushPolygonProperties &cbpp)
{
strm>>cbpp.bpp_ubSurfaceType;
strm>>cbpp.bpp_ubIlluminationType;
strm>>cbpp.bpp_ubShadowBlend;
strm>>cbpp.bpp_ubMirrorType;
strm>>cbpp.bpp_ubGradientType;
strm>>cbpp.bpp_sbShadowClusterSize;
strm>>cbpp.bpp_uwPretenderDistance;
return strm;
}
friend __forceinline CTStream &operator<<(CTStream &strm, const CBrushPolygonProperties &cbpp)
{
strm<<cbpp.bpp_ubSurfaceType;
strm<<cbpp.bpp_ubIlluminationType;
strm<<cbpp.bpp_ubShadowBlend;
strm<<cbpp.bpp_ubMirrorType;
strm<<cbpp.bpp_ubGradientType;
strm<<cbpp.bpp_sbShadowClusterSize;
strm<<cbpp.bpp_uwPretenderDistance;
return strm;
}
}; };
class ENGINE_API CBrushPolygon { class ENGINE_API CBrushPolygon {
public: public:
// implementation: // implementation:
@ -433,13 +468,12 @@ public:
SLONG GetUsedMemory(void); SLONG GetUsedMemory(void);
}; };
// get pointer to embedding brush polygon // get pointer to embedding brush polygon
inline CBrushPolygon *CBrushShadowMap::GetBrushPolygon(void) { inline CBrushPolygon *CBrushShadowMap::GetBrushPolygon(void) {
return (CBrushPolygon *) ((UBYTE*)this-offsetof(CBrushPolygon, bpo_smShadowMap)); return (CBrushPolygon *) ((UBYTE*)this-_offsetof(CBrushPolygon, bpo_smShadowMap));
return(NULL);
} }
// selection of brush polygons // selection of brush polygons
typedef CSelection<CBrushPolygon, BPOF_SELECTED> CBrushPolygonSelection; typedef CSelection<CBrushPolygon, BPOF_SELECTED> CBrushPolygonSelection;
// selection of brush polygons used for CSG // selection of brush polygons used for CSG

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Brushes/Brush.h> #include <Engine/Brushes/Brush.h>
#include <Engine/Brushes/BrushArchive.h> #include <Engine/Brushes/BrushArchive.h>
@ -17,10 +17,15 @@
#include <Engine/Templates/DynamicArray.cpp> #include <Engine/Templates/DynamicArray.cpp>
#include <Engine/Templates/StaticArray.cpp> #include <Engine/Templates/StaticArray.cpp>
// !!! FIXME: This confuses GCC, since CDynamicArray is a #included
// !!! FIXME: source file, and it ends up compiling the template more than
// !!! FIXME: once. :( --ryan.
#ifdef _MSC_VER
template CDynamicArray<CBrush3D>; template CDynamicArray<CBrush3D>;
#endif
extern BOOL _bPortalSectorLinksPreLoaded = FALSE; BOOL _bPortalSectorLinksPreLoaded = FALSE;
extern BOOL _bEntitySectorLinksPreLoaded = FALSE; BOOL _bEntitySectorLinksPreLoaded = FALSE;
/* /*
* Calculate bounding boxes in all brushes. * Calculate bounding boxes in all brushes.

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Brushes/Brush.h> #include <Engine/Brushes/Brush.h>
#include <Engine/World/WorldEditingProfile.h> #include <Engine/World/WorldEditingProfile.h>

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>
#include <Engine/Base/ReplaceFile.h> #include <Engine/Base/ReplaceFile.h>
@ -223,7 +223,7 @@ void CBrushPolygonTexture::Read_t( CTStream &strm) // throw char *
if (bpt_toTexture.GetData()!=NULL) { if (bpt_toTexture.GetData()!=NULL) {
bpt_toTexture.GetData()->AddToCRCTable(); bpt_toTexture.GetData()->AddToCRCTable();
} }
strm.Read_t(&bpt_mdMapping, sizeof(bpt_mdMapping)); strm>>bpt_mdMapping;
strm>>s.bpt_ubScroll; strm>>s.bpt_ubScroll;
strm>>s.bpt_ubBlend; strm>>s.bpt_ubBlend;
strm>>s.bpt_ubFlags; strm>>s.bpt_ubFlags;
@ -402,7 +402,7 @@ void CBrushSector::Read_t( CTStream *pistrm) // throw char *
// for each vertex // for each vertex
{FOREACHINSTATICARRAY(bsc_abvxVertices, CBrushVertex, itbvx) { {FOREACHINSTATICARRAY(bsc_abvxVertices, CBrushVertex, itbvx) {
// read precise vertex coordinates // read precise vertex coordinates
pistrm->Read_t(&itbvx->bvx_vdPreciseRelative, sizeof(DOUBLE3D)); (*pistrm)>>itbvx->bvx_vdPreciseRelative;
// remember sector pointer // remember sector pointer
itbvx->bvx_pbscSector = this; itbvx->bvx_pbscSector = this;
}} }}
@ -417,7 +417,7 @@ void CBrushSector::Read_t( CTStream *pistrm) // throw char *
// for each plane // for each plane
{FOREACHINSTATICARRAY(bsc_abplPlanes, CBrushPlane, itbpl) { {FOREACHINSTATICARRAY(bsc_abplPlanes, CBrushPlane, itbpl) {
// read precise plane coordinates // read precise plane coordinates
pistrm->Read_t(&itbpl->bpl_pldPreciseRelative, sizeof(DOUBLEplane3D)); (*pistrm)>>itbpl->bpl_pldPreciseRelative;
}} }}
(*pistrm).ExpectID_t("EDGs"); // 'edges' (*pistrm).ExpectID_t("EDGs"); // 'edges'
@ -478,7 +478,7 @@ void CBrushSector::Read_t( CTStream *pistrm) // throw char *
bpo.bpo_abptTextures[2].Read_t(*pistrm); bpo.bpo_abptTextures[2].Read_t(*pistrm);
// read other polygon properties // read other polygon properties
(*pistrm).Read_t(&bpo.bpo_bppProperties, sizeof(bpo.bpo_bppProperties)); (*pistrm)>>bpo.bpo_bppProperties;
} else { } else {
// read textures // read textures
@ -495,7 +495,7 @@ void CBrushSector::Read_t( CTStream *pistrm) // throw char *
// read texture mapping // read texture mapping
bpo.bpo_mdShadow.ReadOld_t(*pistrm); bpo.bpo_mdShadow.ReadOld_t(*pistrm);
// read other polygon properties // read other polygon properties
(*pistrm).Read_t(&bpo.bpo_bppProperties, sizeof(bpo.bpo_bppProperties)); (*pistrm)>>bpo.bpo_bppProperties;
// adjust polygon and texture properties // adjust polygon and texture properties
bpo.bpo_abptTextures[0].bpt_mdMapping = bpo.bpo_mdShadow; bpo.bpo_abptTextures[0].bpt_mdMapping = bpo.bpo_mdShadow;
@ -579,7 +579,9 @@ void CBrushSector::Read_t( CTStream *pistrm) // throw char *
bpo.bpo_aiTriangleElements.New(ctElements); bpo.bpo_aiTriangleElements.New(ctElements);
// read all element indices // read all element indices
if (ctElements>0) { if (ctElements>0) {
(*pistrm).Read_t(&bpo.bpo_aiTriangleElements[0], ctElements*sizeof(INDEX)); for (INDEX i = 0; i < ctElements; i++) {
(*pistrm)>>bpo.bpo_aiTriangleElements[i];
}
} }
} }

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Brushes/Brush.h> #include <Engine/Brushes/Brush.h>
#include <Engine/Math/Float.h> #include <Engine/Math/Float.h>

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Brushes/Brush.h> #include <Engine/Brushes/Brush.h>
#include <Engine/World/World.h> #include <Engine/World/World.h>
@ -16,7 +16,7 @@
#include <Engine/Templates/StaticArray.cpp> #include <Engine/Templates/StaticArray.cpp>
#include <Engine/Templates/Selection.cpp> #include <Engine/Templates/Selection.cpp>
template CDynamicArray<CBrushSector>; template class CDynamicArray<CBrushSector>;
// tolerance value for csg selection // tolerance value for csg selection
#define CSG_RANGE_EPSILON (0.25f) #define CSG_RANGE_EPSILON (0.25f)

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Brushes/Brush.h> #include <Engine/Brushes/Brush.h>
#include <Engine/Brushes/BrushTransformed.h> #include <Engine/Brushes/BrushTransformed.h>
@ -13,9 +13,9 @@
#include <Engine/Entities/Entity.h> #include <Engine/Entities/Entity.h>
#include <Engine/Templates/Selection.cpp> #include <Engine/Templates/Selection.cpp>
template CStaticArray<CBrushPolygonEdge>; template class CStaticArray<CBrushPolygonEdge>;
template CStaticArray<CBrushPolygon>; template class CStaticArray<CBrushPolygon>;
template CStaticArray<long>; template class CStaticArray<long>;
// set new absolute position for the vertex // set new absolute position for the vertex
void CBrushVertex::SetAbsolutePosition(const DOUBLE3D &vAbsolute) void CBrushVertex::SetAbsolutePosition(const DOUBLE3D &vAbsolute)

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Brushes/Brush.h> #include <Engine/Brushes/Brush.h>
#include <Engine/Brushes/BrushTransformed.h> #include <Engine/Brushes/BrushTransformed.h>

View File

@ -1,7 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include <Engine/StdH.h>
#include <Engine/Brushes/Brush.h> #include <Engine/Brushes/Brush.h>
#include <Engine/Brushes/BrushTransformed.h> #include <Engine/Brushes/BrushTransformed.h>
#include <Engine/Brushes/BrushArchive.h> #include <Engine/Brushes/BrushArchive.h>

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Brushes/Brush.h> #include <Engine/Brushes/Brush.h>
#include <Engine/Templates/DynamicArray.cpp> #include <Engine/Templates/DynamicArray.cpp>
@ -578,6 +578,7 @@ void CTriangularizer::DPrintF(char *strFormat, ...)
va_list arg; va_list arg;
va_start(arg, strFormat); va_start(arg, strFormat);
vsprintf(strBuffer, strFormat, arg); vsprintf(strBuffer, strFormat, arg);
va_end(arg);
// if the debug output file is not open // if the debug output file is not open
if (!_bDebugOutputOpen) { if (!_bDebugOutputOpen) {
@ -717,7 +718,7 @@ void CTriangularizer::FindBestTriangle(void)
#if 0 #if 0
// if no acceptable triangles have been found // if no acceptable triangles have been found
if (tr_fQualityBest<???) { if (tr_fQualityBest</*???*/sdfsdfd) {
/* dump all sector's vertices */ /* dump all sector's vertices */
/* /*
FOREACHINSTATICARRAY(tr_bpoOriginalPolygon.bpo_pbscSector->bsc_abvxVertices, FOREACHINSTATICARRAY(tr_bpoOriginalPolygon.bpo_pbscSector->bsc_abvxVertices,

View File

@ -2,7 +2,7 @@
5 5
%{ %{
#include "StdH.h" #include <Engine/StdH.h>
#define DECL_DLL ENGINE_API #define DECL_DLL ENGINE_API
#include <Engine/Entities/EntityEvent.h> #include <Engine/Entities/EntityEvent.h>
#include <Engine/Entities/EntityPointer.h> #include <Engine/Entities/EntityPointer.h>

View File

@ -6,7 +6,7 @@
3 3
%{ %{
#include "StdH.h" #include <Engine/StdH.h>
#include <Engine/Entities/InternalClasses.h> #include <Engine/Entities/InternalClasses.h>
%} %}

View File

@ -5,7 +5,7 @@
*/ */
1 1
%{ %{
#include "StdH.h" #include <Engine/StdH.h>
#include <Engine/Entities/InternalClasses.h> #include <Engine/Entities/InternalClasses.h>
#include <Engine/World/PhysicsProfile.h> #include <Engine/World/PhysicsProfile.h>
#include <Engine/Math/Geometry.inl> #include <Engine/Math/Geometry.inl>
@ -36,7 +36,7 @@
%{ %{
#define ANYEXCEPTION ... #define ANYEXCEPTION ...
template CStaticStackArray<CBrushPolygon*>; template class CStaticStackArray<CBrushPolygon*>;
#define MAXCOLLISIONRETRIES 4*4 #define MAXCOLLISIONRETRIES 4*4
extern FLOAT phy_fCollisionCacheAhead; extern FLOAT phy_fCollisionCacheAhead;
@ -1107,12 +1107,12 @@ functions:
BOOL IsStandingOnPolygon(CBrushPolygon *pbpo) BOOL IsStandingOnPolygon(CBrushPolygon *pbpo)
{ {
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
// if cannot optimize for standing on handle // if cannot optimize for standing on handle
if (en_pciCollisionInfo==NULL if (en_pciCollisionInfo==NULL
||!(en_pciCollisionInfo->ci_ulFlags&CIF_CANSTANDONHANDLE)) { ||!(en_pciCollisionInfo->ci_ulFlags&CIF_CANSTANDONHANDLE)) {
// not standing on polygon // not standing on polygon
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return FALSE; return FALSE;
} }
@ -1133,7 +1133,7 @@ functions:
// if handle is not on the plane // if handle is not on the plane
if (plPolygon.PointDistance(vHandle)>0.01f) { if (plPolygon.PointDistance(vHandle)>0.01f) {
// not standing on polygon // not standing on polygon
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return FALSE; return FALSE;
} }
@ -1157,12 +1157,12 @@ functions:
// if the point is inside polygon // if the point is inside polygon
if (isIntersector.IsIntersecting()) { if (isIntersector.IsIntersecting()) {
// entity is standing on polygon // entity is standing on polygon
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return TRUE; return TRUE;
// if the point is outside polygon // if the point is outside polygon
} else { } else {
// entity is not standing on polygon // entity is not standing on polygon
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return FALSE; return FALSE;
} }
} }
@ -1170,13 +1170,13 @@ functions:
// check whether a polygon is below given point, but not too far away // check whether a polygon is below given point, but not too far away
BOOL IsPolygonBelowPoint(CBrushPolygon *pbpo, const FLOAT3D &vPoint, FLOAT fMaxDist) BOOL IsPolygonBelowPoint(CBrushPolygon *pbpo, const FLOAT3D &vPoint, FLOAT fMaxDist)
{ {
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
// if passable or not allowed as ground // if passable or not allowed as ground
if ((pbpo->bpo_ulFlags&BPOF_PASSABLE) if ((pbpo->bpo_ulFlags&BPOF_PASSABLE)
||!AllowForGroundPolygon(pbpo)) { ||!AllowForGroundPolygon(pbpo)) {
// it cannot be below // it cannot be below
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return FALSE; return FALSE;
} }
@ -1188,7 +1188,7 @@ functions:
// if polygon is vertical or upside down // if polygon is vertical or upside down
if (fCos>-0.01f) { if (fCos>-0.01f) {
// it cannot be below // it cannot be below
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return FALSE; return FALSE;
} }
@ -1197,7 +1197,7 @@ functions:
if (fCos>=-stReference.st_fClimbSlopeCos&&fCos<0 if (fCos>=-stReference.st_fClimbSlopeCos&&fCos<0
||stReference.st_ulFlags&STF_SLIDEDOWNSLOPE) { ||stReference.st_ulFlags&STF_SLIDEDOWNSLOPE) {
// it cannot be below // it cannot be below
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return FALSE; return FALSE;
} }
@ -1206,7 +1206,7 @@ functions:
// if the point is behind the plane // if the point is behind the plane
if (fD<-0.01f) { if (fD<-0.01f) {
// it cannot be below // it cannot be below
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return FALSE; return FALSE;
} }
@ -1215,7 +1215,7 @@ functions:
// if too far away // if too far away
if (fDistance > fMaxDist) { if (fDistance > fMaxDist) {
// it cannot be below // it cannot be below
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return FALSE; return FALSE;
} }
// project point to the polygon along gravity vector // project point to the polygon along gravity vector
@ -1241,12 +1241,12 @@ functions:
// if the point is inside polygon // if the point is inside polygon
if (isIntersector.IsIntersecting()) { if (isIntersector.IsIntersecting()) {
// it is below // it is below
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return TRUE; return TRUE;
// if the point is outside polygon // if the point is outside polygon
} else { } else {
// it is not below // it is not below
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
return FALSE; return FALSE;
} }
} }
@ -1399,9 +1399,9 @@ out:;
// set current placement from next position // set current placement from next position
void SetPlacementFromNextPosition(void) void SetPlacementFromNextPosition(void)
{ {
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_SETPLACEMENTFROMNEXTPOSITION); _pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_SETPLACEMENTFROMNEXTPOSITION);
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_SETPLACEMENTFROMNEXTPOSITION); _pfPhysicsProfile.IncrementTimerAveragingCounter((INDEX) CPhysicsProfile::PTI_SETPLACEMENTFROMNEXTPOSITION);
CPlacement3D plNew; CPlacement3D plNew;
plNew.pl_PositionVector = en_vNextPosition; plNew.pl_PositionVector = en_vNextPosition;
DecomposeRotationMatrixNoSnap(plNew.pl_OrientationAngle, en_mNextRotation); DecomposeRotationMatrixNoSnap(plNew.pl_OrientationAngle, en_mNextRotation);
@ -1421,14 +1421,14 @@ out:;
} }
*/ */
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_SETPLACEMENTFROMNEXTPOSITION); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_SETPLACEMENTFROMNEXTPOSITION);
} }
BOOL TryToGoUpstairs(const FLOAT3D &vTranslationAbsolute, const CSurfaceType &stHit, BOOL TryToGoUpstairs(const FLOAT3D &vTranslationAbsolute, const CSurfaceType &stHit,
BOOL bHitStairsOrg) BOOL bHitStairsOrg)
{ {
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_TRYTOGOUPSTAIRS); _pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_TRYTOGOUPSTAIRS); _pfPhysicsProfile.IncrementTimerAveragingCounter((INDEX) CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
// use only horizontal components of the movement // use only horizontal components of the movement
FLOAT3D vTranslationHorizontal; FLOAT3D vTranslationHorizontal;
@ -1439,7 +1439,7 @@ out:;
if(vTranslationHorizontal.Length()<0.001f) { if(vTranslationHorizontal.Length()<0.001f) {
//CPrintF("no value\n"); //CPrintF("no value\n");
// don't do it // don't do it
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOGOUPSTAIRS); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
return FALSE; return FALSE;
} }
FLOAT3D vTranslationHorizontalOrg = vTranslationHorizontal; FLOAT3D vTranslationHorizontalOrg = vTranslationHorizontal;
@ -1557,7 +1557,7 @@ out:;
en_vNextPosition = plOriginal.pl_PositionVector; en_vNextPosition = plOriginal.pl_PositionVector;
SetPlacementFromNextPosition(); SetPlacementFromNextPosition();
// move is unsuccessful // move is unsuccessful
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOGOUPSTAIRS); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
//CPrintF("FAILED\n"); //CPrintF("FAILED\n");
return FALSE; return FALSE;
} }
@ -1572,7 +1572,7 @@ out:;
en_vAppliedTranslation += vTranslationHorizontalOrg; en_vAppliedTranslation += vTranslationHorizontalOrg;
} }
// move is successful // move is successful
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOGOUPSTAIRS); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
//CPrintF("done\n"); //CPrintF("done\n");
return TRUE; return TRUE;
} }
@ -1592,9 +1592,9 @@ out:;
// fail the move // fail the move
return FALSE; return FALSE;
} }
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.IncrementTimerAveragingCounter((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_TRYTOMOVE); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_TRYTOMOVE);
// create new placement with movement // create new placement with movement
if (bTranslate) { if (bTranslate) {
@ -1637,7 +1637,7 @@ out:;
// clip the movement to the entity's world // clip the movement to the entity's world
if (!bTranslate && bIgnoreRotation) { if (!bTranslate && bIgnoreRotation) {
cmMove.cm_fMovementFraction = 2.0f; cmMove.cm_fMovementFraction = 2.0f;
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_TRYTOMOVE_FAST); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_TRYTOMOVE_FAST);
} else { } else {
en_pwoWorld->ClipMove(cmMove); en_pwoWorld->ClipMove(cmMove);
} }
@ -1665,14 +1665,14 @@ out:;
en_mAppliedRotation = en_mMoveRotation*en_mAppliedRotation; en_mAppliedRotation = en_mMoveRotation*en_mAppliedRotation;
} }
// move is successful // move is successful
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_TRYTOMOVE_PASS); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_TRYTOMOVE_PASS);
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
//CPrintF(" successful\n"); //CPrintF(" successful\n");
return TRUE; return TRUE;
// if the move is clipped // if the move is clipped
} else { } else {
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_TRYTOMOVE_CLIP); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_TRYTOMOVE_CLIP);
/* STREAMDUMP START /* STREAMDUMP START
if(GetRenderType()==RT_MODEL) if(GetRenderType()==RT_MODEL)
@ -1694,7 +1694,7 @@ out:;
// if must not retry // if must not retry
if (_ctTryToMoveCheckCounter<=0) { if (_ctTryToMoveCheckCounter<=0) {
// fail // fail
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
return FALSE; return FALSE;
} }
@ -1781,20 +1781,20 @@ out:;
// make sure it is added to the movers list // make sure it is added to the movers list
penBlocking->AddToMoversDuringMoving(); penBlocking->AddToMoversDuringMoving();
// push the blocking entity // push the blocking entity
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
BOOL bUnblocked = penBlocking->TryToMove(penPusher, bTranslate, bRotate); BOOL bUnblocked = penBlocking->TryToMove(penPusher, bTranslate, bRotate);
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
// if it has removed itself // if it has removed itself
if (bUnblocked) { if (bUnblocked) {
// retry the movement // retry the movement
ClearNextPosition(); ClearNextPosition();
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
return TryToMove(penPusher, bTranslate, bRotate); return TryToMove(penPusher, bTranslate, bRotate);
} else { } else {
// move is unsuccessful // move is unsuccessful
SendBlockEvent(cmMove); SendBlockEvent(cmMove);
ClearNextPosition(); ClearNextPosition();
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
return FALSE; return FALSE;
} }
// if entity slides if blocked // if entity slides if blocked
@ -1849,7 +1849,7 @@ out:;
if (cmMove.cm_pbpoHit!=NULL) { if (cmMove.cm_pbpoHit!=NULL) {
CSurfaceType &stHit = en_pwoWorld->wo_astSurfaceTypes[ CSurfaceType &stHit = en_pwoWorld->wo_astSurfaceTypes[
cmMove.cm_pbpoHit->bpo_bppProperties.bpp_ubSurfaceType]; cmMove.cm_pbpoHit->bpo_bppProperties.bpp_ubSurfaceType];
// if it is not beeing pushed, and it can climb stairs // if it is not being pushed, and it can climb stairs
if (penPusher==NULL if (penPusher==NULL
&&(en_ulPhysicsFlags&EPF_ONBLOCK_MASK)==EPF_ONBLOCK_CLIMBORSLIDE) { &&(en_ulPhysicsFlags&EPF_ONBLOCK_MASK)==EPF_ONBLOCK_CLIMBORSLIDE) {
// NOTE: originally, the polygon's plane was considered here. // NOTE: originally, the polygon's plane was considered here.
@ -1874,7 +1874,7 @@ out:;
// if can go upstairs // if can go upstairs
&& TryToGoUpstairs(en_vMoveTranslation, stHit, bHitStairs)) { && TryToGoUpstairs(en_vMoveTranslation, stHit, bHitStairs)) {
// movement is ok // movement is ok
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
return FALSE; return FALSE;
} }
} }
@ -1895,19 +1895,19 @@ out:;
// if initial movement has some substantial value // if initial movement has some substantial value
if(en_vMoveTranslation.Length()>0.001f && cmMove.cm_fMovementFraction>0.002f) { if(en_vMoveTranslation.Length()>0.001f && cmMove.cm_fMovementFraction>0.002f) {
// go to where it is clipped (little bit before) // go to where it is clipped (little bit before)
vSliding += en_vMoveTranslation*(cmMove.cm_fMovementFraction*0.985f); vSliding += en_vMoveTranslation*(cmMove.cm_fMovementFraction*0.98f);
} }
// ignore extremely small sliding // ignore extremely small sliding
if (vSliding.ManhattanNorm()<0.001f) { if (vSliding.ManhattanNorm()<0.001f) {
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
return FALSE; return FALSE;
} }
// recurse // recurse
en_vMoveTranslation = vSliding; en_vMoveTranslation = vSliding;
ClearNextPosition(); ClearNextPosition();
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
TryToMove(penPusher, bTranslate, bRotate); TryToMove(penPusher, bTranslate, bRotate);
// if bouncer // if bouncer
if (bBounce) { if (bBounce) {
@ -1931,7 +1931,7 @@ out:;
if (en_aDesiredRotationRelative.Length()<10) { if (en_aDesiredRotationRelative.Length()<10) {
en_aDesiredRotationRelative = ANGLE3D(0,0,0); en_aDesiredRotationRelative = ANGLE3D(0,0,0);
} }
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
// move is not successful // move is not successful
return FALSE; return FALSE;
} }
@ -1939,13 +1939,13 @@ out:;
en_vMoveTranslation = cmMove.cm_vClippedLine*-1.2f; en_vMoveTranslation = cmMove.cm_vClippedLine*-1.2f;
// recurse // recurse
ClearNextPosition(); ClearNextPosition();
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
TryToMove(penPusher, TRUE, bRotate); TryToMove(penPusher, TRUE, bRotate);
// move is not entirely successful // move is not entirely successful
return FALSE; return FALSE;
} }
// not translating and not rotating? - move is unsuccessful // not translating and not rotating? - move is unsuccessful
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
return FALSE; return FALSE;
// if entity has some other behaviour when blocked // if entity has some other behaviour when blocked
@ -1953,7 +1953,7 @@ out:;
// move is unsuccessful (EPF_ONBLOCK_STOP is assumed) // move is unsuccessful (EPF_ONBLOCK_STOP is assumed)
SendBlockEvent(cmMove); SendBlockEvent(cmMove);
ClearNextPosition(); ClearNextPosition();
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
return FALSE; return FALSE;
} }
} }
@ -2019,8 +2019,8 @@ out:;
ExportEntityPlacementAndSpeed( *(CMovableEntity *)this, "Pre moving (start of function)"); ExportEntityPlacementAndSpeed( *(CMovableEntity *)this, "Pre moving (start of function)");
STREAMDUMP END */ STREAMDUMP END */
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_PREMOVING); _pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_PREMOVING);
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_PREMOVING); _pfPhysicsProfile.IncrementTimerAveragingCounter((INDEX) CPhysicsProfile::PTI_PREMOVING);
// remember old placement for lerping // remember old placement for lerping
en_plLastPlacement = en_plPlacement; en_plLastPlacement = en_plPlacement;
@ -2260,7 +2260,7 @@ out:;
// if gravity can cause the entity to fall // if gravity can cause the entity to fall
if (!bGravityAlongPolygon) { if (!bGravityAlongPolygon) {
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_GRAVITY_NONTRIVIAL); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_GRAVITY_NONTRIVIAL);
// add gravity acceleration // add gravity acceleration
FLOAT fGV=en_fGravityV*fTickQuantum*fSpeedModifier; FLOAT fGV=en_fGravityV*fTickQuantum*fSpeedModifier;
@ -2268,7 +2268,7 @@ out:;
AddGAcceleration(vTranslationAbsolute, en_vGravityDir, fGA, fGV); AddGAcceleration(vTranslationAbsolute, en_vGravityDir, fGA, fGV);
// if entity can only slide down its stand-on polygon // if entity can only slide down its stand-on polygon
} else { } else {
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_GRAVITY_TRIVIAL); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_GRAVITY_TRIVIAL);
// disassemble gravity to parts parallel and normal to plane // disassemble gravity to parts parallel and normal to plane
FLOAT3D vPolygonDir = -en_vReferencePlane; FLOAT3D vPolygonDir = -en_vReferencePlane;
@ -2419,7 +2419,7 @@ out:;
// clear applied movement to be updated during movement // clear applied movement to be updated during movement
en_vAppliedTranslation = FLOAT3D(0.0f, 0.0f, 0.0f); en_vAppliedTranslation = FLOAT3D(0.0f, 0.0f, 0.0f);
en_mAppliedRotation.Diagonal(1.0f); en_mAppliedRotation.Diagonal(1.0f);
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_PREMOVING); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_PREMOVING);
// STREAMDUMP ExportEntityPlacementAndSpeed( *(CMovableEntity *)this, "Pre moving (end of function)"); // STREAMDUMP ExportEntityPlacementAndSpeed( *(CMovableEntity *)this, "Pre moving (end of function)");
} }
@ -2845,16 +2845,16 @@ out:;
} }
// STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Do moving (start of function)"); // STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Do moving (start of function)");
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_DOMOVING); _pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_DOMOVING);
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_DOMOVING); _pfPhysicsProfile.IncrementTimerAveragingCounter((INDEX) CPhysicsProfile::PTI_DOMOVING);
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_DOMOVING); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_DOMOVING);
FLOAT fTickQuantum=_pTimer->TickQuantum; // used for normalizing from SI units to game ticks FLOAT fTickQuantum=_pTimer->TickQuantum; // used for normalizing from SI units to game ticks
// if rotation and translation are synchronized // if rotation and translation are synchronized
if (en_ulPhysicsFlags&EPF_RT_SYNCHRONIZED) { if (en_ulPhysicsFlags&EPF_RT_SYNCHRONIZED) {
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_DOMOVING_SYNC); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_DOMOVING_SYNC);
// move both in translation and rotation // move both in translation and rotation
en_vMoveTranslation = en_vIntendedTranslation-en_vAppliedTranslation; en_vMoveTranslation = en_vIntendedTranslation-en_vAppliedTranslation;
@ -2870,11 +2870,11 @@ out:;
// if rotation and translation are asynchronious // if rotation and translation are asynchronious
} else { } else {
ASSERT((en_ulPhysicsFlags&EPF_ONBLOCK_MASK)!=EPF_ONBLOCK_PUSH); ASSERT((en_ulPhysicsFlags&EPF_ONBLOCK_MASK)!=EPF_ONBLOCK_PUSH);
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_DOMOVING_ASYNC); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_DOMOVING_ASYNC);
// if there is no reference // if there is no reference
if (en_penReference == NULL) { if (en_penReference == NULL) {
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_DOMOVING_ASYNC_SYNCTRY); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_DOMOVING_ASYNC_SYNCTRY);
// try to do simple move both in translation and rotation // try to do simple move both in translation and rotation
en_vMoveTranslation = en_vIntendedTranslation-en_vAppliedTranslation; en_vMoveTranslation = en_vIntendedTranslation-en_vAppliedTranslation;
@ -2885,14 +2885,14 @@ out:;
// if it passes // if it passes
if (bMoveSuccessfull) { if (bMoveSuccessfull) {
// finish // finish
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_DOMOVING_ASYNC_SYNCPASS); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_DOMOVING_ASYNC_SYNCPASS);
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_DOMOVING); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_DOMOVING);
// STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Do moving (return: if it passes)"); // STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Do moving (return: if it passes)");
return; return;
} }
} }
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_DOMOVING_ASYNC_TRANSLATE); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_DOMOVING_ASYNC_TRANSLATE);
// translate // translate
en_vMoveTranslation = en_vIntendedTranslation-en_vAppliedTranslation; en_vMoveTranslation = en_vIntendedTranslation-en_vAppliedTranslation;
InitTryToMove(); InitTryToMove();
@ -2904,13 +2904,13 @@ out:;
en_mMoveRotation(1,1)!=1 || en_mMoveRotation(1,2)!=0 || en_mMoveRotation(1,3)!=0 || en_mMoveRotation(1,1)!=1 || en_mMoveRotation(1,2)!=0 || en_mMoveRotation(1,3)!=0 ||
en_mMoveRotation(2,1)!=0 || en_mMoveRotation(2,2)!=1 || en_mMoveRotation(2,3)!=0 || en_mMoveRotation(2,1)!=0 || en_mMoveRotation(2,2)!=1 || en_mMoveRotation(2,3)!=0 ||
en_mMoveRotation(3,1)!=0 || en_mMoveRotation(3,2)!=0 || en_mMoveRotation(3,3)!=1) { en_mMoveRotation(3,1)!=0 || en_mMoveRotation(3,2)!=0 || en_mMoveRotation(3,3)!=1) {
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_DOMOVING_ASYNC_ROTATE); _pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_DOMOVING_ASYNC_ROTATE);
InitTryToMove(); InitTryToMove();
TryToMove(NULL, FALSE, TRUE); TryToMove(NULL, FALSE, TRUE);
} }
} }
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_DOMOVING); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_DOMOVING);
// STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Do moving (end of function)"); // STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Do moving (end of function)");
} }
@ -2930,8 +2930,8 @@ out:;
// STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Post moving (start of function)"); // STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Post moving (start of function)");
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_POSTMOVING); _pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_POSTMOVING);
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_POSTMOVING); _pfPhysicsProfile.IncrementTimerAveragingCounter((INDEX) CPhysicsProfile::PTI_POSTMOVING);
// remember valid reference if valid // remember valid reference if valid
if (en_penReference!=NULL) { if (en_penReference!=NULL) {
@ -3074,7 +3074,7 @@ out:;
} }
//CPrintF("\n%f", _pTimer->CurrentTick()); //CPrintF("\n%f", _pTimer->CurrentTick());
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_POSTMOVING); _pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_POSTMOVING);
// STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Post moving (end of function)"); // STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Post moving (end of function)");
} }

View File

@ -6,7 +6,7 @@
2 2
%{ %{
#include "StdH.h" #include <Engine/StdH.h>
#include <Engine/Entities/InternalClasses.h> #include <Engine/Entities/InternalClasses.h>
#include <Engine/Base/CRC.h> #include <Engine/Base/CRC.h>
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>

View File

@ -5,7 +5,7 @@
*/ */
4 4
%{ %{
#include "StdH.h" #include <Engine/StdH.h>
#include <Engine/Entities/InternalClasses.h> #include <Engine/Entities/InternalClasses.h>
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>
#include <Engine/Base/CRC.h> #include <Engine/Base/CRC.h>
@ -40,7 +40,9 @@ functions:
if (IsPredictor()) { if (IsPredictor()) {
penMe = GetPredicted(); penMe = GetPredicted();
} }
for (INDEX iPlayer=0; iPlayer<GetMaxPlayers(); iPlayer++) {
INDEX iPlayer;
for (iPlayer=0; iPlayer<GetMaxPlayers(); iPlayer++) {
// if this is ME (this) // if this is ME (this)
if (GetPlayerEntity(iPlayer)==penMe) { if (GetPlayerEntity(iPlayer)==penMe) {
return iPlayer; return iPlayer;
@ -111,7 +113,7 @@ functions:
{ {
CMovableModelEntity::DumpSync_t(strm, iExtensiveSyncCheck); CMovableModelEntity::DumpSync_t(strm, iExtensiveSyncCheck);
strm.FPrintF_t("player: %s\n", strm.FPrintF_t("player: %s\n",
en_pcCharacter.GetName()); (const char *) en_pcCharacter.GetName());
strm.FPrintF_t("GUID: "); strm.FPrintF_t("GUID: ");
{for (INDEX i=0; i<sizeof(en_pcCharacter.pc_aubGUID); i++) { {for (INDEX i=0; i<sizeof(en_pcCharacter.pc_aubGUID); i++) {
strm.FPrintF_t("%02X", en_pcCharacter.pc_aubGUID[i]); strm.FPrintF_t("%02X", en_pcCharacter.pc_aubGUID[i]);

View File

@ -13,12 +13,13 @@
#include <Engine/Base/CRC.h> #include <Engine/Base/CRC.h>
#include <Engine/Base/CRCTable.h> #include <Engine/Base/CRCTable.h>
#include <Engine/Base/ProgressHook.h> #include <Engine/Base/ProgressHook.h>
#include <Engine/Base/FileSystem.h>
#include <Engine/Sound/SoundListener.h> #include <Engine/Sound/SoundListener.h>
#include <Engine/Sound/SoundLibrary.h> #include <Engine/Sound/SoundLibrary.h>
#include <Engine/Graphics/GfxLibrary.h> #include <Engine/Graphics/GfxLibrary.h>
#include <Engine/Graphics/Font.h> #include <Engine/Graphics/Font.h>
#include <Engine/Network/Network.h> #include <Engine/Network/Network.h>
#include <Engine/templates/DynamicContainer.cpp> #include <Engine/Templates/DynamicContainer.cpp>
#include <Engine/Templates/Stock_CAnimData.h> #include <Engine/Templates/Stock_CAnimData.h>
#include <Engine/Templates/Stock_CTextureData.h> #include <Engine/Templates/Stock_CTextureData.h>
#include <Engine/Templates/Stock_CSoundData.h> #include <Engine/Templates/Stock_CSoundData.h>
@ -31,6 +32,10 @@
#include <Engine/Templates/StaticArray.cpp> #include <Engine/Templates/StaticArray.cpp>
#include <Engine/Base/IFeel.h> #include <Engine/Base/IFeel.h>
#if (defined PLATFORM_MACOSX)
#include <Carbon/Carbon.h>
#endif
// this version string can be referenced from outside the engine // this version string can be referenced from outside the engine
ENGINE_API CTString _strEngineBuild = ""; ENGINE_API CTString _strEngineBuild = "";
ENGINE_API ULONG _ulEngineBuildMajor = _SE_BUILD_MAJOR; ENGINE_API ULONG _ulEngineBuildMajor = _SE_BUILD_MAJOR;
@ -40,12 +45,13 @@ ENGINE_API BOOL _bDedicatedServer = FALSE;
ENGINE_API BOOL _bWorldEditorApp = FALSE; ENGINE_API BOOL _bWorldEditorApp = FALSE;
ENGINE_API CTString _strLogFile = ""; ENGINE_API CTString _strLogFile = "";
// global handle for application window // global handle for application windows
extern HWND _hwndMain = NULL; // !!! FIXME rcg10072001 this needs to be abstracted.
extern BOOL _bFullScreen = FALSE; static HWND _hwndMain = NULL;
static BOOL _bFullScreen = FALSE;
CTCriticalSection zip_csLock; // critical section for access to zlib functions
// critical section for access to zlib functions
CTCriticalSection zip_csLock;
// to keep system gamma table // to keep system gamma table
static UWORD auwSystemGamma[256*3]; static UWORD auwSystemGamma[256*3];
@ -83,8 +89,10 @@ static CTString sys_strModName = "";
static CTString sys_strModExt = ""; static CTString sys_strModExt = "";
// enables paranoia checks for allocation array // enables paranoia checks for allocation array
extern BOOL _bAllocationArrayParanoiaCheck = FALSE; BOOL _bAllocationArrayParanoiaCheck = FALSE;
// rcg10072001
#ifdef PLATFORM_WIN32
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{ {
switch (ul_reason_for_call) switch (ul_reason_for_call)
@ -103,14 +111,19 @@ BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReser
static void DetectCPU(void) static void DetectCPU(void)
{ {
#if (defined USE_PORTABLE_C) // rcg10072001
CPrintF(TRANS(" (No CPU detection in this binary.)\n"));
#else
char strVendor[12+1]; char strVendor[12+1];
strVendor[12] = 0; strVendor[12] = 0;
ULONG ulTFMS; ULONG ulTFMS;
ULONG ulFeatures; ULONG ulFeatures;
#if (defined __MSVC_INLINE__)
// test MMX presence and update flag // test MMX presence and update flag
__asm { __asm {
mov eax,0 ;// request for basic id xor eax,eax ;// request for basic id
cpuid cpuid
mov dword ptr [strVendor+0], ebx mov dword ptr [strVendor+0], ebx
mov dword ptr [strVendor+4], edx mov dword ptr [strVendor+4], edx
@ -121,6 +134,43 @@ static void DetectCPU(void)
mov dword ptr [ulFeatures], edx mov dword ptr [ulFeatures], edx
} }
#elif (defined __GNU_INLINE__)
// test MMX presence and update flag
__asm__ __volatile__ (
"pushl %%ebx \n\t"
"xorl %%eax,%%eax \n\t" // request for basic id
"cpuid \n\t"
"movl %%ebx, (%%esi) \n\t"
"movl %%edx, 4(%%esi) \n\t"
"movl %%ecx, 8(%%esi) \n\t"
"popl %%ebx \n\t"
: // no specific outputs.
: "S" (strVendor)
: "eax", "ecx", "edx", "memory"
);
// need to break this into a separate asm block, since I'm clobbering
// too many registers. There's something to be said for letting MSVC
// figure out where on the stack your locals are resting, but yeah,
// I know, that's x86-specific anyhow...
// !!! FIXME: can probably do this right with modern GCC.
__asm__ __volatile__ (
"pushl %%ebx \n\t"
"movl $1, %%eax \n\t" // request for TFMS feature flags
"cpuid \n\t"
"mov %%eax, (%%esi) \n\t" // remember type, family, model and stepping
"mov %%edx, (%%edi) \n\t"
"popl %%ebx \n\t"
: // no specific outputs.
: "S" (&ulTFMS), "D" (&ulFeatures)
: "eax", "ecx", "edx", "memory"
);
#else
#error Please implement for your platform or define USE_PORTABLE_C.
#endif
INDEX iType = (ulTFMS>>12)&0x3; INDEX iType = (ulTFMS>>12)&0x3;
INDEX iFamily = (ulTFMS>> 8)&0xF; INDEX iFamily = (ulTFMS>> 8)&0xF;
INDEX iModel = (ulTFMS>> 4)&0xF; INDEX iModel = (ulTFMS>> 4)&0xF;
@ -137,8 +187,8 @@ static void DetectCPU(void)
CTString strYes = TRANS("Yes"); CTString strYes = TRANS("Yes");
CTString strNo = TRANS("No"); CTString strNo = TRANS("No");
CPrintF(TRANS(" MMX : %s\n"), bMMX ?strYes:strNo); CPrintF(TRANS(" MMX : %s\n"), (const char *) (bMMX ?strYes:strNo));
CPrintF(TRANS(" CMOV: %s\n"), bCMOV?strYes:strNo); CPrintF(TRANS(" CMOV: %s\n"), (const char *) (bCMOV?strYes:strNo));
CPrintF(TRANS(" Clock: %.0fMHz\n"), _pTimer->tm_llCPUSpeedHZ/1E6); CPrintF(TRANS(" Clock: %.0fMHz\n"), _pTimer->tm_llCPUSpeedHZ/1E6);
sys_strCPUVendor = strVendor; sys_strCPUVendor = strVendor;
@ -151,15 +201,27 @@ static void DetectCPU(void)
sys_iCPUMHz = INDEX(_pTimer->tm_llCPUSpeedHZ/1E6); sys_iCPUMHz = INDEX(_pTimer->tm_llCPUSpeedHZ/1E6);
if( !bMMX) FatalError( TRANS("MMX support required but not present!")); if( !bMMX) FatalError( TRANS("MMX support required but not present!"));
#endif // defined USE_PORTABLE_C
} }
static void DetectCPUWrapper(void) static void DetectCPUWrapper(void)
{ {
#ifdef _MSC_VER // rcg10072001
__try { __try {
DetectCPU(); DetectCPU();
} __except(EXCEPTION_EXECUTE_HANDLER) { } __except(EXCEPTION_EXECUTE_HANDLER) {
CPrintF( TRANS("Cannot detect CPU: exception raised.\n")); CPrintF( TRANS("Cannot detect CPU: exception raised.\n"));
} }
#else
// We just have to punt and try this. The exception we're catching here
// is really a matter of whether the CPUID instruction is missing (on a
// pre Pentium system, which can't run this game anyhow) which will raise
// SIGILL on Unix platforms, or the CPU doesn't have MMX, in which case
// FatalError will end the process. USE_PORTABLE_C users will not have
// any exception at all. Have I rationalized this enough, yet? :) --ryan.
DetectCPU();
#endif
} }
// reverses string // reverses string
@ -181,41 +243,80 @@ static char strDirPath[MAX_PATH] = "";
static void AnalyzeApplicationPath(void) static void AnalyzeApplicationPath(void)
{ {
strcpy(strDirPath, "D:\\"); // rcg10072001 rewritten with abstraction layer.
strcpy(strExePath, "D:\\TestExe.xbe"); const char *_dirsep = CFileSystem::GetDirSeparator();
size_t seplen = strlen(_dirsep);
char *dirsep = new char[seplen + 1];
strcpy(dirsep, _dirsep);
StrRev(dirsep);
char strTmpPath[MAX_PATH] = ""; char strTmpPath[MAX_PATH] = "";
// get full path to the exe
GetModuleFileNameA( NULL, strExePath, sizeof(strExePath)-1); _pFileSystem->GetExecutablePath(strExePath, sizeof (strExePath)-1);
// copy that to the path
strncpy(strTmpPath, strExePath, sizeof(strTmpPath)-1); strncpy(strTmpPath, strExePath, sizeof(strTmpPath)-1);
strDirPath[sizeof(strTmpPath)-1] = 0; strDirPath[sizeof(strTmpPath)-1] = 0;
// remove name from application path // remove name from application path
StrRev(strTmpPath); StrRev(strTmpPath);
// find last backslash // find last backslash
char *pstr = strchr( strTmpPath, '\\'); char *pstr = strstr( strTmpPath, dirsep);
if( pstr==NULL) { if( pstr==NULL) {
// not found - path is just "\" // not found - path is just "\"
strcpy( strTmpPath, "\\"); strcpy( strTmpPath, dirsep);
pstr = strTmpPath; pstr = strTmpPath;
} }
// remove 'debug' from app path if needed // remove 'debug' from app path if needed
if( strnicmp( pstr, "\\gubed", 6)==0) pstr += 6; if( strnicmp( pstr, (CTString(dirsep)+"gubed"), 5+seplen)==0) pstr += (5 + seplen);
if( pstr[0] = '\\') pstr++; if( strncmp(pstr, dirsep, seplen) == 0) pstr += seplen;
char *pstrFin = strchr( pstr, '\\'); char *pstrFin = strstr( pstr, dirsep);
if( pstrFin==NULL) { if( pstrFin==NULL) {
strcpy( pstr, "\\"); strcpy( pstr, dirsep);
pstrFin = pstr; pstrFin = pstr;
} }
// copy that to the path // copy that to the path
StrRev(pstrFin); StrRev(pstrFin);
strncpy( strDirPath, pstrFin, sizeof(strDirPath)-1); strncpy( strDirPath, pstrFin, sizeof(strDirPath)-1);
strDirPath[sizeof(strDirPath)-1] = 0; strDirPath[sizeof(strDirPath)-1] = 0;
delete[] dirsep;
} }
// rcg03242003
static void SanityCheckTypes(void)
{
ASSERT(sizeof (SBYTE) == 1);
ASSERT(sizeof (UBYTE) == 1);
ASSERT(sizeof (UWORD) == 2);
ASSERT(sizeof (SWORD) == 2);
ASSERT(sizeof (ULONG) == 4);
ASSERT(sizeof (SLONG) == 4);
ASSERT(sizeof (INDEX) == 4);
ASSERT(sizeof (BOOL) == 4);
ULONG val = 0x02000001;
UBYTE num = *((UBYTE *) &val);
#if PLATFORM_BIGENDIAN
#if PLATFORM_LITTLEENDIAN
#error uh...what?
#endif
ASSERT(num == 0x02);
#endif
#if PLATFORM_LITTLEENDIAN
#if PLATFORM_BIGENDIAN
#error uh...what?
#endif
ASSERT(num == 0x01);
#endif
}
// startup engine // startup engine
ENGINE_API void SE_InitEngine(CTString strGameID) ENGINE_API void SE_InitEngine(const char *argv0, CTString strGameID)
{ {
SanityCheckTypes();
const char *gamename = "UnknownGame";
if (strGameID != "")
gamename = (const char *) strGameID;
_pFileSystem = CFileSystem::GetInstance(argv0, gamename); // rcg10082001
#pragma message(">> Remove this from SE_InitEngine : _bWorldEditorApp") #pragma message(">> Remove this from SE_InitEngine : _bWorldEditorApp")
if(strGameID=="SeriousEditor") { if(strGameID=="SeriousEditor") {
_bWorldEditorApp = TRUE; _bWorldEditorApp = TRUE;
@ -224,6 +325,12 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
AnalyzeApplicationPath(); AnalyzeApplicationPath();
_fnmApplicationPath = CTString(strDirPath); _fnmApplicationPath = CTString(strDirPath);
_fnmApplicationExe = CTString(strExePath); _fnmApplicationExe = CTString(strExePath);
// rcg01012002 calculate user dir.
char buf[MAX_PATH];
_pFileSystem->GetUserDirectory(buf, sizeof (buf));
_fnmUserDir = CTString(buf);
try { try {
_fnmApplicationExe.RemoveApplicationPath_t(); _fnmApplicationExe.RemoveApplicationPath_t();
} catch (char *strError) { } catch (char *strError) {
@ -234,8 +341,10 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
_pConsole = new CConsole; _pConsole = new CConsole;
if (_strLogFile=="") { if (_strLogFile=="") {
_strLogFile = CTFileName(CTString(strExePath)).FileName(); _strLogFile = CTFileName(CTString(strExePath)).FileName();
// chop off end of Unix executable filename... --ryan.
_strLogFile.ReplaceSubstr(CTString("-bin"), CTString(""));
} }
_pConsole->Initialize(_fnmApplicationPath+_strLogFile+".log", 90, 512); _pConsole->Initialize(_fnmUserDir+_strLogFile+".log", 90, 512);
_pAnimStock = new CStock_CAnimData; _pAnimStock = new CStock_CAnimData;
_pTextureStock = new CStock_CTextureData; _pTextureStock = new CStock_CTextureData;
@ -247,6 +356,11 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
_pAnimSetStock = new CStock_CAnimSet; _pAnimSetStock = new CStock_CAnimSet;
_pShaderStock = new CStock_CShader; _pShaderStock = new CStock_CShader;
// rcg11232001 I moved this here so I can register platform-specific cvars.
// init main shell
_pShell = new CShell;
_pShell->Initialize();
_pTimer = new CTimer; _pTimer = new CTimer;
_pGfx = new CGfxLibrary; _pGfx = new CGfxLibrary;
_pSound = new CSoundLibrary; _pSound = new CSoundLibrary;
@ -259,20 +373,23 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
// print basic engine info // print basic engine info
CPrintF(TRANS("--- Serious Engine Startup ---\n")); CPrintF(TRANS("--- Serious Engine Startup ---\n"));
CPrintF(" %s\n\n", _strEngineBuild); CPrintF(" %s\n\n", (const char *) _strEngineBuild);
// print info on the started application // print info on the started application
CPrintF(TRANS("Executable: %s\n"), strExePath); CPrintF(TRANS("Executable: %s\n"), strExePath);
CPrintF(TRANS("Assumed engine directory: %s\n"), _fnmApplicationPath); CPrintF(TRANS("Assumed engine directory: %s\n"), (const char *) _fnmApplicationPath);
CPrintF("\n"); CPrintF("\n");
// report os info // report os info
CPrintF(TRANS("Examining underlying OS...\n")); CPrintF(TRANS("Examining underlying OS...\n"));
OSVERSIONINFOA osv;
// !!! FIXME: Abstract this somehow.
#if (defined PLATFORM_WIN32)
OSVERSIONINFO osv;
memset(&osv, 0, sizeof(osv)); memset(&osv, 0, sizeof(osv));
osv.dwOSVersionInfoSize = sizeof(osv); osv.dwOSVersionInfoSize = sizeof(osv);
if (GetVersionExA(&osv)) { if (GetVersionEx(&osv)) {
switch (osv.dwPlatformId) { switch (osv.dwPlatformId) {
case VER_PLATFORM_WIN32s: sys_strOS = "Win32s"; break; case VER_PLATFORM_WIN32s: sys_strOS = "Win32s"; break;
case VER_PLATFORM_WIN32_WINDOWS: sys_strOS = "Win9x"; break; case VER_PLATFORM_WIN32_WINDOWS: sys_strOS = "Win9x"; break;
@ -292,11 +409,37 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
} else { } else {
CPrintF(TRANS("Error getting OS info: %s\n"), GetWindowsError(GetLastError()) ); CPrintF(TRANS("Error getting OS info: %s\n"), GetWindowsError(GetLastError()) );
} }
#elif (defined PLATFORM_MACOSX)
long osver = 0x0000;
OSErr err = Gestalt(gestaltSystemVersion, &osver);
if (err != noErr)
osver = 0x0000;
sys_iOSMajor = ((osver & 0x0F00) >> 8) + (((osver & 0xF000) >> 12) * 10);
sys_iOSMinor = ((osver & 0x00F0) >> 4);
sys_iOSBuild = ((osver & 0x000F) >> 0);
sys_strOS = "Mac OS X";
sys_strOSMisc = "Mac OS";
CPrintF(TRANS(" Type: %s\n"), (const char*)sys_strOS);
CPrintF(TRANS(" Version: %d.%d.%d\n"),
(int)sys_iOSMajor, (int)sys_iOSMinor, (int)sys_iOSBuild);
#elif (defined PLATFORM_UNIX) // !!! FIXME: rcg10082001 what to do with this?
sys_iOSMajor = 1;
sys_iOSMinor = 0;
sys_iOSBuild = 0;
sys_strOS = "Unix";
sys_strOSMisc = "Unix";
CPrintF(TRANS(" Type: %s\n"), (const char*)sys_strOS);
#else
#error Do something with this for your platform.
#endif
CPrintF("\n"); CPrintF("\n");
// init main shell // (rcg11232001 this is where _pShell was originally created.)
_pShell = new CShell;
_pShell->Initialize();
// report CPU // report CPU
CPrintF(TRANS("Detecting CPU...\n")); CPrintF(TRANS("Detecting CPU...\n"));
@ -307,6 +450,7 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
extern void ReportGlobalMemoryStatus(void); extern void ReportGlobalMemoryStatus(void);
ReportGlobalMemoryStatus(); ReportGlobalMemoryStatus();
#if (defined PLATFORM_WIN32) // !!! FIXME: Abstract this somehow.
MEMORYSTATUS ms; MEMORYSTATUS ms;
GlobalMemoryStatus(&ms); GlobalMemoryStatus(&ms);
@ -314,10 +458,21 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
sys_iRAMPhys = ms.dwTotalPhys /MB; sys_iRAMPhys = ms.dwTotalPhys /MB;
sys_iRAMSwap = ms.dwTotalPageFile/MB; sys_iRAMSwap = ms.dwTotalPageFile/MB;
#elif (defined PLATFORM_UNIX)
sys_iRAMPhys = 1; // !!! FIXME: This is bad. Bad. BAD.
sys_iRAMSwap = 1;
#else
#error Do something with this for your platform.
#endif
// initialize zip semaphore // initialize zip semaphore
zip_csLock.cs_iIndex = -1; // not checked for locking order zip_csLock.cs_iIndex = -1; // not checked for locking order
// rcg10082001 Honestly, all of this is meaningless in a multitasking OS.
// That includes Windows, too.
#if (defined PLATFORM_WIN32) // !!! FIXME: Abstract this somehow.
// get info on the first disk in system // get info on the first disk in system
DWORD dwSerial; DWORD dwSerial;
DWORD dwFreeClusters; DWORD dwFreeClusters;
@ -330,48 +485,57 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
GetVolumeInformationA(strDrive, NULL, 0, &dwSerial, NULL, NULL, NULL, 0); GetVolumeInformationA(strDrive, NULL, 0, &dwSerial, NULL, NULL, NULL, 0);
GetDiskFreeSpaceA(strDrive, &dwSectors, &dwBytes, &dwFreeClusters, &dwClusters); GetDiskFreeSpaceA(strDrive, &dwSectors, &dwBytes, &dwFreeClusters, &dwClusters);
sys_iHDDSize = __int64(dwSectors)*dwBytes*dwClusters/MB; sys_iHDDSize = ((__int64)dwSectors)*dwBytes*dwClusters/MB;
sys_iHDDFree = __int64(dwSectors)*dwBytes*dwFreeClusters/MB; sys_iHDDFree = ((__int64)dwSectors)*dwBytes*dwFreeClusters/MB;
sys_iHDDMisc = dwSerial; sys_iHDDMisc = dwSerial;
#elif (defined PLATFORM_UNIX) // !!! FIXME: Uhh...?
sys_iHDDSize = 1;
sys_iHDDFree = 1;
sys_iHDDMisc = 0xDEADBEEF;
#else
#error Do something with this for your platform.
#endif
// add console variables // add console variables
extern INDEX con_bNoWarnings; extern INDEX con_bNoWarnings;
extern INDEX wld_bFastObjectOptimization; extern INDEX wld_bFastObjectOptimization;
extern INDEX fil_bPreferZips; extern INDEX fil_bPreferZips;
extern FLOAT mth_fCSGEpsilon; extern FLOAT mth_fCSGEpsilon;
_pShell->DeclareSymbol("user INDEX con_bNoWarnings;", &con_bNoWarnings); _pShell->DeclareSymbol("user INDEX con_bNoWarnings;", (void *) &con_bNoWarnings);
_pShell->DeclareSymbol("user INDEX wld_bFastObjectOptimization;", &wld_bFastObjectOptimization); _pShell->DeclareSymbol("user INDEX wld_bFastObjectOptimization;", (void *) &wld_bFastObjectOptimization);
_pShell->DeclareSymbol("user FLOAT mth_fCSGEpsilon;", &mth_fCSGEpsilon); _pShell->DeclareSymbol("user FLOAT mth_fCSGEpsilon;", (void *) &mth_fCSGEpsilon);
_pShell->DeclareSymbol("persistent user INDEX fil_bPreferZips;", &fil_bPreferZips); _pShell->DeclareSymbol("persistent user INDEX fil_bPreferZips;", (void *) &fil_bPreferZips);
// OS info // OS info
_pShell->DeclareSymbol("user const CTString sys_strOS ;", &sys_strOS); _pShell->DeclareSymbol("user const CTString sys_strOS ;", (void *) &sys_strOS);
_pShell->DeclareSymbol("user const INDEX sys_iOSMajor ;", &sys_iOSMajor); _pShell->DeclareSymbol("user const INDEX sys_iOSMajor ;", (void *) &sys_iOSMajor);
_pShell->DeclareSymbol("user const INDEX sys_iOSMinor ;", &sys_iOSMinor); _pShell->DeclareSymbol("user const INDEX sys_iOSMinor ;", (void *) &sys_iOSMinor);
_pShell->DeclareSymbol("user const INDEX sys_iOSBuild ;", &sys_iOSBuild); _pShell->DeclareSymbol("user const INDEX sys_iOSBuild ;", (void *) &sys_iOSBuild);
_pShell->DeclareSymbol("user const CTString sys_strOSMisc;", &sys_strOSMisc); _pShell->DeclareSymbol("user const CTString sys_strOSMisc;", (void *) &sys_strOSMisc);
// CPU info // CPU info
_pShell->DeclareSymbol("user const CTString sys_strCPUVendor;", &sys_strCPUVendor); _pShell->DeclareSymbol("user const CTString sys_strCPUVendor;", (void *) &sys_strCPUVendor);
_pShell->DeclareSymbol("user const INDEX sys_iCPUType ;", &sys_iCPUType ); _pShell->DeclareSymbol("user const INDEX sys_iCPUType ;", (void *) &sys_iCPUType );
_pShell->DeclareSymbol("user const INDEX sys_iCPUFamily ;", &sys_iCPUFamily ); _pShell->DeclareSymbol("user const INDEX sys_iCPUFamily ;", (void *) &sys_iCPUFamily );
_pShell->DeclareSymbol("user const INDEX sys_iCPUModel ;", &sys_iCPUModel ); _pShell->DeclareSymbol("user const INDEX sys_iCPUModel ;", (void *) &sys_iCPUModel );
_pShell->DeclareSymbol("user const INDEX sys_iCPUStepping ;", &sys_iCPUStepping); _pShell->DeclareSymbol("user const INDEX sys_iCPUStepping ;", (void *) &sys_iCPUStepping);
_pShell->DeclareSymbol("user const INDEX sys_bCPUHasMMX ;", &sys_bCPUHasMMX ); _pShell->DeclareSymbol("user const INDEX sys_bCPUHasMMX ;", (void *) &sys_bCPUHasMMX );
_pShell->DeclareSymbol("user const INDEX sys_bCPUHasCMOV ;", &sys_bCPUHasCMOV ); _pShell->DeclareSymbol("user const INDEX sys_bCPUHasCMOV ;", (void *) &sys_bCPUHasCMOV );
_pShell->DeclareSymbol("user const INDEX sys_iCPUMHz ;", &sys_iCPUMHz ); _pShell->DeclareSymbol("user const INDEX sys_iCPUMHz ;", (void *) &sys_iCPUMHz );
_pShell->DeclareSymbol(" const INDEX sys_iCPUMisc ;", &sys_iCPUMisc ); _pShell->DeclareSymbol(" const INDEX sys_iCPUMisc ;", (void *) &sys_iCPUMisc );
// RAM info // RAM info
_pShell->DeclareSymbol("user const INDEX sys_iRAMPhys;", &sys_iRAMPhys); _pShell->DeclareSymbol("user const INDEX sys_iRAMPhys;", (void *) &sys_iRAMPhys);
_pShell->DeclareSymbol("user const INDEX sys_iRAMSwap;", &sys_iRAMSwap); _pShell->DeclareSymbol("user const INDEX sys_iRAMSwap;", (void *) &sys_iRAMSwap);
_pShell->DeclareSymbol("user const INDEX sys_iHDDSize;", &sys_iHDDSize); _pShell->DeclareSymbol("user const INDEX sys_iHDDSize;", (void *) &sys_iHDDSize);
_pShell->DeclareSymbol("user const INDEX sys_iHDDFree;", &sys_iHDDFree); _pShell->DeclareSymbol("user const INDEX sys_iHDDFree;", (void *) &sys_iHDDFree);
_pShell->DeclareSymbol(" const INDEX sys_iHDDMisc;", &sys_iHDDMisc); _pShell->DeclareSymbol(" const INDEX sys_iHDDMisc;", (void *) &sys_iHDDMisc);
// MOD info // MOD info
_pShell->DeclareSymbol("user const CTString sys_strModName;", &sys_strModName); _pShell->DeclareSymbol("user const CTString sys_strModName;", (void *) &sys_strModName);
_pShell->DeclareSymbol("user const CTString sys_strModExt;", &sys_strModExt); _pShell->DeclareSymbol("user const CTString sys_strModExt;", (void *) &sys_strModExt);
// Stock clearing // Stock clearing
extern void FreeUnusedStock(void); extern void FreeUnusedStock(void);
_pShell->DeclareSymbol("user void FreeUnusedStock(void);", &FreeUnusedStock); _pShell->DeclareSymbol("user void FreeUnusedStock(void);", (void *) &FreeUnusedStock);
// Timer tick quantum // Timer tick quantum
_pShell->DeclareSymbol("user const FLOAT fTickQuantum;", (FLOAT*)&_pTimer->TickQuantum); _pShell->DeclareSymbol("user const FLOAT fTickQuantum;", (FLOAT*)&_pTimer->TickQuantum);
@ -434,6 +598,8 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
_pfdDisplayFont = NULL; _pfdDisplayFont = NULL;
_pfdConsoleFont = NULL; _pfdConsoleFont = NULL;
// !!! FIXME: Move this into GfxLibrary...
#ifdef PLATFORM_WIN32
// readout system gamma table // readout system gamma table
HDC hdc = GetDC(NULL); HDC hdc = GetDC(NULL);
BOOL bOK = GetDeviceGammaRamp( hdc, &auwSystemGamma[0]); BOOL bOK = GetDeviceGammaRamp( hdc, &auwSystemGamma[0]);
@ -443,7 +609,13 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
CPrintF( TRANS("\nWARNING: Gamma, brightness and contrast are not adjustable!\n\n")); CPrintF( TRANS("\nWARNING: Gamma, brightness and contrast are not adjustable!\n\n"));
} // done } // done
ReleaseDC( NULL, hdc); ReleaseDC( NULL, hdc);
#else
// !!! FIXME : rcg01072002 This CAN be done with SDL, actually. Move this somewhere.
CPrintF( TRANS("\nWARNING: Gamma, brightness and contrast are not adjustable!\n\n"));
#endif
// !!! FIXME : rcg12072001 Move this somewhere else.
#ifdef PLATFORM_WIN32
// init IFeel // init IFeel
HWND hwnd = NULL;//GetDesktopWindow(); HWND hwnd = NULL;//GetDesktopWindow();
HINSTANCE hInstance = GetModuleHandle(NULL); HINSTANCE hInstance = GetModuleHandle(NULL);
@ -463,12 +635,15 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
} }
CPrintF("\n"); CPrintF("\n");
} }
#endif
} }
// shutdown entire engine // shutdown entire engine
ENGINE_API void SE_EndEngine(void) ENGINE_API void SE_EndEngine(void)
{ {
// !!! FIXME: Move this into GfxLibrary...
#ifdef PLATFORM_WIN32
// restore system gamma table (if needed) // restore system gamma table (if needed)
if( _pGfx->gl_ulFlags&GLF_ADJUSTABLEGAMMA) { if( _pGfx->gl_ulFlags&GLF_ADJUSTABLEGAMMA) {
HDC hdc = GetDC(NULL); HDC hdc = GetDC(NULL);
@ -476,6 +651,7 @@ ENGINE_API void SE_EndEngine(void)
//ASSERT(bOK); //ASSERT(bOK);
ReleaseDC( NULL, hdc); ReleaseDC( NULL, hdc);
} }
#endif
// free stocks // free stocks
delete _pEntityClassStock; _pEntityClassStock = NULL; delete _pEntityClassStock; _pEntityClassStock = NULL;
@ -499,6 +675,7 @@ ENGINE_API void SE_EndEngine(void)
delete _pTimer; _pTimer = NULL; delete _pTimer; _pTimer = NULL;
delete _pShell; _pShell = NULL; delete _pShell; _pShell = NULL;
delete _pConsole; _pConsole = NULL; delete _pConsole; _pConsole = NULL;
delete _pFileSystem; _pFileSystem = NULL;
extern void EndStreams(void); extern void EndStreams(void);
EndStreams(); EndStreams();
@ -562,6 +739,7 @@ ENGINE_API void SE_UpdateWindowHandle( HWND hwndMain)
static BOOL TouchBlock(UBYTE *pubMemoryBlock, INDEX ctBlockSize) static BOOL TouchBlock(UBYTE *pubMemoryBlock, INDEX ctBlockSize)
{ {
#if (defined __MSC_VER)
// cannot pretouch block that are smaller than 64KB :( // cannot pretouch block that are smaller than 64KB :(
ctBlockSize -= 16*0x1000; ctBlockSize -= 16*0x1000;
if( ctBlockSize<4) return FALSE; if( ctBlockSize<4) return FALSE;
@ -589,14 +767,25 @@ touchLoop:
__except(EXCEPTION_EXECUTE_HANDLER) { __except(EXCEPTION_EXECUTE_HANDLER) {
return FALSE; return FALSE;
} }
#else
// !!! FIXME: How necessary is this on a system with a good memory manager?
// !!! More importantly, will this help if the system is paging to disk
// !!! like mad anyhow? Leaving this as a no-op for most systems seems safe
// !!! to me. --ryan.
#endif
return TRUE; return TRUE;
} }
// pretouch all memory commited by process // pretouch all memory commited by process
extern BOOL _bNeedPretouch = FALSE; BOOL _bNeedPretouch = FALSE;
ENGINE_API extern void SE_PretouchIfNeeded(void) ENGINE_API extern void SE_PretouchIfNeeded(void)
{ {
#if (defined PLATFORM_WIN32)
// only if pretouching is needed? // only if pretouching is needed?
extern INDEX gam_bPretouch; extern INDEX gam_bPretouch;
if( !_bNeedPretouch || !gam_bPretouch) return; if( !_bNeedPretouch || !gam_bPretouch) return;
@ -668,6 +857,14 @@ nextRegion:
// some blocks failed? // some blocks failed?
if( ctFails>1) CPrintF( TRANS("(%d blocks were skipped)\n"), ctFails); if( ctFails>1) CPrintF( TRANS("(%d blocks were skipped)\n"), ctFails);
//_pShell->Execute("StockDump();"); //_pShell->Execute("StockDump();");
#else
// See dissertation in TouchBlock(). --ryan.
_bNeedPretouch = FALSE;
#endif
} }

View File

@ -1,7 +1,10 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
// set this to 1 to enable checks whether somethig is deleted while iterating some array/container #ifndef SE_INCL_ENGINE_H
#define CHECKARRAYLOCKING 0 #define SE_INCL_ENGINE_H
#ifdef PRAGMA_ONCE
#pragma once
#endif
#ifdef _WIN32 #ifdef _WIN32
#ifndef PLATFORM_WIN32 #ifndef PLATFORM_WIN32
@ -9,8 +12,10 @@
#endif #endif
#endif #endif
// set this to 1 to enable checks whether somethig is deleted while iterating some array/container
#define CHECKARRAYLOCKING 0
#include <stdlib.h> #include <stdlib.h>
#include <malloc.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -20,6 +25,10 @@
#include <search.h> // for qsort #include <search.h> // for qsort
#include <float.h> // for FPU control #include <float.h> // for FPU control
#if !PLATFORM_MACOSX
#include <malloc.h>
#endif
/* rcg10042001 !!! FIXME: Move these somewhere. */ /* rcg10042001 !!! FIXME: Move these somewhere. */
#if (defined PLATFORM_WIN32) #if (defined PLATFORM_WIN32)
#include <conio.h> #include <conio.h>
@ -53,6 +62,10 @@
#include <Engine/Base/Registry.h> #include <Engine/Base/Registry.h>
#include <Engine/Base/IFeel.h> #include <Engine/Base/IFeel.h>
#include <Engine/Base/DynamicLoader.h> // rcg10082001
#include <Engine/Base/FileSystem.h> // rcg10082001
#include <Engine/Base/ThreadLocalStorage.h> // rcg10242001
#include <Engine/Entities/EntityClass.h> #include <Engine/Entities/EntityClass.h>
#include <Engine/Entities/EntityCollision.h> #include <Engine/Entities/EntityCollision.h>
#include <Engine/Entities/EntityProperties.h> #include <Engine/Entities/EntityProperties.h>
@ -152,24 +165,31 @@
#include <Engine/Templates/Selection.h> #include <Engine/Templates/Selection.h>
#include <Engine/Templates/Selection.cpp> #include <Engine/Templates/Selection.cpp>
// some global stuff // some global stuff
ENGINE_API void SE_InitEngine( CTString strGameID);
// rcg10072001 (argv0) is, literally, argv[0] from your mainline. We need this
// on some platforms to determine where the program is running from in the
// filesystem.
ENGINE_API void SE_InitEngine(const char *argv0, CTString strGameID);
ENGINE_API void SE_EndEngine(void); ENGINE_API void SE_EndEngine(void);
ENGINE_API void SE_LoadDefaultFonts(void); ENGINE_API void SE_LoadDefaultFonts(void);
ENGINE_API void SE_UpdateWindowHandle( HWND hwndWindowed); ENGINE_API void SE_UpdateWindowHandle( HWND hwndWindowed);
ENGINE_API void SE_PretouchIfNeeded(void); ENGINE_API void SE_PretouchIfNeeded(void);
extern ENGINE_API CTString _strEngineBuild; // not valid before InitEngine()! ENGINE_API extern CTString _strEngineBuild; // not valid before InitEngine()!
extern ENGINE_API ULONG _ulEngineBuildMajor; ENGINE_API extern ULONG _ulEngineBuildMajor;
extern ENGINE_API ULONG _ulEngineBuildMinor; ENGINE_API extern ULONG _ulEngineBuildMinor;
extern ENGINE_API BOOL _bDedicatedServer; ENGINE_API extern BOOL _bDedicatedServer;
extern ENGINE_API BOOL _bWorldEditorApp; // is this world edtior app ENGINE_API extern BOOL _bWorldEditorApp; // is this world editor app
extern ENGINE_API CTString _strLogFile; ENGINE_API extern CTString _strLogFile;
// temporary vars for adjustments // temporary vars for adjustments
ENGINE_API extern FLOAT tmp_af[10]; ENGINE_API extern FLOAT tmp_af[10];
ENGINE_API extern INDEX tmp_ai[10]; ENGINE_API extern INDEX tmp_ai[10];
ENGINE_API extern INDEX tmp_i; ENGINE_API extern INDEX tmp_i;
ENGINE_API extern INDEX tmp_fAdd; ENGINE_API extern INDEX tmp_fAdd;
#endif /* include-once blocker. */

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include <Engine/StdH.h>
#include <Engine/Entities/Entity.h> #include <Engine/Entities/Entity.h>
#include <Engine/Entities/EntityClass.h> #include <Engine/Entities/EntityClass.h>
@ -875,7 +875,7 @@ void CEntity::Teleport(const CPlacement3D &plNew, BOOL bTelefrag /*=TRUE*/)
CEntity *ppenObstacleDummy; CEntity *ppenObstacleDummy;
if (pmme->CheckForCollisionNow(pmme->en_iCollisionBox, &ppenObstacleDummy)) { if (pmme->CheckForCollisionNow(pmme->en_iCollisionBox, &ppenObstacleDummy)) {
CPrintF("Entity '%s' was teleported inside a wall at (%g,%g,%g)!\n", CPrintF("Entity '%s' was teleported inside a wall at (%g,%g,%g)!\n",
GetName(), (const char *) GetName(),
en_plPlacement.pl_PositionVector(1), en_plPlacement.pl_PositionVector(1),
en_plPlacement.pl_PositionVector(2), en_plPlacement.pl_PositionVector(2),
en_plPlacement.pl_PositionVector(3)); en_plPlacement.pl_PositionVector(3));
@ -998,7 +998,7 @@ void CEntity::FallDownToFloor( void)
extern CEntity *_penLightUpdating; extern CEntity *_penLightUpdating;
extern BOOL _bDontDiscardLinks = FALSE; BOOL _bDontDiscardLinks = FALSE;
// internal repositioning function // internal repositioning function
void CEntity::SetPlacement_internal(const CPlacement3D &plNew, const FLOATmatrix3D &mRotation, void CEntity::SetPlacement_internal(const CPlacement3D &plNew, const FLOATmatrix3D &mRotation,
@ -1432,8 +1432,8 @@ void CEntity::FindShadingInfo(void)
INDEX iMipLevel = bsm.sm_iFirstMipLevel; INDEX iMipLevel = bsm.sm_iFirstMipLevel;
FLOAT fpixU = FLOAT(vmexShadow(1)+bsm.sm_mexOffsetX)*(1.0f/(1<<iMipLevel)); FLOAT fpixU = FLOAT(vmexShadow(1)+bsm.sm_mexOffsetX)*(1.0f/(1<<iMipLevel));
FLOAT fpixV = FLOAT(vmexShadow(2)+bsm.sm_mexOffsetY)*(1.0f/(1<<iMipLevel)); FLOAT fpixV = FLOAT(vmexShadow(2)+bsm.sm_mexOffsetY)*(1.0f/(1<<iMipLevel));
en_psiShadingInfo->si_pixShadowU = floor(fpixU); en_psiShadingInfo->si_pixShadowU = (PIX) floor(fpixU);
en_psiShadingInfo->si_pixShadowV = floor(fpixV); en_psiShadingInfo->si_pixShadowV = (PIX) floor(fpixV);
en_psiShadingInfo->si_fUDRatio = fpixU-en_psiShadingInfo->si_pixShadowU; en_psiShadingInfo->si_fUDRatio = fpixU-en_psiShadingInfo->si_pixShadowU;
en_psiShadingInfo->si_fLRRatio = fpixV-en_psiShadingInfo->si_pixShadowV; en_psiShadingInfo->si_fLRRatio = fpixV-en_psiShadingInfo->si_pixShadowV;
@ -1444,8 +1444,8 @@ void CEntity::FindShadingInfo(void)
en_psiShadingInfo->si_vNearPoint = _vNearPoint; en_psiShadingInfo->si_vNearPoint = _vNearPoint;
FLOAT2D vTc = CalculateShadingTexCoords(_ptrTerrainNear,_vNearPoint); FLOAT2D vTc = CalculateShadingTexCoords(_ptrTerrainNear,_vNearPoint);
en_psiShadingInfo->si_pixShadowU = floor(vTc(1)); en_psiShadingInfo->si_pixShadowU = (PIX) floor(vTc(1));
en_psiShadingInfo->si_pixShadowV = floor(vTc(2)); en_psiShadingInfo->si_pixShadowV = (PIX) floor(vTc(2));
en_psiShadingInfo->si_fLRRatio = vTc(1) - en_psiShadingInfo->si_pixShadowU; en_psiShadingInfo->si_fLRRatio = vTc(1) - en_psiShadingInfo->si_pixShadowU;
en_psiShadingInfo->si_fUDRatio = vTc(2) - en_psiShadingInfo->si_pixShadowV; en_psiShadingInfo->si_fUDRatio = vTc(2) - en_psiShadingInfo->si_pixShadowV;
@ -2356,7 +2356,7 @@ void CEntity::SetModel(const CTFileName &fnmModel)
// if failed // if failed
} catch(char *strErrorDefault) { } catch(char *strErrorDefault) {
FatalError(TRANS("Cannot load default model '%s':\n%s"), FatalError(TRANS("Cannot load default model '%s':\n%s"),
(CTString&)fnmDefault, strErrorDefault); (const char *) (CTString&)fnmDefault, strErrorDefault);
} }
} }
UpdateSpatialRange(); UpdateSpatialRange();
@ -2419,7 +2419,7 @@ BOOL CEntity::SetSkaModel(const CTString &fnmModel)
// if failed // if failed
} catch(char *strErrorDefault) { } catch(char *strErrorDefault) {
FatalError(TRANS("Cannot load default model '%s':\n%s"), FatalError(TRANS("Cannot load default model '%s':\n%s"),
(CTString&)fnmDefault, strErrorDefault); (const char *) (CTString&)fnmDefault, strErrorDefault);
} }
// set colision info for default model // set colision info for default model
SetSkaColisionInfo(); SetSkaColisionInfo();
@ -2476,7 +2476,7 @@ void CEntity::SetModelMainTexture(const CTFileName &fnmTexture)
// if failed // if failed
} catch(char *strErrorDefault) { } catch(char *strErrorDefault) {
FatalError(TRANS("Cannot load default texture '%s':\n%s"), FatalError(TRANS("Cannot load default texture '%s':\n%s"),
(CTString&)fnmDefault, strErrorDefault); (const char *) (CTString&)fnmDefault, strErrorDefault);
} }
} }
} }
@ -2943,7 +2943,7 @@ void CEntity::PlaySound(CSoundObject &so, const CTFileName &fnmSound, SLONG slPl
// if failed // if failed
} catch(char *strErrorDefault) { } catch(char *strErrorDefault) {
FatalError(TRANS("Cannot load default sound '%s':\n%s"), FatalError(TRANS("Cannot load default sound '%s':\n%s"),
(CTString&)fnmDefault, strErrorDefault); (const char *) (CTString&)fnmDefault, strErrorDefault);
} }
} }
} }
@ -3271,7 +3271,7 @@ void CEntity::Read_t( CTStream *istr) // throw char *
>>en_ulCollisionFlags >>en_ulCollisionFlags
>>en_ulSpawnFlags >>en_ulSpawnFlags
>>en_ulFlags; >>en_ulFlags;
(*istr).Read_t(&en_mRotation, sizeof(en_mRotation)); (*istr)>>en_mRotation;
} else if (istr->PeekID_t()==CChunkID("ENT3")) { // entity v3 } else if (istr->PeekID_t()==CChunkID("ENT3")) { // entity v3
istr->ExpectID_t("ENT3"); istr->ExpectID_t("ENT3");
(*istr)>>(ULONG &)en_RenderType (*istr)>>(ULONG &)en_RenderType
@ -3279,7 +3279,7 @@ void CEntity::Read_t( CTStream *istr) // throw char *
>>en_ulCollisionFlags >>en_ulCollisionFlags
>>en_ulSpawnFlags >>en_ulSpawnFlags
>>en_ulFlags; >>en_ulFlags;
(*istr).Read_t(&en_mRotation, sizeof(en_mRotation)); (*istr)>>en_mRotation;
} else if (istr->PeekID_t()==CChunkID("ENT2")) { // entity v2 } else if (istr->PeekID_t()==CChunkID("ENT2")) { // entity v2
istr->ExpectID_t("ENT2"); istr->ExpectID_t("ENT2");
(*istr)>>(ULONG &)en_RenderType (*istr)>>(ULONG &)en_RenderType
@ -3482,7 +3482,7 @@ void CEntity::DumpSync_t(CTStream &strm, INDEX iExtensiveSyncCheck) // throw ch
strm.FPrintF_t("*** DELETED ***\n"); strm.FPrintF_t("*** DELETED ***\n");
} }
strm.FPrintF_t("class: '%s'\n", GetClass()->ec_pdecDLLClass->dec_strName); strm.FPrintF_t("class: '%s'\n", GetClass()->ec_pdecDLLClass->dec_strName);
strm.FPrintF_t("name: '%s'\n", GetName()); strm.FPrintF_t("name: '%s'\n", (const char *) GetName());
if (iExtensiveSyncCheck>0) { if (iExtensiveSyncCheck>0) {
strm.FPrintF_t("en_ulFlags: 0x%08X\n", en_ulFlags&~ strm.FPrintF_t("en_ulFlags: 0x%08X\n", en_ulFlags&~
(ENF_SELECTED|ENF_INRENDERING|ENF_VALIDSHADINGINFO|ENF_FOUNDINGRIDSEARCH|ENF_WILLBEPREDICTED|ENF_PREDICTABLE)); (ENF_SELECTED|ENF_INRENDERING|ENF_VALIDSHADINGINFO|ENF_FOUNDINGRIDSEARCH|ENF_WILLBEPREDICTED|ENF_PREDICTABLE));
@ -3784,7 +3784,7 @@ void CRationalEntity::Write_t( CTStream *ostr) // throw char *
void CRationalEntity::SetTimerAt(TIME timeAbsolute) void CRationalEntity::SetTimerAt(TIME timeAbsolute)
{ {
// must never set think back in time, except for special 'never' time // must never set think back in time, except for special 'never' time
ASSERTMSG(timeAbsolute>_pTimer->CurrentTick() || ASSERTMSG(timeAbsolute>=_pTimer->CurrentTick() ||
timeAbsolute==THINKTIME_NEVER, "Do not SetThink() back in time!"); timeAbsolute==THINKTIME_NEVER, "Do not SetThink() back in time!");
// set the timer // set the timer
en_timeTimer = timeAbsolute; en_timeTimer = timeAbsolute;
@ -3881,7 +3881,7 @@ void CRationalEntity::Return(SLONG slThisState, const CEntityEvent &eeReturn)
// print stack to debug output // print stack to debug output
const char *CRationalEntity::PrintStackDebug(void) const char *CRationalEntity::PrintStackDebug(void)
{ {
_RPT2(_CRT_WARN, "-- stack of '%s'@%gs\n", GetName(), _pTimer->CurrentTick()); _RPT2(_CRT_WARN, "-- stack of '%s'@%gs\n", (const char *) GetName(), _pTimer->CurrentTick());
INDEX ctStates = en_stslStateStack.Count(); INDEX ctStates = en_stslStateStack.Count();
for(INDEX iState=ctStates-1; iState>=0; iState--) { for(INDEX iState=ctStates-1; iState>=0; iState--) {

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Base/Stream.h> #include <Engine/Base/Stream.h>
#include <Engine/Entities/EntityClass.h> #include <Engine/Entities/EntityClass.h>
@ -208,52 +208,6 @@ void CEntityClass::ReleaseComponents(void)
// overrides from CSerial ///////////////////////////////////////////////////// // overrides from CSerial /////////////////////////////////////////////////////
/*
* Load a Dynamic Link Library.
*/
HINSTANCE LoadDLL_t(const char *strFileName) // throw char *
{
HINSTANCE hiDLL = ::LoadLibraryA(strFileName);
// if the DLL can not be loaded
if (hiDLL==NULL) {
// get the error code
DWORD dwMessageId = GetLastError();
// format the windows error message
LPVOID lpMsgBuf;
DWORD dwSuccess = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwMessageId,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
CTString strWinError;
// if formatting succeeds
if (dwSuccess!=0) {
// copy the result
strWinError = ((char *)lpMsgBuf);
// free the windows message buffer
LocalFree( lpMsgBuf );
} else {
// set our message about the failure
CTString strError;
strError.PrintF(
TRANS("Cannot format error message!\n"
"Original error code: %d,\n"
"Formatting error code: %d.\n"),
dwMessageId, GetLastError());
strWinError = strError;
}
// report error
ThrowF_t(TRANS("Cannot load DLL file '%s':\n%s"), strFileName, strWinError);
}
return hiDLL;
}
/* /*
* Read from stream. * Read from stream.
*/ */
@ -265,31 +219,53 @@ void CEntityClass::Read_t( CTStream *istr) // throw char *
CTString strClassName; CTString strClassName;
strClassName.ReadFromText_t(*istr, "Class: "); strClassName.ReadFromText_t(*istr, "Class: ");
// create name of dll const char *dllName = NULL;
#ifndef NDEBUG
fnmDLL = _fnmApplicationExe.FileDir()+fnmDLL.FileName()+_strModExt+"D"+fnmDLL.FileExt(); // load the DLL
#ifdef STATICALLY_LINKED
ec_hiClassDLL = CDynamicLoader::GetInstance(NULL);
dllName = "(statically linked)";
#else #else
fnmDLL = _fnmApplicationExe.FileDir()+fnmDLL.FileName()+_strModExt+fnmDLL.FileExt(); // create name of dll
#ifndef NDEBUG
fnmDLL = fnmDLL.FileDir()+"Debug\\"+fnmDLL.FileName()+_strModExt+"D"+fnmDLL.FileExt();
#else
fnmDLL = fnmDLL.FileDir()+fnmDLL.FileName()+_strModExt+fnmDLL.FileExt();
#endif
fnmDLL = CDynamicLoader::ConvertLibNameToPlatform(fnmDLL);
CTFileName fnmExpanded;
ExpandFilePath(EFP_READ, fnmDLL, fnmExpanded);
dllName = fnmExpanded;
ec_hiClassDLL = CDynamicLoader::GetInstance(fnmExpanded);
#endif #endif
if (ec_hiClassDLL->GetError() != NULL)
{
CTString err(ec_hiClassDLL->GetError());
delete ec_hiClassDLL;
ec_hiClassDLL = NULL;
ThrowF_t(TRANS("Cannot load DLL file '%s':\n%s"),
(const char *) dllName, (const char *) err);
}
// load the DLL // load the DLL
CTFileName fnmExpanded; CTFileName fnmExpanded;
ExpandFilePath(EFP_READ, fnmDLL, fnmExpanded); ExpandFilePath(EFP_READ, fnmDLL, fnmExpanded);
ec_hiClassDLL = LoadDLL_t(fnmExpanded);
ec_fnmClassDLL = fnmDLL; ec_fnmClassDLL = fnmDLL;
// get the pointer to the DLL class structure // get the pointer to the DLL class structure
ec_pdecDLLClass = (CDLLEntityClass *) GetProcAddress(ec_hiClassDLL, strClassName+"_DLLClass"); ec_pdecDLLClass = (CDLLEntityClass *) ec_hiClassDLL->FindSymbol(strClassName+"_DLLClass");
// if class structure is not found // if class structure is not found
if (ec_pdecDLLClass == NULL) { if (ec_pdecDLLClass == NULL) {
// free the library // free the library
BOOL bSuccess = FreeLibrary(ec_hiClassDLL); delete ec_hiClassDLL;
ASSERT(bSuccess);
ec_hiClassDLL = NULL; ec_hiClassDLL = NULL;
ec_fnmClassDLL.Clear(); ec_fnmClassDLL.Clear();
// report error // report error
ThrowF_t(TRANS("Class '%s' not found in entity class package file '%s'"), strClassName, fnmDLL); ThrowF_t(TRANS("Class '%s' not found in entity class package file '%s'"), (const char *) strClassName, dllName);
} }
// obtain all components needed by the DLL // obtain all components needed by the DLL
@ -356,7 +332,7 @@ CEntity::pEventHandler CEntityClass::HandlerForStateAndEvent(SLONG slState, SLON
/* Get pointer to component from its identifier. */ /* Get pointer to component from its identifier. */
class CEntityComponent *CEntityClass::ComponentForTypeAndID( class CEntityComponent *CEntityClass::ComponentForTypeAndID(
EntityComponentType ectType, SLONG slID) { enum EntityComponentType ectType, SLONG slID) {
return ec_pdecDLLClass->ComponentForTypeAndID(ectType, slID); return ec_pdecDLLClass->ComponentForTypeAndID(ectType, slID);
} }
/* Get pointer to component from the component. */ /* Get pointer to component from the component. */

View File

@ -8,7 +8,8 @@
#include <Engine/Base/Serial.h> #include <Engine/Base/Serial.h>
#include <Engine/Entities/Entity.h> #include <Engine/Entities/Entity.h>
#include <Engine/Entities/EntityProperties.h> /* rcg10042001 */ #include <Engine/Entities/EntityProperties.h> // rcg10042001
#include <Engine/Base/DynamicLoader.h> // rcg10112001
/* /*
* General structure of an entity class. * General structure of an entity class.
@ -21,7 +22,7 @@ public:
void ReleaseComponents(void); void ReleaseComponents(void);
public: public:
CTFileName ec_fnmClassDLL; // filename of the DLL with the class CTFileName ec_fnmClassDLL; // filename of the DLL with the class
HINSTANCE ec_hiClassDLL; // handle to the DLL with the class CDynamicLoader *ec_hiClassDLL;
class CDLLEntityClass *ec_pdecDLLClass; // pointer to DLL class in the DLL class CDLLEntityClass *ec_pdecDLLClass; // pointer to DLL class in the DLL
/* Default constructor. */ /* Default constructor. */
@ -50,9 +51,10 @@ public:
/* Get event handler for given state and event code. */ /* Get event handler for given state and event code. */
CEntity::pEventHandler HandlerForStateAndEvent(SLONG slState, SLONG slEvent); CEntity::pEventHandler HandlerForStateAndEvent(SLONG slState, SLONG slEvent);
/* Get pointer to component from its type and identifier. */ /* Get pointer to component from its type and identifier. */
class CEntityComponent *ComponentForTypeAndID(enum EntityComponentType ectType, SLONG slID); class CEntityComponent *ComponentForTypeAndID(
enum EntityComponentType ectType, SLONG slID);
/* Get pointer to component from the component. */ /* Get pointer to component from the component. */
class CEntityComponent *ComponentForPointer(void *pv); inline class CEntityComponent *ComponentForPointer(void *pv);
// overrides from CSerial // overrides from CSerial
/* Read from stream. */ /* Read from stream. */

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include "Engine/StdH.h"
#include <Engine/Entities/Entity.h> #include <Engine/Entities/Entity.h>
#include <Engine/Entities/EntityCollision.h> #include <Engine/Entities/EntityCollision.h>

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include <Engine/StdH.h>
#include <Engine/Entities/Entity.h> #include <Engine/Entities/Entity.h>
#include <Engine/Entities/LastPositions.h> #include <Engine/Entities/LastPositions.h>
@ -36,7 +36,7 @@ public:
static CStaticArray<CPointerRemapping> _aprRemaps; static CStaticArray<CPointerRemapping> _aprRemaps;
static BOOL _bRemapPointersToNULLs = TRUE; static BOOL _bRemapPointersToNULLs = TRUE;
extern BOOL _bReinitEntitiesWhileCopying = TRUE; BOOL _bReinitEntitiesWhileCopying = TRUE;
static BOOL _bMirrorAndStretch = FALSE; static BOOL _bMirrorAndStretch = FALSE;
static FLOAT _fStretch = 1.0f; static FLOAT _fStretch = 1.0f;
static enum WorldMirrorType _wmtMirror = WMT_NONE; static enum WorldMirrorType _wmtMirror = WMT_NONE;

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "stdh.h" #include <Engine/StdH.h>
#include <Engine/Entities/EntityProperties.h> #include <Engine/Entities/EntityProperties.h>
#include <Engine/Entities/Precaching.h> #include <Engine/Entities/Precaching.h>
@ -183,21 +183,21 @@ void CEntity::ReadProperties_t(CTStream &istrm) // throw char *
case CEntityProperty::EPT_FLOATAABBOX3D: { case CEntityProperty::EPT_FLOATAABBOX3D: {
// skip FLOATAABBOX3D // skip FLOATAABBOX3D
FLOATaabbox3D boxDummy; FLOATaabbox3D boxDummy;
istrm.Read_t(&boxDummy, sizeof(FLOATaabbox3D)); istrm>>boxDummy;
} }
break; break;
// if it is FLOATMATRIX3D // if it is FLOATMATRIX3D
case CEntityProperty::EPT_FLOATMATRIX3D: { case CEntityProperty::EPT_FLOATMATRIX3D: {
// skip FLOATMATRIX3D // skip FLOATMATRIX3D
FLOATmatrix3D boxDummy; FLOATmatrix3D boxDummy;
istrm.Read_t(&boxDummy, sizeof(FLOATmatrix3D)); istrm>>boxDummy;
} }
break; break;
// if it is EPT_FLOATQUAT3D // if it is EPT_FLOATQUAT3D
case CEntityProperty::EPT_FLOATQUAT3D: { case CEntityProperty::EPT_FLOATQUAT3D: {
// skip EPT_FLOATQUAT3D // skip EPT_FLOATQUAT3D
FLOATquat3D qDummy; FLOATquat3D qDummy;
istrm.Read_t(&qDummy, sizeof(FLOATquat3D)); istrm>>qDummy;
} }
break; break;
// if it is FLOAT3D // if it is FLOAT3D
@ -218,7 +218,7 @@ void CEntity::ReadProperties_t(CTStream &istrm) // throw char *
case CEntityProperty::EPT_FLOATplane3D: { case CEntityProperty::EPT_FLOATplane3D: {
// skip FLOATplane3D // skip FLOATplane3D
FLOATplane3D plDummy; FLOATplane3D plDummy;
istrm.Read_t(&plDummy, sizeof(plDummy)); istrm>>plDummy;
} }
break; break;
// if it is MODELOBJECT // if it is MODELOBJECT
@ -331,32 +331,32 @@ void CEntity::ReadProperties_t(CTStream &istrm) // throw char *
// if it is FLOATAABBOX3D // if it is FLOATAABBOX3D
case CEntityProperty::EPT_FLOATAABBOX3D: case CEntityProperty::EPT_FLOATAABBOX3D:
// read FLOATAABBOX3D // read FLOATAABBOX3D
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATaabbox3D), sizeof(FLOATaabbox3D)); istrm>>(PROPERTY(pepProperty->ep_slOffset, FLOATaabbox3D));
break; break;
// if it is FLOATMATRIX3D // if it is FLOATMATRIX3D
case CEntityProperty::EPT_FLOATMATRIX3D: case CEntityProperty::EPT_FLOATMATRIX3D:
// read FLOATMATRIX3D // read FLOATMATRIX3D
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATmatrix3D), sizeof(FLOATmatrix3D)); istrm>>(PROPERTY(pepProperty->ep_slOffset, FLOATmatrix3D));
break; break;
// if it is FLOATQUAT3D // if it is FLOATQUAT3D
case CEntityProperty::EPT_FLOATQUAT3D: case CEntityProperty::EPT_FLOATQUAT3D:
// read FLOATQUAT3D // read FLOATQUAT3D
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATquat3D), sizeof(FLOATquat3D)); istrm>>(PROPERTY(pepProperty->ep_slOffset, FLOATquat3D));
break; break;
// if it is FLOAT3D // if it is FLOAT3D
case CEntityProperty::EPT_FLOAT3D: case CEntityProperty::EPT_FLOAT3D:
// read FLOAT3D // read FLOAT3D
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOAT3D), sizeof(FLOAT3D)); istrm>>(PROPERTY(pepProperty->ep_slOffset, FLOAT3D));
break; break;
// if it is ANGLE3D // if it is ANGLE3D
case CEntityProperty::EPT_ANGLE3D: case CEntityProperty::EPT_ANGLE3D:
// read ANGLE3D // read ANGLE3D
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, ANGLE3D), sizeof(ANGLE3D)); istrm>>(PROPERTY(pepProperty->ep_slOffset, ANGLE3D));
break; break;
// if it is FLOATplane3D // if it is FLOATplane3D
case CEntityProperty::EPT_FLOATplane3D: case CEntityProperty::EPT_FLOATplane3D:
// read FLOATplane3D // read FLOATplane3D
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATplane3D), sizeof(FLOATplane3D)); istrm>>(PROPERTY(pepProperty->ep_slOffset, FLOATplane3D));
break; break;
// if it is MODELOBJECT // if it is MODELOBJECT
case CEntityProperty::EPT_MODELOBJECT: case CEntityProperty::EPT_MODELOBJECT:
@ -385,7 +385,7 @@ void CEntity::ReadProperties_t(CTStream &istrm) // throw char *
// if it is CPlacement3D // if it is CPlacement3D
case CEntityProperty::EPT_PLACEMENT3D: case CEntityProperty::EPT_PLACEMENT3D:
// read CPlacement3D // read CPlacement3D
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, CPlacement3D), sizeof(CPlacement3D)); istrm>>(PROPERTY(pepProperty->ep_slOffset, CPlacement3D));
break; break;
default: default:
ASSERTALWAYS("Unknown property type"); ASSERTALWAYS("Unknown property type");
@ -475,32 +475,32 @@ void CEntity::WriteProperties_t(CTStream &ostrm) // throw char *
// if it is FLOATAABBOX3D // if it is FLOATAABBOX3D
case CEntityProperty::EPT_FLOATAABBOX3D: case CEntityProperty::EPT_FLOATAABBOX3D:
// write FLOATAABBOX3D // write FLOATAABBOX3D
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATaabbox3D), sizeof(FLOATaabbox3D)); ostrm<<PROPERTY(epProperty.ep_slOffset, FLOATaabbox3D);
break; break;
// if it is FLOATMATRIX3D // if it is FLOATMATRIX3D
case CEntityProperty::EPT_FLOATMATRIX3D: case CEntityProperty::EPT_FLOATMATRIX3D:
// write FLOATMATRIX3D // write FLOATMATRIX3D
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATmatrix3D), sizeof(FLOATmatrix3D)); ostrm<<PROPERTY(epProperty.ep_slOffset, FLOATmatrix3D);
break; break;
// if it is FLOATQUAT3D // if it is FLOATQUAT3D
case CEntityProperty::EPT_FLOATQUAT3D: case CEntityProperty::EPT_FLOATQUAT3D:
// write FLOATQUAT3D // write FLOATQUAT3D
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATquat3D), sizeof(FLOATquat3D)); ostrm<<PROPERTY(epProperty.ep_slOffset, FLOATquat3D);
break; break;
// if it is ANGLE3D // if it is ANGLE3D
case CEntityProperty::EPT_ANGLE3D: case CEntityProperty::EPT_ANGLE3D:
// write ANGLE3D // write ANGLE3D
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, ANGLE3D), sizeof(ANGLE3D)); ostrm<<PROPERTY(epProperty.ep_slOffset, ANGLE3D);
break; break;
// if it is FLOAT3D // if it is FLOAT3D
case CEntityProperty::EPT_FLOAT3D: case CEntityProperty::EPT_FLOAT3D:
// write FLOAT3D // write FLOAT3D
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOAT3D), sizeof(FLOAT3D)); ostrm<<PROPERTY(epProperty.ep_slOffset, FLOAT3D);
break; break;
// if it is FLOATplane3D // if it is FLOATplane3D
case CEntityProperty::EPT_FLOATplane3D: case CEntityProperty::EPT_FLOATplane3D:
// write FLOATplane3D // write FLOATplane3D
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATplane3D), sizeof(FLOATplane3D)); ostrm<<PROPERTY(epProperty.ep_slOffset, FLOATplane3D);
break; break;
// if it is ENTITYPTR // if it is ENTITYPTR
case CEntityProperty::EPT_ENTITYPTR: case CEntityProperty::EPT_ENTITYPTR:
@ -530,7 +530,7 @@ void CEntity::WriteProperties_t(CTStream &ostrm) // throw char *
// if it is CPlacement3D // if it is CPlacement3D
case CEntityProperty::EPT_PLACEMENT3D: case CEntityProperty::EPT_PLACEMENT3D:
// write CPlacement3D // write CPlacement3D
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, CPlacement3D), sizeof(CPlacement3D)); ostrm<<PROPERTY(epProperty.ep_slOffset, CPlacement3D);
break; break;
default: default:
ASSERTALWAYS("Unknown property type"); ASSERTALWAYS("Unknown property type");
@ -585,15 +585,15 @@ void CEntityComponent::Obtain_t(void) // throw char *
// if something else // if something else
default: default:
// error // error
ThrowF_t(TRANS("Component '%s'(%d) is of unknown type!"), (CTString&)ec_fnmComponent, ec_slID); ThrowF_t(TRANS("Component '%s'(%d) is of unknown type!"), (const char *) (CTString&)ec_fnmComponent, ec_slID);
} }
// if not already loaded and should not be precaching now // if not already loaded and should not be precaching now
if( ctUsed<=1 && !_precache_bNowPrecaching) { if( ctUsed<=1 && !_precache_bNowPrecaching) {
// report warning // report warning
CPrintF(TRANS("Not precached: (0x%08X)'%s'\n"), this->ec_slID, ec_fnmComponent); CPrintF(TRANS("Not precached: (0x%08X)'%s'\n"), this->ec_slID, (const char *) ec_fnmComponent);
} }
//CPrintF(TRANS("Precaching NOW: (0x%08X)'%s'\n"), this->ec_slID, ec_fnmComponent); //CPrintF(TRANS("Precaching NOW: (0x%08X)'%s'\n"), this->ec_slID, (const char *) ec_fnmComponent);
// add to CRC // add to CRC
AddToCRCTable(); AddToCRCTable();
@ -660,7 +660,7 @@ void CEntityComponent::Release(void)
// if something else // if something else
default: default:
// error // error
ThrowF_t(TRANS("Component '%s'(%d) is of unknown type!"), (CTString&)ec_fnmComponent, ec_slID); ThrowF_t(TRANS("Component '%s'(%d) is of unknown type!"), (const char *) (CTString&)ec_fnmComponent, ec_slID);
} }
// released // released

Some files were not shown because too many files have changed in this diff Show More