2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
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 __SNAP_PROCESSOR_H__
# define __SNAP_PROCESSOR_H__
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2012-11-28 15:47:07 +00:00
idSnapshotProcessor
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
class idSnapshotProcessor
{
2012-11-26 18:58:24 +00:00
public :
static const int INITIAL_SNAP_SEQUENCE = 42 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idSnapshotProcessor ( ) ;
~ idSnapshotProcessor ( ) ;
void Reset ( bool cstor = false ) ;
2012-11-28 15:47:07 +00:00
// TrySetPendingSnapshot Sets the currently pending snap.
2012-11-26 18:58:24 +00:00
// No new snaps will be sent until this snap has been fully sent.
// Returns true of the newly supplied snapshot was accepted (there were no pending snaps)
2012-11-28 15:47:07 +00:00
bool TrySetPendingSnapshot ( idSnapShot & ss ) ;
2012-11-26 18:58:24 +00:00
// Peek into delta to get deltaSequence, and deltaBaseSequence
2012-11-28 15:47:07 +00:00
void PeekDeltaSequence ( const char * deltaMem , int deltaSize , int & deltaSequence , int & deltaBaseSequence ) ;
2012-11-26 18:58:24 +00:00
// Apply a delta to the supplied snapshot
2012-11-28 15:47:07 +00:00
bool ApplyDeltaToSnapshot ( idSnapShot & snap , const char * deltaMem , int deltaSize , int visIndex ) ;
2012-11-26 18:58:24 +00:00
// Attempts to write the currently pending snap to the supplied buffer, which can then be sent as an unreliable msg.
// SubmitPendingSnap will submit the pending snap to a job, so that it can be retrieved later for sending.
2012-11-28 15:47:07 +00:00
void SubmitPendingSnap ( int visIndex , uint8 * objMemory , int objMemorySize , lzwCompressionData_t * lzwData ) ;
2012-11-26 18:58:24 +00:00
// GetPendingSnapDelta
2012-11-28 15:47:07 +00:00
int GetPendingSnapDelta ( byte * outBuffer , int maxLength ) ;
2012-11-26 18:58:24 +00:00
// If PendingSnapReadyToSend is true, then GetPendingSnapDelta will return something to send
2012-11-28 15:47:07 +00:00
bool PendingSnapReadyToSend ( ) const
{
return jobMemory - > lzwInOutData . numlzwDeltas > 0 ;
}
2012-11-26 18:58:24 +00:00
// When you call WritePendingSnapshot, and then send the resulting buffer as a unreliable msg, you will eventually
// receive this on the client. Call this function to receive and apply it to the base state, and possibly return a fully received snap
// to then apply to the client game state
2012-11-28 15:47:07 +00:00
bool ReceiveSnapshotDelta ( const byte * deltaData , int deltaLength , int visIndex , int & outSeq , int & outBaseSeq , idSnapShot & outSnap , bool & fullSnap ) ;
2012-11-26 18:58:24 +00:00
// Function to apply a received (or ack'd) delta to the base state
bool ApplySnapshotDelta ( int visIndex , int snapshotNumber ) ;
// Remove deltas for basestate we no longer have.
// We know we can remove them, because we will never be able to apply them, since
// the basestate needed to generate a full snap from these deltas is gone.
void RemoveDeltasForOldBaseSequence ( ) ;
// Make sure delta sequence and basesequence values are valid, and in order, etc
void SanityCheckDeltas ( ) ;
// HasPendingSnap will return true if there is more of the last TrySetPendingSnapshot to be sent
2012-11-28 15:47:07 +00:00
bool HasPendingSnap ( ) const
{
return hasPendingSnap ;
}
idSnapShot * GetBaseState ( )
{
return & baseState ;
}
idSnapShot * GetPendingSnap ( )
{
return & pendingSnap ;
}
int GetSnapSequence ( )
{
return snapSequence ;
}
int GetBaseSequence ( )
{
return baseSequence ;
}
int GetFullSnapBaseSequence ( )
{
return lastFullSnapBaseSequence ;
}
2012-11-26 18:58:24 +00:00
// This is used to ack the latest delta we have. If we have no deltas, we sent -1 to make sure
// Server knows we don't want to ack, since we are as up to date as we can be
2012-11-28 15:47:07 +00:00
int GetLastAppendedSequence ( )
{
return deltas . Num ( ) = = 0 ? - 1 : deltas . ItemSequence ( deltas . Num ( ) - 1 ) ;
}
int GetSnapQueueSize ( )
{
return deltas . Num ( ) ;
}
2012-11-26 18:58:24 +00:00
bool IsBusyConfirmingPartialSnap ( ) ;
2012-11-28 15:47:07 +00:00
void AddSnapObjTemplate ( int objID , idBitMsg & msg ) ;
2012-11-26 18:58:24 +00:00
static const int MAX_SNAPSHOT_QUEUE = 64 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
private :
// Internal commands to set up, and flush the compressors
2012-11-28 15:47:07 +00:00
static const int MAX_SNAP_SIZE = idPacketProcessor : : MAX_MSG_SIZE ;
2012-11-26 18:58:24 +00:00
static const int MAX_SNAPSHOT_QUEUE_MEM = 64 * 1024 ; // 64k
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// sequence number of the last snapshot we sent/received
// on the server, the sequencing is different for each network peer (net_verboseSnapshot 1)
// on the jobbed snapshot compression path, the sequence is incremented in NewLZWStream and pulled into this in idSnapshotProcessor::GetPendingSnapDelta
int snapSequence ;
int baseSequence ;
int lastFullSnapBaseSequence ; // Latest base sequence number that is a full snap
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idSnapShot baseState ; // known snapshot base on the client
idDataQueue < MAX_SNAPSHOT_QUEUE , MAX_SNAPSHOT_QUEUE_MEM > deltas ; // list of unacknowledged snapshot deltas
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idSnapShot pendingSnap ; // Current snap waiting to be fully sent
bool hasPendingSnap ; // true if pendingSnap is still waiting to be sent
2012-11-28 15:47:07 +00:00
struct jobMemory_t
{
2012-11-26 18:58:24 +00:00
static const int MAX_LZW_DELTAS = 1 ; // FIXME: cleanup the old multiple delta support completely
2012-11-28 15:47:07 +00:00
// @TODO this is a hack fix to allow online to load into coop (where there are lots of entities).
2012-11-26 18:58:24 +00:00
// The real solution should be coming soon.
// Doom MP: we encountered the same problem, going from 1024 to 4096 as well until a better solution is in place
// (initial, useless, exchange of func_statics is killing us)
static const int MAX_OBJ_PARMS = 4096 ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
static const int MAX_LZW_PARMS = 32 ;
static const int MAX_OBJ_HEADERS = 256 ;
static const int MAX_LZW_MEM = 1024 * 8 ; // 8k in the byte * lzwMem buffers, must be <= PS3_DMA_MAX
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Parm memory to jobs
idArray < objParms_t , MAX_OBJ_PARMS > objParms ;
idArray < objHeader_t , MAX_OBJ_HEADERS > headers ;
idArray < lzwParm_t , MAX_LZW_PARMS > lzwParms ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Output memory from jobs
idArray < lzwDelta_t , MAX_LZW_DELTAS > lzwDeltas ; // Info about each pending delta output from jobs
idArray < byte , MAX_LZW_MEM > lzwMem ; // Memory for output from lzw jobs
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
lzwInOutData_t lzwInOutData ; // In/Out data used so lzw data can persist across lzw jobs
} ;
2012-11-28 15:47:07 +00:00
jobMemory_t * jobMemory ;
2012-11-26 18:58:24 +00:00
idSnapShot submittedState ;
idSnapShot templateStates ; // holds default snapshot states for some newly spawned object
idSnapShot submittedTemplateStates ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
int partialBaseSequence ;
} ;
# endif /* !__SNAP_PROCESSOR_H__ */