mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-12-25 07:14:50 +01:00
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:
parent
a7af6eb20b
commit
24cb244d43
|
@ -77,7 +77,7 @@ void SubMain( int argc, char *argv[])
|
|||
}
|
||||
|
||||
// initialize engine
|
||||
SE_InitEngine("");
|
||||
SE_InitEngine(argv[0], "");
|
||||
_fnmApplicationPath = CTString("");
|
||||
|
||||
|
||||
|
@ -103,7 +103,7 @@ void SubMain( int argc, char *argv[])
|
|||
strmSrc.GetLine_t(strLine);
|
||||
|
||||
// try to find address marker in it
|
||||
const char *strAdr = strstr(strLine, "$adr:");
|
||||
char *strAdr = strstr(strLine, "$adr:");
|
||||
// if there is no marker
|
||||
if (strAdr==NULL) {
|
||||
// just copy the line
|
||||
|
|
|
@ -1,58 +1,64 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#ifdef PLATFORM_UNIX /* rcg10072001 */
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include <GameMP/Game.h>
|
||||
#define DECL_DLL
|
||||
|
||||
#if 0 /* rcg10042001 Doesn't seem to exist. */
|
||||
#include <Entities/Global.h>
|
||||
#endif
|
||||
|
||||
// application state variables
|
||||
extern BOOL _bRunning = TRUE;
|
||||
BOOL _bRunning = TRUE;
|
||||
static BOOL _bForceRestart = FALSE;
|
||||
static BOOL _bForceNextMap = FALSE;
|
||||
|
||||
extern CTString _strSamVersion = "no version information";
|
||||
extern INDEX ded_iMaxFPS = 100;
|
||||
extern CTString ded_strConfig = "";
|
||||
extern CTString ded_strLevel = "";
|
||||
extern INDEX ded_bRestartWhenEmpty = TRUE;
|
||||
extern FLOAT ded_tmTimeout = -1;
|
||||
extern CGame *_pGame = NULL;
|
||||
extern CTString sam_strFirstLevel = "Levels\\KarnakDemo.wld";
|
||||
extern CTString sam_strIntroLevel = "Levels\\Intro.wld";
|
||||
extern CTString sam_strGameName = "serioussam";
|
||||
CTString _strSamVersion = "no version information";
|
||||
INDEX ded_iMaxFPS = 100;
|
||||
CTString ded_strConfig = "";
|
||||
CTString ded_strLevel = "";
|
||||
INDEX ded_bRestartWhenEmpty = TRUE;
|
||||
FLOAT ded_tmTimeout = -1;
|
||||
CGame *_pGame = NULL;
|
||||
CTString sam_strFirstLevel = "Levels\\KarnakDemo.wld";
|
||||
CTString sam_strIntroLevel = "Levels\\Intro.wld";
|
||||
CTString sam_strGameName = "serioussam";
|
||||
|
||||
CTimerValue _tvLastLevelEnd(-1i64);
|
||||
CTimerValue _tvLastLevelEnd((__int64) -1);
|
||||
|
||||
void InitializeGame(void)
|
||||
{
|
||||
try {
|
||||
#ifndef NDEBUG
|
||||
#define GAMEDLL _fnmApplicationExe.FileDir()+"Game"+_strModExt+"D.dll"
|
||||
#ifdef STATICALLY_LINKED
|
||||
#define fnmExpanded NULL
|
||||
CPrintF(TRANS("Loading game library '%s'...\n"), "(statically linked)");
|
||||
#else
|
||||
CTFileName fnmDLL;
|
||||
#ifndef NDEBUG
|
||||
fnmDLL = "Bin\\Debug\\Game"+_strModExt+"D.dll";
|
||||
#else
|
||||
#define GAMEDLL _fnmApplicationExe.FileDir()+"Game"+_strModExt+".dll"
|
||||
fnmDLL = "Bin\\Game"+_strModExt+".dll";
|
||||
#endif
|
||||
|
||||
fnmDLL = CDynamicLoader::ConvertLibNameToPlatform(fnmDLL);
|
||||
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);
|
||||
HMODULE hGame = LoadLibraryA(fnmExpanded);
|
||||
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();
|
||||
#endif
|
||||
|
||||
} catch (char *strError) {
|
||||
FatalError("%s", strError);
|
||||
CDynamicLoader *loader = CDynamicLoader::GetInstance(fnmExpanded);
|
||||
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)
|
||||
|
@ -84,12 +90,16 @@ void LimitFrameRate(void)
|
|||
// limit maximum frame rate
|
||||
ded_iMaxFPS = ClampDn( ded_iMaxFPS, 1L);
|
||||
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
|
||||
tvLast = _pTimer->GetHighPrecisionTimer();
|
||||
}
|
||||
|
||||
|
||||
/* rcg10072001 win32ism. */
|
||||
#ifdef PLATFORM_WIN32
|
||||
// break/close handler
|
||||
BOOL WINAPI HandlerRoutine(
|
||||
DWORD dwCtrlType // control signal type
|
||||
|
@ -104,13 +114,22 @@ BOOL WINAPI HandlerRoutine(
|
|||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_UNIX
|
||||
void unix_signal_catcher(int signum)
|
||||
{
|
||||
_bRunning = FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define REFRESHTIME (0.1f)
|
||||
|
||||
static void LoadingHook_t(CProgressHookInfo *pphi)
|
||||
{
|
||||
// measure time since last call
|
||||
static CTimerValue tvLast(0I64);
|
||||
static CTimerValue tvLast((__int64) 0);
|
||||
CTimerValue tvNow = _pTimer->GetHighPrecisionTimer();
|
||||
|
||||
if (!_bRunning) {
|
||||
|
@ -126,8 +145,13 @@ static void LoadingHook_t(CProgressHookInfo *pphi)
|
|||
|
||||
// print status text
|
||||
CTString strRes;
|
||||
#ifdef PLATFORM_WIN32
|
||||
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
|
||||
|
@ -158,14 +182,21 @@ BOOL StartGame(CTString &strLevel)
|
|||
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;
|
||||
strCmd.PrintF("include \"%s\"", str);
|
||||
strCmd.PrintF("include \"%s\"", (const char *) fnmScript);
|
||||
_pShell->Execute(strCmd);
|
||||
}
|
||||
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
#define DelayBeforeExit() fgetc(stdin);
|
||||
#else
|
||||
#define DelayBeforeExit()
|
||||
#endif
|
||||
|
||||
BOOL Init(int argc, char* argv[])
|
||||
{
|
||||
_bDedicatedServer = TRUE;
|
||||
|
@ -174,11 +205,14 @@ BOOL Init(int argc, char* argv[])
|
|||
// NOTE: this cannot be translated - translations are not loaded yet
|
||||
printf("Usage: DedicatedServer <configname> [<modname>]\n"
|
||||
"This starts a server reading configs from directory 'Scripts\\Dedicated\\<configname>\\'\n");
|
||||
getch();
|
||||
|
||||
DelayBeforeExit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
SetConsoleTitleA(argv[1]);
|
||||
#ifdef PLATFORM_WIN32
|
||||
SetConsoleTitle(argv[1]);
|
||||
#endif
|
||||
|
||||
ded_strConfig = CTString("Scripts\\Dedicated\\")+argv[1]+"\\";
|
||||
|
||||
|
@ -190,7 +224,7 @@ BOOL Init(int argc, char* argv[])
|
|||
_strLogFile = CTString("Dedicated_")+argv[1];
|
||||
|
||||
// initialize engine
|
||||
SE_InitEngine(sam_strGameName);
|
||||
SE_InitEngine(argv[0], sam_strGameName);
|
||||
|
||||
// ParseCommandLine(strCmdLine);
|
||||
|
||||
|
@ -211,32 +245,40 @@ BOOL Init(int argc, char* argv[])
|
|||
|
||||
FinishTranslationTable();
|
||||
} 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
|
||||
_pShell->Execute( "con_bNoWarnings=1;");
|
||||
|
||||
// declare shell symbols
|
||||
_pShell->DeclareSymbol("persistent user INDEX ded_iMaxFPS;", &ded_iMaxFPS);
|
||||
_pShell->DeclareSymbol("user void Quit(void);", &QuitGame);
|
||||
_pShell->DeclareSymbol("user CTString ded_strLevel;", &ded_strLevel);
|
||||
_pShell->DeclareSymbol("user FLOAT ded_tmTimeout;", &ded_tmTimeout);
|
||||
_pShell->DeclareSymbol("user INDEX ded_bRestartWhenEmpty;", &ded_bRestartWhenEmpty);
|
||||
_pShell->DeclareSymbol("user void Restart(void);", &RestartGame);
|
||||
_pShell->DeclareSymbol("user void NextMap(void);", &NextMap);
|
||||
_pShell->DeclareSymbol("persistent user CTString sam_strIntroLevel;", &sam_strIntroLevel);
|
||||
_pShell->DeclareSymbol("persistent user CTString sam_strGameName;", &sam_strGameName);
|
||||
_pShell->DeclareSymbol("user CTString sam_strFirstLevel;", &sam_strFirstLevel);
|
||||
_pShell->DeclareSymbol("persistent user INDEX ded_iMaxFPS;", (void *) &ded_iMaxFPS);
|
||||
_pShell->DeclareSymbol("user void Quit(void);", (void *) &QuitGame);
|
||||
_pShell->DeclareSymbol("user CTString ded_strLevel;", (void *) &ded_strLevel);
|
||||
_pShell->DeclareSymbol("user FLOAT ded_tmTimeout;", (void *) &ded_tmTimeout);
|
||||
_pShell->DeclareSymbol("user INDEX ded_bRestartWhenEmpty;", (void *) &ded_bRestartWhenEmpty);
|
||||
_pShell->DeclareSymbol("user void Restart(void);", (void *) &RestartGame);
|
||||
_pShell->DeclareSymbol("user void NextMap(void);", (void *) &NextMap);
|
||||
_pShell->DeclareSymbol("persistent user CTString sam_strIntroLevel;", (void *) &sam_strIntroLevel);
|
||||
_pShell->DeclareSymbol("persistent user CTString sam_strGameName;", (void *) &sam_strGameName);
|
||||
_pShell->DeclareSymbol("user CTString sam_strFirstLevel;", (void *) &sam_strFirstLevel);
|
||||
|
||||
// init game - this will load persistent symbols
|
||||
InitializeGame();
|
||||
_pNetwork->md_strGameID = sam_strGameName;
|
||||
|
||||
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 (_fnmMod!="") {
|
||||
|
@ -269,8 +311,8 @@ void RoundBegin(void)
|
|||
{
|
||||
// repeat generate script names
|
||||
FOREVER {
|
||||
strBegScript.PrintF("%s%d_begin.ini", ded_strConfig, iRound);
|
||||
strEndScript.PrintF("%s%d_end.ini", ded_strConfig, iRound);
|
||||
strBegScript.PrintF("%s%d_begin.ini", (const char *) ded_strConfig, iRound);
|
||||
strEndScript.PrintF("%s%d_end.ini", (const char *) ded_strConfig, iRound);
|
||||
// if start script exists
|
||||
if (FileExists(strBegScript)) {
|
||||
// stop searching
|
||||
|
@ -303,7 +345,7 @@ void RoundBegin(void)
|
|||
_bHadPlayers = 0;
|
||||
_bRestart = 0;
|
||||
DisableLoadingHook();
|
||||
_tvLastLevelEnd = CTimerValue(-1i64);
|
||||
_tvLastLevelEnd = CTimerValue((__int64) -1);
|
||||
CPrintF(TRANS("\nALL OK: Dedicated server is now running!\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"));
|
||||
|
@ -317,7 +359,7 @@ void ForceNextMap(void)
|
|||
_bHadPlayers = 0;
|
||||
_bRestart = 0;
|
||||
DisableLoadingHook();
|
||||
_tvLastLevelEnd = CTimerValue(-1i64);
|
||||
_tvLastLevelEnd = CTimerValue((__int64) -1);
|
||||
}
|
||||
|
||||
void RoundEnd(void)
|
||||
|
@ -331,6 +373,10 @@ void RoundEnd(void)
|
|||
// do the main game loop and render screen
|
||||
void DoGame(void)
|
||||
{
|
||||
#ifdef SINGLE_THREADED
|
||||
_pTimer->HandleTimerHandlers();
|
||||
#endif
|
||||
|
||||
// do the main game loop
|
||||
if( _pGame->gm_bGameOn) {
|
||||
_pGame->GameMainLoop();
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <Engine/Templates/Stock_CModelData.h>
|
||||
#include <GameMP/Game.h>
|
||||
|
||||
/* rcg10042001 protect against Visual C-isms. */
|
||||
// rcg10042001 protect against Visual C-isms.
|
||||
#ifdef _MSC_VER
|
||||
#define DECL_DLL _declspec(dllimport)
|
||||
#endif
|
||||
|
@ -18,6 +18,8 @@
|
|||
#include <EntitiesMP/Global.h>
|
||||
#include <EntitiesMP/Common/Common.h>
|
||||
#include <EntitiesMP/Common/GameInterface.h>
|
||||
#include <EntitiesMP/WorldLink.h> // rcg10072001 needed enum definition.
|
||||
#include <EntitiesMP/Player.h>
|
||||
|
||||
#undef DECL_DLL
|
||||
|
||||
|
|
|
@ -427,18 +427,21 @@ void CDependencyList::ExtractTranslations_t( const CTFileName &fnTranslations)
|
|||
// for each byte in file
|
||||
for(INDEX iByte=0; iByte<slSize-4; iByte++) {
|
||||
UBYTE *pub = pubFile+iByte;
|
||||
ULONG *pul = (ULONG*)pub;
|
||||
ULONG ul = *((ULONG*)pub);
|
||||
|
||||
BYTESWAP(ul);
|
||||
|
||||
// if exe translatable string is here
|
||||
if (*pul=='SRTE') {
|
||||
if (ul=='SRTE') {
|
||||
// get it
|
||||
CTString str = (char*)(pub+4);
|
||||
// add it
|
||||
AddStringForTranslation(str);
|
||||
// if data translatable string is here
|
||||
} else if (*pul=='SRTD') {
|
||||
} else if (ul=='SRTD') {
|
||||
char achr[ 256];
|
||||
INDEX iStrLen = *(INDEX *)(pub + 4);
|
||||
BYTESWAP(iStrLen);
|
||||
if( iStrLen > 254 || iStrLen<0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -449,7 +452,7 @@ void CDependencyList::ExtractTranslations_t( const CTFileName &fnTranslations)
|
|||
// add it
|
||||
AddStringForTranslation(str);
|
||||
// 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
|
||||
char *pchrStart = (char*)pub + 4 + 1;
|
||||
|
|
|
@ -45,7 +45,7 @@ void SubMain( int argc, char *argv[])
|
|||
}
|
||||
|
||||
// initialize engine
|
||||
SE_InitEngine("");
|
||||
SE_InitEngine(argv[0], "");
|
||||
// get application path from cmd line
|
||||
_fnmApplicationPath = CTString(ACHR_APP_DIR);
|
||||
// if not ending with backslash
|
||||
|
|
|
@ -3,6 +3,13 @@
|
|||
#include "Ecc/StdH.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 int _iCurrentClassID;
|
||||
static char *_strCurrentBase;
|
||||
|
@ -125,7 +132,7 @@ void CreateInternalHandlerFunction(char *strFunctionName, char *strID)
|
|||
void DeclareFeatureProperties(void)
|
||||
{
|
||||
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,
|
||||
"255",
|
||||
_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_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,
|
||||
_strCurrentPropertyEnumType,
|
||||
_iCurrentClassID,
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
|
||||
#if !PLATFORM_MACOSX
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_UNIX
|
||||
#include <errno.h>
|
||||
#include <sys/param.h>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include <Engine/StdH.h>
|
||||
|
||||
#include <Engine/Base/Anim.h>
|
||||
|
||||
|
@ -17,7 +17,8 @@
|
|||
/*
|
||||
* One animation of an animateable object
|
||||
*/
|
||||
class COneAnim {
|
||||
class COneAnim
|
||||
{
|
||||
public:
|
||||
COneAnim();
|
||||
~COneAnim();
|
||||
|
@ -61,20 +62,20 @@ CTmpListHead::~CTmpListHead()
|
|||
{
|
||||
FORDELETELIST(COneAnimNode, coan_Node, *this, it)
|
||||
delete &it.Current();
|
||||
};
|
||||
}
|
||||
|
||||
// Remember ptr to animation and add this node at the end of given animation list
|
||||
COneAnimNode::COneAnimNode(COneAnim *AnimToInsert, CListHead *LH)
|
||||
{
|
||||
coan_OneAnim = AnimToInsert;
|
||||
LH->AddTail( coan_Node);
|
||||
};
|
||||
}
|
||||
|
||||
// Constructor sets invalid data
|
||||
COneAnim::COneAnim()
|
||||
{
|
||||
oa_FrameIndices = NULL;
|
||||
};
|
||||
}
|
||||
|
||||
// Free allocated frame indices array for this animation
|
||||
COneAnim::~COneAnim()
|
||||
|
@ -82,7 +83,7 @@ COneAnim::~COneAnim()
|
|||
ASSERT(oa_FrameIndices != NULL);
|
||||
FreeMemory( oa_FrameIndices);
|
||||
oa_FrameIndices = NULL;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy constructor.
|
||||
|
@ -113,18 +114,18 @@ CFileNameNode::CFileNameNode(const char *NewFileName, CListHead *LH)
|
|||
ASSERT(strlen(NewFileName)>0);
|
||||
strcpy( cfnn_FileName, NewFileName);
|
||||
LH->AddTail( cfnn_Node);
|
||||
};
|
||||
}
|
||||
|
||||
CAnimData::CAnimData()
|
||||
{
|
||||
ad_Anims = NULL;
|
||||
ad_NumberOfAnims = 0;
|
||||
};
|
||||
}
|
||||
|
||||
CAnimData::~CAnimData()
|
||||
{
|
||||
Clear();
|
||||
};
|
||||
}
|
||||
|
||||
void CAnimData::Clear()
|
||||
{
|
||||
|
@ -135,7 +136,7 @@ void CAnimData::Clear()
|
|||
|
||||
// clear serial object
|
||||
CSerial::Clear();
|
||||
};
|
||||
}
|
||||
|
||||
// get amount of memory used by this object
|
||||
SLONG CAnimData::GetUsedMemory(void)
|
||||
|
@ -157,19 +158,24 @@ BOOL CAnimData::IsAutoFreed(void)
|
|||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Reference counting functions
|
||||
void CAnimData::AddReference(void) {
|
||||
void CAnimData::AddReference(void)
|
||||
{
|
||||
if (this!=NULL) {
|
||||
MarkUsed();
|
||||
}
|
||||
};
|
||||
void CAnimData::RemReference(void) {
|
||||
}
|
||||
|
||||
void CAnimData::RemReference(void)
|
||||
{
|
||||
if (this!=NULL) {
|
||||
RemReference_internal();
|
||||
}
|
||||
};
|
||||
void CAnimData::RemReference_internal(void) {
|
||||
}
|
||||
|
||||
void CAnimData::RemReference_internal(void)
|
||||
{
|
||||
_pAnimStock->Release(this);
|
||||
};
|
||||
}
|
||||
|
||||
// creates given number of default animations (1 frame, given name and speed)
|
||||
void CAnimData::CreateAnimations( INDEX ctAnimations, CTString strName/*="None"*/,
|
||||
|
@ -228,7 +234,7 @@ void CAnimData::DefaultAnimation()
|
|||
ad_Anims->oa_NumberOfFrames = 1;
|
||||
ad_Anims->oa_FrameIndices = (INDEX *) AllocMemory( sizeof(INDEX));
|
||||
ad_Anims->oa_FrameIndices[0] = 0;
|
||||
};
|
||||
}
|
||||
|
||||
// Returns index of given frame name in global frame names list. If it is not found
|
||||
// new CFileNameObject is added into frames list
|
||||
|
@ -243,7 +249,7 @@ INDEX FindFrameIndex( CListHead *pFrameFileList, const char *pFileName)
|
|||
}
|
||||
new CFileNameNode( pFileName, pFrameFileList);
|
||||
return( i);
|
||||
};
|
||||
}
|
||||
|
||||
CTString GetFrameFileName( CListHead *pFrameFileList, INDEX iMemberInList)
|
||||
{
|
||||
|
@ -306,8 +312,11 @@ void CAnimData::LoadFromScript_t( CTStream *File, CListHead *pFrameFileList) //
|
|||
// if it is not yet there
|
||||
else if( EQUAL_SUB_STR( "DIRECTORY"))
|
||||
{
|
||||
_strupr( ld_line);
|
||||
sscanf( ld_line, "DIRECTORY %s", base_path);
|
||||
// !!! FIXME : rcg10092001 You can't uppercase filenames!
|
||||
//_strupr( ld_line);
|
||||
sscanf( ld_line, "DIRECTORY %s", base_path);
|
||||
|
||||
// !!! FIXME : rcg10092001 Use CFileSystem::GetDirSeparator().
|
||||
if( base_path[ strlen( base_path) - 1] != '\\')
|
||||
strcat( base_path,"\\");
|
||||
}
|
||||
|
@ -430,7 +439,7 @@ void CAnimData::LoadFromScript_t( CTStream *File, CListHead *pFrameFileList) //
|
|||
FORDELETELIST( COneAnimNode, coan_Node, TempAnimationList, litDel)
|
||||
delete &litDel.Current();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
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,
|
||||
ad_Anims[i].oa_NumberOfFrames * sizeof( INDEX));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// print #define <animation name> lines for all animations into given file
|
||||
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++)
|
||||
{
|
||||
// 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);
|
||||
// put it into file
|
||||
ostrFile->PutLine_t( chrLine);
|
||||
|
@ -500,22 +509,37 @@ void CAnimData::AddAnimation(void)
|
|||
}
|
||||
|
||||
// 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);
|
||||
strcpy( ad_Anims[iAnimation].oa_Name, strNewName);};
|
||||
strcpy( ad_Anims[iAnimation].oa_Name, strNewName);
|
||||
}
|
||||
|
||||
// replaces requested animation's speed with given one
|
||||
void CAnimData::SetSpeed( INDEX iAnimation, TIME tmSpeed){
|
||||
ad_Anims[iAnimation].oa_SecsPerFrame = tmSpeed;};
|
||||
void CAnimData::SetSpeed( INDEX iAnimation, TIME tmSpeed)
|
||||
{
|
||||
ad_Anims[iAnimation].oa_SecsPerFrame = tmSpeed;
|
||||
}
|
||||
|
||||
// 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);
|
||||
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
|
||||
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);
|
||||
ad_Anims[iAnimation].oa_FrameIndices[iFramePlace] = iNewFrame;};
|
||||
ad_Anims[iAnimation].oa_FrameIndices[iFramePlace] = iNewFrame;
|
||||
}
|
||||
|
||||
/* Get number of animations. */
|
||||
INDEX CAnimData::GetAnimsCt(void) const {return ad_NumberOfAnims;};
|
||||
INDEX CAnimData::GetAnimsCt(void) const
|
||||
{
|
||||
return ad_NumberOfAnims;
|
||||
}
|
||||
|
||||
// Delete animation
|
||||
void CAnimData::DeleteAnimation(INDEX iAnim)
|
||||
|
@ -549,20 +573,20 @@ void CAnimData::Read_t( CTStream *istrFile) // throw char *
|
|||
// First we recognize main ID
|
||||
istrFile->ExpectID_t( CChunkID( "ADAT"));
|
||||
// Then we load and create number of animations
|
||||
istrFile->Read_t( &ad_NumberOfAnims, sizeof( INDEX));
|
||||
(*istrFile)>>ad_NumberOfAnims;
|
||||
ad_Anims = new COneAnim[ ad_NumberOfAnims];
|
||||
for( i=0; i<ad_NumberOfAnims; i++)
|
||||
{
|
||||
// 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_SecsPerFrame, sizeof( TIME));
|
||||
istrFile->Read_t( &ad_Anims[i].oa_NumberOfFrames, sizeof( INDEX));
|
||||
istrFile->Read_t(ad_Anims[i].oa_Name, sizeof (ad_Anims[i].oa_Name)); // char[32]
|
||||
(*istrFile)>>ad_Anims[i].oa_SecsPerFrame;
|
||||
(*istrFile)>>ad_Anims[i].oa_NumberOfFrames;
|
||||
ad_Anims[i].oa_FrameIndices = (INDEX *)
|
||||
AllocMemory( ad_Anims[i].oa_NumberOfFrames * sizeof( INDEX));
|
||||
istrFile->Read_t( ad_Anims[i].oa_FrameIndices,
|
||||
ad_Anims[i].oa_NumberOfFrames * sizeof( INDEX));
|
||||
for (SLONG j = 0; j < ad_Anims[i].oa_NumberOfFrames; j++)
|
||||
(*istrFile)>>ad_Anims[i].oa_FrameIndices[j];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Default constructor.
|
||||
|
@ -575,13 +599,13 @@ CAnimObject::CAnimObject(void)
|
|||
ao_iCurrentAnim = -1;
|
||||
ao_iLastAnim = -1;
|
||||
ao_ulFlags = AOF_PAUSED;
|
||||
};
|
||||
}
|
||||
|
||||
/* Destructor. */
|
||||
CAnimObject::~CAnimObject(void)
|
||||
{
|
||||
ao_AnimData->RemReference();
|
||||
};
|
||||
}
|
||||
|
||||
// copy from another object of same class
|
||||
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
|
||||
{
|
||||
|
@ -616,7 +640,7 @@ FLOAT CAnimObject::GetAnimLength(INDEX iAnim) const
|
|||
ASSERT( (iAnim >= 0) && (iAnim < ao_AnimData->ad_NumberOfAnims) );
|
||||
COneAnim *pCOA = &ao_AnimData->ad_Anims[iAnim];
|
||||
return pCOA->oa_NumberOfFrames*pCOA->oa_SecsPerFrame;
|
||||
};
|
||||
}
|
||||
|
||||
FLOAT CAnimObject::GetCurrentAnimLength(void) const
|
||||
{
|
||||
|
@ -659,7 +683,8 @@ void CAnimObject::PauseAnim(void)
|
|||
/*
|
||||
* Continues paused animation
|
||||
*/
|
||||
void CAnimObject::ContinueAnim(void){
|
||||
void CAnimObject::ContinueAnim(void)
|
||||
{
|
||||
if( !(ao_ulFlags&AOF_PAUSED)) return;
|
||||
// calculate freezed frame index inside current animation (not in global list of frames!)
|
||||
COneAnim *pCOA = &ao_AnimData->ad_Anims[ao_iCurrentAnim];
|
||||
|
@ -677,7 +702,8 @@ void CAnimObject::ContinueAnim(void){
|
|||
/*
|
||||
* Offsets the animation phase
|
||||
*/
|
||||
void CAnimObject::OffsetPhase(TIME tm){
|
||||
void CAnimObject::OffsetPhase(TIME tm)
|
||||
{
|
||||
ao_tmAnimStart += tm;
|
||||
}
|
||||
|
||||
|
@ -685,19 +711,21 @@ void CAnimObject::OffsetPhase(TIME tm){
|
|||
/*
|
||||
* Loop anims forward
|
||||
*/
|
||||
void CAnimObject::NextAnim(){
|
||||
void CAnimObject::NextAnim()
|
||||
{
|
||||
ASSERT( ao_iCurrentAnim != -1);
|
||||
ASSERT( ao_AnimData != NULL);
|
||||
ao_iCurrentAnim = (ao_iCurrentAnim + 1) % ao_AnimData->ad_NumberOfAnims;
|
||||
ao_iLastAnim = ao_iCurrentAnim;
|
||||
ao_tmAnimStart = _pTimer->CurrentTick();
|
||||
MarkChanged();
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop anims backward
|
||||
*/
|
||||
void CAnimObject::PrevAnim(){
|
||||
void CAnimObject::PrevAnim()
|
||||
{
|
||||
ASSERT( ao_iCurrentAnim != -1);
|
||||
ASSERT( ao_AnimData != NULL);
|
||||
ao_iCurrentAnim = (ao_AnimData->ad_NumberOfAnims + ao_iCurrentAnim - 1) %
|
||||
|
@ -705,7 +733,7 @@ void CAnimObject::PrevAnim(){
|
|||
ao_iLastAnim = ao_iCurrentAnim;
|
||||
ao_tmAnimStart = _pTimer->CurrentTick();
|
||||
MarkChanged();
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Selects frame for given time offset from animation start (0)
|
||||
|
@ -730,31 +758,34 @@ void CAnimObject::LastFrame(void)
|
|||
/*
|
||||
* Loop frames forward
|
||||
*/
|
||||
void CAnimObject::NextFrame(){
|
||||
void CAnimObject::NextFrame()
|
||||
{
|
||||
ASSERT( ao_iCurrentAnim != -1);
|
||||
ASSERT( ao_AnimData != NULL);
|
||||
ASSERT( ao_ulFlags&AOF_PAUSED);
|
||||
ao_tmAnimStart += ao_AnimData->ad_Anims[ ao_iCurrentAnim].oa_SecsPerFrame;
|
||||
MarkChanged();
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop frames backward
|
||||
*/
|
||||
void CAnimObject::PrevFrame(){
|
||||
void CAnimObject::PrevFrame()
|
||||
{
|
||||
ASSERT( ao_iCurrentAnim != -1);
|
||||
ASSERT( ao_AnimData != NULL);
|
||||
ASSERT( ao_ulFlags&AOF_PAUSED);
|
||||
ao_tmAnimStart -= ao_AnimData->ad_Anims[ ao_iCurrentAnim].oa_SecsPerFrame;
|
||||
MarkChanged();
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves paused flag
|
||||
*/
|
||||
BOOL CAnimObject::IsPaused(){
|
||||
BOOL CAnimObject::IsPaused()
|
||||
{
|
||||
return ao_ulFlags&AOF_PAUSED;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
void CAnimObject::SetData(CAnimData *pAD) {
|
||||
void CAnimObject::SetData(CAnimData *pAD)
|
||||
{
|
||||
// mark new data as referenced once more
|
||||
pAD->AddReference();
|
||||
// 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).
|
||||
*/
|
||||
void CAnimObject::SetAnim(INDEX iNew) {
|
||||
void CAnimObject::SetAnim(INDEX iNew)
|
||||
{
|
||||
if(ao_AnimData == NULL) return;
|
||||
// clamp animation
|
||||
if( iNew >= GetAnimsCt() )
|
||||
|
@ -826,18 +859,19 @@ void CAnimObject::SetAnim(INDEX iNew) {
|
|||
ao_iLastAnim=iNew;
|
||||
// mark that something has changed
|
||||
MarkChanged();
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Start new animation.
|
||||
*/
|
||||
void CAnimObject::StartAnim(INDEX iNew) {
|
||||
void CAnimObject::StartAnim(INDEX iNew)
|
||||
{
|
||||
if(ao_AnimData == NULL) return;
|
||||
// set new animation
|
||||
SetAnim( iNew);
|
||||
// set pause off, looping on
|
||||
ao_ulFlags = AOF_LOOPING;
|
||||
};
|
||||
}
|
||||
|
||||
/* Start playing an animation. */
|
||||
void CAnimObject::PlayAnim(INDEX iNew, ULONG ulFlags)
|
||||
|
@ -887,7 +921,7 @@ void CAnimObject::PlayAnim(INDEX iNew, ULONG ulFlags)
|
|||
|
||||
// mark that something has changed
|
||||
MarkChanged();
|
||||
};
|
||||
}
|
||||
|
||||
/* Seamlessly continue playing another animation from same point. */
|
||||
void CAnimObject::SwitchToAnim(INDEX iNew)
|
||||
|
@ -906,13 +940,14 @@ void CAnimObject::SwitchToAnim(INDEX iNew)
|
|||
/*
|
||||
* Reset anim (restart)
|
||||
*/
|
||||
void CAnimObject::ResetAnim() {
|
||||
void CAnimObject::ResetAnim()
|
||||
{
|
||||
if(ao_AnimData == NULL) return;
|
||||
// remember starting time
|
||||
ao_tmAnimStart = _pTimer->CurrentTick();
|
||||
// mark that something has changed
|
||||
MarkChanged();
|
||||
};
|
||||
}
|
||||
|
||||
// Get info about some animation
|
||||
void CAnimObject::GetAnimInfo(INDEX iAnimNo, CAnimInfo &aiInfo) const
|
||||
|
@ -989,14 +1024,13 @@ INDEX CAnimObject::GetAnimsCt(void) const
|
|||
if(ao_AnimData == NULL) return 1;
|
||||
ASSERT( ao_AnimData != NULL);
|
||||
return( ao_AnimData->ad_NumberOfAnims);
|
||||
};
|
||||
}
|
||||
|
||||
// get index of current animation
|
||||
INDEX CAnimObject::GetAnim(void) const
|
||||
{
|
||||
return( ao_iCurrentAnim);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the number of current frame.
|
||||
|
@ -1007,10 +1041,11 @@ INDEX CAnimObject::GetFrame(void) const
|
|||
}
|
||||
|
||||
/* Gets number of frames in current anim. */
|
||||
INDEX CAnimObject::GetFramesInCurrentAnim(void) const {
|
||||
INDEX CAnimObject::GetFramesInCurrentAnim(void) const
|
||||
{
|
||||
ASSERT( ao_AnimData != NULL);
|
||||
return ao_AnimData->ad_Anims[ao_iCurrentAnim].oa_NumberOfFrames;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 *
|
||||
{
|
||||
(*pstr).WriteID_t("ANOB");
|
||||
(*pstr).WriteRawChunk_t( &ao_tmAnimStart, sizeof( TIME));
|
||||
(*pstr).WriteRawChunk_t( &ao_iCurrentAnim, sizeof( INDEX));
|
||||
(*pstr).WriteRawChunk_t( &ao_iLastAnim, sizeof( INDEX));
|
||||
(*pstr).WriteRawChunk_t( &ao_ulFlags, sizeof( INDEX));
|
||||
};
|
||||
(*pstr)<<ao_tmAnimStart;
|
||||
(*pstr)<<ao_iCurrentAnim;
|
||||
(*pstr)<<ao_iLastAnim;
|
||||
(*pstr)<<ao_ulFlags;
|
||||
}
|
||||
|
||||
void CAnimObject::Read_t( CTStream *pstr) // throw char *
|
||||
{
|
||||
if ((*pstr).PeekID_t()==CChunkID("ANOB")) {
|
||||
(*pstr).ExpectID_t("ANOB");
|
||||
(*pstr).ReadRawChunk_t( &ao_tmAnimStart, sizeof( TIME));
|
||||
(*pstr).ReadRawChunk_t( &ao_iCurrentAnim, sizeof( INDEX));
|
||||
(*pstr).ReadRawChunk_t( &ao_iLastAnim, sizeof( INDEX));
|
||||
(*pstr).ReadRawChunk_t( &ao_ulFlags, sizeof( INDEX));
|
||||
(*pstr)>>ao_tmAnimStart;
|
||||
(*pstr)>>ao_iCurrentAnim;
|
||||
(*pstr)>>ao_iLastAnim;
|
||||
(*pstr)>>ao_ulFlags;
|
||||
} else {
|
||||
(*pstr).ReadRawChunk_t( &ao_tmAnimStart, sizeof( TIME));
|
||||
(*pstr).ReadRawChunk_t( &ao_iCurrentAnim, sizeof( INDEX));
|
||||
(*pstr)>>ao_tmAnimStart;
|
||||
(*pstr)>>ao_iCurrentAnim;
|
||||
ao_iLastAnim = ao_iCurrentAnim;
|
||||
ao_ulFlags = 0;
|
||||
}
|
||||
|
@ -1101,4 +1136,5 @@ void CAnimObject::Read_t( CTStream *pstr) // throw char *
|
|||
{
|
||||
ao_iLastAnim = 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,11 @@
|
|||
|
||||
#define NAME_SIZE 32
|
||||
typedef char NAME[NAME_SIZE];
|
||||
#define PATH_MAX 260
|
||||
|
||||
#if (!defined PATH_MAX)
|
||||
#define PATH_MAX 260
|
||||
#endif
|
||||
|
||||
typedef char FILE_NAME[PATH_MAX];
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* 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,
|
||||
// is in fact identical to the Adler32 used in ZIP's CRC calculation.
|
||||
|
|
|
@ -17,7 +17,7 @@ inline void CRC_AddBYTE( ULONG &ulCRC, UBYTE 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>> 0));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "StdH.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/CRCTable.h>
|
||||
#include <Engine/Base/FileName.h>
|
||||
|
@ -48,7 +48,7 @@ extern BOOL FileMatchesList(CDynamicStackArray<CTFileName> &afnm, const CTFileNa
|
|||
static CDynamicStackArray<CCRCEntry> _aceEntries;
|
||||
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
|
||||
void CRCT_Init(void)
|
||||
|
@ -169,13 +169,14 @@ ULONG CRCT_MakeCRCForFiles_t(CTStream &strmFiles) // throw char *
|
|||
// read the name
|
||||
CTString strName;
|
||||
strmFiles>>strName;
|
||||
CTFileName fname = strName;
|
||||
// try to find it in table
|
||||
CCRCEntry *pce = _ntEntries.Find(strName);
|
||||
CCRCEntry *pce = _ntEntries.Find(fname);
|
||||
// if not there
|
||||
if (pce==NULL) {
|
||||
CRCT_AddFile_t(strName);
|
||||
CRCT_AddFile_t(fname);
|
||||
// add it now
|
||||
pce = _ntEntries.Find(strName);
|
||||
pce = _ntEntries.Find(fname);
|
||||
}
|
||||
// add the crc
|
||||
CRC_AddLONG(ulCRC, pce->ce_ulCRC);
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/CTString.h>
|
||||
#include <Engine/Base/Memory.h>
|
||||
#include <Engine/Base/Stream.h>
|
||||
#include <Engine/Base/Console.h>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <stdio.h> // for vsscanf()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Equality comparison.
|
||||
|
@ -456,6 +459,7 @@ INDEX CTString::PrintF(const char *strFormat, ...)
|
|||
va_list arg;
|
||||
va_start(arg, strFormat);
|
||||
return VPrintF(strFormat, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -491,8 +495,8 @@ INDEX CTString::VPrintF(const char *strFormat, va_list arg)
|
|||
return iLen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// !!! FIXME: maybe don't do this, and just use the vsscanf() version. --ryan.
|
||||
#ifdef _MSC_VER
|
||||
static void *psscanf = &sscanf;
|
||||
// Scan formatted from a string
|
||||
__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)
|
||||
void CTString::Split( INDEX iPos, CTString &str1, CTString &str2)
|
||||
|
@ -541,10 +559,10 @@ void CTString::DeleteChar( INDEX iPos)
|
|||
if (ctChars==0) {
|
||||
return;
|
||||
}
|
||||
if( iPos>ctChars) iPos=ctChars;
|
||||
if( iPos>ctChars) iPos=ctChars - 1;
|
||||
else if( iPos<0) iPos=0;
|
||||
// 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
|
||||
ShrinkMemory( (void**)&str_String, ctChars);
|
||||
}
|
||||
|
@ -630,7 +648,7 @@ void CTString::LoadVar(const class CTFileName &fnmFile)
|
|||
str.Load_t(fnmFile);
|
||||
*this = str;
|
||||
} 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 {
|
||||
Save_t(fnmFile);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ ENGINE_API CTString::CTString(INDEX iDummy, const char *strFormat, ...)
|
|||
va_list arg;
|
||||
va_start(arg, strFormat);
|
||||
VPrintF(strFormat, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Changeable.h>
|
||||
#include <Engine/Base/ChangeableRT.h>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* 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_Internal.h>
|
||||
#include <Engine/Base/Console_internal.h>
|
||||
|
||||
#include <Engine/Base/Timer.h>
|
||||
#include <Engine/Base/ErrorReporting.h>
|
||||
|
@ -13,11 +13,11 @@
|
|||
|
||||
#include <Engine/Math/Functions.h>
|
||||
|
||||
extern CConsole *_pConsole = NULL;
|
||||
CConsole *_pConsole = NULL;
|
||||
|
||||
extern INDEX con_iLastLines;
|
||||
extern BOOL con_bCapture = FALSE;
|
||||
extern CTString con_strCapture = "";
|
||||
BOOL con_bCapture = FALSE;
|
||||
CTString con_strCapture = "";
|
||||
|
||||
|
||||
// Constructor.
|
||||
|
@ -262,7 +262,7 @@ void CConsole::CloseLog(void)
|
|||
}
|
||||
|
||||
// Print formated text to the main console.
|
||||
extern void CPrintF(const char *strFormat, ...)
|
||||
void CPrintF(const char *strFormat, ...)
|
||||
{
|
||||
if (_pConsole==NULL) {
|
||||
return;
|
||||
|
@ -272,6 +272,7 @@ extern void CPrintF(const char *strFormat, ...)
|
|||
va_start(arg, strFormat);
|
||||
CTString strBuffer;
|
||||
strBuffer.VPrintF(strFormat, arg);
|
||||
va_end(arg);
|
||||
|
||||
// print it to the main console
|
||||
_pConsole->PutString(strBuffer);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
#include <Engine/Base/Stream.h>
|
||||
#include <Engine/Base/FileName.h>
|
||||
#include <Engine/Base/Unzip.h>
|
||||
#include <Engine/Base/FileSystem.h>
|
||||
#include <Engine/Templates/DynamicStackArray.cpp>
|
||||
#include <io.h>
|
||||
|
||||
extern CDynamicStackArray<CTFileName> _afnmBaseBrowseInc;
|
||||
extern CDynamicStackArray<CTFileName> _afnmBaseBrowseExc;
|
||||
|
@ -49,32 +49,33 @@ void FillDirList_internal(const CTFileName &fnmBasePath,
|
|||
continue;
|
||||
}
|
||||
|
||||
const char *dirsep = CFileSystem::GetDirSeparator();
|
||||
|
||||
// start listing the directory
|
||||
struct _finddata_t c_file; long hFile;
|
||||
hFile = _findfirst( (const char *)(fnmBasePath+fnmDir+"*"), &c_file );
|
||||
|
||||
CDynamicArray<CTString> *files;
|
||||
files = _pFileSystem->FindFiles(fnmBasePath+fnmDir, "*");
|
||||
int max = files->Count();
|
||||
|
||||
// for each file in the directory
|
||||
for (
|
||||
BOOL bFileExists = hFile!=-1;
|
||||
bFileExists;
|
||||
bFileExists = _findnext( hFile, &c_file )==0) {
|
||||
for (int i = 0; i < max; i++) {
|
||||
const char *fname = (*files)[i];
|
||||
|
||||
// if dummy dir (this dir, parent dir, or any dir starting with '.')
|
||||
if (c_file.name[0]=='.') {
|
||||
if (_pFileSystem->IsDummyFile(fname)) {
|
||||
// skip it
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the file's filepath
|
||||
CTFileName fnm = fnmDir+c_file.name;
|
||||
CTFileName fnm = fnmDir + fname;
|
||||
|
||||
// if it is a directory
|
||||
if (c_file.attrib&_A_SUBDIR) {
|
||||
if (_pFileSystem->IsDirectory(fnm)) {
|
||||
// if recursive reading
|
||||
if (bRecursive) {
|
||||
// add it to the list of directories to search
|
||||
CDirToRead *pdrNew = new CDirToRead;
|
||||
pdrNew->dr_strDir = fnm+"\\";
|
||||
pdrNew->dr_strDir = fnm + dirsep;
|
||||
lhDirs.AddTail(pdrNew->dr_lnNode);
|
||||
}
|
||||
// if it matches the pattern
|
||||
|
@ -83,13 +84,15 @@ void FillDirList_internal(const CTFileName &fnmBasePath,
|
|||
afnm.Push() = fnm;
|
||||
}
|
||||
}
|
||||
|
||||
delete files;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// make a list of all files in a directory
|
||||
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();
|
||||
BOOL bRecursive = ulFlags&DLI_RECURSIVE;
|
||||
|
@ -99,17 +102,21 @@ ENGINE_API void MakeDirList(
|
|||
CDynamicStackArray<CTFileName> afnm;
|
||||
|
||||
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);
|
||||
if (bSearchCD) {
|
||||
FillDirList_internal(_fnmCDPath, afnm, fnmDir, strPattern, bRecursive,
|
||||
FillDirList_internal(_fnmCDPath, afnm, fnmDir, fnmPattern, bRecursive,
|
||||
&_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 {
|
||||
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) {
|
||||
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 (strPattern!="" && !fnm.Matches(strPattern)) {
|
||||
if (fnmPattern!="" && !fnm.Matches(fnmPattern)) {
|
||||
// skip it
|
||||
continue;
|
||||
}
|
||||
|
|
42
Sources/Engine/Base/DynamicLoader.h
Normal file
42
Sources/Engine/Base/DynamicLoader.h
Normal 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 ...
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/ErrorReporting.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)
|
||||
CDS_ResetMode();
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
// hide fullscreen window if any
|
||||
if( _bFullScreen) {
|
||||
// must do minimize first - don't know why :(
|
||||
ShowWindow( _hwndMain, SW_MINIMIZE);
|
||||
ShowWindow( _hwndMain, SW_HIDE);
|
||||
}
|
||||
#endif
|
||||
|
||||
// format the message in buffer
|
||||
va_list arg;
|
||||
va_start(arg, strFormat);
|
||||
CTString strBuffer;
|
||||
strBuffer.VPrintF(strFormat, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (_pConsole!=NULL) {
|
||||
// print the buffer to the console
|
||||
|
@ -55,14 +58,20 @@ void FatalError(const char *strFormat, ...)
|
|||
_pConsole->CloseLog();
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
// create message box with just OK button
|
||||
MessageBoxA(NULL, strBuffer, TRANS("Fatal Error"),
|
||||
MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
|
||||
|
||||
_bInFatalError = FALSE;
|
||||
|
||||
extern void EnableWindowsKeys(void);
|
||||
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(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -77,13 +86,18 @@ void WarningMessage(const char *strFormat, ...)
|
|||
va_start(arg, strFormat);
|
||||
CTString strBuffer;
|
||||
strBuffer.VPrintF(strFormat, arg);
|
||||
va_end(arg);
|
||||
|
||||
// print it to console
|
||||
CPrintF("%s\n", strBuffer);
|
||||
CPrintF("%s\n", (const char *) strBuffer);
|
||||
// if warnings are enabled
|
||||
if( !con_bNoWarnings) {
|
||||
// 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);
|
||||
CTString strBuffer;
|
||||
strBuffer.VPrintF(strFormat, arg);
|
||||
va_end(arg);
|
||||
|
||||
// print it to console
|
||||
CPrintF("%s\n", strBuffer);
|
||||
CPrintF("%s\n", (const char *) strBuffer);
|
||||
|
||||
// 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). */
|
||||
|
@ -109,11 +129,27 @@ BOOL YesNoMessage(const char *strFormat, ...)
|
|||
va_start(arg, strFormat);
|
||||
CTString strBuffer;
|
||||
strBuffer.VPrintF(strFormat, arg);
|
||||
va_end(arg);
|
||||
|
||||
// print it to console
|
||||
CPrintF("%s\n", strBuffer);
|
||||
CPrintF("%s\n", (const char *) strBuffer);
|
||||
|
||||
// create message box
|
||||
#ifdef PLATFORM_WIN32
|
||||
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 *
|
||||
{
|
||||
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
|
||||
va_list arg;
|
||||
va_start(arg, strFormat); // variable arguments start after this argument
|
||||
_vsnprintf(strBuffer, slBufferSize, strFormat, arg);
|
||||
va_end(arg);
|
||||
throw strBuffer;
|
||||
}
|
||||
|
||||
|
@ -161,7 +204,8 @@ void ThrowF_t(char *strFormat, ...) // throws char *
|
|||
*/
|
||||
extern const CTString GetWindowsError(DWORD dwWindowsErrorCode)
|
||||
{
|
||||
// buffer to receive error description
|
||||
#ifdef PLATFORM_WIN32
|
||||
// buffer to recieve error description
|
||||
LPVOID lpMsgBuf;
|
||||
// call function that will prepare text abount given windows error code
|
||||
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
|
@ -172,10 +216,23 @@ void ThrowF_t(char *strFormat, ...) // throws char *
|
|||
// Free the buffer.
|
||||
LocalFree( lpMsgBuf );
|
||||
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
|
||||
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;
|
||||
#elif (defined __GNU_INLINE__)
|
||||
__asm__ __volatile__ ("int $3\n\t");
|
||||
#else
|
||||
#error Please define something for your platform.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,105 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/FileName.h>
|
||||
|
||||
#include <Engine/Base/ErrorReporting.h>
|
||||
#include <Engine/Base/Stream.h>
|
||||
#include <Engine/Base/FileSystem.h>
|
||||
#include <Engine/Templates/NameTable_CTFileName.h>
|
||||
#include <Engine/Templates/DynamicStackArray.cpp>
|
||||
|
||||
template CDynamicArray<CTFileName>;
|
||||
template CDynamicStackArray<CTFileName>;
|
||||
template class CDynamicArray<CTFileName>;
|
||||
template class CDynamicStackArray<CTFileName>;
|
||||
#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.
|
||||
|
@ -24,14 +111,32 @@ CTFileName CTFileName::FileDir() const
|
|||
// make a temporary copy of string
|
||||
CTFileName strPath(*this);
|
||||
// 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( pPathBackSlash == NULL) {
|
||||
// return emptystring as directory
|
||||
return( CTFileName(""));
|
||||
}
|
||||
|
||||
for (char *p = pPathBackSlash;
|
||||
(p = strstr(p + 1, dirsep)) != NULL;
|
||||
pPathBackSlash = p)
|
||||
{
|
||||
// (*yawn*).
|
||||
}
|
||||
|
||||
// set end of string after where the backslash was
|
||||
pPathBackSlash[strlen(dirsep)] = 0;
|
||||
|
||||
#else
|
||||
|
||||
char *pPathBackSlash = strrchr( strPath.str_String, '\\');
|
||||
pPathBackSlash[1] = 0;
|
||||
#endif
|
||||
|
||||
// return a copy of temporary string
|
||||
return( CTFileName( strPath));
|
||||
}
|
||||
|
@ -51,23 +156,50 @@ CTFileName CTFileName::FileName() const
|
|||
|
||||
// make a temporary copy of string
|
||||
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
|
||||
char *pDot = strrchr( strPath.str_String, '.');
|
||||
char *pDot = strrchr(pBackSlash, '.');
|
||||
// if there is a dot
|
||||
if( pDot != NULL) {
|
||||
// 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, '\\');
|
||||
|
||||
// if there is no backslash
|
||||
if( pBackSlash == NULL) {
|
||||
// return it all as filename
|
||||
return( CTFileName(strPath));
|
||||
}
|
||||
|
||||
// return a copy of temporary string, starting after the backslash
|
||||
return( CTFileName( pBackSlash+1));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -93,88 +225,22 @@ CTFileName CTFileName::NoExt() const
|
|||
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
|
||||
BOOL bIsRelative = RemovePrefix(fnmApp);
|
||||
BOOL bHadRightPath = RemovePrefix(_fnmApplicationPath);
|
||||
if (_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!
|
||||
// skip dependency catcher header
|
||||
strmStream.ExpectID_t(strTag); // data filename
|
||||
|
||||
// read the string
|
||||
#ifdef PLATFORM_WIN32
|
||||
strmStream>>(CTString &)fnmFileName;
|
||||
#else
|
||||
CTString ctstr;
|
||||
strmStream>>ctstr;
|
||||
fnmFileName = CTString(CTFileName::convertFromWin32(ctstr)); // converts from win32 paths.
|
||||
#endif
|
||||
|
||||
fnmFileName.fnm_pserPreloaded = NULL;
|
||||
}
|
||||
|
||||
|
@ -228,12 +302,24 @@ BOOL CTFileName::RemoveApplicationPath_t(void) // throws char *
|
|||
// write dependency catcher header
|
||||
strmStream.WriteID_t(strTag); // data filename
|
||||
// write the string
|
||||
#ifdef PLATFORM_WIN32
|
||||
strmStream<<(CTString &)fnmFileName;
|
||||
#else
|
||||
strmStream<<CTString(CTFileName::convertToWin32(fnmFileName));
|
||||
#endif
|
||||
}
|
||||
|
||||
return strmStream;
|
||||
}
|
||||
|
||||
|
||||
// rcg01062002
|
||||
CTString CTFileName::Win32FmtString(void) const
|
||||
{
|
||||
return(CTString(convertToWin32(*this)));
|
||||
}
|
||||
|
||||
|
||||
void CTFileName::ReadFromText_t(CTStream &strmStream,
|
||||
const CTString &strKeyword) // throw char *
|
||||
{
|
||||
|
|
|
@ -13,25 +13,32 @@
|
|||
*/
|
||||
class ENGINE_API CTFileName : public CTString {
|
||||
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
|
||||
private:
|
||||
|
||||
/* 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:
|
||||
/* Default constructor. */
|
||||
inline CTFileName(void) : fnm_pserPreloaded(NULL) {};
|
||||
/* 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. */
|
||||
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. */
|
||||
CTFileName &operator=(const char *strCharString);
|
||||
inline void operator=(const CTString &strOther) {
|
||||
CTString::operator=(strOther);
|
||||
CTString::operator=(convertFromWin32(strOther));
|
||||
fnm_pserPreloaded = NULL;
|
||||
};
|
||||
|
||||
/* Get CTString with win32-style dir separators for string compares. */
|
||||
CTString Win32FmtString(void) const;
|
||||
|
||||
/* Get directory part of a filename. */
|
||||
CTFileName FileDir(void) const;
|
||||
/* Get name part of a filename. */
|
||||
|
@ -40,10 +47,8 @@ public:
|
|||
CTFileName FileExt(void) const;
|
||||
/* Get path and file name without extension. */
|
||||
CTFileName NoExt(void) const;
|
||||
/* Set path to the absolute path, taking \.. and /.. into account. */
|
||||
void SetAbsolutePath(void);
|
||||
/* 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)
|
||||
inline const CTFileName &GetName(void) { return *this; };
|
||||
|
|
74
Sources/Engine/Base/FileSystem.h
Normal file
74
Sources/Engine/Base/FileSystem.h
Normal 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 ...
|
||||
|
||||
|
|
@ -1,14 +1,20 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
#include <Engine/Base/IFeel.h>
|
||||
#include <Engine/Base/FileName.h>
|
||||
#include <Engine/Base/Stream.h>
|
||||
#include <Engine/Base/Console.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
|
||||
HINSTANCE _hLib = NULL;
|
||||
CDynamicLoader *_hLib = NULL;
|
||||
BOOL (*immCreateDevice)(HINSTANCE &hInstance, HWND &hWnd) = NULL;
|
||||
void (*immDeleteDevice)(void) = NULL;
|
||||
BOOL (*immProductName)(char *strProduct,int iMaxCount) = NULL;
|
||||
|
@ -86,16 +92,16 @@ CTString IFeel_GetProjectFileName()
|
|||
if(strProduct == strDeviceName) return strProjectFile;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
// inits imm ifeel device
|
||||
BOOL IFeel_InitDevice(HINSTANCE &hInstance, HWND &hWnd)
|
||||
{
|
||||
_pShell->DeclareSymbol("void inp_IFeelGainChange(INDEX);", &ifeel_GainChange);
|
||||
_pShell->DeclareSymbol("persistent user FLOAT inp_fIFeelGain post:inp_IFeelGainChange;", &ifeel_fGain);
|
||||
_pShell->DeclareSymbol("const user INDEX sys_bIFeelEnabled;", &ifeel_bEnabled);
|
||||
_pShell->DeclareSymbol("void inp_IFeelGainChange(INDEX);", (void *) &ifeel_GainChange);
|
||||
_pShell->DeclareSymbol("persistent user FLOAT inp_fIFeelGain post:inp_IFeelGainChange;", (void *) &ifeel_fGain);
|
||||
_pShell->DeclareSymbol("const user INDEX sys_bIFeelEnabled;", (void *) &ifeel_bEnabled);
|
||||
IFeel_ChangeGain(ifeel_fGain);
|
||||
|
||||
// load iFeel lib
|
||||
|
@ -103,24 +109,34 @@ BOOL IFeel_InitDevice(HINSTANCE &hInstance, HWND &hWnd)
|
|||
ExpandFilePath(EFP_READ | EFP_NOZIPS,(CTString)IFEEL_DLL_NAME,fnmExpanded);
|
||||
if(_hLib!=NULL) return FALSE;
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
UINT iOldErrorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
|
||||
_hLib = LoadLibraryA(fnmExpanded);
|
||||
#endif
|
||||
|
||||
_hLib = CDynamicLoader::GetInstance(fnmExpanded);
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
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;
|
||||
}
|
||||
|
||||
// take func pointers
|
||||
immCreateDevice = (BOOL(*)(HINSTANCE &hInstance, HWND &hWnd)) GetProcAddress(_hLib,"Imm_CreateDevice");
|
||||
immDeleteDevice = (void(*)(void)) GetProcAddress(_hLib,"Imm_DeleteDevice");
|
||||
immProductName = (BOOL(*)(char *strProduct,int iMaxCount)) GetProcAddress(_hLib,"Imm_GetProductName");
|
||||
immLoadFile = (BOOL(*)(const char *fnFile))GetProcAddress(_hLib,"Imm_LoadFile");
|
||||
immUnloadFile = (void(*)(void))GetProcAddress(_hLib,"immUnloadFile");
|
||||
immPlayEffect = (void(*)(const char *pstrEffectName))GetProcAddress(_hLib,"Imm_PlayEffect");
|
||||
immStopEffect = (void(*)(const char *pstrEffectName))GetProcAddress(_hLib,"Imm_StopEffect");
|
||||
immChangeGain = (void(*)(const float fGain))GetProcAddress(_hLib,"Imm_ChangeGain");
|
||||
immCreateDevice = (BOOL(*)(HINSTANCE &hInstance, HWND &hWnd)) _hLib->FindSymbol("Imm_CreateDevice");
|
||||
immDeleteDevice = (void(*)(void)) _hLib->FindSymbol("Imm_DeleteDevice");
|
||||
immProductName = (BOOL(*)(char *strProduct,int iMaxCount)) _hLib->FindSymbol("Imm_GetProductName");
|
||||
immLoadFile = (BOOL(*)(const char *fnFile))_hLib->FindSymbol("Imm_LoadFile");
|
||||
immUnloadFile = (void(*)(void))_hLib->FindSymbol("immUnloadFile");
|
||||
immPlayEffect = (void(*)(const char *pstrEffectName))_hLib->FindSymbol("Imm_PlayEffect");
|
||||
immStopEffect = (void(*)(const char *pstrEffectName))_hLib->FindSymbol("Imm_StopEffect");
|
||||
immChangeGain = (void(*)(const float fGain))_hLib->FindSymbol("Imm_ChangeGain");
|
||||
|
||||
// create device
|
||||
if(immCreateDevice == NULL)
|
||||
|
@ -151,7 +167,7 @@ void IFeel_DeleteDevice()
|
|||
immStopEffect = NULL;
|
||||
immChangeGain = NULL;
|
||||
|
||||
if(_hLib != NULL) FreeLibrary(_hLib);
|
||||
if(_hLib != NULL) delete _hLib;
|
||||
_hLib = NULL;
|
||||
}
|
||||
// loads project file
|
||||
|
@ -165,12 +181,12 @@ BOOL IFeel_LoadFile(CTFileName fnFile)
|
|||
BOOL hr = immLoadFile((const char*)fnmExpanded);
|
||||
if(hr)
|
||||
{
|
||||
CPrintF("IFeel project file '%s' loaded\n", fnFile);
|
||||
CPrintF("IFeel project file '%s' loaded\n", (const char *) fnFile);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
CPrintF("Error loading IFeel project file '%s'\n", fnFile);
|
||||
CPrintF("Error loading IFeel project file '%s'\n", (const char *) fnFile);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -117,6 +117,14 @@ public:
|
|||
// Get given button's current state
|
||||
inline BOOL GetButtonState( INDEX iButtonNo) const {
|
||||
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
|
||||
|
|
|
@ -146,79 +146,6 @@
|
|||
#define KID_2MOUSE2 0xD1
|
||||
#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. */
|
||||
|
||||
|
|
|
@ -81,17 +81,17 @@ public:
|
|||
|
||||
// get the pointer to the first element in the list
|
||||
#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
|
||||
#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
|
||||
#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
|
||||
#define LIST_SUCC(element, baseclass, member) \
|
||||
( (baseclass *) ( ((UBYTE *)(&(element).member.Succ())) - offsetof(baseclass, member) ) )
|
||||
( (baseclass *) ( ((UBYTE *)(&(element).member.Succ())) - _offsetof(baseclass, member) ) )
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Lists.h>
|
||||
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Memory.h>
|
||||
#include <Engine/Base/Translation.h>
|
||||
|
||||
#include <Engine/Base/ErrorReporting.h>
|
||||
|
||||
/* rcg10282005 "new.h" is deprecated in newer C++ standards... --ryan. */
|
||||
#ifdef _MSC_VER
|
||||
#include <new.h>
|
||||
#else
|
||||
#include <new>
|
||||
#endif
|
||||
|
||||
extern FLOAT _bCheckAllAllocations = FALSE;
|
||||
FLOAT _bCheckAllAllocations = FALSE;
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
/*
|
||||
* 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)
|
||||
#pragma comment (lib, "user32.lib")
|
||||
#endif
|
||||
|
||||
|
||||
// if not enough memory
|
||||
#ifdef _MSC_VER
|
||||
int NewHandler(size_t size)
|
||||
{
|
||||
// terminate program
|
||||
FatalError(TRANS("Not enough memory (%d bytes needed)!"), size);
|
||||
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 CMemHandlerInit {
|
||||
|
@ -52,7 +70,9 @@ CMemHandlerInit::CMemHandlerInit(void)
|
|||
// set our not-enough-memory handler
|
||||
_set_new_handler(NewHandler);
|
||||
// make malloc use that handler
|
||||
#ifdef _MSC_VER
|
||||
_set_new_mode(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef AllocMemory
|
||||
|
@ -73,6 +93,7 @@ void *AllocMemory( SLONG memsize )
|
|||
return pmem;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef NDEBUG
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void *AllocMemoryAligned( SLONG memsize, SLONG slAlignPow2)
|
||||
{
|
||||
|
|
21
Sources/Engine/Base/NullSynchronization.cpp
Normal file
21
Sources/Engine/Base/NullSynchronization.cpp
Normal 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 ...
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
%{
|
||||
#include "StdH.h"
|
||||
#include <Engine/StdH.h>
|
||||
|
||||
#include <Engine/Base/Console.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
|
||||
// if error occurs in parsing
|
||||
void yyerror(char *str)
|
||||
|
@ -95,7 +100,7 @@ void Declaration(
|
|||
if (!ShellTypeIsSame(ssNew.ss_istType, istType) ||
|
||||
((ssNew.ss_ulFlags&SSF_CONSTANT)!=(ulQualifiers&SSF_CONSTANT))) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -112,7 +117,7 @@ void Declaration(
|
|||
NOTHING; // function values are not retained
|
||||
} else {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
@ -331,7 +336,7 @@ pre_func_opt
|
|||
||_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[_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 {
|
||||
void *pv = $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[$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) {
|
||||
_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 {
|
||||
$$ = (void(*)(INDEX))$3->ss_pvValue;
|
||||
}
|
||||
|
@ -430,7 +435,7 @@ statement
|
|||
| lvalue '=' expression ';' {
|
||||
// if it is 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
|
||||
} else {
|
||||
// if it can be changed
|
||||
|
@ -473,7 +478,7 @@ statement
|
|||
// if it is constant
|
||||
if (ssSymbol.ss_ulFlags&SSF_CONSTANT) {
|
||||
// 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
|
||||
|
@ -496,7 +501,7 @@ statement
|
|||
_pShell->ErrorF("Warning: assigning INDEX to FLOAT!");
|
||||
*(FLOAT*)ssSymbol.ss_pvValue = $5.iIndex;
|
||||
} 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 {
|
||||
|
@ -566,7 +571,7 @@ lvalue
|
|||
$$.lv_pssSymbol = &ssSymbol;
|
||||
if (!ssSymbol.IsDeclared()) {
|
||||
// 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;
|
||||
$$.lv_sttType = STT_VOID;
|
||||
$$.lv_pvAddress = &fDummy;
|
||||
|
@ -578,7 +583,7 @@ lvalue
|
|||
// if the identifier is something else
|
||||
} else {
|
||||
// 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;
|
||||
$$.lv_sttType = STT_VOID;
|
||||
$$.lv_pvAddress = &fDummy;
|
||||
|
@ -616,7 +621,7 @@ lvalue
|
|||
}
|
||||
}
|
||||
} 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;
|
||||
$$.lv_pvAddress = &fDummy;
|
||||
}
|
||||
|
@ -673,7 +678,7 @@ expression
|
|||
} else {
|
||||
$$.sttType = STT_FLOAT;
|
||||
$$.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 */
|
||||
|
@ -975,7 +980,7 @@ expression
|
|||
// if the identifier is not declared
|
||||
if (!$1->IsDeclared()) {
|
||||
// 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
|
||||
} else {
|
||||
// get its type
|
||||
|
@ -989,52 +994,76 @@ expression
|
|||
_shell_ast[_shell_ast[$3.istType].st_istBaseType].st_sttType = stResult.st_sttType;
|
||||
// if types are same
|
||||
if (ShellTypeIsSame($3.istType, $1->ss_istType)) {
|
||||
bool callfunc = true;
|
||||
|
||||
#define PUSHPARAMS \
|
||||
memcpy(_alloca($3.ctBytes), _ubStack+_iStack-$3.ctBytes, $3.ctBytes);
|
||||
|
||||
// if void
|
||||
if (stResult.st_sttType==STT_VOID) {
|
||||
// just call the function
|
||||
$$.sttType = STT_VOID;
|
||||
//PUSHPARAMS;
|
||||
((void (*)(void*))$1->ss_pvValue)(_ubStack+_iStack-$3.ctBytes);
|
||||
// if index
|
||||
} else if (stResult.st_sttType==STT_INDEX) {
|
||||
// call the function and return result
|
||||
$$.sttType = STT_INDEX;
|
||||
PUSHPARAMS;
|
||||
$$.iIndex = ((INDEX (*)(void))$1->ss_pvValue)();
|
||||
// if float
|
||||
} else if (stResult.st_sttType==STT_FLOAT) {
|
||||
// call the function and return result
|
||||
$$.sttType = STT_FLOAT;
|
||||
PUSHPARAMS;
|
||||
$$.fFloat = ((FLOAT (*)(void))$1->ss_pvValue)();
|
||||
// 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 (*)(void))$1->ss_pvValue)();
|
||||
$$.strString = (const char*)strNew;
|
||||
} else {
|
||||
ASSERT(FALSE);
|
||||
$$.sttType = STT_FLOAT;
|
||||
$$.fFloat = -666.0f;
|
||||
// !!! FIXME: maybe just dump the win32 codepath here? This will break on Win64, and maybe break on different compilers/compiler versions, etc.
|
||||
#ifdef PLATFORM_WIN32
|
||||
#define CALLPARAMS
|
||||
#define FUNCSIG void
|
||||
#define PUSHPARAMS memcpy(_alloca($3.ctBytes), _ubStack+_iStack-$3.ctBytes, $3.ctBytes);
|
||||
#else
|
||||
// This is possibly more portable, but no less scary than the alloca hack.
|
||||
#define MAXSCRIPTFUNCARGS 5
|
||||
void *ARG[MAXSCRIPTFUNCARGS];
|
||||
if (($3.ctBytes > sizeof (ARG)))
|
||||
{
|
||||
_pShell->ErrorF("Function '%s' has too many arguments!", (const char *) $1->ss_strName);
|
||||
callfunc = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(ARG, _ubStack+_iStack-$3.ctBytes, $3.ctBytes);
|
||||
memset(((char *) ARG) + $3.ctBytes, '\0', sizeof (ARG) - $3.ctBytes);
|
||||
}
|
||||
#define PUSHPARAMS
|
||||
#define FUNCSIG void*, void*, void*, void*, void*
|
||||
#define CALLPARAMS ARG[0], ARG[1], ARG[2], ARG[3], ARG[4]
|
||||
#endif
|
||||
|
||||
if (callfunc) {
|
||||
// if void
|
||||
if (stResult.st_sttType==STT_VOID) {
|
||||
// just call the function
|
||||
$$.sttType = STT_VOID;
|
||||
PUSHPARAMS;
|
||||
((void (*)(FUNCSIG))$1->ss_pvValue)(CALLPARAMS);
|
||||
// if index
|
||||
} 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
|
||||
} else {
|
||||
// error
|
||||
$$.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
|
||||
} else {
|
||||
// error
|
||||
$$.sttType = STT_VOID;
|
||||
_pShell->ErrorF("Can't call '%s'", $1->ss_strName);
|
||||
_pShell->ErrorF("Can't call '%s'", (const char *) $1->ss_strName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,14 @@
|
|||
#include <Engine/Templates/AllocationArray.h>
|
||||
|
||||
// needed for parser and scanner
|
||||
#ifdef PLATFORM_WIN32
|
||||
#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 int yyparse(void);
|
||||
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
|
||||
#ifndef SE_INCL_PRIORITY_INL
|
||||
#define SE_INCL_PRIORITY_INL
|
||||
#ifdef PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CSetPriority {
|
||||
public:
|
||||
#ifdef PLATFORM_WIN32
|
||||
DWORD sp_dwProcessOld;
|
||||
int sp_iThreadOld;
|
||||
HANDLE sp_hThread;
|
||||
|
@ -21,4 +29,14 @@ public:
|
|||
BOOL bSuccessThread = SetThreadPriority(sp_hThread, sp_iThreadOld);
|
||||
ASSERT(bSuccessProcess && bSuccessThread);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CSetPriority(DWORD dwProcess, int iThread) { STUBBED(""); }
|
||||
~CSetPriority(void) { STUBBED(""); }
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* include-once blocker. */
|
||||
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Profiling.h>
|
||||
|
||||
#include <Engine/Templates/StaticArray.cpp>
|
||||
template CStaticArray<CProfileCounter>;
|
||||
template CStaticArray<CProfileTimer>;
|
||||
template class CStaticArray<CProfileCounter>;
|
||||
template class CStaticArray<CProfileTimer>;
|
||||
|
||||
#if (defined USE_PORTABLE_C)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
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;
|
||||
__asm {
|
||||
rdtsc
|
||||
|
@ -18,6 +27,22 @@ static inline __int64 ReadTSC_profile(void)
|
|||
mov dword ptr [mmRet+4],edx
|
||||
}
|
||||
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
|
||||
// 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++) {
|
||||
pfCalibration.Reset();
|
||||
pfCalibration.StartTimer(ETI_TOTAL);
|
||||
|
@ -75,7 +108,7 @@ void CProfileForm::CalibrateProfilingTimers(void)
|
|||
_tvStartStopEpsilon = llMinStartStopTime;
|
||||
|
||||
// measure how much it takes to start timer
|
||||
__int64 llMinStartTime(0x7fffffffffffffff);
|
||||
__int64 llMinStartTime = BIGBIGNUMBER;
|
||||
{for (INDEX i=0; i<REPEATCOUNT; i++) {
|
||||
pfCalibration.Reset();
|
||||
pfCalibration.StartTimer(ETI_TOTAL);
|
||||
|
@ -93,7 +126,8 @@ void CProfileForm::CalibrateProfilingTimers(void)
|
|||
_tvStartEpsilon = llMinStartTime;
|
||||
|
||||
// measure how much it takes to stop timer
|
||||
__int64 llMinStopTime(0x7fffffffffffffff);
|
||||
|
||||
__int64 llMinStopTime = BIGBIGNUMBER;
|
||||
{for (INDEX i=0; i<REPEATCOUNT; i++) {
|
||||
pfCalibration.Reset();
|
||||
pfCalibration.StartTimer(ETI_TOTAL);
|
||||
|
@ -141,7 +175,7 @@ CProfileForm::CProfileForm(
|
|||
FOREACHINSTATICARRAY(pf_aptTimers, CProfileTimer, itpt) {
|
||||
// clear the timer
|
||||
itpt->pt_tvElapsed.Clear();
|
||||
itpt->pt_tvStarted.tv_llValue = -__int64(1);
|
||||
itpt->pt_tvStarted.tv_llValue = (__int64) -1;
|
||||
itpt->pt_ctAveraging = 0;
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +231,7 @@ void CProfileForm::StopTimer_internal(INDEX iTimer)
|
|||
if (pf_ctRunningTimers==0) {
|
||||
pf_tvOverAllElapsed += tvNow-pf_tvOverAllStarted;
|
||||
}
|
||||
IFDEBUG(pt.pt_tvStarted.tv_llValue = -__int64(1));
|
||||
IFDEBUG(pt.pt_tvStarted.tv_llValue = (__int64) -1);
|
||||
_tvCurrentProfilingEpsilon += _tvStopEpsilon;
|
||||
}
|
||||
|
||||
|
@ -259,7 +293,7 @@ void CProfileForm::Reset(void)
|
|||
FOREACHINSTATICARRAY(pf_aptTimers, CProfileTimer, itpt) {
|
||||
// clear the timer
|
||||
itpt->pt_tvElapsed.Clear();
|
||||
itpt->pt_tvStarted.tv_llValue = -__int64(1);
|
||||
itpt->pt_tvStarted.tv_llValue = (__int64) -1;
|
||||
itpt->pt_ctAveraging = 0;
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +305,7 @@ void CProfileCounter::Report(char *&strBuffer, INDEX ctAveragingCount)
|
|||
ctAveragingCount = 1;
|
||||
}
|
||||
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. */
|
||||
|
@ -285,7 +319,7 @@ void CProfileTimer::Report(char *&strBuffer,
|
|||
|
||||
if (pt_strAveragingName=="") {
|
||||
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()/tvModElapsed.GetSeconds()*100,
|
||||
pt_tvElapsed.GetSeconds()/ctAveragingCount*1000
|
||||
|
@ -296,12 +330,12 @@ void CProfileTimer::Report(char *&strBuffer,
|
|||
ctLocalAveraging = 1;
|
||||
}
|
||||
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()/tvModElapsed.GetSeconds()*100,
|
||||
pt_tvElapsed.GetSeconds()/ctAveragingCount*1000,
|
||||
pt_tvElapsed.GetSeconds()/ctLocalAveraging*_pTimer->tm_llCPUSpeedHZ,
|
||||
pt_strAveragingName,
|
||||
(const char *) pt_strAveragingName,
|
||||
pt_ctAveraging/ctAveragingCount
|
||||
);
|
||||
}
|
||||
|
@ -328,7 +362,9 @@ void CProfileForm::Report(CTString &strReport)
|
|||
CTimerValue tvModuleElapsed = pf_tvOverAllElapsed;
|
||||
// print the main header
|
||||
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
|
||||
strBuffer += sprintf(strBuffer,
|
||||
|
|
|
@ -47,7 +47,7 @@ private:
|
|||
// this file just defines TIMER_PROFILING as 1 or 0
|
||||
#include <Engine/Base/ProfilingEnabled.h>
|
||||
|
||||
#endif ENGINE_INTERNAL
|
||||
#endif //ENGINE_INTERNAL
|
||||
|
||||
/*
|
||||
* Class for gathering and reporting profiling information.
|
||||
|
@ -153,6 +153,19 @@ public:
|
|||
/* Get percentage of module time in application time. */
|
||||
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
|
||||
|
||||
/* Reset all profiling values. */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#define TIMER_PROFILING 0
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "StdH.h"
|
||||
#include <Engine/StdH.h>
|
||||
#include <Engine/Base/CTString.h>
|
||||
#include <Engine/Base/ProgressHook.h>
|
||||
#include <Engine/Network/Network.h>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include <Engine\Base\Protection.h>
|
||||
#include <Engine/Base/Protection.h>
|
||||
|
||||
#pragma warning (disable: 4244)
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifdef PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
#define COPY_PROTECTION 1
|
||||
|
||||
typedef struct {
|
||||
unsigned long P[16 + 2];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
#include <Engine/Base/CTString.h>
|
||||
#include <Engine/Base/FileName.h>
|
||||
#include <Engine/Base/Registry.h>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Relations.h>
|
||||
|
||||
|
|
|
@ -62,10 +62,10 @@ void ENGINE_API AddRelationPairHeadHead(CRelationSrc &rsSrc, CRelationDst &rdDst
|
|||
|
||||
// get a domain member related to a codomain member through a link
|
||||
#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
|
||||
#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
|
||||
#define FOREACHDSTOFSRC(srchead, dstclass, dstmember, pdst) \
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/ReplaceFile.h>
|
||||
#include <Engine/Base/Stream.h>
|
||||
#include <Engine/Base/ErrorReporting.h>
|
||||
#include <Engine/Base/Anim.h>
|
||||
#include <Engine/Base/Shell.h>
|
||||
#include <Engine/Graphics/Texture.h>
|
||||
#include <Engine/Models/ModelObject.h>
|
||||
#include <Engine/Sound/SoundObject.h>
|
||||
|
@ -41,6 +40,7 @@ extern INDEX wed_bUseBaseForReplacement;
|
|||
|
||||
static CTFileName CallFileRequester(char *achrTitle, char *achrSelectedFile, char *pFilter)
|
||||
{
|
||||
#ifdef PLATFORM_WIN32
|
||||
typedef CTFileName FileRequester_t(
|
||||
char *pchrTitle,
|
||||
char *pchrFilters,
|
||||
|
@ -62,6 +62,13 @@ static CTFileName CallFileRequester(char *achrTitle, char *achrSelectedFile, cha
|
|||
}
|
||||
|
||||
return pFileRequester( achrTitle, pFilter, "Replace file directory", achrSelectedFile);
|
||||
|
||||
#else
|
||||
|
||||
STUBBED("wtf?!");
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
BOOL GetReplacingFile(CTFileName fnSourceFile, CTFileName &fnReplacingFile,
|
||||
|
@ -105,7 +112,7 @@ BOOL GetReplacingFile(CTFileName fnSourceFile, CTFileName &fnReplacingFile,
|
|||
(void) strError;
|
||||
}
|
||||
CTString strTitle;
|
||||
strTitle.PrintF(TRANS("For:\"%s\""), (CTString&)fnSourceFile);
|
||||
strTitle.PrintF(TRANS("For:\"%s\""), (const char *) (CTString&)fnSourceFile);
|
||||
// call file requester for substituting file
|
||||
CTString strDefaultFile;
|
||||
strDefaultFile = fnSourceFile.FileName() + fnSourceFile.FileExt();
|
||||
|
@ -122,7 +129,7 @@ BOOL GetReplacingFile(CTFileName fnSourceFile, CTFileName &fnReplacingFile,
|
|||
strBase.Load_t( fnBaseName);
|
||||
}
|
||||
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.Save_t( fnBaseName);
|
||||
}
|
||||
|
@ -162,7 +169,7 @@ void SetTextureWithPossibleReplacing_t(CTextureObject &to, CTFileName &fnmTextur
|
|||
to.SetData_t(fnmTexture);
|
||||
} else {
|
||||
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
|
||||
fnTexture = fnReplacingTexture;
|
||||
} 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
|
||||
fnModel = fnReplacingModel;
|
||||
} 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
|
||||
// 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);
|
||||
strm<<strParenBoneID;
|
||||
|
||||
|
@ -635,7 +642,7 @@ void ReadModelInstanceOld_t(CTStream &strm, CModelInstance &mi)
|
|||
}
|
||||
|
||||
// read model instance offset and parent bone
|
||||
strm.Read_t(&mi.mi_qvOffset,sizeof(QVect));
|
||||
strm>>mi.mi_qvOffset;
|
||||
CTString strParenBoneID;
|
||||
strm>>strParenBoneID;
|
||||
mi.mi_iParentBoneID = ska_GetIDFromStringTable(strParenBoneID);
|
||||
|
@ -789,7 +796,7 @@ void ReadOffsetAndChildren_t(CTStream &strm, CModelInstance &mi)
|
|||
INDEX ctcmi = 0;
|
||||
strm.ExpectID_t("MIOF"); // model instance offset
|
||||
// read model instance offset and parent bone
|
||||
strm.Read_t(&mi.mi_qvOffset,sizeof(QVect));
|
||||
strm>>mi.mi_qvOffset;
|
||||
CTString strParenBoneID;
|
||||
strm>>strParenBoneID;
|
||||
mi.mi_iParentBoneID = ska_GetIDFromStringTable(strParenBoneID);
|
||||
|
@ -873,7 +880,7 @@ void ReadAnimObject_t(CTStream &strm, CAnimObject &ao)
|
|||
// replacing anim was provided
|
||||
fnAnim = fnReplacingAnim;
|
||||
} else {
|
||||
ThrowF_t( TRANS("Cannot find substitution for \"%s\""), (CTString&)fnAnim);
|
||||
ThrowF_t( TRANS("Cannot find substitution for \"%s\""), (const char *) (CTString&)fnAnim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
174
Sources/Engine/Base/SDL/SDLEvents.cpp
Normal file
174
Sources/Engine/Base/SDL/SDLEvents.cpp
Normal 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 ...
|
||||
|
||||
|
132
Sources/Engine/Base/SDL/SDLEvents.h
Normal file
132
Sources/Engine/Base/SDL/SDLEvents.h
Normal 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. */
|
||||
|
||||
|
1036
Sources/Engine/Base/SDL/SDLInput.cpp
Normal file
1036
Sources/Engine/Base/SDL/SDLInput.cpp
Normal file
File diff suppressed because it is too large
Load Diff
144
Sources/Engine/Base/SDL/SDLSynchronization.cpp
Normal file
144
Sources/Engine/Base/SDL/SDLSynchronization.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
15
Sources/Engine/Base/SDL/SDLThreadLocalStorage.cpp
Normal file
15
Sources/Engine/Base/SDL/SDLThreadLocalStorage.cpp
Normal 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 ...
|
||||
|
||||
|
16
Sources/Engine/Base/SDL/SDLTimer.cpp
Normal file
16
Sources/Engine/Base/SDL/SDLTimer.cpp
Normal 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 ...
|
||||
|
||||
|
|
@ -13,6 +13,10 @@
|
|||
#define YY_DECL int yylex (YYSTYPE *lvalp)
|
||||
#define yylval (*lvalp)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { int yywrap(void); }
|
||||
#endif
|
||||
|
||||
int yywrap(void)
|
||||
{
|
||||
// no more bufers
|
||||
|
@ -113,8 +117,8 @@ PARAMCONTENT ([^\ \n\";]|(\\\ ))
|
|||
if (strParam.FindSubstr(strParamNo)!=-1) {
|
||||
_pShell->ErrorF("Parameter substitution recursion detected!");
|
||||
} else {
|
||||
INDEX ctFound=0;
|
||||
for(;; ctFound++) {
|
||||
INDEX ctFound;
|
||||
for(ctFound=0;; ctFound++) {
|
||||
if (!_strCmd.ReplaceSubstr(strParamNo, strParam)) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Serial.h>
|
||||
|
||||
|
@ -81,7 +81,7 @@ void CSerial::Reload(void)
|
|||
// if there is some error while reloading
|
||||
//} catch (char *strError) {
|
||||
// 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)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* 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_internal.h>
|
||||
|
@ -14,17 +14,17 @@
|
|||
#include <Engine/Templates/DynamicArray.cpp>
|
||||
#include <Engine/Templates/DynamicStackArray.cpp>
|
||||
|
||||
template CDynamicArray<CShellSymbol>;
|
||||
template class CDynamicArray<CShellSymbol>;
|
||||
|
||||
// shell type used for undeclared symbols
|
||||
extern INDEX _shell_istUndeclared = -1;
|
||||
INDEX _shell_istUndeclared = -1;
|
||||
|
||||
// pointer to global shell object
|
||||
CShell *_pShell = NULL;
|
||||
void *_pvNextToDeclare=NULL; // != NULL if declaring external symbol defined in exe code
|
||||
|
||||
// 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);
|
||||
|
||||
|
@ -99,10 +99,10 @@ CDynamicStackArray<FLOAT> _shell_afExtFloats;
|
|||
|
||||
static const char *strCommandLine = "";
|
||||
|
||||
ENGINE_API extern FLOAT tmp_af[10] = { 0 };
|
||||
ENGINE_API extern INDEX tmp_ai[10] = { 0 };
|
||||
ENGINE_API extern INDEX tmp_fAdd = 0.0f;
|
||||
ENGINE_API extern INDEX tmp_i = 0;
|
||||
FLOAT tmp_af[10] = { 0 };
|
||||
INDEX tmp_ai[10] = { 0 };
|
||||
INDEX tmp_fAdd = 0;
|
||||
INDEX tmp_i = 0;
|
||||
|
||||
void CShellSymbol::Clear(void)
|
||||
{
|
||||
|
@ -175,7 +175,7 @@ void MakeAccessViolation(void* pArgs)
|
|||
*p=1;
|
||||
}
|
||||
|
||||
extern int _a=123;
|
||||
int _a=123;
|
||||
void MakeStackOverflow(void* pArgs)
|
||||
{
|
||||
INDEX bDont = NEXTARGUMENT(INDEX);
|
||||
|
@ -196,6 +196,7 @@ void MakeFatalError(void* pArgs)
|
|||
|
||||
extern void ReportGlobalMemoryStatus(void)
|
||||
{
|
||||
#ifdef PLATFORM_WIN32
|
||||
CPrintF(TRANS("Global memory status...\n"));
|
||||
|
||||
MEMORYSTATUS ms;
|
||||
|
@ -211,13 +212,15 @@ extern void ReportGlobalMemoryStatus(void)
|
|||
DWORD dwMax;
|
||||
GetProcessWorkingSetSize(GetCurrentProcess(), &dwMin, &dwMax);
|
||||
CPrintF(TRANS(" Process working set: %dMB-%dMB\n\n"), dwMin/(1024*1024), dwMax/(1024*1024));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void MemoryInfo(void)
|
||||
{
|
||||
ReportGlobalMemoryStatus();
|
||||
|
||||
_HEAPINFO hinfo;
|
||||
#ifdef PLATFORM_WIN32
|
||||
_HEAPINFO hinfo;
|
||||
int heapstatus;
|
||||
hinfo._pentry = NULL;
|
||||
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 free: %d bytes (%.2f MB) in %d blocks\n", slTotalFree, slTotalFree/1024.0f/1024.0f, ctFree);
|
||||
#endif
|
||||
}
|
||||
|
||||
// get help for a shell symbol
|
||||
|
@ -293,14 +297,14 @@ extern void PrintShellSymbolHelp(const CTString &strSymbol)
|
|||
try {
|
||||
CTString strHelp = GetShellSymbolHelp_t(strSymbol);
|
||||
if (strHelp!="") {
|
||||
CPrintF("%s\n", strHelp);
|
||||
CPrintF("%s\n", (const char *) strHelp);
|
||||
} else {
|
||||
CPrintF( TRANS("No help found for '%s'.\n"), strSymbol);
|
||||
CPrintF( TRANS("No help found for '%s'.\n"), (const char *) strSymbol);
|
||||
}
|
||||
// if failed
|
||||
} catch(char *strError) {
|
||||
// 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
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
// get base type
|
||||
ShellType &stBase = _shell_ast[st.st_istBaseType];
|
||||
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) {
|
||||
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) {
|
||||
CPrintF("CTString %s[%d]", ss.ss_strName, st.st_ctArraySize);
|
||||
CPrintF("CTString %s[%d]", (const char *) ss.ss_strName, st.st_ctArraySize);
|
||||
} else {
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
@ -421,7 +425,7 @@ void LoadCommands(void)
|
|||
{
|
||||
// list all command files
|
||||
CDynamicStackArray<CTFileName> afnmCmds;
|
||||
MakeDirList( afnmCmds, CTString("Scripts\\Commands\\"), "*.ini", DLI_RECURSIVE);
|
||||
MakeDirList( afnmCmds, CTString("Scripts\\Commands\\"), CTString("*.ini"), DLI_RECURSIVE);
|
||||
// for each file
|
||||
for(INDEX i=0; i<afnmCmds.Count(); i++) {
|
||||
CTFileName &fnm = afnmCmds[i];
|
||||
|
@ -452,7 +456,7 @@ void LoadCommands(void)
|
|||
// assign value
|
||||
*(CTString*)ssNew.ss_pvValue = "!command "+strCmd;
|
||||
} 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 NO;", (void*)&_bFALSE);
|
||||
|
||||
DeclareSymbol("user void LoadCommands(void);", &LoadCommands);
|
||||
DeclareSymbol("user void ListSymbols(void);", &ListSymbols);
|
||||
DeclareSymbol("user void MemoryInfo(void);", &MemoryInfo);
|
||||
DeclareSymbol("user void MakeAccessViolation(INDEX);", &MakeAccessViolation);
|
||||
DeclareSymbol("user void MakeStackOverflow(INDEX);", &MakeStackOverflow);
|
||||
DeclareSymbol("user void MakeFatalError(INDEX);", &MakeFatalError);
|
||||
DeclareSymbol("persistent user INDEX con_iLastLines;", &con_iLastLines);
|
||||
DeclareSymbol("persistent user FLOAT tmp_af[10];", &tmp_af);
|
||||
DeclareSymbol("persistent user INDEX tmp_ai[10];", &tmp_ai);
|
||||
DeclareSymbol("persistent user INDEX tmp_i;", &tmp_i);
|
||||
DeclareSymbol("persistent user FLOAT tmp_fAdd;", &tmp_fAdd);
|
||||
DeclareSymbol("user void LoadCommands(void);", (void *)&LoadCommands);
|
||||
DeclareSymbol("user void ListSymbols(void);", (void *)&ListSymbols);
|
||||
DeclareSymbol("user void MemoryInfo(void);", (void *)&MemoryInfo);
|
||||
DeclareSymbol("user void MakeAccessViolation(INDEX);", (void *)&MakeAccessViolation);
|
||||
DeclareSymbol("user void MakeStackOverflow(INDEX);", (void *)&MakeStackOverflow);
|
||||
DeclareSymbol("user void MakeFatalError(INDEX);", (void *)&MakeFatalError);
|
||||
DeclareSymbol("persistent user INDEX con_iLastLines;", (void *)&con_iLastLines);
|
||||
DeclareSymbol("persistent user FLOAT tmp_af[10];", (void *)&tmp_af);
|
||||
DeclareSymbol("persistent user INDEX tmp_ai[10];", (void *)&tmp_ai);
|
||||
DeclareSymbol("persistent user INDEX tmp_i;", (void *)&tmp_i);
|
||||
DeclareSymbol("persistent user FLOAT tmp_fAdd;", (void *)&tmp_fAdd);
|
||||
|
||||
DeclareSymbol("user void Echo(CTString);", &Echo);
|
||||
DeclareSymbol("user CTString UndecorateString(CTString);", &UndecorateString);
|
||||
DeclareSymbol("user INDEX Matches(CTString, CTString);", &MatchStrings);
|
||||
DeclareSymbol("user CTString LoadString(CTString);", &MyLoadString);
|
||||
DeclareSymbol("user void SaveString(CTString, CTString);", &MySaveString);
|
||||
DeclareSymbol("user CTString RemoveSubstring(CTString, CTString);", &RemoveSubstringCfunc);
|
||||
DeclareSymbol("user CTString ToUpper(CTString);", &ToUpperCfunc);
|
||||
DeclareSymbol("user CTString ToLower(CTString);", &ToLowerCfunc);
|
||||
DeclareSymbol("user void Echo(CTString);", (void *)&Echo);
|
||||
DeclareSymbol("user CTString UndecorateString(CTString);", (void *)&UndecorateString);
|
||||
DeclareSymbol("user INDEX Matches(CTString, CTString);", (void *)&MatchStrings);
|
||||
DeclareSymbol("user CTString LoadString(CTString);", (void *)&MyLoadString);
|
||||
DeclareSymbol("user void SaveString(CTString, CTString);", (void *)&MySaveString);
|
||||
DeclareSymbol("user CTString RemoveSubstring(CTString, CTString);", (void *)&RemoveSubstringCfunc);
|
||||
DeclareSymbol("user CTString ToUpper(CTString);", (void *)&ToUpperCfunc);
|
||||
DeclareSymbol("user CTString ToLower(CTString);", (void *)&ToLowerCfunc);
|
||||
}
|
||||
|
||||
static BOOL _iParsing = 0;
|
||||
|
||||
// Declare a symbol in the shell.
|
||||
/* rcg10072001 Added second version of DeclareSymbol()... */
|
||||
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
|
||||
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
|
||||
_pvNextToDeclare = NULL;
|
||||
};
|
||||
}
|
||||
|
||||
// Execute command(s).
|
||||
void CShell::Execute(const CTString &strCommands)
|
||||
|
@ -813,6 +823,7 @@ void CShell::ErrorF(const char *strFormat, ...)
|
|||
va_start(arg, strFormat);
|
||||
CTString strBuffer;
|
||||
strBuffer.VPrintF(strFormat, arg);
|
||||
va_end(arg);
|
||||
|
||||
// print it to the main console
|
||||
CPrintF(strBuffer);
|
||||
|
@ -843,7 +854,7 @@ void CShell::StorePersistentSymbols(const CTFileName &fnScript)
|
|||
continue;
|
||||
}
|
||||
|
||||
char *strUser = (ss.ss_ulFlags & SSF_USER)?"user ":"";
|
||||
const char *strUser = (ss.ss_ulFlags & SSF_USER)?"user ":"";
|
||||
|
||||
// get its type
|
||||
ShellType &st = _shell_ast[ss.ss_istType];
|
||||
|
@ -856,39 +867,39 @@ void CShell::StorePersistentSymbols(const CTFileName &fnScript)
|
|||
if (stBase.st_sttType==STT_FLOAT) {
|
||||
// dump all members as floats
|
||||
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
|
||||
} else if (stBase.st_sttType==STT_INDEX) {
|
||||
// dump all members as indices
|
||||
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
|
||||
} else if (stBase.st_sttType==STT_STRING) {
|
||||
// dump all members
|
||||
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
|
||||
} 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
|
||||
} else if (st.st_sttType==STT_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
|
||||
} else if (st.st_sttType==STT_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
|
||||
} else if (st.st_sttType==STT_STRING) {
|
||||
// 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
|
||||
} else {
|
||||
ThrowF_t("%s of wrong type", ss.ss_strName);
|
||||
ThrowF_t("%s of wrong type", (const char *) ss.ss_strName);
|
||||
}
|
||||
}
|
||||
} catch (char *strError) {
|
||||
|
|
|
@ -36,6 +36,8 @@ public:
|
|||
|
||||
// Declare a symbol in the shell.
|
||||
void DeclareSymbol(const CTString &strDeclaration, void *pvValue);
|
||||
/* rcg10072001 Added this version of DeclareSymbol()... */
|
||||
void DeclareSymbol(const char *strDeclaration, void *pvValue);
|
||||
// Execute command(s).
|
||||
void Execute(const CTString &strCommands);
|
||||
// Save shell commands to restore persistent symbols to a script file
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* 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_internal.h>
|
||||
|
|
|
@ -23,6 +23,17 @@ enum ShellTypeType {
|
|||
|
||||
// data type structure
|
||||
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;
|
||||
|
||||
INDEX st_ctArraySize; // number of members if an array
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Console_Internal.h>
|
||||
|
||||
#include <Engine/Build.h>
|
||||
|
||||
#if (!defined PLATFORM_WIN32)
|
||||
#error You probably should not try to compile this.
|
||||
#endif
|
||||
|
||||
extern ULONG _ulEngineBuildMajor;
|
||||
extern ULONG _ulEngineBuildMinor;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* 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_Internal.h>
|
||||
|
@ -8,9 +8,9 @@
|
|||
#include <Engine/Templates/DynamicContainer.cpp>
|
||||
#include <Engine/Templates/StaticArray.cpp>
|
||||
|
||||
template CStaticArray<CStatCounter>;
|
||||
template CStaticArray<CStatTimer>;
|
||||
template CStaticArray<CStatLabel>;
|
||||
template class CStaticArray<CStatCounter>;
|
||||
template class CStaticArray<CStatTimer>;
|
||||
template class CStaticArray<CStatLabel>;
|
||||
|
||||
// one globaly used stats report
|
||||
CStatForm _sfStats;
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <sys\types.h>
|
||||
#include <sys\stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.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/Memory.h>
|
||||
|
@ -19,6 +22,7 @@
|
|||
#include <Engine/Base/Unzip.h>
|
||||
#include <Engine/Base/CRC.h>
|
||||
#include <Engine/Base/Shell.h>
|
||||
#include <Engine/Base/FileSystem.h>
|
||||
#include <Engine/Templates/NameTable_CTFileName.h>
|
||||
#include <Engine/Templates/StaticArray.cpp>
|
||||
#include <Engine/Templates/DynamicStackArray.cpp>
|
||||
|
@ -28,22 +32,23 @@
|
|||
|
||||
// default size of page used for stream IO operations (4Kb)
|
||||
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;
|
||||
extern INDEX fil_bPreferZips = FALSE;
|
||||
INDEX fil_bPreferZips = FALSE;
|
||||
|
||||
// set if current thread has currently enabled stream handling
|
||||
static _declspec(thread) BOOL _bThreadCanHandleStreams = FALSE;
|
||||
THREADLOCAL(BOOL, _bThreadCanHandleStreams, FALSE);
|
||||
// list of currently opened streams
|
||||
static _declspec(thread) CListHead *_plhOpenedStreams = NULL;
|
||||
|
||||
ULONG _ulVirtuallyAllocatedSpace = 0;
|
||||
ULONG _ulVirtuallyAllocatedSpaceTotal = 0;
|
||||
THREADLOCAL(CListHead *, _plhOpenedStreams, NULL);
|
||||
|
||||
// global string with application path
|
||||
CTFileName _fnmApplicationPath;
|
||||
// global string with filename of the started application
|
||||
CTFileName _fnmApplicationExe;
|
||||
// global string with user-specific writable directory.
|
||||
CTFileName _fnmUserDir;
|
||||
// global string with current MOD path
|
||||
CTFileName _fnmMod;
|
||||
// global string with current name (the parameter that is passed on cmdline)
|
||||
|
@ -104,10 +109,15 @@ static CTFileName _fnmApp;
|
|||
void InitStreams(void)
|
||||
{
|
||||
// obtain information about system
|
||||
// !!! FIXME: Move this into an abstraction of some sort...
|
||||
#ifdef PLATFORM_WIN32
|
||||
SYSTEM_INFO siSystemInfo;
|
||||
GetSystemInfo( &siSystemInfo);
|
||||
// and remember page size
|
||||
_ulPageSize = siSystemInfo.dwPageSize*16; // cca. 64kB on WinNT/Win95
|
||||
#else
|
||||
_ulPageSize = PAGESIZE;
|
||||
#endif
|
||||
|
||||
// keep a copy of path for setting purposes
|
||||
_fnmApp = _fnmApplicationPath;
|
||||
|
@ -118,7 +128,9 @@ void InitStreams(void)
|
|||
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 (_fnmMod!="") {
|
||||
// load mod's include/exclude lists
|
||||
|
@ -163,54 +175,49 @@ void InitStreams(void)
|
|||
}
|
||||
_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 (_fnmMod!="") {
|
||||
// for each group file in mod directory
|
||||
struct _finddata_t c_file;
|
||||
long hFile;
|
||||
hFile = _findfirst(_fnmApplicationPath+_fnmMod+"*.gro", &c_file);
|
||||
BOOL bOK = (hFile!=-1);
|
||||
while(bOK) {
|
||||
if (CTString(c_file.name).Matches("*.gro")) {
|
||||
// add it to active set
|
||||
UNZIPAddArchive(_fnmApplicationPath+_fnmMod+c_file.name);
|
||||
}
|
||||
bOK = _findnext(hFile, &c_file)==0;
|
||||
}
|
||||
_findclose( hFile );
|
||||
files = _pFileSystem->FindFiles(_fnmApplicationPath+_fnmMod, "*.gro");
|
||||
max = files->Count();
|
||||
for (i = 0; i < max; i++) {
|
||||
UNZIPAddArchive( _fnmApplicationPath + _fnmMod + ((*files)[i]) );
|
||||
}
|
||||
delete files;
|
||||
}
|
||||
|
||||
// if there is a CD path
|
||||
if (_fnmCDPath!="") {
|
||||
// for each group file on the CD
|
||||
struct _finddata_t c_file;
|
||||
long hFile;
|
||||
hFile = _findfirst(_fnmCDPath+"*.gro", &c_file);
|
||||
BOOL bOK = (hFile!=-1);
|
||||
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;
|
||||
files = _pFileSystem->FindFiles(_fnmCDPath, "*.gro");
|
||||
max = files->Count();
|
||||
for (i = 0; i < max; i++) {
|
||||
UNZIPAddArchive( _fnmCDPath + ((*files)[i]) );
|
||||
}
|
||||
_findclose( hFile );
|
||||
delete files;
|
||||
|
||||
// if there is a mod active
|
||||
if (_fnmMod!="") {
|
||||
// for each group file in mod directory
|
||||
struct _finddata_t c_file;
|
||||
long hFile;
|
||||
hFile = _findfirst(_fnmCDPath+_fnmMod+"*.gro", &c_file);
|
||||
BOOL bOK = (hFile!=-1);
|
||||
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;
|
||||
files = _pFileSystem->FindFiles(_fnmCDPath+_fnmMod, "*.gro");
|
||||
max = files->Count();
|
||||
for (i = 0; i < max; i++) {
|
||||
UNZIPAddArchive( _fnmCDPath + _fnmMod + ((*files)[i]) );
|
||||
}
|
||||
_findclose( hFile );
|
||||
delete files;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +232,8 @@ void InitStreams(void)
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
@ -268,6 +276,7 @@ void CTStream::DisableStreamHandling(void)
|
|||
_plhOpenedStreams = NULL;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
int CTStream::ExceptionFilter(DWORD dwCode, _EXCEPTION_POINTERS *pExceptionInfoPtrs)
|
||||
{
|
||||
// If the exception is not a page fault, exit.
|
||||
|
@ -312,6 +321,7 @@ void CTStream::ExceptionFatalError(void)
|
|||
{
|
||||
FatalError( GetWindowsError( GetLastError()) );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Throw an exception of formatted string.
|
||||
|
@ -320,13 +330,20 @@ void CTStream::Throw_t(char *strFormat, ...) // throws char *
|
|||
{
|
||||
const SLONG slBufferSize = 256;
|
||||
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
|
||||
_snprintf(strFormatBuffer, slBufferSize, "%s (%s)", strFormat, strm_strStreamDescription);
|
||||
_snprintf(strFormatBuffer, slBufferSize, "%s (%s)", strFormat, (const char *) strm_strStreamDescription);
|
||||
// format the message in buffer
|
||||
va_list arg;
|
||||
va_start(arg, strFormat); // variable arguments start after this argument
|
||||
_vsnprintf(strBuffer, slBufferSize, strFormatBuffer, arg);
|
||||
va_end(arg);
|
||||
throw strBuffer;
|
||||
}
|
||||
|
||||
|
@ -379,7 +396,7 @@ void CTStream::GetLine_t(char *strBuffer, SLONG slBufferSize, char cDelimiter /*
|
|||
INDEX iLetters = 0;
|
||||
// test if EOF reached
|
||||
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
|
||||
FOREVER
|
||||
|
@ -466,6 +483,7 @@ void CTStream::FPrintF_t(const char *strFormat, ...) // throw char *
|
|||
va_list arg;
|
||||
va_start(arg, strFormat); // variable arguments start after this argument
|
||||
_vsnprintf(strBuffer, slBufferSize, strFormat, arg);
|
||||
va_end(arg);
|
||||
// print the buffer
|
||||
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 *
|
||||
{
|
||||
// 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;
|
||||
(*this)>>chKeywordChar;
|
||||
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);
|
||||
}
|
||||
} 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) {
|
||||
// error
|
||||
::ThrowF_t(TRANS("Cannot open file `%s', stream handling is not enabled for this thread"),
|
||||
(CTString&)fnFileName);
|
||||
(const char *) (CTString&)fnFileName);
|
||||
}
|
||||
|
||||
|
||||
// check parameters
|
||||
ASSERT(strlen(fnFileName)>0);
|
||||
// check that the file is not open
|
||||
|
@ -972,7 +992,7 @@ void CTFileStream::Create_t(const CTFileName &fnFileName,
|
|||
if(fstrm_pFile == NULL)
|
||||
{
|
||||
// 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));
|
||||
}
|
||||
// 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
|
||||
file_handle = _open( fnmExpanded, _O_RDONLY | _O_BINARY);
|
||||
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;
|
||||
}
|
||||
struct stat statFileStatus;
|
||||
|
@ -1457,6 +1477,7 @@ static INDEX ExpandFilePath_read(ULONG ulType, const CTFileName &fnmFile, CTFile
|
|||
{
|
||||
// search for the file in zips
|
||||
INDEX iFileInZip = UNZIPGetFileIndex(fnmFile);
|
||||
const BOOL userdir_not_basedir = (_fnmUserDir != _fnmApplicationPath);
|
||||
|
||||
// if a mod is active
|
||||
if (_fnmMod!="") {
|
||||
|
@ -1542,6 +1563,44 @@ static INDEX ExpandFilePath_read(ULONG ulType, const CTFileName &fnmFile, CTFile
|
|||
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
|
||||
INDEX ExpandFilePath(ULONG ulType, const CTFileName &fnmFile, CTFileName &fnmExpanded)
|
||||
{
|
||||
|
|
|
@ -357,12 +357,14 @@ ENGINE_API INDEX ExpandFilePath(ULONG ulType, const CTFileName &fnmFile, CTFileN
|
|||
ENGINE_API void MakeDirList(
|
||||
CDynamicStackArray<CTFileName> &adeDir,
|
||||
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
|
||||
);
|
||||
|
||||
// global string with application path
|
||||
ENGINE_API extern CTFileName _fnmApplicationPath;
|
||||
// global string with user-specific writable directory.
|
||||
ENGINE_API extern CTFileName _fnmUserDir;
|
||||
// global string with current MOD path
|
||||
ENGINE_API extern CTFileName _fnmMod;
|
||||
// global string with current name (the parameter that is passed on cmdline)
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
#endif
|
||||
|
||||
// intra-process mutex (only used by thread of same process)
|
||||
// NOTE: mutex has no interface - it is locked using CTSingleLock
|
||||
class CTCriticalSection {
|
||||
public:
|
||||
// !!! FIXME : rcg10142001 This would be better with a real subclass,
|
||||
// !!! FIXME : and not void pointers.
|
||||
void *cs_pvObject; // object is internal to implementation
|
||||
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
|
||||
|
@ -18,6 +19,10 @@ public:
|
|||
INDEX Lock(void);
|
||||
INDEX TryToLock(void);
|
||||
INDEX Unlock(void);
|
||||
|
||||
private:
|
||||
ULONG LockCounter;
|
||||
ULONG owner;
|
||||
};
|
||||
|
||||
// lock object for locking a mutex with automatic unlocking
|
||||
|
@ -34,6 +39,6 @@ public:
|
|||
ENGINE_API void Unlock(void);
|
||||
};
|
||||
|
||||
|
||||
#endif /* include-once check. */
|
||||
|
||||
|
||||
|
|
147
Sources/Engine/Base/ThreadLocalStorage.h
Normal file
147
Sources/Engine/Base/ThreadLocalStorage.h
Normal 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 ...
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Timer.h>
|
||||
#include <Engine/Base/Console.h>
|
||||
#include <Engine/Base/Translation.h>
|
||||
#include <Engine/Base/ThreadLocalStorage.h> //rcg10242001
|
||||
|
||||
#include <Engine/Base/Registry.h>
|
||||
#include <Engine/Base/Profiling.h>
|
||||
|
@ -14,9 +15,23 @@
|
|||
#include <Engine/Base/ListIterator.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)
|
||||
{
|
||||
#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;
|
||||
__asm {
|
||||
rdtsc
|
||||
|
@ -24,14 +39,32 @@ static inline __int64 ReadTSC(void)
|
|||
mov dword ptr [mmRet+4],edx
|
||||
}
|
||||
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
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "winmm.lib")
|
||||
#endif
|
||||
|
||||
// current game time always valid for the currently active task
|
||||
static _declspec(thread) TIME _CurrentTickTimer = 0.0f;
|
||||
THREADLOCAL(TIME, _CurrentTickTimer, 0.0f);
|
||||
|
||||
// CTimer implementation
|
||||
|
||||
|
@ -76,9 +109,30 @@ void CTimer_TimerFunc_internal(void)
|
|||
// streams and to group file before enabling that!
|
||||
// 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
|
||||
_pTimer->tm_RealTimeTimer += _pTimer->TickQuantum;
|
||||
|
||||
#endif
|
||||
|
||||
// get the current time for real and in ticks
|
||||
CTimerValue tvTimeNow = _pTimer->GetHighPrecisionTimer();
|
||||
TIME tmTickNow = _pTimer->tm_RealTimeTimer;
|
||||
|
@ -104,6 +158,10 @@ void CTimer_TimerFunc_internal(void)
|
|||
|
||||
// } 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)
|
||||
{
|
||||
// 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
|
||||
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()
|
||||
|
||||
|
@ -121,6 +190,7 @@ static INDEX _aiTries[MAX_MEASURE_TRIES];
|
|||
// Get processor speed in Hertz
|
||||
static __int64 GetCPUSpeedHz(void)
|
||||
{
|
||||
#ifdef PLATFORM_WIN32
|
||||
// get the frequency of the 'high' precision timer
|
||||
__int64 llTimerFrequency;
|
||||
BOOL bPerformanceCounterPresent = QueryPerformanceFrequency((LARGE_INTEGER*)&llTimerFrequency);
|
||||
|
@ -138,8 +208,7 @@ static __int64 GetCPUSpeedHz(void)
|
|||
__int64 llSpeedMeasured;
|
||||
|
||||
// try to measure 10 times
|
||||
INDEX iSet=0;
|
||||
for( ; iSet<10; iSet++)
|
||||
for( INDEX iSet=0; iSet<10; iSet++)
|
||||
{ // one time has several tries
|
||||
for( iTry=0; iTry<MAX_MEASURE_TRIES; iTry++)
|
||||
{ // wait the state change on the timer
|
||||
|
@ -202,20 +271,40 @@ static __int64 GetCPUSpeedHz(void)
|
|||
// use measured value
|
||||
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.
|
||||
*/
|
||||
CTimer::CTimer(BOOL bInterrupt /*=TRUE*/)
|
||||
{
|
||||
#if (defined SINGLE_THREADED)
|
||||
bInterrupt = FALSE;
|
||||
#endif
|
||||
|
||||
tm_csHooks.cs_iIndex = 1000;
|
||||
// set global pointer
|
||||
ASSERT(_pTimer == NULL);
|
||||
_pTimer = this;
|
||||
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
|
||||
CSetPriority sp(REALTIME_PRIORITY_CLASS, THREAD_PRIORITY_TIME_CRITICAL);
|
||||
tm_llCPUSpeedHZ = GetCPUSpeedHz();
|
||||
|
@ -225,6 +314,54 @@ CTimer::CTimer(BOOL bInterrupt /*=TRUE*/)
|
|||
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
|
||||
_CurrentTickTimer = TIME(0);
|
||||
tm_RealTimeTimer = TIME(0);
|
||||
|
@ -236,8 +373,18 @@ CTimer::CTimer(BOOL bInterrupt /*=TRUE*/)
|
|||
tm_fLerpFactor2 = 1.0f;
|
||||
|
||||
// start interrupt (eventually)
|
||||
#if (defined SINGLE_THREADED)
|
||||
|
||||
tm_InitialTimerUpkeep = GetHighPrecisionTimer();
|
||||
|
||||
#else
|
||||
|
||||
if( tm_bInterrupt)
|
||||
{
|
||||
|
||||
// !!! FIXME : rcg10192001 Abstract this!
|
||||
#ifdef PLATFORM_WIN32
|
||||
|
||||
tm_TimerID = timeSetEvent(
|
||||
ULONG(TickQuantum*1000.0f), // period value [ms]
|
||||
0, // resolution (0==max. possible)
|
||||
|
@ -248,18 +395,27 @@ CTimer::CTimer(BOOL bInterrupt /*=TRUE*/)
|
|||
// check that interrupt was properly started
|
||||
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
|
||||
INDEX iTry=1;
|
||||
for( ; iTry<=3; iTry++) {
|
||||
INDEX iTry;
|
||||
for(iTry=1; iTry<=3; iTry++) {
|
||||
const TIME tmTickBefore = GetRealTimeTick();
|
||||
Sleep(1000* iTry*3 *TickQuantum);
|
||||
const TIME tmTickAfter = GetRealTimeTick();
|
||||
ASSERT(tmTickBefore <= tmTickAfter);
|
||||
if( tmTickBefore!=tmTickAfter) break;
|
||||
Sleep(1000*iTry);
|
||||
}
|
||||
// report fatal
|
||||
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)
|
||||
{
|
||||
// !!! FIXME : abstract this.
|
||||
#if (!defined SINGLE_THREADED)
|
||||
#ifdef PLATFORM_WIN32
|
||||
ASSERT(_pTimer == this);
|
||||
|
||||
// destroy timer
|
||||
if (tm_bInterrupt) {
|
||||
ASSERT(tm_TimerID!=NULL);
|
||||
ASSERT(tm_TimerID);
|
||||
ULONG rval = timeKillEvent(tm_TimerID);
|
||||
ASSERT(rval == TIMERR_NOERROR);
|
||||
}
|
||||
// check that all handlers have been removed
|
||||
ASSERT(tm_lhHooks.IsEmpty());
|
||||
|
||||
#else
|
||||
SDL_SetTimer(0, NULL);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// clear global pointer
|
||||
_pTimer = NULL;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -315,6 +481,13 @@ void CTimer::HandleTimerHandlers(void)
|
|||
CTimer_TimerFunc_internal();
|
||||
}
|
||||
|
||||
/*
|
||||
* Get current timer value of high precision timer.
|
||||
*/
|
||||
CTimerValue CTimer::GetHighPrecisionTimer(void)
|
||||
{
|
||||
return ReadTSC();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the real time tick value.
|
||||
|
@ -377,7 +550,7 @@ void CTimer::DisableLerp(void)
|
|||
CTString TimeToString(FLOAT fTime)
|
||||
{
|
||||
CTString strTime;
|
||||
int iSec = floor(fTime);
|
||||
int iSec = (int) floor(fTime);
|
||||
int iMin = iSec/60;
|
||||
iSec = iSec%60;
|
||||
int iHou = iMin/60;
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
inline CTimerValue(__int64 llValue) : tv_llValue(llValue) {};
|
||||
public:
|
||||
/* Constructor. */
|
||||
inline CTimerValue(void) {};
|
||||
inline CTimerValue(void) : tv_llValue((__int64) -1) {}
|
||||
/* Constructor from seconds. */
|
||||
inline CTimerValue(double dSeconds);
|
||||
/* Clear timer value (set it to zero). */
|
||||
|
@ -118,13 +118,20 @@ public:
|
|||
inline FLOAT GetLerpFactor2(void) const { return tm_fLerpFactor2; };
|
||||
|
||||
/* Get current timer value of high precision timer. */
|
||||
inline CTimerValue GetHighPrecisionTimer(void) {
|
||||
__int64 mmRet;
|
||||
_asm rdtsc
|
||||
_asm mov dword ptr [mmRet+0],eax
|
||||
_asm mov dword ptr [mmRet+4],edx
|
||||
return mmRet;
|
||||
};
|
||||
CTimerValue GetHighPrecisionTimer(void);
|
||||
|
||||
/*
|
||||
* rcg10072001
|
||||
* put current process to sleep for at least (milliseconds) milliseconds.
|
||||
* 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
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
/* Constructor from seconds. */
|
||||
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). */
|
||||
inline void CTimerValue::Clear(void)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/CTString.h>
|
||||
#include <Engine/Base/Translation.h>
|
||||
|
|
|
@ -6,12 +6,16 @@
|
|||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define __MSVC_INLINE__
|
||||
#endif
|
||||
|
||||
#include <Engine/Base/Base.h>
|
||||
#include <Engine/Graphics/gl_types.h>
|
||||
|
||||
typedef signed long int SLONG;
|
||||
typedef signed short int SWORD;
|
||||
typedef signed char SBYTE;
|
||||
typedef signed char SBYTE;
|
||||
typedef signed int SINT;
|
||||
|
||||
typedef unsigned long int ULONG;
|
||||
|
@ -20,27 +24,194 @@ typedef unsigned char UBYTE;
|
|||
typedef unsigned int UINT;
|
||||
|
||||
|
||||
#ifdef PLATFORM_UNIX /* rcg10042001 */
|
||||
#define __forceinline inline
|
||||
#if __POWERPC__ /* rcg03232004 */
|
||||
#define PLATFORM_BIGENDIAN 1
|
||||
#define PLATFORM_LITTLEENDIAN 0
|
||||
#else
|
||||
#define PLATFORM_BIGENDIAN 0
|
||||
#define PLATFORM_LITTLEENDIAN 1
|
||||
#endif
|
||||
|
||||
#if (!defined MAX_PATH)
|
||||
#define MAX_PATH 256
|
||||
// Mac symbols have an underscore prepended...
|
||||
#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
|
||||
|
||||
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 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 *HINSTANCE; /* !!! FIXME this sucks. */
|
||||
typedef void *HGLRC; /* !!! FIXME this sucks. */
|
||||
typedef void *HGLOBAL; /* !!! FIXME this sucks. */
|
||||
typedef ULONG COLORREF; /* !!! FIXME this sucks. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LONG x;
|
||||
LONG y;
|
||||
} POINT;
|
||||
} POINT, *LPPOINT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -49,6 +220,20 @@ typedef unsigned int UINT;
|
|||
LONG right;
|
||||
LONG bottom;
|
||||
} RECT;
|
||||
|
||||
#define WAVE_FORMAT_PCM 0x0001
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SWORD wFormatTag;
|
||||
WORD nChannels;
|
||||
DWORD nSamplesPerSec;
|
||||
WORD wBitsPerSample;
|
||||
WORD nBlockAlign;
|
||||
DWORD nAvgBytesPerSec;
|
||||
WORD cbSize;
|
||||
} WAVEFORMATEX;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -93,10 +278,18 @@ typedef long int INDEX; // for indexed values and quantities
|
|||
#define ANGLE_270 (270.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) \
|
||||
( (struct structure *) ( ((UBYTE *)(ptr)) - \
|
||||
offsetof(struct structure, member)) )
|
||||
_offsetof(struct structure, member)) )
|
||||
|
||||
// standard types
|
||||
|
||||
|
@ -396,6 +589,9 @@ typedef BSPCutter<FLOAT, 3> FLOATbspcutter3D;
|
|||
template<class cType>
|
||||
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
|
||||
inline void Clear(signed long int sli) {};
|
||||
inline void Clear(unsigned long int uli) {};
|
||||
|
@ -404,7 +600,101 @@ inline void Clear(float i) {};
|
|||
inline void Clear(double i) {};
|
||||
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. */
|
||||
|
||||
|
|
122
Sources/Engine/Base/Unix/UnixDynamicLoader.cpp
Normal file
122
Sources/Engine/Base/Unix/UnixDynamicLoader.cpp
Normal 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 ...
|
||||
|
||||
|
345
Sources/Engine/Base/Unix/UnixFileSystem.cpp
Normal file
345
Sources/Engine/Base/Unix/UnixFileSystem.cpp
Normal 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 ...
|
||||
|
||||
|
||||
|
156
Sources/Engine/Base/Unix/UnixSynchronization.cpp
Normal file
156
Sources/Engine/Base/Unix/UnixSynchronization.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// 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/FileName.h>
|
||||
#include <Engine/Base/Translation.h>
|
||||
|
@ -83,7 +83,7 @@ struct EndOfDir {
|
|||
SWORD eod_swEntriesInDir;
|
||||
SLONG eod_slSizeOfDir;
|
||||
SLONG eod_slDirOffsetInFile;
|
||||
SWORD eod_swCommentLenght;
|
||||
SWORD eod_swCommentLength;
|
||||
// follows:
|
||||
// zipfile comment (variable size)
|
||||
};
|
||||
|
@ -180,9 +180,11 @@ void CZipHandle::Clear(void)
|
|||
void CZipHandle::ThrowZLIBError_t(int ierr, const CTString &strDescription)
|
||||
{
|
||||
ThrowF_t(TRANS("(%s/%s) %s - ZLIB error: %s - %s"),
|
||||
(const CTString&)*zh_zeEntry.ze_pfnmArchive,
|
||||
(const CTString&)zh_zeEntry.ze_fnm,
|
||||
strDescription, GetZlibError(ierr), zh_zstream.msg);
|
||||
(const char *) (const CTString&)*zh_zeEntry.ze_pfnmArchive,
|
||||
(const char *) (const CTString&)zh_zeEntry.ze_fnm,
|
||||
(const char *) strDescription,
|
||||
(const char *) GetZlibError(ierr),
|
||||
(const char *) zh_zstream.msg);
|
||||
}
|
||||
|
||||
// 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
|
||||
void ReadZIPDirectory_t(CTFileName *pfnmZip)
|
||||
{
|
||||
|
||||
FILE *f = fopen(*pfnmZip, "rb");
|
||||
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
|
||||
fseek(f, 0, SEEK_END);
|
||||
|
@ -226,22 +230,30 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
|
|||
for(; iPos>iMinPos; iPos--) {
|
||||
// read signature
|
||||
fseek(f, iPos, SEEK_SET);
|
||||
int slSig;
|
||||
SLONG slSig;
|
||||
fread(&slSig, sizeof(slSig), 1, f);
|
||||
BYTESWAP(slSig);
|
||||
// if this is the sig
|
||||
if (slSig==SIGNATURE_EOD) {
|
||||
// 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 (eod.eod_swDiskNo!=0||eod.eod_swDirStartDiskNo!=0
|
||||
||eod.eod_swEntriesInDirOnThisDisk!=eod.eod_swEntriesInDir) {
|
||||
// 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
|
||||
if (eod.eod_swEntriesInDir<=0) {
|
||||
// fail
|
||||
ThrowF_t(TRANS("%s: Empty zip"), (CTString&)*pfnmZip);
|
||||
ThrowF_t(TRANS("%s: Empty zip"), (const char *) (CTString&)*pfnmZip);
|
||||
}
|
||||
// all ok
|
||||
bEODFound = TRUE;
|
||||
|
@ -251,7 +263,7 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
|
|||
// if eod not found
|
||||
if (!bEODFound) {
|
||||
// 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
|
||||
|
@ -265,26 +277,44 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
|
|||
// for each file
|
||||
for (INDEX iFile=0; iFile<eod.eod_swEntriesInDir; iFile++) {
|
||||
// read the sig
|
||||
int slSig;
|
||||
SLONG slSig;
|
||||
fread(&slSig, sizeof(slSig), 1, f);
|
||||
BYTESWAP(slSig);
|
||||
|
||||
// if this is not the expected sig
|
||||
if (slSig!=SIGNATURE_FH) {
|
||||
// fail
|
||||
ThrowF_t(TRANS("%s: Wrong signature for 'file header' number %d'"),
|
||||
(CTString&)*pfnmZip, iFile);
|
||||
(const char *) (CTString&)*pfnmZip, iFile);
|
||||
}
|
||||
// read its header
|
||||
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
|
||||
const SLONG slMaxFileName = 512;
|
||||
char strBuffer[slMaxFileName+1];
|
||||
memset(strBuffer, 0, sizeof(strBuffer));
|
||||
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) {
|
||||
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);
|
||||
|
||||
|
@ -299,7 +329,7 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
|
|||
if (fh.fh_slUncompressedSize!=0
|
||||
||fh.fh_slCompressedSize!=0) {
|
||||
ThrowF_t(TRANS("%s/%s: Invalid directory"),
|
||||
(CTString&)*pfnmZip, strBuffer);
|
||||
(const char *) (CTString&)*pfnmZip, strBuffer);
|
||||
}
|
||||
|
||||
// if the file is real file
|
||||
|
@ -324,7 +354,8 @@ void ReadZIPDirectory_t(CTFileName *pfnmZip)
|
|||
ze.ze_bStored = FALSE;
|
||||
} else {
|
||||
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 (ferror(f)) {
|
||||
// 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
|
||||
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
|
||||
|
@ -449,7 +480,7 @@ void UNZIPReadDirectoriesReverse_t(void)
|
|||
// if there were errors
|
||||
if (strAllErrors!="") {
|
||||
// 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 (pze==NULL) {
|
||||
// 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
|
||||
BOOL bHandleFound = FALSE;
|
||||
INDEX iHandle=1;
|
||||
for (; iHandle<_azhHandles.Count(); iHandle++) {
|
||||
INDEX iHandle;
|
||||
for (iHandle=1; iHandle<_azhHandles.Count(); iHandle++) {
|
||||
// if unused
|
||||
if (!_azhHandles[iHandle].zh_bOpen) {
|
||||
// use that one
|
||||
|
@ -570,23 +601,34 @@ INDEX UNZIPOpen_t(const CTFileName &fnm)
|
|||
// clear the handle
|
||||
zh.Clear();
|
||||
// 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));
|
||||
}
|
||||
// seek to the local header of the entry
|
||||
fseek(zh.zh_fFile, zh.zh_zeEntry.ze_slDataOffset, SEEK_SET);
|
||||
// read the sig
|
||||
int slSig;
|
||||
SLONG slSig;
|
||||
fread(&slSig, sizeof(slSig), 1, zh.zh_fFile);
|
||||
BYTESWAP(slSig);
|
||||
// if this is not the expected sig
|
||||
if (slSig!=SIGNATURE_LFH) {
|
||||
// fail
|
||||
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
|
||||
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
|
||||
zh.zh_zeEntry.ze_slDataOffset =
|
||||
ftell(zh.zh_fFile)+lfh.lfh_swFileNameLen+lfh.lfh_swExtraFieldLen;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Updateable.h>
|
||||
#include <Engine/Base/UpdateableRT.h>
|
||||
|
|
89
Sources/Engine/Base/Win32/Win32DynamicLoader.cpp
Normal file
89
Sources/Engine/Base/Win32/Win32DynamicLoader.cpp
Normal 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 ...
|
||||
|
||||
|
121
Sources/Engine/Base/Win32/Win32FileSystem.cpp
Normal file
121
Sources/Engine/Base/Win32/Win32FileSystem.cpp
Normal 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 ...
|
||||
|
||||
|
986
Sources/Engine/Base/Win32/Win32Input.cpp
Normal file
986
Sources/Engine/Base/Win32/Win32Input.cpp
Normal 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 ...
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "StdH.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Synchronization.h>
|
||||
|
||||
|
@ -303,3 +303,4 @@ void CTSingleLock::Unlock(void)
|
|||
}
|
||||
sl_bLocked = FALSE;
|
||||
}
|
||||
|
15
Sources/Engine/Base/Win32/Win32Timer.cpp
Normal file
15
Sources/Engine/Base/Win32/Win32Timer.cpp
Normal 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 ...
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Brushes/Brush.h>
|
||||
#include <Engine/World/World.h>
|
||||
|
|
|
@ -254,16 +254,30 @@ public:
|
|||
CMappingDefinition bpt_mdMapping; // mapping of texture on polygon
|
||||
|
||||
union {
|
||||
struct {
|
||||
UBYTE bpt_ubScroll; // texture scroll
|
||||
UBYTE bpt_ubBlend; // type of texture blending used
|
||||
UBYTE bpt_ubFlags; // additional flags
|
||||
UBYTE bpt_ubDummy; // unused (alignment)
|
||||
COLOR bpt_colColor; // defines constant color and alpha of polygon
|
||||
} s;
|
||||
struct {
|
||||
UBYTE bpt_ubScroll; // texture scroll
|
||||
UBYTE bpt_ubBlend; // type of texture blending used
|
||||
UBYTE bpt_ubFlags; // additional flags
|
||||
UBYTE bpt_ubDummy; // unused (alignment)
|
||||
COLOR bpt_colColor; // defines constant color and alpha of polygon
|
||||
} s;
|
||||
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)
|
||||
{
|
||||
s.bpt_ubScroll = 0;
|
||||
|
@ -347,8 +361,29 @@ struct CBrushPolygonProperties {
|
|||
UWORD bpp_uwPretenderDistance; // distance for pretender switching [m]
|
||||
/* Default constructor. */
|
||||
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 {
|
||||
public:
|
||||
// implementation:
|
||||
|
@ -433,13 +468,12 @@ public:
|
|||
SLONG GetUsedMemory(void);
|
||||
};
|
||||
|
||||
|
||||
// get pointer to embedding brush polygon
|
||||
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
|
||||
typedef CSelection<CBrushPolygon, BPOF_SELECTED> CBrushPolygonSelection;
|
||||
// selection of brush polygons used for CSG
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Brushes/Brush.h>
|
||||
#include <Engine/Brushes/BrushArchive.h>
|
||||
|
@ -17,10 +17,15 @@
|
|||
#include <Engine/Templates/DynamicArray.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>;
|
||||
#endif
|
||||
|
||||
extern BOOL _bPortalSectorLinksPreLoaded = FALSE;
|
||||
extern BOOL _bEntitySectorLinksPreLoaded = FALSE;
|
||||
BOOL _bPortalSectorLinksPreLoaded = FALSE;
|
||||
BOOL _bEntitySectorLinksPreLoaded = FALSE;
|
||||
|
||||
/*
|
||||
* Calculate bounding boxes in all brushes.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Brushes/Brush.h>
|
||||
#include <Engine/World/WorldEditingProfile.h>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Stream.h>
|
||||
#include <Engine/Base/ReplaceFile.h>
|
||||
|
@ -223,7 +223,7 @@ void CBrushPolygonTexture::Read_t( CTStream &strm) // throw char *
|
|||
if (bpt_toTexture.GetData()!=NULL) {
|
||||
bpt_toTexture.GetData()->AddToCRCTable();
|
||||
}
|
||||
strm.Read_t(&bpt_mdMapping, sizeof(bpt_mdMapping));
|
||||
strm>>bpt_mdMapping;
|
||||
strm>>s.bpt_ubScroll;
|
||||
strm>>s.bpt_ubBlend;
|
||||
strm>>s.bpt_ubFlags;
|
||||
|
@ -402,7 +402,7 @@ void CBrushSector::Read_t( CTStream *pistrm) // throw char *
|
|||
// for each vertex
|
||||
{FOREACHINSTATICARRAY(bsc_abvxVertices, CBrushVertex, itbvx) {
|
||||
// read precise vertex coordinates
|
||||
pistrm->Read_t(&itbvx->bvx_vdPreciseRelative, sizeof(DOUBLE3D));
|
||||
(*pistrm)>>itbvx->bvx_vdPreciseRelative;
|
||||
// remember sector pointer
|
||||
itbvx->bvx_pbscSector = this;
|
||||
}}
|
||||
|
@ -417,7 +417,7 @@ void CBrushSector::Read_t( CTStream *pistrm) // throw char *
|
|||
// for each plane
|
||||
{FOREACHINSTATICARRAY(bsc_abplPlanes, CBrushPlane, itbpl) {
|
||||
// read precise plane coordinates
|
||||
pistrm->Read_t(&itbpl->bpl_pldPreciseRelative, sizeof(DOUBLEplane3D));
|
||||
(*pistrm)>>itbpl->bpl_pldPreciseRelative;
|
||||
}}
|
||||
|
||||
(*pistrm).ExpectID_t("EDGs"); // 'edges'
|
||||
|
@ -478,7 +478,7 @@ void CBrushSector::Read_t( CTStream *pistrm) // throw char *
|
|||
bpo.bpo_abptTextures[2].Read_t(*pistrm);
|
||||
|
||||
// read other polygon properties
|
||||
(*pistrm).Read_t(&bpo.bpo_bppProperties, sizeof(bpo.bpo_bppProperties));
|
||||
(*pistrm)>>bpo.bpo_bppProperties;
|
||||
|
||||
} else {
|
||||
// read textures
|
||||
|
@ -495,7 +495,7 @@ void CBrushSector::Read_t( CTStream *pistrm) // throw char *
|
|||
// read texture mapping
|
||||
bpo.bpo_mdShadow.ReadOld_t(*pistrm);
|
||||
// read other polygon properties
|
||||
(*pistrm).Read_t(&bpo.bpo_bppProperties, sizeof(bpo.bpo_bppProperties));
|
||||
(*pistrm)>>bpo.bpo_bppProperties;
|
||||
|
||||
// adjust polygon and texture properties
|
||||
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);
|
||||
// read all element indices
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Brushes/Brush.h>
|
||||
#include <Engine/Math/Float.h>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Brushes/Brush.h>
|
||||
#include <Engine/World/World.h>
|
||||
|
@ -16,7 +16,7 @@
|
|||
#include <Engine/Templates/StaticArray.cpp>
|
||||
#include <Engine/Templates/Selection.cpp>
|
||||
|
||||
template CDynamicArray<CBrushSector>;
|
||||
template class CDynamicArray<CBrushSector>;
|
||||
|
||||
// tolerance value for csg selection
|
||||
#define CSG_RANGE_EPSILON (0.25f)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Brushes/Brush.h>
|
||||
#include <Engine/Brushes/BrushTransformed.h>
|
||||
|
@ -13,9 +13,9 @@
|
|||
#include <Engine/Entities/Entity.h>
|
||||
#include <Engine/Templates/Selection.cpp>
|
||||
|
||||
template CStaticArray<CBrushPolygonEdge>;
|
||||
template CStaticArray<CBrushPolygon>;
|
||||
template CStaticArray<long>;
|
||||
template class CStaticArray<CBrushPolygonEdge>;
|
||||
template class CStaticArray<CBrushPolygon>;
|
||||
template class CStaticArray<long>;
|
||||
|
||||
// set new absolute position for the vertex
|
||||
void CBrushVertex::SetAbsolutePosition(const DOUBLE3D &vAbsolute)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Brushes/Brush.h>
|
||||
#include <Engine/Brushes/BrushTransformed.h>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
|
||||
#include <Engine/StdH.h>
|
||||
#include <Engine/Brushes/Brush.h>
|
||||
#include <Engine/Brushes/BrushTransformed.h>
|
||||
#include <Engine/Brushes/BrushArchive.h>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Brushes/Brush.h>
|
||||
#include <Engine/Templates/DynamicArray.cpp>
|
||||
|
@ -578,6 +578,7 @@ void CTriangularizer::DPrintF(char *strFormat, ...)
|
|||
va_list arg;
|
||||
va_start(arg, strFormat);
|
||||
vsprintf(strBuffer, strFormat, arg);
|
||||
va_end(arg);
|
||||
|
||||
// if the debug output file is not open
|
||||
if (!_bDebugOutputOpen) {
|
||||
|
@ -717,7 +718,7 @@ void CTriangularizer::FindBestTriangle(void)
|
|||
|
||||
#if 0
|
||||
// if no acceptable triangles have been found
|
||||
if (tr_fQualityBest<???) {
|
||||
if (tr_fQualityBest</*???*/sdfsdfd) {
|
||||
/* dump all sector's vertices */
|
||||
/*
|
||||
FOREACHINSTATICARRAY(tr_bpoOriginalPolygon.bpo_pbscSector->bsc_abvxVertices,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
5
|
||||
%{
|
||||
#include "StdH.h"
|
||||
#include <Engine/StdH.h>
|
||||
#define DECL_DLL ENGINE_API
|
||||
#include <Engine/Entities/EntityEvent.h>
|
||||
#include <Engine/Entities/EntityPointer.h>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
3
|
||||
%{
|
||||
#include "StdH.h"
|
||||
#include <Engine/StdH.h>
|
||||
#include <Engine/Entities/InternalClasses.h>
|
||||
%}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
1
|
||||
%{
|
||||
#include "StdH.h"
|
||||
#include <Engine/StdH.h>
|
||||
#include <Engine/Entities/InternalClasses.h>
|
||||
#include <Engine/World/PhysicsProfile.h>
|
||||
#include <Engine/Math/Geometry.inl>
|
||||
|
@ -36,7 +36,7 @@
|
|||
%{
|
||||
|
||||
#define ANYEXCEPTION ...
|
||||
template CStaticStackArray<CBrushPolygon*>;
|
||||
template class CStaticStackArray<CBrushPolygon*>;
|
||||
|
||||
#define MAXCOLLISIONRETRIES 4*4
|
||||
extern FLOAT phy_fCollisionCacheAhead;
|
||||
|
@ -1107,12 +1107,12 @@ functions:
|
|||
|
||||
BOOL IsStandingOnPolygon(CBrushPolygon *pbpo)
|
||||
{
|
||||
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
// if cannot optimize for standing on handle
|
||||
if (en_pciCollisionInfo==NULL
|
||||
||!(en_pciCollisionInfo->ci_ulFlags&CIF_CANSTANDONHANDLE)) {
|
||||
// not standing on polygon
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1133,7 +1133,7 @@ functions:
|
|||
// if handle is not on the plane
|
||||
if (plPolygon.PointDistance(vHandle)>0.01f) {
|
||||
// not standing on polygon
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1157,12 +1157,12 @@ functions:
|
|||
// if the point is inside polygon
|
||||
if (isIntersector.IsIntersecting()) {
|
||||
// entity is standing on polygon
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return TRUE;
|
||||
// if the point is outside polygon
|
||||
} else {
|
||||
// entity is not standing on polygon
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1170,13 +1170,13 @@ functions:
|
|||
// check whether a polygon is below given point, but not too far away
|
||||
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 ((pbpo->bpo_ulFlags&BPOF_PASSABLE)
|
||||
||!AllowForGroundPolygon(pbpo)) {
|
||||
// it cannot be below
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1188,7 +1188,7 @@ functions:
|
|||
// if polygon is vertical or upside down
|
||||
if (fCos>-0.01f) {
|
||||
// it cannot be below
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1197,7 +1197,7 @@ functions:
|
|||
if (fCos>=-stReference.st_fClimbSlopeCos&&fCos<0
|
||||
||stReference.st_ulFlags&STF_SLIDEDOWNSLOPE) {
|
||||
// it cannot be below
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1206,7 +1206,7 @@ functions:
|
|||
// if the point is behind the plane
|
||||
if (fD<-0.01f) {
|
||||
// it cannot be below
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1215,7 +1215,7 @@ functions:
|
|||
// if too far away
|
||||
if (fDistance > fMaxDist) {
|
||||
// it cannot be below
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return FALSE;
|
||||
}
|
||||
// project point to the polygon along gravity vector
|
||||
|
@ -1241,12 +1241,12 @@ functions:
|
|||
// if the point is inside polygon
|
||||
if (isIntersector.IsIntersecting()) {
|
||||
// it is below
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return TRUE;
|
||||
// if the point is outside polygon
|
||||
} else {
|
||||
// it is not below
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_ISSTANDINGONPOLYGON);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1399,9 +1399,9 @@ out:;
|
|||
// set current placement from next position
|
||||
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;
|
||||
plNew.pl_PositionVector = en_vNextPosition;
|
||||
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 bHitStairsOrg)
|
||||
{
|
||||
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
|
||||
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
|
||||
_pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
|
||||
_pfPhysicsProfile.IncrementTimerAveragingCounter((INDEX) CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
|
||||
|
||||
// use only horizontal components of the movement
|
||||
FLOAT3D vTranslationHorizontal;
|
||||
|
@ -1439,7 +1439,7 @@ out:;
|
|||
if(vTranslationHorizontal.Length()<0.001f) {
|
||||
//CPrintF("no value\n");
|
||||
// don't do it
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
|
||||
return FALSE;
|
||||
}
|
||||
FLOAT3D vTranslationHorizontalOrg = vTranslationHorizontal;
|
||||
|
@ -1557,7 +1557,7 @@ out:;
|
|||
en_vNextPosition = plOriginal.pl_PositionVector;
|
||||
SetPlacementFromNextPosition();
|
||||
// move is unsuccessful
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
|
||||
//CPrintF("FAILED\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1572,7 +1572,7 @@ out:;
|
|||
en_vAppliedTranslation += vTranslationHorizontalOrg;
|
||||
}
|
||||
// move is successful
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOGOUPSTAIRS);
|
||||
//CPrintF("done\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1592,9 +1592,9 @@ out:;
|
|||
// fail the move
|
||||
return FALSE;
|
||||
}
|
||||
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_TRYTOMOVE);
|
||||
_pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.IncrementTimerAveragingCounter((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_TRYTOMOVE);
|
||||
|
||||
// create new placement with movement
|
||||
if (bTranslate) {
|
||||
|
@ -1637,7 +1637,7 @@ out:;
|
|||
// clip the movement to the entity's world
|
||||
if (!bTranslate && bIgnoreRotation) {
|
||||
cmMove.cm_fMovementFraction = 2.0f;
|
||||
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_TRYTOMOVE_FAST);
|
||||
_pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_TRYTOMOVE_FAST);
|
||||
} else {
|
||||
en_pwoWorld->ClipMove(cmMove);
|
||||
}
|
||||
|
@ -1665,14 +1665,14 @@ out:;
|
|||
en_mAppliedRotation = en_mMoveRotation*en_mAppliedRotation;
|
||||
}
|
||||
// move is successful
|
||||
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_TRYTOMOVE_PASS);
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_TRYTOMOVE_PASS);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
//CPrintF(" successful\n");
|
||||
return TRUE;
|
||||
|
||||
// if the move is clipped
|
||||
} else {
|
||||
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_TRYTOMOVE_CLIP);
|
||||
_pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_TRYTOMOVE_CLIP);
|
||||
|
||||
/* STREAMDUMP START
|
||||
if(GetRenderType()==RT_MODEL)
|
||||
|
@ -1694,7 +1694,7 @@ out:;
|
|||
// if must not retry
|
||||
if (_ctTryToMoveCheckCounter<=0) {
|
||||
// fail
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1781,20 +1781,20 @@ out:;
|
|||
// make sure it is added to the movers list
|
||||
penBlocking->AddToMoversDuringMoving();
|
||||
// push the blocking entity
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
BOOL bUnblocked = penBlocking->TryToMove(penPusher, bTranslate, bRotate);
|
||||
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
// if it has removed itself
|
||||
if (bUnblocked) {
|
||||
// retry the movement
|
||||
ClearNextPosition();
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
return TryToMove(penPusher, bTranslate, bRotate);
|
||||
} else {
|
||||
// move is unsuccessful
|
||||
SendBlockEvent(cmMove);
|
||||
ClearNextPosition();
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
return FALSE;
|
||||
}
|
||||
// if entity slides if blocked
|
||||
|
@ -1849,7 +1849,7 @@ out:;
|
|||
if (cmMove.cm_pbpoHit!=NULL) {
|
||||
CSurfaceType &stHit = en_pwoWorld->wo_astSurfaceTypes[
|
||||
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
|
||||
&&(en_ulPhysicsFlags&EPF_ONBLOCK_MASK)==EPF_ONBLOCK_CLIMBORSLIDE) {
|
||||
// NOTE: originally, the polygon's plane was considered here.
|
||||
|
@ -1874,7 +1874,7 @@ out:;
|
|||
// if can go upstairs
|
||||
&& TryToGoUpstairs(en_vMoveTranslation, stHit, bHitStairs)) {
|
||||
// movement is ok
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1895,19 +1895,19 @@ out:;
|
|||
// if initial movement has some substantial value
|
||||
if(en_vMoveTranslation.Length()>0.001f && cmMove.cm_fMovementFraction>0.002f) {
|
||||
// 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
|
||||
if (vSliding.ManhattanNorm()<0.001f) {
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// recurse
|
||||
en_vMoveTranslation = vSliding;
|
||||
ClearNextPosition();
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
TryToMove(penPusher, bTranslate, bRotate);
|
||||
// if bouncer
|
||||
if (bBounce) {
|
||||
|
@ -1931,7 +1931,7 @@ out:;
|
|||
if (en_aDesiredRotationRelative.Length()<10) {
|
||||
en_aDesiredRotationRelative = ANGLE3D(0,0,0);
|
||||
}
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
// move is not successful
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1939,13 +1939,13 @@ out:;
|
|||
en_vMoveTranslation = cmMove.cm_vClippedLine*-1.2f;
|
||||
// recurse
|
||||
ClearNextPosition();
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
TryToMove(penPusher, TRUE, bRotate);
|
||||
// move is not entirely successful
|
||||
return FALSE;
|
||||
}
|
||||
// not translating and not rotating? - move is unsuccessful
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
return FALSE;
|
||||
|
||||
// if entity has some other behaviour when blocked
|
||||
|
@ -1953,7 +1953,7 @@ out:;
|
|||
// move is unsuccessful (EPF_ONBLOCK_STOP is assumed)
|
||||
SendBlockEvent(cmMove);
|
||||
ClearNextPosition();
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_TRYTOTRANSLATE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -2019,8 +2019,8 @@ out:;
|
|||
ExportEntityPlacementAndSpeed( *(CMovableEntity *)this, "Pre moving (start of function)");
|
||||
STREAMDUMP END */
|
||||
|
||||
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_PREMOVING);
|
||||
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_PREMOVING);
|
||||
_pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_PREMOVING);
|
||||
_pfPhysicsProfile.IncrementTimerAveragingCounter((INDEX) CPhysicsProfile::PTI_PREMOVING);
|
||||
|
||||
// remember old placement for lerping
|
||||
en_plLastPlacement = en_plPlacement;
|
||||
|
@ -2260,7 +2260,7 @@ out:;
|
|||
|
||||
// if gravity can cause the entity to fall
|
||||
if (!bGravityAlongPolygon) {
|
||||
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_GRAVITY_NONTRIVIAL);
|
||||
_pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_GRAVITY_NONTRIVIAL);
|
||||
|
||||
// add gravity acceleration
|
||||
FLOAT fGV=en_fGravityV*fTickQuantum*fSpeedModifier;
|
||||
|
@ -2268,7 +2268,7 @@ out:;
|
|||
AddGAcceleration(vTranslationAbsolute, en_vGravityDir, fGA, fGV);
|
||||
// if entity can only slide down its stand-on polygon
|
||||
} else {
|
||||
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_GRAVITY_TRIVIAL);
|
||||
_pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_GRAVITY_TRIVIAL);
|
||||
|
||||
// disassemble gravity to parts parallel and normal to plane
|
||||
FLOAT3D vPolygonDir = -en_vReferencePlane;
|
||||
|
@ -2419,7 +2419,7 @@ out:;
|
|||
// clear applied movement to be updated during movement
|
||||
en_vAppliedTranslation = FLOAT3D(0.0f, 0.0f, 0.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)");
|
||||
}
|
||||
|
||||
|
@ -2845,16 +2845,16 @@ out:;
|
|||
}
|
||||
// STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Do moving (start of function)");
|
||||
|
||||
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_DOMOVING);
|
||||
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_DOMOVING);
|
||||
_pfPhysicsProfile.StartTimer((INDEX) 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
|
||||
|
||||
// if rotation and translation are 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
|
||||
en_vMoveTranslation = en_vIntendedTranslation-en_vAppliedTranslation;
|
||||
|
@ -2870,11 +2870,11 @@ out:;
|
|||
// if rotation and translation are asynchronious
|
||||
} else {
|
||||
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 (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
|
||||
en_vMoveTranslation = en_vIntendedTranslation-en_vAppliedTranslation;
|
||||
|
@ -2885,14 +2885,14 @@ out:;
|
|||
// if it passes
|
||||
if (bMoveSuccessfull) {
|
||||
// finish
|
||||
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_DOMOVING_ASYNC_SYNCPASS);
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_DOMOVING);
|
||||
_pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_DOMOVING_ASYNC_SYNCPASS);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_DOMOVING);
|
||||
// STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Do moving (return: if it passes)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_pfPhysicsProfile.IncrementCounter(CPhysicsProfile::PCI_DOMOVING_ASYNC_TRANSLATE);
|
||||
_pfPhysicsProfile.IncrementCounter((INDEX) CPhysicsProfile::PCI_DOMOVING_ASYNC_TRANSLATE);
|
||||
// translate
|
||||
en_vMoveTranslation = en_vIntendedTranslation-en_vAppliedTranslation;
|
||||
InitTryToMove();
|
||||
|
@ -2904,13 +2904,13 @@ out:;
|
|||
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(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();
|
||||
TryToMove(NULL, FALSE, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
_pfPhysicsProfile.StopTimer(CPhysicsProfile::PTI_DOMOVING);
|
||||
_pfPhysicsProfile.StopTimer((INDEX) CPhysicsProfile::PTI_DOMOVING);
|
||||
// STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Do moving (end of function)");
|
||||
}
|
||||
|
||||
|
@ -2930,8 +2930,8 @@ out:;
|
|||
|
||||
// STREAMDUMP ExportEntityPlacementAndSpeed(*(CMovableEntity *)this, "Post moving (start of function)");
|
||||
|
||||
_pfPhysicsProfile.StartTimer(CPhysicsProfile::PTI_POSTMOVING);
|
||||
_pfPhysicsProfile.IncrementTimerAveragingCounter(CPhysicsProfile::PTI_POSTMOVING);
|
||||
_pfPhysicsProfile.StartTimer((INDEX) CPhysicsProfile::PTI_POSTMOVING);
|
||||
_pfPhysicsProfile.IncrementTimerAveragingCounter((INDEX) CPhysicsProfile::PTI_POSTMOVING);
|
||||
|
||||
// remember valid reference if valid
|
||||
if (en_penReference!=NULL) {
|
||||
|
@ -3074,7 +3074,7 @@ out:;
|
|||
}
|
||||
|
||||
//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)");
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
2
|
||||
%{
|
||||
#include "StdH.h"
|
||||
#include <Engine/StdH.h>
|
||||
#include <Engine/Entities/InternalClasses.h>
|
||||
#include <Engine/Base/CRC.h>
|
||||
#include <Engine/Base/Stream.h>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
4
|
||||
%{
|
||||
#include "StdH.h"
|
||||
#include <Engine/StdH.h>
|
||||
#include <Engine/Entities/InternalClasses.h>
|
||||
#include <Engine/Base/Stream.h>
|
||||
#include <Engine/Base/CRC.h>
|
||||
|
@ -40,7 +40,9 @@ functions:
|
|||
if (IsPredictor()) {
|
||||
penMe = GetPredicted();
|
||||
}
|
||||
for (INDEX iPlayer=0; iPlayer<GetMaxPlayers(); iPlayer++) {
|
||||
|
||||
INDEX iPlayer;
|
||||
for (iPlayer=0; iPlayer<GetMaxPlayers(); iPlayer++) {
|
||||
// if this is ME (this)
|
||||
if (GetPlayerEntity(iPlayer)==penMe) {
|
||||
return iPlayer;
|
||||
|
@ -111,7 +113,7 @@ functions:
|
|||
{
|
||||
CMovableModelEntity::DumpSync_t(strm, iExtensiveSyncCheck);
|
||||
strm.FPrintF_t("player: %s\n",
|
||||
en_pcCharacter.GetName());
|
||||
(const char *) en_pcCharacter.GetName());
|
||||
strm.FPrintF_t("GUID: ");
|
||||
{for (INDEX i=0; i<sizeof(en_pcCharacter.pc_aubGUID); i++) {
|
||||
strm.FPrintF_t("%02X", en_pcCharacter.pc_aubGUID[i]);
|
||||
|
|
|
@ -13,12 +13,13 @@
|
|||
#include <Engine/Base/CRC.h>
|
||||
#include <Engine/Base/CRCTable.h>
|
||||
#include <Engine/Base/ProgressHook.h>
|
||||
#include <Engine/Base/FileSystem.h>
|
||||
#include <Engine/Sound/SoundListener.h>
|
||||
#include <Engine/Sound/SoundLibrary.h>
|
||||
#include <Engine/Graphics/GfxLibrary.h>
|
||||
#include <Engine/Graphics/Font.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_CTextureData.h>
|
||||
#include <Engine/Templates/Stock_CSoundData.h>
|
||||
|
@ -31,6 +32,10 @@
|
|||
#include <Engine/Templates/StaticArray.cpp>
|
||||
#include <Engine/Base/IFeel.h>
|
||||
|
||||
#if (defined PLATFORM_MACOSX)
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
// this version string can be referenced from outside the engine
|
||||
ENGINE_API CTString _strEngineBuild = "";
|
||||
ENGINE_API ULONG _ulEngineBuildMajor = _SE_BUILD_MAJOR;
|
||||
|
@ -40,12 +45,13 @@ ENGINE_API BOOL _bDedicatedServer = FALSE;
|
|||
ENGINE_API BOOL _bWorldEditorApp = FALSE;
|
||||
ENGINE_API CTString _strLogFile = "";
|
||||
|
||||
// global handle for application window
|
||||
extern HWND _hwndMain = NULL;
|
||||
extern BOOL _bFullScreen = FALSE;
|
||||
// global handle for application windows
|
||||
// !!! FIXME rcg10072001 this needs to be abstracted.
|
||||
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
|
||||
static UWORD auwSystemGamma[256*3];
|
||||
|
@ -83,8 +89,10 @@ static CTString sys_strModName = "";
|
|||
static CTString sys_strModExt = "";
|
||||
|
||||
// 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
#if (defined USE_PORTABLE_C) // rcg10072001
|
||||
CPrintF(TRANS(" (No CPU detection in this binary.)\n"));
|
||||
|
||||
#else
|
||||
char strVendor[12+1];
|
||||
strVendor[12] = 0;
|
||||
ULONG ulTFMS;
|
||||
ULONG ulFeatures;
|
||||
|
||||
#if (defined __MSVC_INLINE__)
|
||||
// test MMX presence and update flag
|
||||
__asm {
|
||||
mov eax,0 ;// request for basic id
|
||||
xor eax,eax ;// request for basic id
|
||||
cpuid
|
||||
mov dword ptr [strVendor+0], ebx
|
||||
mov dword ptr [strVendor+4], edx
|
||||
|
@ -121,6 +134,43 @@ static void DetectCPU(void)
|
|||
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 iFamily = (ulTFMS>> 8)&0xF;
|
||||
INDEX iModel = (ulTFMS>> 4)&0xF;
|
||||
|
@ -137,8 +187,8 @@ static void DetectCPU(void)
|
|||
CTString strYes = TRANS("Yes");
|
||||
CTString strNo = TRANS("No");
|
||||
|
||||
CPrintF(TRANS(" MMX : %s\n"), bMMX ?strYes:strNo);
|
||||
CPrintF(TRANS(" CMOV: %s\n"), bCMOV?strYes:strNo);
|
||||
CPrintF(TRANS(" MMX : %s\n"), (const char *) (bMMX ?strYes:strNo));
|
||||
CPrintF(TRANS(" CMOV: %s\n"), (const char *) (bCMOV?strYes:strNo));
|
||||
CPrintF(TRANS(" Clock: %.0fMHz\n"), _pTimer->tm_llCPUSpeedHZ/1E6);
|
||||
|
||||
sys_strCPUVendor = strVendor;
|
||||
|
@ -151,15 +201,27 @@ static void DetectCPU(void)
|
|||
sys_iCPUMHz = INDEX(_pTimer->tm_llCPUSpeedHZ/1E6);
|
||||
|
||||
if( !bMMX) FatalError( TRANS("MMX support required but not present!"));
|
||||
|
||||
#endif // defined USE_PORTABLE_C
|
||||
}
|
||||
|
||||
static void DetectCPUWrapper(void)
|
||||
{
|
||||
#ifdef _MSC_VER // rcg10072001
|
||||
__try {
|
||||
DetectCPU();
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
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
|
||||
|
@ -181,41 +243,80 @@ static char strDirPath[MAX_PATH] = "";
|
|||
|
||||
static void AnalyzeApplicationPath(void)
|
||||
{
|
||||
strcpy(strDirPath, "D:\\");
|
||||
strcpy(strExePath, "D:\\TestExe.xbe");
|
||||
// rcg10072001 rewritten with abstraction layer.
|
||||
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] = "";
|
||||
// get full path to the exe
|
||||
GetModuleFileNameA( NULL, strExePath, sizeof(strExePath)-1);
|
||||
// copy that to the path
|
||||
|
||||
_pFileSystem->GetExecutablePath(strExePath, sizeof (strExePath)-1);
|
||||
strncpy(strTmpPath, strExePath, sizeof(strTmpPath)-1);
|
||||
strDirPath[sizeof(strTmpPath)-1] = 0;
|
||||
// remove name from application path
|
||||
StrRev(strTmpPath);
|
||||
// find last backslash
|
||||
char *pstr = strchr( strTmpPath, '\\');
|
||||
char *pstr = strstr( strTmpPath, dirsep);
|
||||
if( pstr==NULL) {
|
||||
// not found - path is just "\"
|
||||
strcpy( strTmpPath, "\\");
|
||||
strcpy( strTmpPath, dirsep);
|
||||
pstr = strTmpPath;
|
||||
}
|
||||
// remove 'debug' from app path if needed
|
||||
if( strnicmp( pstr, "\\gubed", 6)==0) pstr += 6;
|
||||
if( pstr[0] = '\\') pstr++;
|
||||
char *pstrFin = strchr( pstr, '\\');
|
||||
if( strnicmp( pstr, (CTString(dirsep)+"gubed"), 5+seplen)==0) pstr += (5 + seplen);
|
||||
if( strncmp(pstr, dirsep, seplen) == 0) pstr += seplen;
|
||||
char *pstrFin = strstr( pstr, dirsep);
|
||||
if( pstrFin==NULL) {
|
||||
strcpy( pstr, "\\");
|
||||
strcpy( pstr, dirsep);
|
||||
pstrFin = pstr;
|
||||
}
|
||||
// copy that to the path
|
||||
StrRev(pstrFin);
|
||||
strncpy( strDirPath, pstrFin, sizeof(strDirPath)-1);
|
||||
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
|
||||
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")
|
||||
if(strGameID=="SeriousEditor") {
|
||||
_bWorldEditorApp = TRUE;
|
||||
|
@ -224,6 +325,12 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
|
|||
AnalyzeApplicationPath();
|
||||
_fnmApplicationPath = CTString(strDirPath);
|
||||
_fnmApplicationExe = CTString(strExePath);
|
||||
|
||||
// rcg01012002 calculate user dir.
|
||||
char buf[MAX_PATH];
|
||||
_pFileSystem->GetUserDirectory(buf, sizeof (buf));
|
||||
_fnmUserDir = CTString(buf);
|
||||
|
||||
try {
|
||||
_fnmApplicationExe.RemoveApplicationPath_t();
|
||||
} catch (char *strError) {
|
||||
|
@ -234,8 +341,10 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
|
|||
_pConsole = new CConsole;
|
||||
if (_strLogFile=="") {
|
||||
_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;
|
||||
_pTextureStock = new CStock_CTextureData;
|
||||
|
@ -247,6 +356,11 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
|
|||
_pAnimSetStock = new CStock_CAnimSet;
|
||||
_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;
|
||||
_pGfx = new CGfxLibrary;
|
||||
_pSound = new CSoundLibrary;
|
||||
|
@ -259,20 +373,23 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
|
|||
|
||||
// print basic engine info
|
||||
CPrintF(TRANS("--- Serious Engine Startup ---\n"));
|
||||
CPrintF(" %s\n\n", _strEngineBuild);
|
||||
CPrintF(" %s\n\n", (const char *) _strEngineBuild);
|
||||
|
||||
// print info on the started application
|
||||
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");
|
||||
|
||||
// report os info
|
||||
CPrintF(TRANS("Examining underlying OS...\n"));
|
||||
OSVERSIONINFOA osv;
|
||||
|
||||
// !!! FIXME: Abstract this somehow.
|
||||
#if (defined PLATFORM_WIN32)
|
||||
OSVERSIONINFO osv;
|
||||
memset(&osv, 0, sizeof(osv));
|
||||
osv.dwOSVersionInfoSize = sizeof(osv);
|
||||
if (GetVersionExA(&osv)) {
|
||||
if (GetVersionEx(&osv)) {
|
||||
switch (osv.dwPlatformId) {
|
||||
case VER_PLATFORM_WIN32s: sys_strOS = "Win32s"; break;
|
||||
case VER_PLATFORM_WIN32_WINDOWS: sys_strOS = "Win9x"; break;
|
||||
|
@ -292,11 +409,37 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
|
|||
} else {
|
||||
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");
|
||||
|
||||
// init main shell
|
||||
_pShell = new CShell;
|
||||
_pShell->Initialize();
|
||||
// (rcg11232001 this is where _pShell was originally created.)
|
||||
|
||||
// report CPU
|
||||
CPrintF(TRANS("Detecting CPU...\n"));
|
||||
|
@ -307,6 +450,7 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
|
|||
extern void ReportGlobalMemoryStatus(void);
|
||||
ReportGlobalMemoryStatus();
|
||||
|
||||
#if (defined PLATFORM_WIN32) // !!! FIXME: Abstract this somehow.
|
||||
MEMORYSTATUS ms;
|
||||
GlobalMemoryStatus(&ms);
|
||||
|
||||
|
@ -314,10 +458,21 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
|
|||
sys_iRAMPhys = ms.dwTotalPhys /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
|
||||
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
|
||||
DWORD dwSerial;
|
||||
DWORD dwFreeClusters;
|
||||
|
@ -330,48 +485,57 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
|
|||
|
||||
GetVolumeInformationA(strDrive, NULL, 0, &dwSerial, NULL, NULL, NULL, 0);
|
||||
GetDiskFreeSpaceA(strDrive, &dwSectors, &dwBytes, &dwFreeClusters, &dwClusters);
|
||||
sys_iHDDSize = __int64(dwSectors)*dwBytes*dwClusters/MB;
|
||||
sys_iHDDFree = __int64(dwSectors)*dwBytes*dwFreeClusters/MB;
|
||||
sys_iHDDSize = ((__int64)dwSectors)*dwBytes*dwClusters/MB;
|
||||
sys_iHDDFree = ((__int64)dwSectors)*dwBytes*dwFreeClusters/MB;
|
||||
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
|
||||
extern INDEX con_bNoWarnings;
|
||||
extern INDEX wld_bFastObjectOptimization;
|
||||
extern INDEX fil_bPreferZips;
|
||||
extern FLOAT mth_fCSGEpsilon;
|
||||
_pShell->DeclareSymbol("user INDEX con_bNoWarnings;", &con_bNoWarnings);
|
||||
_pShell->DeclareSymbol("user INDEX wld_bFastObjectOptimization;", &wld_bFastObjectOptimization);
|
||||
_pShell->DeclareSymbol("user FLOAT mth_fCSGEpsilon;", &mth_fCSGEpsilon);
|
||||
_pShell->DeclareSymbol("persistent user INDEX fil_bPreferZips;", &fil_bPreferZips);
|
||||
_pShell->DeclareSymbol("user INDEX con_bNoWarnings;", (void *) &con_bNoWarnings);
|
||||
_pShell->DeclareSymbol("user INDEX wld_bFastObjectOptimization;", (void *) &wld_bFastObjectOptimization);
|
||||
_pShell->DeclareSymbol("user FLOAT mth_fCSGEpsilon;", (void *) &mth_fCSGEpsilon);
|
||||
_pShell->DeclareSymbol("persistent user INDEX fil_bPreferZips;", (void *) &fil_bPreferZips);
|
||||
// OS info
|
||||
_pShell->DeclareSymbol("user const CTString sys_strOS ;", &sys_strOS);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iOSMajor ;", &sys_iOSMajor);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iOSMinor ;", &sys_iOSMinor);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iOSBuild ;", &sys_iOSBuild);
|
||||
_pShell->DeclareSymbol("user const CTString sys_strOSMisc;", &sys_strOSMisc);
|
||||
_pShell->DeclareSymbol("user const CTString sys_strOS ;", (void *) &sys_strOS);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iOSMajor ;", (void *) &sys_iOSMajor);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iOSMinor ;", (void *) &sys_iOSMinor);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iOSBuild ;", (void *) &sys_iOSBuild);
|
||||
_pShell->DeclareSymbol("user const CTString sys_strOSMisc;", (void *) &sys_strOSMisc);
|
||||
// CPU info
|
||||
_pShell->DeclareSymbol("user const CTString sys_strCPUVendor;", &sys_strCPUVendor);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iCPUType ;", &sys_iCPUType );
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iCPUFamily ;", &sys_iCPUFamily );
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iCPUModel ;", &sys_iCPUModel );
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iCPUStepping ;", &sys_iCPUStepping);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_bCPUHasMMX ;", &sys_bCPUHasMMX );
|
||||
_pShell->DeclareSymbol("user const INDEX sys_bCPUHasCMOV ;", &sys_bCPUHasCMOV );
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iCPUMHz ;", &sys_iCPUMHz );
|
||||
_pShell->DeclareSymbol(" const INDEX sys_iCPUMisc ;", &sys_iCPUMisc );
|
||||
_pShell->DeclareSymbol("user const CTString sys_strCPUVendor;", (void *) &sys_strCPUVendor);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iCPUType ;", (void *) &sys_iCPUType );
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iCPUFamily ;", (void *) &sys_iCPUFamily );
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iCPUModel ;", (void *) &sys_iCPUModel );
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iCPUStepping ;", (void *) &sys_iCPUStepping);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_bCPUHasMMX ;", (void *) &sys_bCPUHasMMX );
|
||||
_pShell->DeclareSymbol("user const INDEX sys_bCPUHasCMOV ;", (void *) &sys_bCPUHasCMOV );
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iCPUMHz ;", (void *) &sys_iCPUMHz );
|
||||
_pShell->DeclareSymbol(" const INDEX sys_iCPUMisc ;", (void *) &sys_iCPUMisc );
|
||||
// RAM info
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iRAMPhys;", &sys_iRAMPhys);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iRAMSwap;", &sys_iRAMSwap);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iHDDSize;", &sys_iHDDSize);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iHDDFree;", &sys_iHDDFree);
|
||||
_pShell->DeclareSymbol(" const INDEX sys_iHDDMisc;", &sys_iHDDMisc);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iRAMPhys;", (void *) &sys_iRAMPhys);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iRAMSwap;", (void *) &sys_iRAMSwap);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iHDDSize;", (void *) &sys_iHDDSize);
|
||||
_pShell->DeclareSymbol("user const INDEX sys_iHDDFree;", (void *) &sys_iHDDFree);
|
||||
_pShell->DeclareSymbol(" const INDEX sys_iHDDMisc;", (void *) &sys_iHDDMisc);
|
||||
// MOD info
|
||||
_pShell->DeclareSymbol("user const CTString sys_strModName;", &sys_strModName);
|
||||
_pShell->DeclareSymbol("user const CTString sys_strModExt;", &sys_strModExt);
|
||||
_pShell->DeclareSymbol("user const CTString sys_strModName;", (void *) &sys_strModName);
|
||||
_pShell->DeclareSymbol("user const CTString sys_strModExt;", (void *) &sys_strModExt);
|
||||
|
||||
// Stock clearing
|
||||
extern void FreeUnusedStock(void);
|
||||
_pShell->DeclareSymbol("user void FreeUnusedStock(void);", &FreeUnusedStock);
|
||||
_pShell->DeclareSymbol("user void FreeUnusedStock(void);", (void *) &FreeUnusedStock);
|
||||
|
||||
// Timer tick quantum
|
||||
_pShell->DeclareSymbol("user const FLOAT fTickQuantum;", (FLOAT*)&_pTimer->TickQuantum);
|
||||
|
@ -434,6 +598,8 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
|
|||
_pfdDisplayFont = NULL;
|
||||
_pfdConsoleFont = NULL;
|
||||
|
||||
// !!! FIXME: Move this into GfxLibrary...
|
||||
#ifdef PLATFORM_WIN32
|
||||
// readout system gamma table
|
||||
HDC hdc = GetDC(NULL);
|
||||
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"));
|
||||
} // done
|
||||
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
|
||||
HWND hwnd = NULL;//GetDesktopWindow();
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
|
@ -463,12 +635,15 @@ ENGINE_API void SE_InitEngine(CTString strGameID)
|
|||
}
|
||||
CPrintF("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// shutdown entire engine
|
||||
ENGINE_API void SE_EndEngine(void)
|
||||
{
|
||||
// !!! FIXME: Move this into GfxLibrary...
|
||||
#ifdef PLATFORM_WIN32
|
||||
// restore system gamma table (if needed)
|
||||
if( _pGfx->gl_ulFlags&GLF_ADJUSTABLEGAMMA) {
|
||||
HDC hdc = GetDC(NULL);
|
||||
|
@ -476,6 +651,7 @@ ENGINE_API void SE_EndEngine(void)
|
|||
//ASSERT(bOK);
|
||||
ReleaseDC( NULL, hdc);
|
||||
}
|
||||
#endif
|
||||
|
||||
// free stocks
|
||||
delete _pEntityClassStock; _pEntityClassStock = NULL;
|
||||
|
@ -499,6 +675,7 @@ ENGINE_API void SE_EndEngine(void)
|
|||
delete _pTimer; _pTimer = NULL;
|
||||
delete _pShell; _pShell = NULL;
|
||||
delete _pConsole; _pConsole = NULL;
|
||||
delete _pFileSystem; _pFileSystem = NULL;
|
||||
extern void EndStreams(void);
|
||||
EndStreams();
|
||||
|
||||
|
@ -562,6 +739,7 @@ ENGINE_API void SE_UpdateWindowHandle( HWND hwndMain)
|
|||
|
||||
static BOOL TouchBlock(UBYTE *pubMemoryBlock, INDEX ctBlockSize)
|
||||
{
|
||||
#if (defined __MSC_VER)
|
||||
// cannot pretouch block that are smaller than 64KB :(
|
||||
ctBlockSize -= 16*0x1000;
|
||||
if( ctBlockSize<4) return FALSE;
|
||||
|
@ -589,14 +767,25 @@ touchLoop:
|
|||
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// pretouch all memory commited by process
|
||||
extern BOOL _bNeedPretouch = FALSE;
|
||||
BOOL _bNeedPretouch = FALSE;
|
||||
ENGINE_API extern void SE_PretouchIfNeeded(void)
|
||||
{
|
||||
#if (defined PLATFORM_WIN32)
|
||||
// only if pretouching is needed?
|
||||
extern INDEX gam_bPretouch;
|
||||
if( !_bNeedPretouch || !gam_bPretouch) return;
|
||||
|
@ -668,6 +857,14 @@ nextRegion:
|
|||
// some blocks failed?
|
||||
if( ctFails>1) CPrintF( TRANS("(%d blocks were skipped)\n"), ctFails);
|
||||
//_pShell->Execute("StockDump();");
|
||||
|
||||
#else
|
||||
|
||||
// See dissertation in TouchBlock(). --ryan.
|
||||
|
||||
_bNeedPretouch = FALSE;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
/* 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
|
||||
#define CHECKARRAYLOCKING 0
|
||||
#ifndef SE_INCL_ENGINE_H
|
||||
#define SE_INCL_ENGINE_H
|
||||
#ifdef PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef PLATFORM_WIN32
|
||||
|
@ -9,8 +12,10 @@
|
|||
#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 <malloc.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -20,6 +25,10 @@
|
|||
#include <search.h> // for qsort
|
||||
#include <float.h> // for FPU control
|
||||
|
||||
#if !PLATFORM_MACOSX
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
/* rcg10042001 !!! FIXME: Move these somewhere. */
|
||||
#if (defined PLATFORM_WIN32)
|
||||
#include <conio.h>
|
||||
|
@ -53,6 +62,10 @@
|
|||
#include <Engine/Base/Registry.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/EntityCollision.h>
|
||||
#include <Engine/Entities/EntityProperties.h>
|
||||
|
@ -152,24 +165,31 @@
|
|||
#include <Engine/Templates/Selection.h>
|
||||
#include <Engine/Templates/Selection.cpp>
|
||||
|
||||
|
||||
// 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_LoadDefaultFonts(void);
|
||||
ENGINE_API void SE_UpdateWindowHandle( HWND hwndWindowed);
|
||||
ENGINE_API void SE_PretouchIfNeeded(void);
|
||||
|
||||
extern ENGINE_API CTString _strEngineBuild; // not valid before InitEngine()!
|
||||
extern ENGINE_API ULONG _ulEngineBuildMajor;
|
||||
extern ENGINE_API ULONG _ulEngineBuildMinor;
|
||||
ENGINE_API extern CTString _strEngineBuild; // not valid before InitEngine()!
|
||||
ENGINE_API extern ULONG _ulEngineBuildMajor;
|
||||
ENGINE_API extern ULONG _ulEngineBuildMinor;
|
||||
|
||||
extern ENGINE_API BOOL _bDedicatedServer;
|
||||
extern ENGINE_API BOOL _bWorldEditorApp; // is this world edtior app
|
||||
extern ENGINE_API CTString _strLogFile;
|
||||
ENGINE_API extern BOOL _bDedicatedServer;
|
||||
ENGINE_API extern BOOL _bWorldEditorApp; // is this world editor app
|
||||
ENGINE_API extern CTString _strLogFile;
|
||||
|
||||
// temporary vars for adjustments
|
||||
ENGINE_API extern FLOAT tmp_af[10];
|
||||
ENGINE_API extern INDEX tmp_ai[10];
|
||||
ENGINE_API extern INDEX tmp_i;
|
||||
ENGINE_API extern INDEX tmp_fAdd;
|
||||
|
||||
#endif /* include-once blocker. */
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include <Engine/StdH.h>
|
||||
|
||||
#include <Engine/Entities/Entity.h>
|
||||
#include <Engine/Entities/EntityClass.h>
|
||||
|
@ -875,7 +875,7 @@ void CEntity::Teleport(const CPlacement3D &plNew, BOOL bTelefrag /*=TRUE*/)
|
|||
CEntity *ppenObstacleDummy;
|
||||
if (pmme->CheckForCollisionNow(pmme->en_iCollisionBox, &ppenObstacleDummy)) {
|
||||
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(2),
|
||||
en_plPlacement.pl_PositionVector(3));
|
||||
|
@ -998,7 +998,7 @@ void CEntity::FallDownToFloor( void)
|
|||
|
||||
|
||||
extern CEntity *_penLightUpdating;
|
||||
extern BOOL _bDontDiscardLinks = FALSE;
|
||||
BOOL _bDontDiscardLinks = FALSE;
|
||||
|
||||
// internal repositioning function
|
||||
void CEntity::SetPlacement_internal(const CPlacement3D &plNew, const FLOATmatrix3D &mRotation,
|
||||
|
@ -1432,8 +1432,8 @@ void CEntity::FindShadingInfo(void)
|
|||
INDEX iMipLevel = bsm.sm_iFirstMipLevel;
|
||||
FLOAT fpixU = FLOAT(vmexShadow(1)+bsm.sm_mexOffsetX)*(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_pixShadowV = floor(fpixV);
|
||||
en_psiShadingInfo->si_pixShadowU = (PIX) floor(fpixU);
|
||||
en_psiShadingInfo->si_pixShadowV = (PIX) floor(fpixV);
|
||||
en_psiShadingInfo->si_fUDRatio = fpixU-en_psiShadingInfo->si_pixShadowU;
|
||||
en_psiShadingInfo->si_fLRRatio = fpixV-en_psiShadingInfo->si_pixShadowV;
|
||||
|
||||
|
@ -1444,8 +1444,8 @@ void CEntity::FindShadingInfo(void)
|
|||
en_psiShadingInfo->si_vNearPoint = _vNearPoint;
|
||||
|
||||
FLOAT2D vTc = CalculateShadingTexCoords(_ptrTerrainNear,_vNearPoint);
|
||||
en_psiShadingInfo->si_pixShadowU = floor(vTc(1));
|
||||
en_psiShadingInfo->si_pixShadowV = floor(vTc(2));
|
||||
en_psiShadingInfo->si_pixShadowU = (PIX) floor(vTc(1));
|
||||
en_psiShadingInfo->si_pixShadowV = (PIX) floor(vTc(2));
|
||||
en_psiShadingInfo->si_fLRRatio = vTc(1) - en_psiShadingInfo->si_pixShadowU;
|
||||
en_psiShadingInfo->si_fUDRatio = vTc(2) - en_psiShadingInfo->si_pixShadowV;
|
||||
|
||||
|
@ -2356,7 +2356,7 @@ void CEntity::SetModel(const CTFileName &fnmModel)
|
|||
// if failed
|
||||
} catch(char *strErrorDefault) {
|
||||
FatalError(TRANS("Cannot load default model '%s':\n%s"),
|
||||
(CTString&)fnmDefault, strErrorDefault);
|
||||
(const char *) (CTString&)fnmDefault, strErrorDefault);
|
||||
}
|
||||
}
|
||||
UpdateSpatialRange();
|
||||
|
@ -2419,7 +2419,7 @@ BOOL CEntity::SetSkaModel(const CTString &fnmModel)
|
|||
// if failed
|
||||
} catch(char *strErrorDefault) {
|
||||
FatalError(TRANS("Cannot load default model '%s':\n%s"),
|
||||
(CTString&)fnmDefault, strErrorDefault);
|
||||
(const char *) (CTString&)fnmDefault, strErrorDefault);
|
||||
}
|
||||
// set colision info for default model
|
||||
SetSkaColisionInfo();
|
||||
|
@ -2476,7 +2476,7 @@ void CEntity::SetModelMainTexture(const CTFileName &fnmTexture)
|
|||
// if failed
|
||||
} catch(char *strErrorDefault) {
|
||||
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
|
||||
} catch(char *strErrorDefault) {
|
||||
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_ulSpawnFlags
|
||||
>>en_ulFlags;
|
||||
(*istr).Read_t(&en_mRotation, sizeof(en_mRotation));
|
||||
(*istr)>>en_mRotation;
|
||||
} else if (istr->PeekID_t()==CChunkID("ENT3")) { // entity v3
|
||||
istr->ExpectID_t("ENT3");
|
||||
(*istr)>>(ULONG &)en_RenderType
|
||||
|
@ -3279,7 +3279,7 @@ void CEntity::Read_t( CTStream *istr) // throw char *
|
|||
>>en_ulCollisionFlags
|
||||
>>en_ulSpawnFlags
|
||||
>>en_ulFlags;
|
||||
(*istr).Read_t(&en_mRotation, sizeof(en_mRotation));
|
||||
(*istr)>>en_mRotation;
|
||||
} else if (istr->PeekID_t()==CChunkID("ENT2")) { // entity v2
|
||||
istr->ExpectID_t("ENT2");
|
||||
(*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("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) {
|
||||
strm.FPrintF_t("en_ulFlags: 0x%08X\n", en_ulFlags&~
|
||||
(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)
|
||||
{
|
||||
// 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!");
|
||||
// set the timer
|
||||
en_timeTimer = timeAbsolute;
|
||||
|
@ -3881,7 +3881,7 @@ void CRationalEntity::Return(SLONG slThisState, const CEntityEvent &eeReturn)
|
|||
// print stack to debug output
|
||||
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();
|
||||
for(INDEX iState=ctStates-1; iState>=0; iState--) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Base/Stream.h>
|
||||
#include <Engine/Entities/EntityClass.h>
|
||||
|
@ -208,52 +208,6 @@ void CEntityClass::ReleaseComponents(void)
|
|||
|
||||
// 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.
|
||||
*/
|
||||
|
@ -265,31 +219,53 @@ void CEntityClass::Read_t( CTStream *istr) // throw char *
|
|||
CTString strClassName;
|
||||
strClassName.ReadFromText_t(*istr, "Class: ");
|
||||
|
||||
// create name of dll
|
||||
#ifndef NDEBUG
|
||||
fnmDLL = _fnmApplicationExe.FileDir()+fnmDLL.FileName()+_strModExt+"D"+fnmDLL.FileExt();
|
||||
const char *dllName = NULL;
|
||||
|
||||
// load the DLL
|
||||
#ifdef STATICALLY_LINKED
|
||||
ec_hiClassDLL = CDynamicLoader::GetInstance(NULL);
|
||||
dllName = "(statically linked)";
|
||||
#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
|
||||
|
||||
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
|
||||
CTFileName fnmExpanded;
|
||||
ExpandFilePath(EFP_READ, fnmDLL, fnmExpanded);
|
||||
|
||||
ec_hiClassDLL = LoadDLL_t(fnmExpanded);
|
||||
ec_fnmClassDLL = fnmDLL;
|
||||
|
||||
// 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 (ec_pdecDLLClass == NULL) {
|
||||
// free the library
|
||||
BOOL bSuccess = FreeLibrary(ec_hiClassDLL);
|
||||
ASSERT(bSuccess);
|
||||
delete ec_hiClassDLL;
|
||||
ec_hiClassDLL = NULL;
|
||||
ec_fnmClassDLL.Clear();
|
||||
// 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
|
||||
|
@ -356,7 +332,7 @@ CEntity::pEventHandler CEntityClass::HandlerForStateAndEvent(SLONG slState, SLON
|
|||
|
||||
/* Get pointer to component from its identifier. */
|
||||
class CEntityComponent *CEntityClass::ComponentForTypeAndID(
|
||||
EntityComponentType ectType, SLONG slID) {
|
||||
enum EntityComponentType ectType, SLONG slID) {
|
||||
return ec_pdecDLLClass->ComponentForTypeAndID(ectType, slID);
|
||||
}
|
||||
/* Get pointer to component from the component. */
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
#include <Engine/Base/Serial.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.
|
||||
|
@ -21,7 +22,7 @@ public:
|
|||
void ReleaseComponents(void);
|
||||
public:
|
||||
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
|
||||
|
||||
/* Default constructor. */
|
||||
|
@ -50,9 +51,10 @@ public:
|
|||
/* Get event handler for given state and event code. */
|
||||
CEntity::pEventHandler HandlerForStateAndEvent(SLONG slState, SLONG slEvent);
|
||||
/* 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. */
|
||||
class CEntityComponent *ComponentForPointer(void *pv);
|
||||
inline class CEntityComponent *ComponentForPointer(void *pv);
|
||||
|
||||
// overrides from CSerial
|
||||
/* Read from stream. */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include "Engine/StdH.h"
|
||||
|
||||
#include <Engine/Entities/Entity.h>
|
||||
#include <Engine/Entities/EntityCollision.h>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include <Engine/StdH.h>
|
||||
|
||||
#include <Engine/Entities/Entity.h>
|
||||
#include <Engine/Entities/LastPositions.h>
|
||||
|
@ -36,7 +36,7 @@ public:
|
|||
|
||||
static CStaticArray<CPointerRemapping> _aprRemaps;
|
||||
static BOOL _bRemapPointersToNULLs = TRUE;
|
||||
extern BOOL _bReinitEntitiesWhileCopying = TRUE;
|
||||
BOOL _bReinitEntitiesWhileCopying = TRUE;
|
||||
static BOOL _bMirrorAndStretch = FALSE;
|
||||
static FLOAT _fStretch = 1.0f;
|
||||
static enum WorldMirrorType _wmtMirror = WMT_NONE;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||||
|
||||
#include "stdh.h"
|
||||
#include <Engine/StdH.h>
|
||||
|
||||
#include <Engine/Entities/EntityProperties.h>
|
||||
#include <Engine/Entities/Precaching.h>
|
||||
|
@ -183,21 +183,21 @@ void CEntity::ReadProperties_t(CTStream &istrm) // throw char *
|
|||
case CEntityProperty::EPT_FLOATAABBOX3D: {
|
||||
// skip FLOATAABBOX3D
|
||||
FLOATaabbox3D boxDummy;
|
||||
istrm.Read_t(&boxDummy, sizeof(FLOATaabbox3D));
|
||||
istrm>>boxDummy;
|
||||
}
|
||||
break;
|
||||
// if it is FLOATMATRIX3D
|
||||
case CEntityProperty::EPT_FLOATMATRIX3D: {
|
||||
// skip FLOATMATRIX3D
|
||||
FLOATmatrix3D boxDummy;
|
||||
istrm.Read_t(&boxDummy, sizeof(FLOATmatrix3D));
|
||||
istrm>>boxDummy;
|
||||
}
|
||||
break;
|
||||
// if it is EPT_FLOATQUAT3D
|
||||
case CEntityProperty::EPT_FLOATQUAT3D: {
|
||||
// skip EPT_FLOATQUAT3D
|
||||
FLOATquat3D qDummy;
|
||||
istrm.Read_t(&qDummy, sizeof(FLOATquat3D));
|
||||
istrm>>qDummy;
|
||||
}
|
||||
break;
|
||||
// if it is FLOAT3D
|
||||
|
@ -218,7 +218,7 @@ void CEntity::ReadProperties_t(CTStream &istrm) // throw char *
|
|||
case CEntityProperty::EPT_FLOATplane3D: {
|
||||
// skip FLOATplane3D
|
||||
FLOATplane3D plDummy;
|
||||
istrm.Read_t(&plDummy, sizeof(plDummy));
|
||||
istrm>>plDummy;
|
||||
}
|
||||
break;
|
||||
// if it is MODELOBJECT
|
||||
|
@ -331,32 +331,32 @@ void CEntity::ReadProperties_t(CTStream &istrm) // throw char *
|
|||
// if it is FLOATAABBOX3D
|
||||
case CEntityProperty::EPT_FLOATAABBOX3D:
|
||||
// read FLOATAABBOX3D
|
||||
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATaabbox3D), sizeof(FLOATaabbox3D));
|
||||
istrm>>(PROPERTY(pepProperty->ep_slOffset, FLOATaabbox3D));
|
||||
break;
|
||||
// if it is FLOATMATRIX3D
|
||||
case CEntityProperty::EPT_FLOATMATRIX3D:
|
||||
// read FLOATMATRIX3D
|
||||
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATmatrix3D), sizeof(FLOATmatrix3D));
|
||||
istrm>>(PROPERTY(pepProperty->ep_slOffset, FLOATmatrix3D));
|
||||
break;
|
||||
// if it is FLOATQUAT3D
|
||||
case CEntityProperty::EPT_FLOATQUAT3D:
|
||||
// read FLOATQUAT3D
|
||||
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATquat3D), sizeof(FLOATquat3D));
|
||||
istrm>>(PROPERTY(pepProperty->ep_slOffset, FLOATquat3D));
|
||||
break;
|
||||
// if it is FLOAT3D
|
||||
case CEntityProperty::EPT_FLOAT3D:
|
||||
// read FLOAT3D
|
||||
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOAT3D), sizeof(FLOAT3D));
|
||||
istrm>>(PROPERTY(pepProperty->ep_slOffset, FLOAT3D));
|
||||
break;
|
||||
// if it is ANGLE3D
|
||||
case CEntityProperty::EPT_ANGLE3D:
|
||||
// read ANGLE3D
|
||||
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, ANGLE3D), sizeof(ANGLE3D));
|
||||
istrm>>(PROPERTY(pepProperty->ep_slOffset, ANGLE3D));
|
||||
break;
|
||||
// if it is FLOATplane3D
|
||||
case CEntityProperty::EPT_FLOATplane3D:
|
||||
// read FLOATplane3D
|
||||
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATplane3D), sizeof(FLOATplane3D));
|
||||
istrm>>(PROPERTY(pepProperty->ep_slOffset, FLOATplane3D));
|
||||
break;
|
||||
// if it is MODELOBJECT
|
||||
case CEntityProperty::EPT_MODELOBJECT:
|
||||
|
@ -385,7 +385,7 @@ void CEntity::ReadProperties_t(CTStream &istrm) // throw char *
|
|||
// if it is CPlacement3D
|
||||
case CEntityProperty::EPT_PLACEMENT3D:
|
||||
// read CPlacement3D
|
||||
istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, CPlacement3D), sizeof(CPlacement3D));
|
||||
istrm>>(PROPERTY(pepProperty->ep_slOffset, CPlacement3D));
|
||||
break;
|
||||
default:
|
||||
ASSERTALWAYS("Unknown property type");
|
||||
|
@ -475,32 +475,32 @@ void CEntity::WriteProperties_t(CTStream &ostrm) // throw char *
|
|||
// if it is FLOATAABBOX3D
|
||||
case CEntityProperty::EPT_FLOATAABBOX3D:
|
||||
// write FLOATAABBOX3D
|
||||
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATaabbox3D), sizeof(FLOATaabbox3D));
|
||||
ostrm<<PROPERTY(epProperty.ep_slOffset, FLOATaabbox3D);
|
||||
break;
|
||||
// if it is FLOATMATRIX3D
|
||||
case CEntityProperty::EPT_FLOATMATRIX3D:
|
||||
// write FLOATMATRIX3D
|
||||
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATmatrix3D), sizeof(FLOATmatrix3D));
|
||||
ostrm<<PROPERTY(epProperty.ep_slOffset, FLOATmatrix3D);
|
||||
break;
|
||||
// if it is FLOATQUAT3D
|
||||
case CEntityProperty::EPT_FLOATQUAT3D:
|
||||
// write FLOATQUAT3D
|
||||
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATquat3D), sizeof(FLOATquat3D));
|
||||
ostrm<<PROPERTY(epProperty.ep_slOffset, FLOATquat3D);
|
||||
break;
|
||||
// if it is ANGLE3D
|
||||
case CEntityProperty::EPT_ANGLE3D:
|
||||
// write ANGLE3D
|
||||
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, ANGLE3D), sizeof(ANGLE3D));
|
||||
ostrm<<PROPERTY(epProperty.ep_slOffset, ANGLE3D);
|
||||
break;
|
||||
// if it is FLOAT3D
|
||||
case CEntityProperty::EPT_FLOAT3D:
|
||||
// write FLOAT3D
|
||||
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOAT3D), sizeof(FLOAT3D));
|
||||
ostrm<<PROPERTY(epProperty.ep_slOffset, FLOAT3D);
|
||||
break;
|
||||
// if it is FLOATplane3D
|
||||
case CEntityProperty::EPT_FLOATplane3D:
|
||||
// write FLOATplane3D
|
||||
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATplane3D), sizeof(FLOATplane3D));
|
||||
ostrm<<PROPERTY(epProperty.ep_slOffset, FLOATplane3D);
|
||||
break;
|
||||
// if it is ENTITYPTR
|
||||
case CEntityProperty::EPT_ENTITYPTR:
|
||||
|
@ -530,7 +530,7 @@ void CEntity::WriteProperties_t(CTStream &ostrm) // throw char *
|
|||
// if it is CPlacement3D
|
||||
case CEntityProperty::EPT_PLACEMENT3D:
|
||||
// write CPlacement3D
|
||||
ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, CPlacement3D), sizeof(CPlacement3D));
|
||||
ostrm<<PROPERTY(epProperty.ep_slOffset, CPlacement3D);
|
||||
break;
|
||||
default:
|
||||
ASSERTALWAYS("Unknown property type");
|
||||
|
@ -585,15 +585,15 @@ void CEntityComponent::Obtain_t(void) // throw char *
|
|||
// if something else
|
||||
default:
|
||||
// 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( ctUsed<=1 && !_precache_bNowPrecaching) {
|
||||
// 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
|
||||
AddToCRCTable();
|
||||
|
@ -660,7 +660,7 @@ void CEntityComponent::Release(void)
|
|||
// if something else
|
||||
default:
|
||||
// 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
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user