]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/idlib/BitMsg.cpp
hello world
[icculus/iodoom3.git] / neo / idlib / BitMsg.cpp
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 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 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 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 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 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
29 #include "precompiled.h"
30 #pragma hdrstop
31
32
33 /*
34 ==============================================================================
35
36   idBitMsg
37
38 ==============================================================================
39 */
40
41 /*
42 ================
43 idBitMsg::idBitMsg
44 ================
45 */
46 idBitMsg::idBitMsg() {
47         writeData = NULL;
48         readData = NULL;
49         maxSize = 0;
50         curSize = 0;
51         writeBit = 0;
52         readCount = 0;
53         readBit = 0;
54         allowOverflow = false;
55         overflowed = false;
56 }
57
58 /*
59 ================
60 idBitMsg::CheckOverflow
61 ================
62 */
63 bool idBitMsg::CheckOverflow( int numBits ) {
64         assert( numBits >= 0 );
65         if ( numBits > GetRemainingWriteBits() ) {
66                 if ( !allowOverflow ) {
67                         idLib::common->FatalError( "idBitMsg: overflow without allowOverflow set" );
68                 }
69                 if ( numBits > ( maxSize << 3 ) ) {
70                         idLib::common->FatalError( "idBitMsg: %i bits is > full message size", numBits );
71                 }
72                 idLib::common->Printf( "idBitMsg: overflow\n" );
73                 BeginWriting();
74                 overflowed = true;
75                 return true;
76         }
77         return false;
78 }
79
80 /*
81 ================
82 idBitMsg::GetByteSpace
83 ================
84 */
85 byte *idBitMsg::GetByteSpace( int length ) {
86         byte *ptr;
87
88         if ( !writeData ) {
89                 idLib::common->FatalError( "idBitMsg::GetByteSpace: cannot write to message" );
90         }
91
92         // round up to the next byte
93         WriteByteAlign();
94
95         // check for overflow
96         CheckOverflow( length << 3 );
97
98         ptr = writeData + curSize;
99         curSize += length;
100         return ptr;
101 }
102
103 /*
104 ================
105 idBitMsg::WriteBits
106
107   If the number of bits is negative a sign is included.
108 ================
109 */
110 void idBitMsg::WriteBits( int value, int numBits ) {
111         int             put;
112         int             fraction;
113
114         if ( !writeData ) {
115                 idLib::common->Error( "idBitMsg::WriteBits: cannot write to message" );
116         }
117
118         // check if the number of bits is valid
119         if ( numBits == 0 || numBits < -31 || numBits > 32 ) {
120                 idLib::common->Error( "idBitMsg::WriteBits: bad numBits %i", numBits );
121         }
122
123         // check for value overflows
124         // this should be an error really, as it can go unnoticed and cause either bandwidth or corrupted data transmitted
125         if ( numBits != 32 ) {
126                 if ( numBits > 0 ) {
127                         if ( value > ( 1 << numBits ) - 1 ) {
128                                 idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits );
129                         } else if ( value < 0 ) {
130                                 idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits );
131                         }
132                 } else {
133                         int r = 1 << ( - 1 - numBits );
134                         if ( value > r - 1 ) {
135                                 idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits );
136                         } else if ( value < -r ) {
137                                 idLib::common->Warning( "idBitMsg::WriteBits: value overflow %d %d", value, numBits );
138                         }
139                 }
140         }
141
142         if ( numBits < 0 ) {
143                 numBits = -numBits;
144         }
145
146         // check for msg overflow
147         if ( CheckOverflow( numBits ) ) {
148                 return;
149         }
150
151         // write the bits
152         while( numBits ) {
153                 if ( writeBit == 0 ) {
154                         writeData[curSize] = 0;
155                         curSize++;
156                 }
157                 put = 8 - writeBit;
158                 if ( put > numBits ) {
159                         put = numBits;
160                 }
161                 fraction = value & ( ( 1 << put ) - 1 );
162                 writeData[curSize - 1] |= fraction << writeBit;
163                 numBits -= put;
164                 value >>= put;
165                 writeBit = ( writeBit + put ) & 7;
166         }
167 }
168
169 /*
170 ================
171 idBitMsg::WriteString
172 ================
173 */
174 void idBitMsg::WriteString( const char *s, int maxLength, bool make7Bit ) {
175         if ( !s ) {
176                 WriteData( "", 1 );
177         } else {
178                 int i, l;
179                 byte *dataPtr;
180                 const byte *bytePtr;
181
182                 l = idStr::Length( s );
183                 if ( maxLength >= 0 && l >= maxLength ) {
184                         l = maxLength - 1;
185                 }
186                 dataPtr = GetByteSpace( l + 1 );
187                 bytePtr = reinterpret_cast<const byte *>(s);
188                 if ( make7Bit ) {
189                         for ( i = 0; i < l; i++ ) {
190                                 if ( bytePtr[i] > 127 ) {
191                                         dataPtr[i] = '.';
192                                 } else {
193                                         dataPtr[i] = bytePtr[i];
194                                 }
195                         }
196                 } else {
197                         for ( i = 0; i < l; i++ ) {
198                                 dataPtr[i] = bytePtr[i];
199                         }
200                 }
201                 dataPtr[i] = '\0';
202         }
203 }
204
205 /*
206 ================
207 idBitMsg::WriteData
208 ================
209 */
210 void idBitMsg::WriteData( const void *data, int length ) {
211         memcpy( GetByteSpace( length ), data, length );
212 }
213
214 /*
215 ================
216 idBitMsg::WriteNetadr
217 ================
218 */
219 void idBitMsg::WriteNetadr( const netadr_t adr ) {
220         byte *dataPtr;
221         dataPtr = GetByteSpace( 4 );
222         memcpy( dataPtr, adr.ip, 4 );
223         WriteUShort( adr.port );
224 }
225
226 /*
227 ================
228 idBitMsg::WriteDelta
229 ================
230 */
231 void idBitMsg::WriteDelta( int oldValue, int newValue, int numBits ) {
232         if ( oldValue == newValue ) {
233                 WriteBits( 0, 1 );
234                 return;
235         }
236         WriteBits( 1, 1 );
237         WriteBits( newValue, numBits );
238 }
239
240 /*
241 ================
242 idBitMsg::WriteDeltaByteCounter
243 ================
244 */
245 void idBitMsg::WriteDeltaByteCounter( int oldValue, int newValue ) {
246         int i, x;
247
248         x = oldValue ^ newValue;
249         for ( i = 7; i > 0; i-- ) {
250                 if ( x & ( 1 << i ) ) {
251                         i++;
252                         break;
253                 }
254         }
255         WriteBits( i, 3 );
256         if ( i ) {
257                 WriteBits( ( ( 1 << i ) - 1 ) & newValue, i );
258         }
259 }
260
261 /*
262 ================
263 idBitMsg::WriteDeltaShortCounter
264 ================
265 */
266 void idBitMsg::WriteDeltaShortCounter( int oldValue, int newValue ) {
267         int i, x;
268
269         x = oldValue ^ newValue;
270         for ( i = 15; i > 0; i-- ) {
271                 if ( x & ( 1 << i ) ) {
272                         i++;
273                         break;
274                 }
275         }
276         WriteBits( i, 4 );
277         if ( i ) {
278                 WriteBits( ( ( 1 << i ) - 1 ) & newValue, i );
279         }
280 }
281
282 /*
283 ================
284 idBitMsg::WriteDeltaLongCounter
285 ================
286 */
287 void idBitMsg::WriteDeltaLongCounter( int oldValue, int newValue ) {
288         int i, x;
289
290         x = oldValue ^ newValue;
291         for ( i = 31; i > 0; i-- ) {
292                 if ( x & ( 1 << i ) ) {
293                         i++;
294                         break;
295                 }
296         }
297         WriteBits( i, 5 );
298         if ( i ) {
299                 WriteBits( ( ( 1 << i ) - 1 ) & newValue, i );
300         }
301 }
302
303 /*
304 ==================
305 idBitMsg::WriteDeltaDict
306 ==================
307 */
308 bool idBitMsg::WriteDeltaDict( const idDict &dict, const idDict *base ) {
309         int i;
310         const idKeyValue *kv, *basekv;
311         bool changed = false;
312
313         if ( base != NULL ) {
314
315                 for ( i = 0; i < dict.GetNumKeyVals(); i++ ) {
316                         kv = dict.GetKeyVal( i );
317                         basekv = base->FindKey( kv->GetKey() );
318                         if ( basekv == NULL || basekv->GetValue().Icmp( kv->GetValue() ) != 0 ) {
319                                 WriteString( kv->GetKey() );
320                                 WriteString( kv->GetValue() );
321                                 changed = true;
322                         }
323                 }
324
325                 WriteString( "" );
326
327                 for ( i = 0; i < base->GetNumKeyVals(); i++ ) {
328                         basekv = base->GetKeyVal( i );
329                         kv = dict.FindKey( basekv->GetKey() );
330                         if ( kv == NULL ) {
331                                 WriteString( basekv->GetKey() );
332                                 changed = true;
333                         }
334                 }
335
336                 WriteString( "" );
337
338         } else {
339
340                 for ( i = 0; i < dict.GetNumKeyVals(); i++ ) {
341                         kv = dict.GetKeyVal( i );
342                         WriteString( kv->GetKey() );
343                         WriteString( kv->GetValue() );
344                         changed = true;
345                 }
346                 WriteString( "" );
347
348                 WriteString( "" );
349
350         }
351
352         return changed;
353 }
354
355 /*
356 ================
357 idBitMsg::ReadBits
358
359   If the number of bits is negative a sign is included.
360 ================
361 */
362 int idBitMsg::ReadBits( int numBits ) const {
363         int             value;
364         int             valueBits;
365         int             get;
366         int             fraction;
367         bool    sgn;
368
369         if ( !readData ) {
370                 idLib::common->FatalError( "idBitMsg::ReadBits: cannot read from message" );
371         }
372
373         // check if the number of bits is valid
374         if ( numBits == 0 || numBits < -31 || numBits > 32 ) {
375                 idLib::common->FatalError( "idBitMsg::ReadBits: bad numBits %i", numBits );
376         }
377
378         value = 0;
379         valueBits = 0;
380
381         if ( numBits < 0 ) {
382                 numBits = -numBits;
383                 sgn = true;
384         } else {
385                 sgn = false;
386         }
387
388         // check for overflow
389         if ( numBits > GetRemainingReadBits() ) {
390                 return -1;
391         }
392
393         while ( valueBits < numBits ) {
394                 if ( readBit == 0 ) {
395                         readCount++;
396                 }
397                 get = 8 - readBit;
398                 if ( get > (numBits - valueBits) ) {
399                         get = numBits - valueBits;
400                 }
401                 fraction = readData[readCount - 1];
402                 fraction >>= readBit;
403                 fraction &= ( 1 << get ) - 1;
404                 value |= fraction << valueBits;
405
406                 valueBits += get;
407                 readBit = ( readBit + get ) & 7;
408         }
409
410         if ( sgn ) {
411                 if ( value & ( 1 << ( numBits - 1 ) ) ) {
412                         value |= -1 ^ ( ( 1 << numBits ) - 1 );
413                 }
414         }
415
416         return value;
417 }
418
419 /*
420 ================
421 idBitMsg::ReadString
422 ================
423 */
424 int idBitMsg::ReadString( char *buffer, int bufferSize ) const {
425         int     l, c;
426         
427         ReadByteAlign();
428         l = 0;
429         while( 1 ) {
430                 c = ReadByte();
431                 if ( c <= 0 || c >= 255 ) {
432                         break;
433                 }
434                 // translate all fmt spec to avoid crash bugs in string routines
435                 if ( c == '%' ) {
436                         c = '.';
437                 }
438
439                 // we will read past any excessively long string, so
440                 // the following data can be read, but the string will
441                 // be truncated
442                 if ( l < bufferSize - 1 ) {
443                         buffer[l] = c;
444                         l++;
445                 }
446         }
447         
448         buffer[l] = 0;
449         return l;
450 }
451
452 /*
453 ================
454 idBitMsg::ReadData
455 ================
456 */
457 int idBitMsg::ReadData( void *data, int length ) const {
458         int cnt;
459
460         ReadByteAlign();
461         cnt = readCount;
462
463         if ( readCount + length > curSize ) {
464                 if ( data ) {
465                         memcpy( data, readData + readCount, GetRemaingData() );
466                 }
467                 readCount = curSize;
468         } else {
469                 if ( data ) {
470                         memcpy( data, readData + readCount, length );
471                 }
472                 readCount += length;
473         }
474
475         return ( readCount - cnt );
476 }
477
478 /*
479 ================
480 idBitMsg::ReadNetadr
481 ================
482 */
483 void idBitMsg::ReadNetadr( netadr_t *adr ) const {
484         int i;
485  
486         adr->type = NA_IP;
487         for ( i = 0; i < 4; i++ ) {
488                 adr->ip[ i ] = ReadByte();
489         }
490         adr->port = ReadUShort();
491 }
492
493 /*
494 ================
495 idBitMsg::ReadDelta
496 ================
497 */
498 int idBitMsg::ReadDelta( int oldValue, int numBits ) const {
499         if ( ReadBits( 1 ) ) {
500                 return ReadBits( numBits );
501         }
502         return oldValue;
503 }
504
505 /*
506 ================
507 idBitMsg::ReadDeltaByteCounter
508 ================
509 */
510 int idBitMsg::ReadDeltaByteCounter( int oldValue ) const {
511         int i, newValue;
512
513         i = ReadBits( 3 );
514         if ( !i ) {
515                 return oldValue;
516         }
517         newValue = ReadBits( i );
518         return ( oldValue & ~( ( 1 << i ) - 1 ) | newValue );
519 }
520
521 /*
522 ================
523 idBitMsg::ReadDeltaShortCounter
524 ================
525 */
526 int idBitMsg::ReadDeltaShortCounter( int oldValue ) const {
527         int i, newValue;
528
529         i = ReadBits( 4 );
530         if ( !i ) {
531                 return oldValue;
532         }
533         newValue = ReadBits( i );
534         return ( oldValue & ~( ( 1 << i ) - 1 ) | newValue );
535 }
536
537 /*
538 ================
539 idBitMsg::ReadDeltaLongCounter
540 ================
541 */
542 int idBitMsg::ReadDeltaLongCounter( int oldValue ) const {
543         int i, newValue;
544
545         i = ReadBits( 5 );
546         if ( !i ) {
547                 return oldValue;
548         }
549         newValue = ReadBits( i );
550         return ( oldValue & ~( ( 1 << i ) - 1 ) | newValue );
551 }
552
553 /*
554 ==================
555 idBitMsg::ReadDeltaDict
556 ==================
557 */
558 bool idBitMsg::ReadDeltaDict( idDict &dict, const idDict *base ) const {
559         char            key[MAX_STRING_CHARS];
560         char            value[MAX_STRING_CHARS];
561         bool            changed = false;
562
563         if ( base != NULL ) {
564                 dict = *base;
565         } else {
566                 dict.Clear();
567         }
568
569         while( ReadString( key, sizeof( key ) ) != 0 ) {
570                 ReadString( value, sizeof( value ) );
571                 dict.Set( key, value );
572                 changed = true;
573         }
574
575         while( ReadString( key, sizeof( key ) ) != 0 ) {
576                 dict.Delete( key );
577                 changed = true;
578         }
579
580         return changed;
581 }
582
583 /*
584 ================
585 idBitMsg::DirToBits
586 ================
587 */
588 int idBitMsg::DirToBits( const idVec3 &dir, int numBits ) {
589         int max, bits;
590         float bias;
591
592         assert( numBits >= 6 && numBits <= 32 );
593         assert( dir.LengthSqr() - 1.0f < 0.01f );
594
595         numBits /= 3;
596         max = ( 1 << ( numBits - 1 ) ) - 1;
597         bias = 0.5f / max;
598
599         bits = FLOATSIGNBITSET( dir.x ) << ( numBits * 3 - 1 );
600         bits |= ( idMath::Ftoi( ( idMath::Fabs( dir.x ) + bias ) * max ) ) << ( numBits * 2 );
601         bits |= FLOATSIGNBITSET( dir.y ) << ( numBits * 2 - 1 );
602         bits |= ( idMath::Ftoi( ( idMath::Fabs( dir.y ) + bias ) * max ) ) << ( numBits * 1 );
603         bits |= FLOATSIGNBITSET( dir.z ) << ( numBits * 1 - 1 );
604         bits |= ( idMath::Ftoi( ( idMath::Fabs( dir.z ) + bias ) * max ) ) << ( numBits * 0 );
605         return bits;
606 }
607
608 /*
609 ================
610 idBitMsg::BitsToDir
611 ================
612 */
613 idVec3 idBitMsg::BitsToDir( int bits, int numBits ) {
614         static float sign[2] = { 1.0f, -1.0f };
615         int max;
616         float invMax;
617         idVec3 dir;
618
619         assert( numBits >= 6 && numBits <= 32 );
620
621         numBits /= 3;
622         max = ( 1 << ( numBits - 1 ) ) - 1;
623         invMax = 1.0f / max;
624
625         dir.x = sign[( bits >> ( numBits * 3 - 1 ) ) & 1] * ( ( bits >> ( numBits * 2 ) ) & max ) * invMax;
626         dir.y = sign[( bits >> ( numBits * 2 - 1 ) ) & 1] * ( ( bits >> ( numBits * 1 ) ) & max ) * invMax;
627         dir.z = sign[( bits >> ( numBits * 1 - 1 ) ) & 1] * ( ( bits >> ( numBits * 0 ) ) & max ) * invMax;
628         dir.NormalizeFast();
629         return dir;
630 }
631
632
633 /*
634 ==============================================================================
635
636   idBitMsgDelta
637
638 ==============================================================================
639 */
640
641 const int MAX_DATA_BUFFER               = 1024;
642
643 /*
644 ================
645 idBitMsgDelta::WriteBits
646 ================
647 */
648 void idBitMsgDelta::WriteBits( int value, int numBits ) {
649         if ( newBase ) {
650                 newBase->WriteBits( value, numBits );
651         }
652
653         if ( !base ) {
654                 writeDelta->WriteBits( value, numBits );
655                 changed = true;
656         } else {
657                 int baseValue = base->ReadBits( numBits );
658                 if ( baseValue == value ) {
659                         writeDelta->WriteBits( 0, 1 );
660                 } else {
661                         writeDelta->WriteBits( 1, 1 );
662                         writeDelta->WriteBits( value, numBits );
663                         changed = true;
664                 }
665         }
666 }
667
668 /*
669 ================
670 idBitMsgDelta::WriteDelta
671 ================
672 */
673 void idBitMsgDelta::WriteDelta( int oldValue, int newValue, int numBits ) {
674         if ( newBase ) {
675                 newBase->WriteBits( newValue, numBits );
676         }
677
678         if ( !base ) {
679                 if ( oldValue == newValue ) {
680                         writeDelta->WriteBits( 0, 1 );
681                 } else {
682                         writeDelta->WriteBits( 1, 1 );
683                         writeDelta->WriteBits( newValue, numBits );
684                 }
685                 changed = true;
686         } else {
687                 int baseValue = base->ReadBits( numBits );
688                 if ( baseValue == newValue ) {
689                         writeDelta->WriteBits( 0, 1 );
690                 } else {
691                         writeDelta->WriteBits( 1, 1 );
692                         if ( oldValue == newValue ) {
693                                 writeDelta->WriteBits( 0, 1 );
694                                 changed = true;
695                         } else {
696                                 writeDelta->WriteBits( 1, 1 );
697                                 writeDelta->WriteBits( newValue, numBits );
698                                 changed = true;
699                         }
700                 }
701         }
702 }
703
704 /*
705 ================
706 idBitMsgDelta::ReadBits
707 ================
708 */
709 int idBitMsgDelta::ReadBits( int numBits ) const {
710         int value;
711
712         if ( !base ) {
713                 value = readDelta->ReadBits( numBits );
714                 changed = true;
715         } else {
716                 int baseValue = base->ReadBits( numBits );
717                 if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) {
718                         value = baseValue;
719                 } else {
720                         value = readDelta->ReadBits( numBits );
721                         changed = true;
722                 }
723         }
724
725         if ( newBase ) {
726                 newBase->WriteBits( value, numBits );
727         }
728         return value;
729 }
730
731 /*
732 ================
733 idBitMsgDelta::ReadDelta
734 ================
735 */
736 int idBitMsgDelta::ReadDelta( int oldValue, int numBits ) const {
737         int value;
738
739         if ( !base ) {
740                 if ( readDelta->ReadBits( 1 ) == 0 ) {
741                         value = oldValue;
742                 } else {
743                         value = readDelta->ReadBits( numBits );
744                 }
745                 changed = true;
746         } else {
747                 int baseValue = base->ReadBits( numBits );
748                 if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) {
749                         value = baseValue;
750                 } else if ( readDelta->ReadBits( 1 ) == 0 ) {
751                         value = oldValue;
752                         changed = true;
753                 } else {
754                         value = readDelta->ReadBits( numBits );
755                         changed = true;
756                 }
757         }
758
759         if ( newBase ) {
760                 newBase->WriteBits( value, numBits );
761         }
762         return value;
763 }
764
765 /*
766 ================
767 idBitMsgDelta::WriteString
768 ================
769 */
770 void idBitMsgDelta::WriteString( const char *s, int maxLength ) {
771         if ( newBase ) {
772                 newBase->WriteString( s, maxLength );
773         }
774
775         if ( !base ) {
776                 writeDelta->WriteString( s, maxLength );
777                 changed = true;
778         } else {
779                 char baseString[MAX_DATA_BUFFER];
780                 base->ReadString( baseString, sizeof( baseString ) );
781                 if ( idStr::Cmp( s, baseString ) == 0 ) {
782                         writeDelta->WriteBits( 0, 1 );
783                 } else {
784                         writeDelta->WriteBits( 1, 1 );
785                         writeDelta->WriteString( s, maxLength );
786                         changed = true;
787                 }
788         }
789 }
790
791 /*
792 ================
793 idBitMsgDelta::WriteData
794 ================
795 */
796 void idBitMsgDelta::WriteData( const void *data, int length ) {
797         if ( newBase ) {
798                 newBase->WriteData( data, length );
799         }
800
801         if ( !base ) {
802                 writeDelta->WriteData( data, length );
803                 changed = true;
804         } else {
805                 byte baseData[MAX_DATA_BUFFER];
806                 assert( length < sizeof( baseData ) );
807                 base->ReadData( baseData, length );
808                 if ( memcmp( data, baseData, length ) == 0 ) {
809                         writeDelta->WriteBits( 0, 1 );
810                 } else {
811                         writeDelta->WriteBits( 1, 1 );
812                         writeDelta->WriteData( data, length );
813                         changed = true;
814                 }
815         }
816 }
817
818 /*
819 ================
820 idBitMsgDelta::WriteDict
821 ================
822 */
823 void idBitMsgDelta::WriteDict( const idDict &dict ) {
824         if ( newBase ) {
825                 newBase->WriteDeltaDict( dict, NULL );
826         }
827
828         if ( !base ) {
829                 writeDelta->WriteDeltaDict( dict, NULL );
830                 changed = true;
831         } else {
832                 idDict baseDict;
833                 base->ReadDeltaDict( baseDict, NULL );
834                 changed = writeDelta->WriteDeltaDict( dict, &baseDict );
835         }
836 }
837
838 /*
839 ================
840 idBitMsgDelta::WriteDeltaByteCounter
841 ================
842 */
843 void idBitMsgDelta::WriteDeltaByteCounter( int oldValue, int newValue ) {
844         if ( newBase ) {
845                 newBase->WriteBits( newValue, 8 );
846         }
847
848         if ( !base ) {
849                 writeDelta->WriteDeltaByteCounter( oldValue, newValue );
850                 changed = true;
851         } else {
852                 int baseValue = base->ReadBits( 8 );
853                 if ( baseValue == newValue ) {
854                         writeDelta->WriteBits( 0, 1 );
855                 } else {
856                         writeDelta->WriteBits( 1, 1 );
857                         writeDelta->WriteDeltaByteCounter( oldValue, newValue );
858                         changed = true;
859                 }
860         }
861 }
862
863 /*
864 ================
865 idBitMsgDelta::WriteDeltaShortCounter
866 ================
867 */
868 void idBitMsgDelta::WriteDeltaShortCounter( int oldValue, int newValue ) {
869         if ( newBase ) {
870                 newBase->WriteBits( newValue, 16 );
871         }
872
873         if ( !base ) {
874                 writeDelta->WriteDeltaShortCounter( oldValue, newValue );
875                 changed = true;
876         } else {
877                 int baseValue = base->ReadBits( 16 );
878                 if ( baseValue == newValue ) {
879                         writeDelta->WriteBits( 0, 1 );
880                 } else {
881                         writeDelta->WriteBits( 1, 1 );
882                         writeDelta->WriteDeltaShortCounter( oldValue, newValue );
883                         changed = true;
884                 }
885         }
886 }
887
888 /*
889 ================
890 idBitMsgDelta::WriteDeltaLongCounter
891 ================
892 */
893 void idBitMsgDelta::WriteDeltaLongCounter( int oldValue, int newValue ) {
894         if ( newBase ) {
895                 newBase->WriteBits( newValue, 32 );
896         }
897
898         if ( !base ) {
899                 writeDelta->WriteDeltaLongCounter( oldValue, newValue );
900                 changed = true;
901         } else {
902                 int baseValue = base->ReadBits( 32 );
903                 if ( baseValue == newValue ) {
904                         writeDelta->WriteBits( 0, 1 );
905                 } else {
906                         writeDelta->WriteBits( 1, 1 );
907                         writeDelta->WriteDeltaLongCounter( oldValue, newValue );
908                         changed = true;
909                 }
910         }
911 }
912
913 /*
914 ================
915 idBitMsgDelta::ReadString
916 ================
917 */
918 void idBitMsgDelta::ReadString( char *buffer, int bufferSize ) const {
919         if ( !base ) {
920                 readDelta->ReadString( buffer, bufferSize );
921                 changed = true;
922         } else {
923                 char baseString[MAX_DATA_BUFFER];
924                 base->ReadString( baseString, sizeof( baseString ) );
925                 if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) {
926                         idStr::Copynz( buffer, baseString, bufferSize );
927                 } else {
928                         readDelta->ReadString( buffer, bufferSize );
929                         changed = true;
930                 }
931         }
932
933         if ( newBase ) {
934                 newBase->WriteString( buffer );
935         }
936 }
937
938 /*
939 ================
940 idBitMsgDelta::ReadData
941 ================
942 */
943 void idBitMsgDelta::ReadData( void *data, int length ) const {
944         if ( !base ) {
945                 readDelta->ReadData( data, length );
946                 changed = true;
947         } else {
948                 char baseData[MAX_DATA_BUFFER];
949                 assert( length < sizeof( baseData ) );
950                 base->ReadData( baseData, length );
951                 if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) {
952                         memcpy( data, baseData, length );
953                 } else {
954                         readDelta->ReadData( data, length );
955                         changed = true;
956                 }
957         }
958
959         if ( newBase ) {
960                 newBase->WriteData( data, length );
961         }
962 }
963
964 /*
965 ================
966 idBitMsgDelta::ReadDict
967 ================
968 */
969 void idBitMsgDelta::ReadDict( idDict &dict ) {
970         if ( !base ) {
971                 readDelta->ReadDeltaDict( dict, NULL );
972                 changed = true;
973         } else {
974                 idDict baseDict;
975                 base->ReadDeltaDict( baseDict, NULL );
976                 if ( !readDelta ) {
977                         dict = baseDict;
978                 } else {
979                         changed = readDelta->ReadDeltaDict( dict, &baseDict );
980                 }
981         }
982
983         if ( newBase ) {
984                 newBase->WriteDeltaDict( dict, NULL );
985         }
986 }
987
988 /*
989 ================
990 idBitMsgDelta::ReadDeltaByteCounter
991 ================
992 */
993 int idBitMsgDelta::ReadDeltaByteCounter( int oldValue ) const {
994         int value;
995
996         if ( !base ) {
997                 value = readDelta->ReadDeltaByteCounter( oldValue );
998                 changed = true;
999         } else {
1000                 int baseValue = base->ReadBits( 8 );
1001                 if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) {
1002                         value = baseValue;
1003                 } else {
1004                         value = readDelta->ReadDeltaByteCounter( oldValue );
1005                         changed = true;
1006                 }
1007         }
1008
1009         if ( newBase ) {
1010                 newBase->WriteBits( value, 8 );
1011         }
1012         return value;
1013 }
1014
1015 /*
1016 ================
1017 idBitMsgDelta::ReadDeltaShortCounter
1018 ================
1019 */
1020 int idBitMsgDelta::ReadDeltaShortCounter( int oldValue ) const {
1021         int value;
1022
1023         if ( !base ) {
1024                 value = readDelta->ReadDeltaShortCounter( oldValue );
1025                 changed = true;
1026         } else {
1027                 int baseValue = base->ReadBits( 16 );
1028                 if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) {
1029                         value = baseValue;
1030                 } else {
1031                         value = readDelta->ReadDeltaShortCounter( oldValue );
1032                         changed = true;
1033                 }
1034         }
1035
1036         if ( newBase ) {
1037                 newBase->WriteBits( value, 16 );
1038         }
1039         return value;
1040 }
1041
1042 /*
1043 ================
1044 idBitMsgDelta::ReadDeltaLongCounter
1045 ================
1046 */
1047 int idBitMsgDelta::ReadDeltaLongCounter( int oldValue ) const {
1048         int value;
1049
1050         if ( !base ) {
1051                 value = readDelta->ReadDeltaLongCounter( oldValue );
1052                 changed = true;
1053         } else {
1054                 int baseValue = base->ReadBits( 32 );
1055                 if ( !readDelta || readDelta->ReadBits( 1 ) == 0 ) {
1056                         value = baseValue;
1057                 } else {
1058                         value = readDelta->ReadDeltaLongCounter( oldValue );
1059                         changed = true;
1060                 }
1061         }
1062
1063         if ( newBase ) {
1064                 newBase->WriteBits( value, 32 );
1065         }
1066         return value;
1067 }