mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2024-11-25 13:31:12 +00:00
202 lines
8.7 KiB
C
202 lines
8.7 KiB
C
|
/*
|
||
|
===========================================================================
|
||
|
|
||
|
Doom 3 BFG Edition GPL Source Code
|
||
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||
|
|
||
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||
|
|
||
|
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||
|
|
||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||
|
|
||
|
===========================================================================
|
||
|
*/
|
||
|
#ifndef __SNAPSHOT_H__
|
||
|
#define __SNAPSHOT_H__
|
||
|
|
||
|
#include "snapshot_jobs.h"
|
||
|
|
||
|
extern idCVar net_verboseSnapshot;
|
||
|
#define NET_VERBOSESNAPSHOT_PRINT if ( net_verboseSnapshot.GetInteger() > 0 ) idLib::Printf
|
||
|
#define NET_VERBOSESNAPSHOT_PRINT_LEVEL( X, Y ) if ( net_verboseSnapshot.GetInteger() >= ( X ) ) idLib::Printf( Y )
|
||
|
|
||
|
/*
|
||
|
A snapshot contains a list of objects and their states
|
||
|
*/
|
||
|
class idSnapShot {
|
||
|
public:
|
||
|
idSnapShot();
|
||
|
idSnapShot( const idSnapShot & other );
|
||
|
~idSnapShot();
|
||
|
|
||
|
void operator=( const idSnapShot & other );
|
||
|
|
||
|
// clears the snapshot
|
||
|
void Clear();
|
||
|
|
||
|
int GetTime() const { return time; }
|
||
|
void SetTime( int t ) { time = t; }
|
||
|
|
||
|
int GetRecvTime() const { return recvTime; }
|
||
|
void SetRecvTime( int t ) { recvTime = t; }
|
||
|
|
||
|
// Loads only sequence and baseSequence values from the compressed stream
|
||
|
static void PeekDeltaSequence( const char * deltaMem, int deltaSize, int & sequence, int & baseSequence );
|
||
|
|
||
|
// Reads a new object state packet, which is assumed to be delta compressed against this snapshot
|
||
|
bool ReadDeltaForJob( const char * deltaMem, int deltaSize, int visIndex, idSnapShot * templateStates );
|
||
|
bool ReadDelta( idFile * file, int visIndex );
|
||
|
|
||
|
// Writes an object state packet which is delta compressed against the old snapshot
|
||
|
struct objectBuffer_t {
|
||
|
objectBuffer_t() : data( NULL ), size( 0 ) { }
|
||
|
objectBuffer_t( int s ) : data( NULL ), size( s ) { Alloc( s ); }
|
||
|
objectBuffer_t( const objectBuffer_t & o ) : data( NULL ), size( 0 ) { *this = o; }
|
||
|
~objectBuffer_t() { _Release(); }
|
||
|
void Alloc( int size );
|
||
|
int NumRefs() { return data == NULL ? 0 : data[size]; }
|
||
|
objectSize_t Size() const { return size; }
|
||
|
byte * Ptr() { return data == NULL ? NULL : data ; }
|
||
|
byte & operator[]( int i ) { return data[i]; }
|
||
|
void operator=( const objectBuffer_t & other );
|
||
|
|
||
|
// (not making private because of idSnapshot)
|
||
|
void _AddRef();
|
||
|
void _Release();
|
||
|
private:
|
||
|
byte * data;
|
||
|
objectSize_t size;
|
||
|
};
|
||
|
|
||
|
struct objectState_t {
|
||
|
objectState_t() :
|
||
|
objectNum( 0 ),
|
||
|
visMask( MAX_UNSIGNED_TYPE( uint32 ) ),
|
||
|
stale( false ),
|
||
|
deleted( false ),
|
||
|
changedCount( 0 ),
|
||
|
createdFromTemplate( false ),
|
||
|
|
||
|
expectedSequence( 0 )
|
||
|
{ }
|
||
|
void Print( const char * name );
|
||
|
|
||
|
uint16 objectNum;
|
||
|
objectBuffer_t buffer;
|
||
|
uint32 visMask;
|
||
|
bool stale; // easy way for clients to check if ss obj is stale. Probably temp till client side of vismask system is more fleshed out
|
||
|
bool deleted;
|
||
|
int changedCount; // Incremented each time the state changed
|
||
|
int expectedSequence;
|
||
|
bool createdFromTemplate;
|
||
|
};
|
||
|
|
||
|
struct submitDeltaJobsInfo_t {
|
||
|
objParms_t * objParms; // Start of object parms
|
||
|
int maxObjParms; // Max parms (which will dictate how many objects can be processed)
|
||
|
uint8 * objMemory; // Memory that objects were written out to
|
||
|
objHeader_t * headers; // Memory for headers
|
||
|
int maxHeaders;
|
||
|
int maxObjMemory; // Max memory (which will dictate when syncs need to occur)
|
||
|
lzwParm_t * lzwParms; // Start of lzw parms
|
||
|
int maxDeltaParms; // Max lzw parms (which will dictate how many syncs we can have)
|
||
|
|
||
|
idSnapShot * oldSnap; // snap we are comparing this snap to (to produce a delta)
|
||
|
int visIndex;
|
||
|
int baseSequence;
|
||
|
|
||
|
idSnapShot * templateStates; // states for new snapObj that arent in old states
|
||
|
|
||
|
lzwInOutData_t * lzwInOutData;
|
||
|
};
|
||
|
|
||
|
void SubmitWriteDeltaToJobs( const submitDeltaJobsInfo_t & submitDeltaJobInfo );
|
||
|
|
||
|
bool WriteDelta( idSnapShot & old, int visIndex, idFile * file, int maxLength, int optimalLength = 0 );
|
||
|
|
||
|
// Adds an object to the state, overwrites any existing object with the same number
|
||
|
objectState_t * S_AddObject( int objectNum, uint32 visMask, const idBitMsg & msg, const char * tag = NULL ) { return S_AddObject( objectNum, visMask, msg.GetReadData(), msg.GetSize(), tag ); }
|
||
|
objectState_t * S_AddObject( int objectNum, uint32 visMask, const byte * buffer, int size, const char * tag = NULL ) { return S_AddObject( objectNum, visMask, (const char *)buffer, size, tag ); }
|
||
|
objectState_t * S_AddObject( int objectNum, uint32 visMask, const char * buffer, int size, const char * tag = NULL );
|
||
|
bool CopyObject( const idSnapShot & oldss, int objectNum, bool forceStale = false );
|
||
|
int CompareObject( const idSnapShot * oldss, int objectNum, int start=0, int end=0, int oldStart=0 );
|
||
|
|
||
|
// returns the number of objects in this snapshot
|
||
|
int NumObjects() const { return objectStates.Num(); }
|
||
|
|
||
|
// Returns the object number of the specified object, also fills the bitmsg
|
||
|
int GetObjectMsgByIndex( int i, idBitMsg & msg, bool ignoreIfStale = false ) const;
|
||
|
|
||
|
// returns true if the object was found in the snapshot
|
||
|
bool GetObjectMsgByID( int objectNum, idBitMsg & msg, bool ignoreIfStale = false ) { return GetObjectMsgByIndex( FindObjectIndexByID( objectNum ), msg, ignoreIfStale ) == objectNum; }
|
||
|
|
||
|
// returns the object index or -1 if it's not found
|
||
|
int FindObjectIndexByID( int objectNum ) const;
|
||
|
|
||
|
// returns the object by id, or NULL if not found
|
||
|
objectState_t * FindObjectByID( int objectNum ) const;
|
||
|
|
||
|
// Returns whether or not an object is stale
|
||
|
bool ObjectIsStaleByIndex( int i ) const;
|
||
|
|
||
|
int ObjectChangedCountByIndex( int i ) const;
|
||
|
|
||
|
// clears the empty states from the snapshot snapshot
|
||
|
void CleanupEmptyStates();
|
||
|
|
||
|
void PrintReport();
|
||
|
|
||
|
void UpdateExpectedSeq( int newSeq );
|
||
|
|
||
|
void ApplyToExistingState( int objId, idBitMsg & msg );
|
||
|
objectState_t * GetTemplateState( int objNum, idSnapShot * templateStates, objectState_t * newState = NULL );
|
||
|
|
||
|
void RemoveObject( int objId );
|
||
|
|
||
|
private:
|
||
|
|
||
|
idList< objectState_t *, TAG_IDLIB_LIST_SNAPSHOT> objectStates;
|
||
|
idBlockAlloc< objectState_t, 16, TAG_NETWORKING > allocatedObjs;
|
||
|
|
||
|
int time;
|
||
|
int recvTime;
|
||
|
|
||
|
int BinarySearch( int objectNum ) const;
|
||
|
objectState_t & FindOrCreateObjectByID( int objectNum ); // objIndex is optional parm for returning the index of the obj
|
||
|
|
||
|
void SubmitObjectJob( const submitDeltaJobsInfo_t & submitDeltaJobsInfo, // Struct containing parameters originally passed in to SubmitWriteDeltaToJobs
|
||
|
objectState_t * newState, // New obj state (can be NULL, which means deleted)
|
||
|
objectState_t * oldState, // Old obj state (can be NULL, which means new)
|
||
|
objParms_t *& baseObjParm, // Starting obj parm of current stream
|
||
|
objParms_t *& curObjParm, // Current obj parm of current stream
|
||
|
objHeader_t *& curHeader, // Current header dest
|
||
|
uint8 *& curObjDest, // Current write pos of current obj
|
||
|
lzwParm_t *& curlzwParm ); // Current delta parm for next lzw job
|
||
|
void SubmitLZWJob(
|
||
|
const submitDeltaJobsInfo_t & writeDeltaInfo, // Struct containing parameters originally passed in to SubmitWriteDeltaToJobs
|
||
|
objParms_t *& baseObjParm, // Pointer to the first obj parm for the current stream
|
||
|
objParms_t *& curObjParm, // Current obj parm
|
||
|
lzwParm_t *& curlzwParm, // Current delta parm
|
||
|
bool saveDictionary // If true, this is the first of several calls which will be appended
|
||
|
);
|
||
|
|
||
|
void WriteObject( idFile * file, int visIndex, objectState_t * newState, objectState_t * oldState, int & lastobjectNum );
|
||
|
void FreeObjectState( int index );
|
||
|
};
|
||
|
|
||
|
#endif // __SNAPSHOT_H__
|