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

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

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

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

View File

@ -77,7 +77,7 @@ void SubMain( int argc, char *argv[])
}
// initialize engine
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

View File

@ -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 {
#ifdef STATICALLY_LINKED
#define fnmExpanded NULL
CPrintF(TRANS("Loading game library '%s'...\n"), "(statically linked)");
#else
CTFileName fnmDLL;
#ifndef NDEBUG
#define GAMEDLL _fnmApplicationExe.FileDir()+"Game"+_strModExt+"D.dll"
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();

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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>

View File

@ -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;
}
};
}

View File

@ -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];
/*

View File

@ -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.

View File

@ -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));

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}
/*

View File

@ -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>

View File

@ -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);

View File

@ -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;
}

View File

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

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#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
}

View File

@ -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 *
{

View File

@ -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; };

View File

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

View File

@ -1,14 +1,20 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#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

View File

@ -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

View File

@ -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. */

View File

@ -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) ) )

View File

@ -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>

View File

@ -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)
{

View File

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

View File

@ -1,5 +1,5 @@
%{
#include "StdH.h"
#include <Engine/StdH.h>
#include <Engine/Base/Console.h>
#include <Engine/Base/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);
// !!! 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 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;
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);
}
}

View File

@ -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);

View File

@ -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. */

View File

@ -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,

View File

@ -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. */

View File

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

View File

@ -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>

View File

@ -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)

View File

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

View File

@ -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>

View File

@ -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>

View File

@ -62,10 +62,10 @@ void ENGINE_API AddRelationPairHeadHead(CRelationSrc &rsSrc, CRelationDst &rdDst
// get a domain member related to a codomain member through a link
#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) \

View File

@ -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);
}
}
}

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@ -13,6 +13,10 @@
#define YY_DECL int yylex (YYSTYPE *lvalp)
#define 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;
}

View File

@ -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)

View 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>
@ -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) {

View File

@ -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

View 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>

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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)

View File

@ -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. */

View File

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

View File

@ -1,10 +1,11 @@
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#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;

View File

@ -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

View File

@ -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)

View File

@ -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>

View File

@ -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. */

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@
// unzip.cpp : Defines the entry point for the console application.
//
#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;

View File

@ -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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

View File

@ -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.

View File

@ -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>

View File

@ -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];
}
}
}

View File

@ -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>

View File

@ -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)

View File

@ -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)

View File

@ -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>

View File

@ -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>

View File

@ -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,

View File

@ -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>

View File

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

View File

@ -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)");
}

View File

@ -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>

View File

@ -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]);

View File

@ -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
}

View File

@ -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. */

View File

@ -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--) {

View File

@ -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. */

View File

@ -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. */

View File

@ -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>

View File

@ -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;

View File

@ -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