SnapshotProcessor.h (7361B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 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. 23 24 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. 25 26 =========================================================================== 27 */ 28 #ifndef __SNAP_PROCESSOR_H__ 29 #define __SNAP_PROCESSOR_H__ 30 31 /* 32 ================================================ 33 idSnapshotProcessor 34 ================================================ 35 */ 36 class idSnapshotProcessor { 37 public: 38 static const int INITIAL_SNAP_SEQUENCE = 42; 39 40 idSnapshotProcessor(); 41 ~idSnapshotProcessor(); 42 43 void Reset( bool cstor = false ); 44 45 // TrySetPendingSnapshot Sets the currently pending snap. 46 // No new snaps will be sent until this snap has been fully sent. 47 // Returns true of the newly supplied snapshot was accepted (there were no pending snaps) 48 bool TrySetPendingSnapshot( idSnapShot & ss ); 49 // Peek into delta to get deltaSequence, and deltaBaseSequence 50 void PeekDeltaSequence( const char * deltaMem, int deltaSize, int & deltaSequence, int & deltaBaseSequence ); 51 // Apply a delta to the supplied snapshot 52 bool ApplyDeltaToSnapshot( idSnapShot & snap, const char * deltaMem, int deltaSize, int visIndex ); 53 // Attempts to write the currently pending snap to the supplied buffer, which can then be sent as an unreliable msg. 54 // SubmitPendingSnap will submit the pending snap to a job, so that it can be retrieved later for sending. 55 void SubmitPendingSnap( int visIndex, uint8 * objMemory, int objMemorySize, lzwCompressionData_t * lzwData ); 56 // GetPendingSnapDelta 57 int GetPendingSnapDelta( byte * outBuffer, int maxLength ); 58 // If PendingSnapReadyToSend is true, then GetPendingSnapDelta will return something to send 59 bool PendingSnapReadyToSend() const { return jobMemory->lzwInOutData.numlzwDeltas > 0; } 60 // When you call WritePendingSnapshot, and then send the resulting buffer as a unreliable msg, you will eventually 61 // receive this on the client. Call this function to receive and apply it to the base state, and possibly return a fully received snap 62 // to then apply to the client game state 63 bool ReceiveSnapshotDelta( const byte * deltaData, int deltaLength, int visIndex, int & outSeq, int & outBaseSeq, idSnapShot & outSnap, bool & fullSnap ); 64 // Function to apply a received (or ack'd) delta to the base state 65 bool ApplySnapshotDelta( int visIndex, int snapshotNumber ); 66 // Remove deltas for basestate we no longer have. 67 // We know we can remove them, because we will never be able to apply them, since 68 // the basestate needed to generate a full snap from these deltas is gone. 69 void RemoveDeltasForOldBaseSequence(); 70 // Make sure delta sequence and basesequence values are valid, and in order, etc 71 void SanityCheckDeltas(); 72 // HasPendingSnap will return true if there is more of the last TrySetPendingSnapshot to be sent 73 bool HasPendingSnap() const { return hasPendingSnap; } 74 75 idSnapShot * GetBaseState() { return &baseState; } 76 idSnapShot * GetPendingSnap(){ return &pendingSnap; } 77 78 int GetSnapSequence() { return snapSequence; } 79 int GetBaseSequence() { return baseSequence; } 80 int GetFullSnapBaseSequence() { return lastFullSnapBaseSequence; } 81 82 // This is used to ack the latest delta we have. If we have no deltas, we sent -1 to make sure 83 // Server knows we don't want to ack, since we are as up to date as we can be 84 int GetLastAppendedSequence() { return deltas.Num() == 0 ? -1 : deltas.ItemSequence( deltas.Num() - 1 ); } 85 86 int GetSnapQueueSize() { return deltas.Num(); } 87 88 bool IsBusyConfirmingPartialSnap(); 89 90 void AddSnapObjTemplate( int objID, idBitMsg & msg ); 91 92 static const int MAX_SNAPSHOT_QUEUE = 64; 93 94 private: 95 96 // Internal commands to set up, and flush the compressors 97 static const int MAX_SNAP_SIZE = idPacketProcessor::MAX_MSG_SIZE; 98 static const int MAX_SNAPSHOT_QUEUE_MEM = 64 * 1024; // 64k 99 100 // sequence number of the last snapshot we sent/received 101 // on the server, the sequencing is different for each network peer (net_verboseSnapshot 1) 102 // on the jobbed snapshot compression path, the sequence is incremented in NewLZWStream and pulled into this in idSnapshotProcessor::GetPendingSnapDelta 103 int snapSequence; 104 int baseSequence; 105 int lastFullSnapBaseSequence; // Latest base sequence number that is a full snap 106 107 idSnapShot baseState; // known snapshot base on the client 108 idDataQueue< MAX_SNAPSHOT_QUEUE, MAX_SNAPSHOT_QUEUE_MEM > deltas; // list of unacknowledged snapshot deltas 109 110 idSnapShot pendingSnap; // Current snap waiting to be fully sent 111 bool hasPendingSnap; // true if pendingSnap is still waiting to be sent 112 113 struct jobMemory_t { 114 static const int MAX_LZW_DELTAS = 1; // FIXME: cleanup the old multiple delta support completely 115 116 // @TODO this is a hack fix to allow online to load into coop (where there are lots of entities). 117 // The real solution should be coming soon. 118 // Doom MP: we encountered the same problem, going from 1024 to 4096 as well until a better solution is in place 119 // (initial, useless, exchange of func_statics is killing us) 120 static const int MAX_OBJ_PARMS = 4096; 121 122 static const int MAX_LZW_PARMS = 32; 123 static const int MAX_OBJ_HEADERS = 256; 124 static const int MAX_LZW_MEM = 1024 * 8; // 8k in the byte * lzwMem buffers, must be <= PS3_DMA_MAX 125 126 // Parm memory to jobs 127 idArray<objParms_t, MAX_OBJ_PARMS> objParms; 128 idArray<objHeader_t, MAX_OBJ_HEADERS> headers; 129 idArray<lzwParm_t, MAX_LZW_PARMS> lzwParms; 130 131 // Output memory from jobs 132 idArray<lzwDelta_t, MAX_LZW_DELTAS> lzwDeltas; // Info about each pending delta output from jobs 133 idArray<byte, MAX_LZW_MEM> lzwMem; // Memory for output from lzw jobs 134 135 lzwInOutData_t lzwInOutData; // In/Out data used so lzw data can persist across lzw jobs 136 }; 137 138 jobMemory_t * jobMemory; 139 140 idSnapShot submittedState; 141 142 idSnapShot templateStates; // holds default snapshot states for some newly spawned object 143 idSnapShot submittedTemplateStates; 144 145 int partialBaseSequence; 146 }; 147 148 #endif /* !__SNAP_PROCESSOR_H__ */