11 Jan 2009
This commit is contained in:
parent
df6f03c2ba
commit
dff851cc74
|
@ -629,6 +629,8 @@ public:
|
|||
// user messages
|
||||
int _cdecl MsgFunc_Damage( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_RoomType( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_ScreenFade( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf );
|
||||
int _cdecl MsgFunc_ResetHUD( const char *pszName, int iSize, void *pbuf);
|
||||
int _cdecl MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf );
|
||||
|
|
|
@ -22,10 +22,12 @@
|
|||
// CHud message handlers
|
||||
DECLARE_HUDMESSAGE( HUDColor );
|
||||
DECLARE_HUDMESSAGE( SetFog );
|
||||
DECLARE_HUDMESSAGE( RoomType );
|
||||
DECLARE_HUDMESSAGE( SetSky );
|
||||
DECLARE_HUDMESSAGE( RainData );
|
||||
DECLARE_HUDMESSAGE( SetBody );
|
||||
DECLARE_HUDMESSAGE( SetSkin );
|
||||
DECLARE_HUDMESSAGE( ScreenFade );
|
||||
DECLARE_HUDMESSAGE( WeaponAnim );
|
||||
DECLARE_HUDMESSAGE( ResetHUD );
|
||||
DECLARE_HUDMESSAGE( InitHUD );
|
||||
|
@ -51,6 +53,7 @@ int CHud :: InitMessages( void )
|
|||
HOOK_MESSAGE( InitHUD );
|
||||
HOOK_MESSAGE( ViewMode );
|
||||
HOOK_MESSAGE( Concuss );
|
||||
HOOK_MESSAGE( RoomType );
|
||||
HOOK_MESSAGE( HUDColor );
|
||||
HOOK_MESSAGE( Particle );
|
||||
HOOK_MESSAGE( TempEntity );
|
||||
|
@ -64,6 +67,7 @@ int CHud :: InitMessages( void )
|
|||
HOOK_MESSAGE( AddMirror);
|
||||
HOOK_MESSAGE( AddScreen );
|
||||
HOOK_MESSAGE( AddPortal );
|
||||
HOOK_MESSAGE( ScreenFade );
|
||||
HOOK_MESSAGE( ScreenShake );
|
||||
|
||||
viewEntityIndex = 0; // trigger_viewset stuff
|
||||
|
@ -389,6 +393,18 @@ int CHud::MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf )
|
|||
return 1;
|
||||
}
|
||||
|
||||
int CHud :: MsgFunc_RoomType( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
// FIXME: needs callback to sound engine
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CHud :: MsgFunc_ScreenFade( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
// FIXME: implement
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CHud::MsgFunc_ScreenShake( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
BEGIN_READ( pszName, iSize, pbuf );
|
||||
|
|
|
@ -219,6 +219,7 @@ typedef struct
|
|||
DLL_FUNCTIONS dllFuncs; // dll exported funcs
|
||||
byte *mempool; // edicts pool
|
||||
byte *private; // server.dll private pool
|
||||
byte *temppool; // for parse, save and restore edicts
|
||||
|
||||
// library exports table
|
||||
word *ordinals;
|
||||
|
@ -384,6 +385,7 @@ void SV_CopyTraceToGlobal( trace_t *trace );
|
|||
void SV_CopyTraceResult( TraceResult *out, trace_t trace );
|
||||
float SV_AngleMod( float ideal, float current, float speed );
|
||||
void SV_SpawnEntities( const char *mapname, script_t *entities );
|
||||
edict_t* SV_AllocPrivateData( edict_t *ent, string_t className );
|
||||
string_t SV_AllocString( const char *szValue );
|
||||
const char *SV_GetString( string_t iString );
|
||||
|
||||
|
|
|
@ -557,8 +557,11 @@ void SV_SetModel( edict_t *ent, const char *name )
|
|||
break;
|
||||
}
|
||||
|
||||
Matrix3x3_FromAngles( angles, ent->v.m_pmatrix );
|
||||
Matrix3x3_Transpose( ent->v.m_pmatrix, ent->v.m_pmatrix );
|
||||
if( !sv.loadgame )
|
||||
{
|
||||
Matrix3x3_FromAngles( angles, ent->v.m_pmatrix );
|
||||
Matrix3x3_Transpose( ent->v.m_pmatrix, ent->v.m_pmatrix );
|
||||
}
|
||||
SV_CreatePhysBody( ent );
|
||||
}
|
||||
|
||||
|
@ -696,6 +699,39 @@ edict_t *SV_AllocEdict( void )
|
|||
return pEdict;
|
||||
}
|
||||
|
||||
edict_t* SV_AllocPrivateData( edict_t *ent, string_t className )
|
||||
{
|
||||
const char *pszClassName;
|
||||
LINK_ENTITY_FUNC SpawnEdict;
|
||||
|
||||
pszClassName = STRING( className );
|
||||
if( !ent ) ent = SV_AllocEdict();
|
||||
else if( ent->free ) SV_InitEdict( ent ); // FIXME
|
||||
ent->v.classname = className;
|
||||
ent->v.pContainingEntity = ent; // re-link
|
||||
|
||||
// allocate edict private memory (passed by dlls)
|
||||
SpawnEdict = (LINK_ENTITY_FUNC)Com_GetProcAddress( svgame.hInstance, pszClassName );
|
||||
if( !SpawnEdict )
|
||||
{
|
||||
// attempt to create custom entity
|
||||
if( svgame.dllFuncs.pfnCreate( ent, pszClassName ) == -1 )
|
||||
{
|
||||
ent->v.flags |= FL_KILLME;
|
||||
MsgDev( D_ERROR, "No spawn function for %s\n", pszClassName );
|
||||
return ent; // this edict will be removed from map
|
||||
}
|
||||
}
|
||||
else SpawnEdict( &ent->v );
|
||||
|
||||
Com_Assert( ent->pvServerData == NULL )
|
||||
|
||||
// also register classname to send for client
|
||||
ent->pvServerData->s.classname = SV_ClassIndex( pszClassName );
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
void SV_FreeEdicts( void )
|
||||
{
|
||||
int i;
|
||||
|
@ -1265,31 +1301,7 @@ pfnCreateNamedEntity
|
|||
*/
|
||||
edict_t* pfnCreateNamedEntity( string_t className )
|
||||
{
|
||||
edict_t *ent;
|
||||
const char *pszClassName;
|
||||
LINK_ENTITY_FUNC SpawnEdict;
|
||||
|
||||
pszClassName = STRING( className );
|
||||
ent = pfnCreateEntity();
|
||||
ent->v.classname = className;
|
||||
|
||||
// allocate edict private memory (passed by dlls)
|
||||
SpawnEdict = (LINK_ENTITY_FUNC)Com_GetProcAddress( svgame.hInstance, pszClassName );
|
||||
if( !SpawnEdict )
|
||||
{
|
||||
// attempt to create custom entity
|
||||
if( svgame.dllFuncs.pfnCreate( ent, pszClassName ) == -1 )
|
||||
{
|
||||
MsgDev( D_ERROR, "No spawn function for %s\n", pszClassName );
|
||||
return ent; // this edict needs to be alloced pvPrivateData
|
||||
}
|
||||
}
|
||||
else SpawnEdict( &ent->v );
|
||||
|
||||
// also register classname to send for client
|
||||
ent->pvServerData->s.classname = SV_ClassIndex( pszClassName );
|
||||
|
||||
return ent;
|
||||
return SV_AllocPrivateData( NULL, className );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2818,11 +2830,9 @@ bool SV_ParseEdict( script_t *script, edict_t *ent )
|
|||
KeyValueData pkvd[256]; // per one entity
|
||||
int i, numpairs = 0;
|
||||
const char *classname = NULL;
|
||||
LINK_ENTITY_FUNC SpawnEdict;
|
||||
byte *tempstr;
|
||||
token_t token;
|
||||
|
||||
tempstr = Mem_AllocPool( "SV Temp Strings" );
|
||||
svgame.temppool = Mem_AllocPool( "SV Temp Strings" );
|
||||
|
||||
// go through all the dictionary pairs
|
||||
while( 1 )
|
||||
|
@ -2848,8 +2858,8 @@ bool SV_ParseEdict( script_t *script, edict_t *ent )
|
|||
|
||||
// create keyvalue strings
|
||||
pkvd[numpairs].szClassName = (char *)classname; // unknown at this moment
|
||||
pkvd[numpairs].szKeyName = com.stralloc( tempstr, keyname, __FILE__, __LINE__ );
|
||||
pkvd[numpairs].szValue = com.stralloc( tempstr, token.string, __FILE__, __LINE__ );
|
||||
pkvd[numpairs].szKeyName = com.stralloc( svgame.temppool, keyname, __FILE__, __LINE__ );
|
||||
pkvd[numpairs].szValue = com.stralloc( svgame.temppool, token.string, __FILE__, __LINE__ );
|
||||
pkvd[numpairs].fHandled = false;
|
||||
|
||||
if( !com.strcmp( keyname, "classname" ) && classname == NULL )
|
||||
|
@ -2857,33 +2867,15 @@ bool SV_ParseEdict( script_t *script, edict_t *ent )
|
|||
if( ++numpairs >= 256 ) break;
|
||||
}
|
||||
|
||||
// allocate edict private memory (passed by dlls)
|
||||
SpawnEdict = (LINK_ENTITY_FUNC)Com_GetProcAddress( svgame.hInstance, classname );
|
||||
if( !SpawnEdict )
|
||||
{
|
||||
// attempt to create custom entity
|
||||
if( svgame.dllFuncs.pfnCreate( ent, classname ) == -1 )
|
||||
{
|
||||
MsgDev( D_ERROR, "No spawn function for %s\n", classname );
|
||||
Mem_FreePool( &tempstr );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ent->v.classname = MAKE_STRING( classname );
|
||||
SpawnEdict( &ent->v );
|
||||
}
|
||||
ent = SV_AllocPrivateData( ent, MAKE_STRING( classname ));
|
||||
|
||||
// apply classname to keyvalue containers and parse fields
|
||||
ent->pvServerData->s.classname = SV_ClassIndex( classname );
|
||||
for( i = 0; i < numpairs; i++ )
|
||||
{
|
||||
if( pkvd[i].fHandled ) continue;
|
||||
pkvd[i].szClassName = (char *)classname;
|
||||
svgame.dllFuncs.pfnKeyValue( ent, &pkvd[i] );
|
||||
}
|
||||
Mem_FreePool( &tempstr );
|
||||
Mem_FreePool( &svgame.temppool );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -57,40 +57,51 @@ static TYPEDESCRIPTION gETable[] =
|
|||
DEFINE_FIELD( ENTITYTABLE, classname, FIELD_STRING ),
|
||||
};
|
||||
|
||||
// TEST
|
||||
uint HashString( const char *pszToken )
|
||||
// FIXME: implement _rotr into Xash::stdlib
|
||||
static uint SV_HashString( const char *pszToken )
|
||||
{
|
||||
uint hash = 0;
|
||||
uint hash = 0;
|
||||
|
||||
while( *pszToken )
|
||||
hash = _rotr( hash, 4 ) ^ *pszToken++;
|
||||
return hash;
|
||||
}
|
||||
|
||||
word TokenHash( const char *pszToken, const char **pTokens, uint tokenCount )
|
||||
static word SV_TokenHash( const char *pszToken )
|
||||
{
|
||||
word hash = (word)(HashString( pszToken ) % (uint)tokenCount );
|
||||
int i, index;
|
||||
word hash;
|
||||
int i, index;
|
||||
|
||||
for( i = 0; i < tokenCount; i++ )
|
||||
// only valid if SAVERESTOREDATA have been initialized
|
||||
if( !svgame.SaveData.pTokens || !svgame.SaveData.tokenCount ) return 0;
|
||||
|
||||
hash = (word)(SV_HashString( pszToken ) % (uint)svgame.SaveData.tokenCount );
|
||||
for( i = 0; i < svgame.SaveData.tokenCount; i++ )
|
||||
{
|
||||
index = hash + i;
|
||||
if( index >= tokenCount )
|
||||
index -= tokenCount;
|
||||
if( index >= svgame.SaveData.tokenCount )
|
||||
index -= svgame.SaveData.tokenCount;
|
||||
|
||||
if( !pTokens[index] || !com.strcmp( pszToken, pTokens[index] ))
|
||||
if( !svgame.SaveData.pTokens[index] || !com.strcmp( pszToken, svgame.SaveData.pTokens[index] ))
|
||||
{
|
||||
pTokens[index] = (char *)pszToken;
|
||||
svgame.SaveData.pTokens[index] = (char *)pszToken;
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
// Token hash table full!!!
|
||||
// [Consider doing overflow table(s) after the main table & limiting linear hash table search]
|
||||
MsgDev( D_ERROR, "CSaveRestoreBuffer :: TokenHash() is COMPLETELY FULL!" );
|
||||
|
||||
// consider doing overflow table(s) after the main table & limiting linear hash table search
|
||||
MsgDev( D_ERROR, "SV_TokenHash is completely full!\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SV_UpdateTokens( const TYPEDESCRIPTION *fields, int fieldCount )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < fieldCount; i++, fields++ )
|
||||
SV_TokenHash( fields->fieldName );
|
||||
}
|
||||
|
||||
static void SV_AddSaveLump( wfile_t *f, const char *lumpname, void *data, size_t len, bool compress )
|
||||
{
|
||||
if( f ) WAD_Write( f, lumpname, data, len, TYPE_BINDATA, ( compress ? CMP_ZLIB : CMP_NONE ));
|
||||
|
@ -104,6 +115,26 @@ static void SV_SetPair( const char *name, const char *value, dkeyvalue_t *cvars,
|
|||
(*numpairs)++; // increase epairs
|
||||
}
|
||||
|
||||
static void SV_SaveBuffer( wfile_t *f, const char *lumpname, bool compress )
|
||||
{
|
||||
// write result into lump
|
||||
SV_AddSaveLump( f, lumpname, svgame.SaveData.pBaseData, svgame.SaveData.size, compress );
|
||||
|
||||
// clear buffer after writing
|
||||
Mem_Set( svgame.SaveData.pBaseData, 0, svgame.SaveData.bufferSize );
|
||||
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
|
||||
svgame.SaveData.size = 0; // reset current bufSize
|
||||
}
|
||||
|
||||
static void SV_ReadBuffer( wfile_t *f, const char *lumpname )
|
||||
{
|
||||
// an older pointer will automatically free memory when calling WAD_Close
|
||||
// so we don't need to care about it
|
||||
svgame.SaveData.pBaseData = WAD_Read( f, lumpname, &svgame.SaveData.bufferSize, TYPE_BINDATA );
|
||||
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
|
||||
svgame.SaveData.size = 0; // reset current bufSize
|
||||
}
|
||||
|
||||
static void SV_SaveEngineData( wfile_t *f )
|
||||
{
|
||||
byte *portalstate = NULL;
|
||||
|
@ -130,22 +161,22 @@ static void SV_SaveEngineData( wfile_t *f )
|
|||
static void SV_SaveServerData( wfile_t *f )
|
||||
{
|
||||
SAVERESTOREDATA *pSaveData;
|
||||
byte *savepool;
|
||||
string_t hash_strings[4095];
|
||||
int i, numstrings;
|
||||
ENTITYTABLE *pTable;
|
||||
save_header_t shdr;
|
||||
game_header_t ghdr;
|
||||
int i;
|
||||
|
||||
// initialize local mempool
|
||||
savepool = Mem_AllocPool( "Save Pool" );
|
||||
svgame.temppool = Mem_AllocPool( "Save Pool" );
|
||||
|
||||
// initialize SAVERESTOREDATA
|
||||
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
|
||||
svgame.SaveData.bufferSize = 0x80000; // reserve 512K for now
|
||||
svgame.SaveData.pBaseData = Mem_Alloc( savepool, svgame.SaveData.bufferSize );
|
||||
svgame.SaveData.pBaseData = Mem_Alloc( svgame.temppool, svgame.SaveData.bufferSize );
|
||||
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
|
||||
svgame.SaveData.tokenCount = 0xFFF; // assume a maximum of 4K-1 symbol table entries
|
||||
svgame.SaveData.pTokens = Mem_Alloc( savepool, svgame.SaveData.tokenCount * sizeof( char* ));
|
||||
svgame.SaveData.pTokens = Mem_Alloc( svgame.temppool, svgame.SaveData.tokenCount * sizeof( char* ));
|
||||
svgame.SaveData.time = svgame.globals->time;
|
||||
pSaveData = svgame.globals->pSaveData = &svgame.SaveData;
|
||||
|
||||
|
@ -165,7 +196,7 @@ static void SV_SaveServerData( wfile_t *f )
|
|||
|
||||
// initialize ENTITYTABLE
|
||||
pSaveData->tableCount = svgame.globals->numEntities;
|
||||
pSaveData->pTable = Mem_Alloc( savepool, pSaveData->tableCount * sizeof( ENTITYTABLE ));
|
||||
pSaveData->pTable = Mem_Alloc( svgame.temppool, pSaveData->tableCount * sizeof( ENTITYTABLE ));
|
||||
|
||||
for( i = 0; i < svgame.globals->numEntities; i++ )
|
||||
{
|
||||
|
@ -173,7 +204,6 @@ static void SV_SaveServerData( wfile_t *f )
|
|||
|
||||
pTable = &pSaveData->pTable[i];
|
||||
pTable->id = pent->serialnumber;
|
||||
if( pent->free ) pTable->flags |= FENTTABLE_REMOVED;
|
||||
pTable->pent = pent;
|
||||
|
||||
// setup some flags
|
||||
|
@ -191,16 +221,20 @@ static void SV_SaveServerData( wfile_t *f )
|
|||
svgame.dllFuncs.pfnSaveWriteFields( pSaveData, "ADJACENCY", pList, gAdjacency, ARRAYSIZE( gAdjacency ));
|
||||
}
|
||||
|
||||
SV_SaveBuffer( f, LUMP_ADJACENCY, false );
|
||||
|
||||
// write entity descriptions
|
||||
for( i = 0; i < svgame.globals->numEntities; i++ )
|
||||
{
|
||||
edict_t *pent = EDICT_NUM( i );
|
||||
|
||||
if( pent->free ) continue;
|
||||
svgame.dllFuncs.pfnSave( pent, pSaveData );
|
||||
if( !pent->free && pent->v.classname )
|
||||
svgame.dllFuncs.pfnSave( pent, pSaveData );
|
||||
pSaveData->currentIndex++; // move pointer
|
||||
}
|
||||
|
||||
SV_SaveBuffer( f, LUMP_ENTITIES, false );
|
||||
|
||||
// write entity table
|
||||
for( i = 0; i < pSaveData->tableCount; i++ )
|
||||
{
|
||||
|
@ -209,12 +243,7 @@ static void SV_SaveServerData( wfile_t *f )
|
|||
}
|
||||
|
||||
// write result into lump
|
||||
SV_AddSaveLump( f, LUMP_ENTITIES, pSaveData->pBaseData, pSaveData->size, false );
|
||||
|
||||
// clear buffer for global lump
|
||||
Mem_Set( pSaveData->pBaseData, 0, pSaveData->size );
|
||||
pSaveData->pCurrentData = pSaveData->pBaseData;
|
||||
pSaveData->size = 0;
|
||||
SV_SaveBuffer( f, LUMP_ENTTABLE, false );
|
||||
|
||||
// write game header
|
||||
svgame.dllFuncs.pfnSaveWriteFields( pSaveData, "Game Header", &ghdr, gGameHeader, ARRAYSIZE( gGameHeader ));
|
||||
|
@ -223,12 +252,23 @@ static void SV_SaveServerData( wfile_t *f )
|
|||
svgame.dllFuncs.pfnSaveGlobalState( pSaveData );
|
||||
|
||||
// write result into lump
|
||||
SV_AddSaveLump( f, LUMP_GLOBALS, pSaveData->pBaseData, pSaveData->size, false );
|
||||
SV_SaveBuffer( f, LUMP_GLOBALS, false );
|
||||
|
||||
// save used hash strings
|
||||
for( i = numstrings = 0; i < svgame.SaveData.tokenCount; i++ )
|
||||
{
|
||||
if( !svgame.SaveData.pTokens[i] ) continue;
|
||||
hash_strings[numstrings] = StringTable_SetString( svgame.hStringTable, svgame.SaveData.pTokens[i] );
|
||||
numstrings++;
|
||||
}
|
||||
|
||||
// save hash table
|
||||
SV_AddSaveLump( f, LUMP_HASHTABLE, hash_strings, numstrings * sizeof( string_t ), true );
|
||||
|
||||
// do cleanup operations
|
||||
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
|
||||
svgame.globals->pSaveData = NULL;
|
||||
Mem_FreePool( &savepool );
|
||||
Mem_FreePool( &svgame.temppool );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -268,7 +308,7 @@ void SV_WriteSaveFile( const char *name, bool autosave )
|
|||
// write lumps
|
||||
SV_SaveEngineData( savfile );
|
||||
SV_SaveServerData( savfile );
|
||||
StringTable_Save( svgame.hStringTable, savfile );
|
||||
StringTable_Save( svgame.hStringTable, savfile ); // must be last
|
||||
|
||||
WAD_Close( savfile );
|
||||
|
||||
|
@ -279,29 +319,35 @@ void SV_ReadComment( wfile_t *l )
|
|||
{
|
||||
SAVERESTOREDATA *pSaveData;
|
||||
game_header_t ghdr;
|
||||
int i;
|
||||
|
||||
// initialize SAVERESTOREDATA
|
||||
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
|
||||
svgame.SaveData.pBaseData = WAD_Read( l, LUMP_GLOBALS, &svgame.SaveData.bufferSize, TYPE_BINDATA );
|
||||
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
|
||||
svgame.SaveData.tokenCount = 0xFFF; // assume a maximum of 4K-1 symbol table entries
|
||||
svgame.SaveData.pTokens = (char **)Z_Malloc( svgame.SaveData.tokenCount * sizeof( char* ));
|
||||
pSaveData = svgame.globals->pSaveData = &svgame.SaveData;
|
||||
SV_ReadBuffer( l, LUMP_GLOBALS );
|
||||
|
||||
// TEST: tokenize strings
|
||||
for( i = 0; i < ARRAYSIZE( gGameHeader ); i++ )
|
||||
TokenHash( gGameHeader[i].fieldName, svgame.SaveData.pTokens, svgame.SaveData.tokenCount );
|
||||
SV_UpdateTokens( gGameHeader, ARRAYSIZE( gGameHeader ));
|
||||
|
||||
// read game header
|
||||
svgame.dllFuncs.pfnSaveReadFields( pSaveData, "Game Header", &ghdr, gGameHeader, ARRAYSIZE( gGameHeader ));
|
||||
|
||||
com.strncpy( svs.comment, ghdr.comment, CS_SIZE );
|
||||
if( svgame.SaveData.pTokens ) Mem_Free( svgame.SaveData.pTokens );
|
||||
if( svgame.SaveData.pBaseData ) Mem_Free( svgame.SaveData.pBaseData );
|
||||
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
|
||||
}
|
||||
|
||||
void SV_ReadHashTable( wfile_t *l )
|
||||
{
|
||||
string_t *in_table;
|
||||
int i, hash_size;
|
||||
|
||||
in_table = (string_t *)WAD_Read( l, LUMP_HASHTABLE, &hash_size, TYPE_BINDATA );
|
||||
|
||||
for( i = 0; i < hash_size / sizeof( string_t ); i++, in_table++ )
|
||||
SV_TokenHash( STRING( *in_table ));
|
||||
}
|
||||
|
||||
void SV_ReadCvars( wfile_t *l )
|
||||
{
|
||||
dkeyvalue_t *in;
|
||||
|
@ -346,24 +392,19 @@ void SV_ReadAreaPortals( wfile_t *l )
|
|||
void SV_ReadGlobals( wfile_t *l )
|
||||
{
|
||||
SAVERESTOREDATA *pSaveData;
|
||||
byte *restorepool;
|
||||
game_header_t ghdr;
|
||||
int i;
|
||||
|
||||
// initialize local mempool
|
||||
// restorepool = Mem_AllocPool( "Restore Pool" );
|
||||
svgame.temppool = Mem_AllocPool( "Restore Pool" );
|
||||
|
||||
// initialize SAVERESTOREDATA
|
||||
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
|
||||
svgame.SaveData.pBaseData = WAD_Read( l, LUMP_GLOBALS, &svgame.SaveData.bufferSize, TYPE_BINDATA );
|
||||
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
|
||||
svgame.SaveData.tokenCount = 0xFFF; // assume a maximum of 4K-1 symbol table entries
|
||||
svgame.SaveData.pTokens = Mem_Alloc( svgame.mempool, svgame.SaveData.tokenCount * sizeof( char* ));
|
||||
svgame.SaveData.pTokens = Mem_Alloc( svgame.temppool, svgame.SaveData.tokenCount * sizeof( char* ));
|
||||
pSaveData = svgame.globals->pSaveData = &svgame.SaveData;
|
||||
SV_ReadBuffer( l, LUMP_GLOBALS );
|
||||
|
||||
// TEST: tokenize strings
|
||||
for( i = 0; i < ARRAYSIZE( gGameHeader ); i++ )
|
||||
TokenHash( gGameHeader[i].fieldName, svgame.SaveData.pTokens, svgame.SaveData.tokenCount );
|
||||
SV_ReadHashTable( l );
|
||||
|
||||
// read the game header
|
||||
svgame.dllFuncs.pfnSaveReadFields( pSaveData, "Game Header", &ghdr, gGameHeader, ARRAYSIZE( gGameHeader ));
|
||||
|
@ -376,49 +417,50 @@ void SV_ReadGlobals( wfile_t *l )
|
|||
svgame.dllFuncs.pfnRestoreGlobalState( pSaveData );
|
||||
svgame.dllFuncs.pfnServerDeactivate();
|
||||
|
||||
//Mem_FreePool( &restorepool );
|
||||
// leave pool unfreed, because we have partially filled hash tokens
|
||||
}
|
||||
|
||||
void SV_RestoreEdict( edict_t *ent )
|
||||
{
|
||||
SV_SetPhysForce( ent ); // restore forces ...
|
||||
SV_SetMassCentre( ent ); // and mass force
|
||||
}
|
||||
|
||||
void SV_ReadEntities( wfile_t *l )
|
||||
{
|
||||
SAVERESTOREDATA *pSaveData;
|
||||
byte *restorepool;
|
||||
ENTITYTABLE *pTable;
|
||||
LEVELLIST *pList;
|
||||
save_header_t shdr;
|
||||
int i;
|
||||
|
||||
// initialize local mempool
|
||||
//restorepool = Mem_AllocPool( "Restore Pool" );
|
||||
|
||||
// SAVERESTOREDATA partially initialized, continue filling
|
||||
pSaveData = svgame.globals->pSaveData = &svgame.SaveData;
|
||||
svgame.SaveData.pBaseData = WAD_Read( l, LUMP_ENTITIES, &svgame.SaveData.bufferSize, TYPE_BINDATA );
|
||||
svgame.SaveData.pCurrentData = svgame.SaveData.pBaseData;
|
||||
svgame.SaveData.size = 0;
|
||||
SV_ReadBuffer( l, LUMP_ADJACENCY );
|
||||
|
||||
// TEST: tokenize strings
|
||||
for( i = 0; i < ARRAYSIZE( gSaveHeader ); i++ )
|
||||
TokenHash( gSaveHeader[i].fieldName, svgame.SaveData.pTokens, svgame.SaveData.tokenCount );
|
||||
|
||||
// read save header
|
||||
svgame.dllFuncs.pfnSaveReadFields( pSaveData, "Save Header", &shdr, gSaveHeader, ARRAYSIZE( gSaveHeader ));
|
||||
|
||||
SV_ConfigString( CS_MAXCLIENTS, va("%i", Host_MaxClients()));
|
||||
SV_ConfigString( CS_MAXCLIENTS, va( "%i", Host_MaxClients( )));
|
||||
com.strncpy( sv.name, shdr.mapName, MAX_STRING );
|
||||
svgame.globals->mapname = MAKE_STRING( sv.name );
|
||||
svgame.globals->time = sv.time = shdr.time;
|
||||
pSaveData->connectionCount = shdr.numConnections;
|
||||
|
||||
// read ADJACENCY sections
|
||||
for( i = 0; i < pSaveData->connectionCount; i++ )
|
||||
{
|
||||
pList = &pSaveData->levelList[i];
|
||||
svgame.dllFuncs.pfnSaveReadFields( pSaveData, "ADJACENCY", pList, gAdjacency, ARRAYSIZE( gAdjacency ));
|
||||
}
|
||||
|
||||
// initialize ENTITYTABLE
|
||||
pSaveData->tableCount = shdr.numEntities;
|
||||
pSaveData->pTable = Mem_Alloc( svgame.mempool, pSaveData->tableCount * sizeof( ENTITYTABLE ));
|
||||
pSaveData->pTable = Mem_Alloc( svgame.temppool, pSaveData->tableCount * sizeof( ENTITYTABLE ));
|
||||
while( svgame.globals->numEntities < shdr.numEntities ) SV_AllocEdict(); // allocate edicts
|
||||
|
||||
// TEST: tokenize strings
|
||||
for( i = 0; i < ARRAYSIZE( gETable ); i++ )
|
||||
TokenHash( gETable[i].fieldName, svgame.SaveData.pTokens, svgame.SaveData.tokenCount );
|
||||
|
||||
SV_ReadBuffer( l, LUMP_ENTTABLE );
|
||||
|
||||
// read entity table
|
||||
for( i = 0; i < pSaveData->tableCount; i++ )
|
||||
{
|
||||
|
@ -430,20 +472,13 @@ void SV_ReadEntities( wfile_t *l )
|
|||
if( pTable->id != pent->serialnumber )
|
||||
MsgDev( D_ERROR, "ETABLE id( %i ) != edict->id( %i )\n", pTable->id, pent->serialnumber );
|
||||
if( pTable->flags & FENTTABLE_REMOVED ) SV_FreeEdict( pent );
|
||||
else pent = SV_AllocPrivateData( pent, pTable->classname );
|
||||
pTable->pent = pent;
|
||||
}
|
||||
|
||||
// TEST: tokenize strings
|
||||
for( i = 0; i < ARRAYSIZE( gAdjacency ); i++ )
|
||||
TokenHash( gAdjacency[i].fieldName, svgame.SaveData.pTokens, svgame.SaveData.tokenCount );
|
||||
SV_ReadBuffer( l, LUMP_ENTITIES );
|
||||
pSaveData->fUseLandmark = true;
|
||||
|
||||
// read ADJACENCY sections
|
||||
for( i = 0; i < pSaveData->connectionCount; i++ )
|
||||
{
|
||||
pList = &pSaveData->levelList[i];
|
||||
svgame.dllFuncs.pfnSaveReadFields( pSaveData, "ADJACENCY", pList, gAdjacency, ARRAYSIZE( gAdjacency ));
|
||||
}
|
||||
Com_Assert( 1 );
|
||||
// and read entities ...
|
||||
for( i = 0; i < pSaveData->tableCount; i++ )
|
||||
{
|
||||
|
@ -451,14 +486,18 @@ void SV_ReadEntities( wfile_t *l )
|
|||
pTable = &pSaveData->pTable[i];
|
||||
|
||||
// ignore removed edicts
|
||||
if( pTable->flags & FENTTABLE_REMOVED ) continue;
|
||||
svgame.dllFuncs.pfnRestore( pent, pSaveData, (pTable->flags & FENTTABLE_GLOBAL));
|
||||
if( !pent->free && pTable->classname )
|
||||
{
|
||||
svgame.dllFuncs.pfnRestore( pent, pSaveData, false );
|
||||
SV_RestoreEdict( pent );
|
||||
}
|
||||
pSaveData->currentIndex++;
|
||||
}
|
||||
|
||||
|
||||
// do cleanup operations
|
||||
Mem_Set( &svgame.SaveData, 0, sizeof( SAVERESTOREDATA ));
|
||||
svgame.globals->pSaveData = NULL;
|
||||
//Mem_FreePool( &restorepool );
|
||||
Mem_FreePool( &svgame.temppool );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -544,13 +583,4 @@ bool SV_GetComment( char *comment, int savenum )
|
|||
WAD_Close( savfile );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SV_RestoreEdict( edict_t *ent )
|
||||
{
|
||||
// link it into the bsp tree
|
||||
SV_LinkEdict( ent );
|
||||
SV_CreatePhysBody( ent );
|
||||
SV_SetPhysForce( ent ); // restore forces ...
|
||||
SV_SetMassCentre( ent ); // and mass force
|
||||
}
|
|
@ -289,7 +289,7 @@ int StringTable_CreateNewSystem( const char *name, size_t max_strings )
|
|||
{
|
||||
// found free slot
|
||||
dstring[i] = Mem_Alloc( Sys.basepool, sizeof( stringtable_t ));
|
||||
dstring[i]->mempool = Mem_AllocPool( va( "StringTable_%s", name ));
|
||||
dstring[i]->mempool = Mem_AllocPool( va( "StringTable_%s", name ));
|
||||
com.strncpy( dstring[i]->name, name, MAX_STRING );
|
||||
dstring[i]->maxdatasize = max_strings * 8;
|
||||
dstring[i]->maxstrings = max_strings;
|
||||
|
@ -393,13 +393,22 @@ bool StringTable_SaveSystem( int h, wfile_t *wad )
|
|||
|
||||
int StringTable_LoadSystem( wfile_t *wad, const char *name )
|
||||
{
|
||||
int datasize, table_size;
|
||||
int h = StringTable_CreateNewSystem( name, 0x10000 ); // 65535 unique strings
|
||||
int datasize, numstrings;
|
||||
char *data = (char *)W_LoadLump( wad, "stringdata", &datasize, TYPE_STRDATA );
|
||||
int *table = (int *)W_LoadLump( wad, "stringtable", &table_size, TYPE_STRDATA );
|
||||
|
||||
dstring[h]->data = W_LoadLump( wad, "stringdata", &datasize, TYPE_STRDATA );
|
||||
dstring[h]->table = (int *)W_LoadLump( wad, "stringtable", &numstrings, TYPE_STRDATA );
|
||||
if(( datasize > dstring[h]->maxdatasize ) || ((table_size / sizeof( int )) > dstring[h]->maxstrings ))
|
||||
Sys_Error( "Too small StringTable for loading\n" );
|
||||
|
||||
#ifndef ST_STATIC_ALLOCATE
|
||||
dstring[h]->data = Mem_Realloc( dstring[handle]->mempool, dstring[handle]->data, datasize );
|
||||
dstring[h]->table = Mem_Realloc( dstring[handle]->mempool, dstring[handle]->table, table_size );
|
||||
#endif
|
||||
Mem_Copy( dstring[h]->data, data, datasize );
|
||||
Mem_Copy( dstring[h]->table, table, table_size );
|
||||
dstring[h]->datasize = datasize;
|
||||
dstring[h]->numstrings = numstrings / sizeof(int);
|
||||
dstring[h]->numstrings = table_size / sizeof( int );
|
||||
return h;
|
||||
}
|
||||
|
||||
|
|
|
@ -903,9 +903,12 @@ included global, and both (client & server) pent list
|
|||
*/
|
||||
#define LUMP_CFGSTRING "configstrings"
|
||||
#define LUMP_AREASTATE "areaportals"
|
||||
#define LUMP_ENTITIES "entities"
|
||||
#define LUMP_GLOBALS "global_data"
|
||||
#define LUMP_ENTITIES "entities" // entvars + CBase->fields
|
||||
#define LUMP_ENTTABLE "enttable" // entity transition table
|
||||
#define LUMP_ADJACENCY "adjacency" // Save Header + ADJACENCY
|
||||
#define LUMP_GLOBALS "global_data" // Game Header + Global State
|
||||
#define LUMP_GAMECVARS "latched_cvars"
|
||||
#define LUMP_HASHTABLE "hashtable" // contains string_t only for used hash-values
|
||||
#define LUMP_SNAPSHOT "saveshot" // currently not implemented
|
||||
|
||||
#define DENT_KEY 0
|
||||
|
|
|
@ -228,7 +228,7 @@ typedef struct
|
|||
} ENTITYTABLE;
|
||||
|
||||
#define FTYPEDESC_GLOBAL 0x0001 // This field is masked for global entity save/restore
|
||||
#define MAX_LEVEL_CONNECTIONS 32 // These are encoded in the lower 16bits of ENTITYTABLE->flags
|
||||
#define MAX_LEVEL_CONNECTIONS 16 // These are encoded in the lower 16bits of ENTITYTABLE->flags
|
||||
|
||||
#define FENTTABLE_GLOBAL 0x10000000
|
||||
#define FENTTABLE_MOVEABLE 0x20000000
|
||||
|
@ -300,6 +300,7 @@ typedef struct
|
|||
#define DEFINE_FIELD( type, name, fieldtype ) _FIELD( type, name, fieldtype, 1, 0 )
|
||||
#define DEFINE_ARRAY( type, name, fieldtype, count ) _FIELD( type, name, fieldtype, count, 0 )
|
||||
#define DEFINE_ENTITY_FIELD( name, fieldtype ) _FIELD( entvars_t, name, fieldtype, 1, 0 )
|
||||
#define DEFINE_ENTITY_FIELD_ARRAY( name, fieldtype, count ) _FIELD( entvars_t, name, fieldtype, count, 0 )
|
||||
#define DEFINE_ENTITY_GLOBAL_FIELD( name, fieldtype ) _FIELD( entvars_t, name, fieldtype, 1, FTYPEDESC_GLOBAL )
|
||||
#define DEFINE_GLOBAL_FIELD( type, name, fieldtype ) _FIELD( type, name, fieldtype, 1, FTYPEDESC_GLOBAL )
|
||||
|
||||
|
|
|
@ -71,5 +71,5 @@ if exist vsound\vsound.plg del /f /q vsound\vsound.plg
|
|||
echo Build succeeded!
|
||||
echo Please wait. Xash is now loading
|
||||
cd D:\Xash3D\
|
||||
quake.exe -game tmpQuArK -dev 3 -log +map dm_knot
|
||||
quake.exe -game tmpQuArK -dev 3 -log +map qctest
|
||||
:done
|
|
@ -891,7 +891,10 @@ int CBaseEntity :: Restore( CRestore &restore )
|
|||
status = restore.ReadEntVars( "ENTVARS", pev );
|
||||
if( status ) status = restore.ReadFields( "BASE", this, m_SaveData, ARRAYSIZE( m_SaveData ));
|
||||
|
||||
if( pev->modelindex != 0 && !FStringNull( pev->model ))
|
||||
// restore edict class here
|
||||
SetObjectClass( m_iClassType );
|
||||
|
||||
if( pev->modelindex != 0 && !FStringNull( pev->model ))
|
||||
{
|
||||
Vector mins = pev->mins, maxs = pev->maxs; // Set model is about to destroy these
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//=======================================================================
|
||||
// Copyright (C) Shambler Team 2004
|
||||
// logicentity.cpp - all entities with prefix "logic_"
|
||||
// logicentity.cpp - all entities with prefix "logic_"
|
||||
// additional entities for smart system
|
||||
//=======================================================================
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
//=======================================================================
|
||||
// Copyright (C) XashXT Group 2008
|
||||
//=======================================================================
|
||||
|
||||
#include "extdll.h"
|
||||
#include "utils.h"
|
||||
#include "cbase.h"
|
||||
#include "client.h"
|
||||
|
||||
class CPhysEntity : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
void Precache( void )
|
||||
{
|
||||
UTIL_PrecacheModel( pev->model, (char *)Model() );
|
||||
}
|
||||
void Spawn( void )
|
||||
{
|
||||
Precache();
|
||||
|
||||
pev->movetype = MOVETYPE_PHYSIC;
|
||||
pev->solid = SolidType();
|
||||
pev->owner = ENT( pev ); // g-cont. i'm forget what for needs this stuff :)
|
||||
|
||||
UTIL_SetOrigin( this, pev->origin );
|
||||
UTIL_SetModel( ENT( pev ), pev->model, (char *)Model() );
|
||||
|
||||
SetObjectClass( ED_RIGIDBODY );
|
||||
}
|
||||
virtual const char *Model( void ){ return NULL; }
|
||||
virtual int SolidType( void ){ return SOLID_MESH; } // generic but slow
|
||||
void PostActivate( void ) { } // stub
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( func_physbox, CPhysEntity );
|
||||
|
||||
// some rigid bodies for Xash3D 0.56 beta
|
||||
class CPhysSphere : public CPhysEntity
|
||||
{
|
||||
public:
|
||||
virtual const char *Model( void ){ return "models/props/nexplode.mdl"; }
|
||||
virtual int SolidType( void ){ return SOLID_SPHERE; }
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( misc_sphere, CPhysSphere );
|
||||
|
||||
class CPhysBarrel : public CPhysEntity
|
||||
{
|
||||
public:
|
||||
virtual const char *Model( void ){ return "models/props/barrel2.mdl"; }
|
||||
virtual int SolidType( void ){ return SOLID_CYLINDER; }
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( misc_barrel, CPhysBarrel );
|
||||
|
||||
class CPhysBox : public CPhysEntity
|
||||
{
|
||||
public:
|
||||
virtual const char *Model( void ){ return "models/props/box.mdl"; }
|
||||
virtual int SolidType( void ){ return SOLID_BOX; }
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS( misc_physbox, CPhysBox );
|
|
@ -239,11 +239,12 @@ int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity
|
|||
{
|
||||
CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);
|
||||
|
||||
if ( pEntity && pSaveData )
|
||||
if( pEntity && pSaveData )
|
||||
{
|
||||
entvars_t tmpVars;
|
||||
Vector oldOffset;
|
||||
|
||||
ALERT( at_console, "DispatchRestore( %s )\n", STRING( pent->v.classname ));
|
||||
CRestore restoreHelper( pSaveData );
|
||||
if ( globalEntity )
|
||||
{
|
||||
|
|
|
@ -95,7 +95,17 @@ TYPEDESCRIPTION gEntvarsDescription[] =
|
|||
|
||||
DEFINE_ENTITY_FIELD( spawnflags, FIELD_INTEGER ),
|
||||
DEFINE_ENTITY_FIELD( flags, FIELD_INTEGER64 ),
|
||||
|
||||
#if 0
|
||||
DEFINE_ENTITY_FIELD_ARRAY( m_pmatrix, FIELD_VECTOR, 3 ),
|
||||
DEFINE_ENTITY_FIELD_ARRAY( m_pcentre, FIELD_VECTOR, 3 ),
|
||||
#else
|
||||
DEFINE_ENTITY_FIELD( m_pmatrix[0], FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( m_pmatrix[1], FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( m_pmatrix[2], FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( m_pcentre[0], FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( m_pcentre[1], FIELD_VECTOR ),
|
||||
DEFINE_ENTITY_FIELD( m_pcentre[2], FIELD_VECTOR ),
|
||||
#endif
|
||||
DEFINE_ENTITY_FIELD( colormap, FIELD_INTEGER ),
|
||||
DEFINE_ENTITY_FIELD( team, FIELD_INTEGER ),
|
||||
|
||||
|
@ -988,8 +998,6 @@ void CRestore::BufferReadHeader( HEADER *pheader )
|
|||
pheader->token = ReadShort(); // Read field name token
|
||||
pheader->pData = BufferPointer(); // Field Data is next
|
||||
BufferSkipBytes( pheader->size ); // Advance to next field
|
||||
|
||||
ALERT( at_console, "header.token is %i\n", pheader->token );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -185,6 +185,10 @@ SOURCE=.\ents\basepath.cpp
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ents\basephys.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ents\baserockets.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
Reference in New Issue