core/bitbuf.cpp
author Michael McKoy <ferret99gt@gmail.com>
Sat Nov 24 03:28:33 2007 +0000 (2007-11-24)
changeset 1719 c9d5e55f0899
parent 1541 e46ad208b9b4
permissions -rw-r--r--
The current map played shouldn't appear in MapChooser votes or RTV votes now. It can still be nominated in RTV though.
faluco@1541
     1
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
faluco@1541
     2
//
faluco@1541
     3
// Purpose: 
faluco@1541
     4
//
faluco@1541
     5
// $NoKeywords: $
faluco@1541
     6
//
faluco@1541
     7
//=============================================================================//
faluco@1541
     8
faluco@1541
     9
#include "bitbuf.h"
faluco@1541
    10
#include "coordsize.h"
faluco@1541
    11
#include "vector.h"
faluco@1541
    12
#include "mathlib/math_base.h"
faluco@1541
    13
#include "vstdlib/strtools.h"
faluco@1541
    14
faluco@1541
    15
faluco@1541
    16
// FIXME: Can't use this until we get multithreaded allocations in tier0 working for tools
faluco@1541
    17
// This is used by VVIS and fails to link
faluco@1541
    18
// NOTE: This must be the last file included!!!
faluco@1541
    19
//#include "tier0/memdbgon.h"
faluco@1541
    20
faluco@1541
    21
#ifdef _XBOX
faluco@1541
    22
// mandatory ... wary of above comment and isolating, tier0 is built as MT though
faluco@1541
    23
#include "tier0/memdbgon.h"
faluco@1541
    24
#endif
faluco@1541
    25
faluco@1541
    26
static BitBufErrorHandler g_BitBufErrorHandler = 0;
faluco@1541
    27
faluco@1541
    28
faluco@1541
    29
void InternalBitBufErrorHandler( BitBufErrorType errorType, const char *pDebugName )
faluco@1541
    30
{
faluco@1541
    31
	if ( g_BitBufErrorHandler )
faluco@1541
    32
		g_BitBufErrorHandler( errorType, pDebugName );
faluco@1541
    33
}
faluco@1541
    34
faluco@1541
    35
faluco@1541
    36
void SetBitBufErrorHandler( BitBufErrorHandler fn )
faluco@1541
    37
{
faluco@1541
    38
	g_BitBufErrorHandler = fn;
faluco@1541
    39
}
faluco@1541
    40
faluco@1541
    41
faluco@1541
    42
// #define BB_PROFILING
faluco@1541
    43
faluco@1541
    44
faluco@1541
    45
// Precalculated bit masks for WriteUBitLong. Using these tables instead of 
faluco@1541
    46
// doing the calculations gives a 33% speedup in WriteUBitLong.
faluco@1541
    47
unsigned long g_BitWriteMasks[32][33];
faluco@1541
    48
faluco@1541
    49
// (1 << i) - 1
faluco@1541
    50
unsigned long g_ExtraMasks[32];
faluco@1541
    51
faluco@1541
    52
class CBitWriteMasksInit
faluco@1541
    53
{
faluco@1541
    54
public:
faluco@1541
    55
	CBitWriteMasksInit()
faluco@1541
    56
	{
faluco@1541
    57
		for( unsigned int startbit=0; startbit < 32; startbit++ )
faluco@1541
    58
		{
faluco@1541
    59
			for( unsigned int nBitsLeft=0; nBitsLeft < 33; nBitsLeft++ )
faluco@1541
    60
			{
faluco@1541
    61
				unsigned int endbit = startbit + nBitsLeft;
faluco@1541
    62
				g_BitWriteMasks[startbit][nBitsLeft] = (1 << startbit) - 1;
faluco@1541
    63
				if(endbit < 32)
faluco@1541
    64
					g_BitWriteMasks[startbit][nBitsLeft] |= ~((1 << endbit) - 1);
faluco@1541
    65
			}
faluco@1541
    66
		}
faluco@1541
    67
faluco@1541
    68
		for ( unsigned int maskBit=0; maskBit < 32; maskBit++ )
faluco@1541
    69
			g_ExtraMasks[maskBit] = (1 << maskBit) - 1;
faluco@1541
    70
	}
faluco@1541
    71
};
faluco@1541
    72
CBitWriteMasksInit g_BitWriteMasksInit;
faluco@1541
    73
faluco@1541
    74
faluco@1541
    75
// ---------------------------------------------------------------------------------------- //
faluco@1541
    76
// bf_write
faluco@1541
    77
// ---------------------------------------------------------------------------------------- //
faluco@1541
    78
faluco@1541
    79
bf_write::bf_write()
faluco@1541
    80
{
faluco@1541
    81
	m_pData = NULL;
faluco@1541
    82
	m_nDataBytes = 0;
faluco@1541
    83
	m_nDataBits = -1; // set to -1 so we generate overflow on any operation
faluco@1541
    84
	m_iCurBit = 0;
faluco@1541
    85
	m_bOverflow = false;
faluco@1541
    86
	m_bAssertOnOverflow = true;
faluco@1541
    87
	m_pDebugName = NULL;
faluco@1541
    88
}
faluco@1541
    89
faluco@1541
    90
bf_write::bf_write( const char *pDebugName, void *pData, int nBytes, int nBits )
faluco@1541
    91
{
faluco@1541
    92
	m_bAssertOnOverflow = true;
faluco@1541
    93
	m_pDebugName = pDebugName;
faluco@1541
    94
	StartWriting( pData, nBytes, 0, nBits );
faluco@1541
    95
}
faluco@1541
    96
faluco@1541
    97
bf_write::bf_write( void *pData, int nBytes, int nBits )
faluco@1541
    98
{
faluco@1541
    99
	m_bAssertOnOverflow = true;
faluco@1541
   100
	StartWriting( pData, nBytes, 0, nBits );
faluco@1541
   101
}
faluco@1541
   102
faluco@1541
   103
void bf_write::StartWriting( void *pData, int nBytes, int iStartBit, int nBits )
faluco@1541
   104
{
faluco@1541
   105
	// Make sure it's dword aligned and padded.
faluco@1541
   106
	Assert( (nBytes % 4) == 0 );
faluco@1541
   107
	Assert(((unsigned long)pData & 3) == 0);
faluco@1541
   108
faluco@1541
   109
	m_pData = (unsigned char*)pData;
faluco@1541
   110
	m_nDataBytes = nBytes;
faluco@1541
   111
faluco@1541
   112
	if ( nBits == -1 )
faluco@1541
   113
	{
faluco@1541
   114
		m_nDataBits = nBytes << 3;
faluco@1541
   115
	}
faluco@1541
   116
	else
faluco@1541
   117
	{
faluco@1541
   118
		Assert( nBits <= nBytes*8 );
faluco@1541
   119
		m_nDataBits = nBits;
faluco@1541
   120
	}
faluco@1541
   121
faluco@1541
   122
	m_iCurBit = iStartBit;
faluco@1541
   123
	m_bOverflow = false;
faluco@1541
   124
}
faluco@1541
   125
faluco@1541
   126
void bf_write::Reset()
faluco@1541
   127
{
faluco@1541
   128
	m_iCurBit = 0;
faluco@1541
   129
	m_bOverflow = false;
faluco@1541
   130
}
faluco@1541
   131
faluco@1541
   132
faluco@1541
   133
void bf_write::SetAssertOnOverflow( bool bAssert )
faluco@1541
   134
{
faluco@1541
   135
	m_bAssertOnOverflow = bAssert;
faluco@1541
   136
}
faluco@1541
   137
faluco@1541
   138
faluco@1541
   139
const char* bf_write::GetDebugName()
faluco@1541
   140
{
faluco@1541
   141
	return m_pDebugName;
faluco@1541
   142
}
faluco@1541
   143
faluco@1541
   144
faluco@1541
   145
void bf_write::SetDebugName( const char *pDebugName )
faluco@1541
   146
{
faluco@1541
   147
	m_pDebugName = pDebugName;
faluco@1541
   148
}
faluco@1541
   149
faluco@1541
   150
faluco@1541
   151
void bf_write::SeekToBit( int bitPos )
faluco@1541
   152
{
faluco@1541
   153
	m_iCurBit = bitPos;
faluco@1541
   154
}
faluco@1541
   155
faluco@1541
   156
faluco@1541
   157
// Sign bit comes first
faluco@1541
   158
void bf_write::WriteSBitLong( int data, int numbits )
faluco@1541
   159
{
faluco@1541
   160
	// Do we have a valid # of bits to encode with?
faluco@1541
   161
	Assert( numbits >= 1 );
faluco@1541
   162
faluco@1541
   163
	// Note: it does this wierdness here so it's bit-compatible with regular integer data in the buffer.
faluco@1541
   164
	// (Some old code writes direct integers right into the buffer).
faluco@1541
   165
	if(data < 0)
faluco@1541
   166
	{
faluco@1541
   167
#ifdef _DEBUG
faluco@1541
   168
	if( numbits < 32 )
faluco@1541
   169
	{
faluco@1541
   170
		// Make sure it doesn't overflow.
faluco@1541
   171
faluco@1541
   172
		if( data < 0 )
faluco@1541
   173
		{
faluco@1541
   174
			Assert( data >= -(1 << (numbits-1)) );
faluco@1541
   175
		}
faluco@1541
   176
		else
faluco@1541
   177
		{
faluco@1541
   178
			Assert( data < (1 << (numbits-1)) );
faluco@1541
   179
		}
faluco@1541
   180
	}
faluco@1541
   181
#endif
faluco@1541
   182
faluco@1541
   183
		WriteUBitLong( (unsigned int)(0x80000000 + data), numbits - 1, false );
faluco@1541
   184
		WriteOneBit( 1 );
faluco@1541
   185
	}
faluco@1541
   186
	else
faluco@1541
   187
	{
faluco@1541
   188
		WriteUBitLong((unsigned int)data, numbits - 1);
faluco@1541
   189
		WriteOneBit( 0 );
faluco@1541
   190
	}
faluco@1541
   191
}
faluco@1541
   192
faluco@1541
   193
// writes an unsigned integer with variable bit length
faluco@1541
   194
void bf_write::WriteUBitVar( unsigned int data )
faluco@1541
   195
{
faluco@1541
   196
	unsigned int bits = 0;
faluco@1541
   197
	unsigned int base = 0;
faluco@1541
   198
faluco@1541
   199
	while (data > (base<<1))
faluco@1541
   200
	{
faluco@1541
   201
		bits++;
faluco@1541
   202
		base = (1<<bits)-1;
faluco@1541
   203
	}
faluco@1541
   204
faluco@1541
   205
	// how many bits do we use
faluco@1541
   206
	if ( bits > 0)
faluco@1541
   207
		WriteUBitLong( 0, bits );
faluco@1541
   208
faluco@1541
   209
	// end marker
faluco@1541
   210
	WriteOneBit( 1 );  
faluco@1541
   211
faluco@1541
   212
	// write the value
faluco@1541
   213
	if ( bits > 0)
faluco@1541
   214
		WriteUBitLong( data - base , bits );
faluco@1541
   215
}
faluco@1541
   216
faluco@1541
   217
void bf_write::WriteBitLong(unsigned int data, int numbits, bool bSigned)
faluco@1541
   218
{
faluco@1541
   219
	if(bSigned)
faluco@1541
   220
		WriteSBitLong((int)data, numbits);
faluco@1541
   221
	else
faluco@1541
   222
		WriteUBitLong(data, numbits);
faluco@1541
   223
}
faluco@1541
   224
faluco@1541
   225
bool bf_write::WriteBits(const void *pInData, int nBits)
faluco@1541
   226
{
faluco@1541
   227
#if defined( BB_PROFILING )
faluco@1541
   228
	VPROF( "bf_write::WriteBits" );
faluco@1541
   229
#endif
faluco@1541
   230
faluco@1541
   231
	unsigned char *pOut = (unsigned char*)pInData;
faluco@1541
   232
	int nBitsLeft = nBits;
faluco@1541
   233
faluco@1541
   234
	if((m_iCurBit+nBits) > m_nDataBits)
faluco@1541
   235
	{
faluco@1541
   236
		SetOverflowFlag();
faluco@1541
   237
		CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() );
faluco@1541
   238
		return false;
faluco@1541
   239
	}
faluco@1541
   240
faluco@1541
   241
	// Get output dword-aligned.
faluco@1541
   242
	while(((unsigned long)pOut & 3) != 0 && nBitsLeft >= 8)
faluco@1541
   243
	{
faluco@1541
   244
faluco@1541
   245
		WriteUBitLong( *pOut, 8, false );
faluco@1541
   246
		++pOut;
faluco@1541
   247
		nBitsLeft -= 8;
faluco@1541
   248
	}
faluco@1541
   249
	
faluco@1541
   250
	// check if we can use fast memcpy if m_iCurBit is byte aligned
faluco@1541
   251
	if ( (nBitsLeft >= 32) && (m_iCurBit & 7) == 0 )
faluco@1541
   252
	{
faluco@1541
   253
		int numbytes = (nBitsLeft >> 3); 
faluco@1541
   254
		int numbits = numbytes << 3;
faluco@1541
   255
		
faluco@1541
   256
		// Bounds checking..
faluco@1541
   257
		// TODO: May not need this check anymore
faluco@1541
   258
		if((m_iCurBit+numbits) > m_nDataBits)
faluco@1541
   259
		{
faluco@1541
   260
			m_iCurBit = m_nDataBits;
faluco@1541
   261
			SetOverflowFlag();
faluco@1541
   262
			CallErrorHandler( BITBUFERROR_BUFFER_OVERRUN, GetDebugName() );
faluco@1541
   263
			return false;
faluco@1541
   264
		}
faluco@1541
   265
		
faluco@1541
   266
		Q_memcpy( m_pData+(m_iCurBit>>3), pOut, numbytes );
faluco@1541
   267
		pOut += numbytes;
faluco@1541
   268
		nBitsLeft -= numbits;
faluco@1541
   269
		m_iCurBit += numbits;
faluco@1541
   270
	}
faluco@1541
   271
faluco@1541
   272
	// Read dwords.
faluco@1541
   273
	while(nBitsLeft >= 32)
faluco@1541
   274
	{
faluco@1541
   275
		WriteUBitLong( *((unsigned long*)pOut), 32, false );
faluco@1541
   276
		pOut += sizeof(unsigned long);
faluco@1541
   277
		nBitsLeft -= 32;
faluco@1541
   278
	}
faluco@1541
   279
faluco@1541
   280
	// Read the remaining bytes.
faluco@1541
   281
	while(nBitsLeft >= 8)
faluco@1541
   282
	{
faluco@1541
   283
		WriteUBitLong( *pOut, 8, false );
faluco@1541
   284
		++pOut;
faluco@1541
   285
		nBitsLeft -= 8;
faluco@1541
   286
	}
faluco@1541
   287
	
faluco@1541
   288
	// Read the remaining bits.
faluco@1541
   289
	if(nBitsLeft)
faluco@1541
   290
	{
faluco@1541
   291
		WriteUBitLong( *pOut, nBitsLeft, false );
faluco@1541
   292
	}
faluco@1541
   293
faluco@1541
   294
	return !IsOverflowed();
faluco@1541
   295
}
faluco@1541
   296
faluco@1541
   297
faluco@1541
   298
bool bf_write::WriteBitsFromBuffer( bf_read *pIn, int nBits )
faluco@1541
   299
{
faluco@1541
   300
	// This could be optimized a little by
faluco@1541
   301
	while ( nBits > 32 )
faluco@1541
   302
	{
faluco@1541
   303
		WriteUBitLong( pIn->ReadUBitLong( 32 ), 32 );
faluco@1541
   304
		nBits -= 32;
faluco@1541
   305
	}
faluco@1541
   306
faluco@1541
   307
	WriteUBitLong( pIn->ReadUBitLong( nBits ), nBits );
faluco@1541
   308
	return !IsOverflowed() && !pIn->IsOverflowed();
faluco@1541
   309
}
faluco@1541
   310
faluco@1541
   311
faluco@1541
   312
void bf_write::WriteBitAngle( float fAngle, int numbits )
faluco@1541
   313
{
faluco@1541
   314
	int d;
faluco@1541
   315
	unsigned int mask;
faluco@1541
   316
	unsigned int shift;
faluco@1541
   317
faluco@1541
   318
	shift = (1<<numbits);
faluco@1541
   319
	mask = shift - 1;
faluco@1541
   320
faluco@1541
   321
	d = (int)( (fAngle / 360.0) * shift );
faluco@1541
   322
	d &= mask;
faluco@1541
   323
faluco@1541
   324
	WriteUBitLong((unsigned int)d, numbits);
faluco@1541
   325
}
faluco@1541
   326
faluco@1541
   327
void bf_write::WriteBitCoord (const float f)
faluco@1541
   328
{
faluco@1541
   329
#if defined( BB_PROFILING )
faluco@1541
   330
	VPROF( "bf_write::WriteBitCoord" );
faluco@1541
   331
#endif
faluco@1541
   332
	int		signbit = (f <= -COORD_RESOLUTION);
faluco@1541
   333
	int		intval = abs(static_cast<int>(f));
faluco@1541
   334
	int		fractval = abs((int)(f*COORD_DENOMINATOR)) & (COORD_DENOMINATOR-1);
faluco@1541
   335
faluco@1541
   336
faluco@1541
   337
	// Send the bit flags that indicate whether we have an integer part and/or a fraction part.
faluco@1541
   338
	WriteOneBit( intval );
faluco@1541
   339
	WriteOneBit( fractval );
faluco@1541
   340
faluco@1541
   341
	if ( intval || fractval )
faluco@1541
   342
	{
faluco@1541
   343
		// Send the sign bit
faluco@1541
   344
		WriteOneBit( signbit );
faluco@1541
   345
faluco@1541
   346
		// Send the integer if we have one.
faluco@1541
   347
		if ( intval )
faluco@1541
   348
		{
faluco@1541
   349
			// Adjust the integers from [1..MAX_COORD_VALUE] to [0..MAX_COORD_VALUE-1]
faluco@1541
   350
			intval--;
faluco@1541
   351
			WriteUBitLong( (unsigned int)intval, COORD_INTEGER_BITS );
faluco@1541
   352
		}
faluco@1541
   353
		
faluco@1541
   354
		// Send the fraction if we have one
faluco@1541
   355
		if ( fractval )
faluco@1541
   356
		{
faluco@1541
   357
			WriteUBitLong( (unsigned int)fractval, COORD_FRACTIONAL_BITS );
faluco@1541
   358
		}
faluco@1541
   359
	}
faluco@1541
   360
}
faluco@1541
   361
faluco@1541
   362
void bf_write::WriteBitFloat(float val)
faluco@1541
   363
{
faluco@1541
   364
	long intVal;
faluco@1541
   365
faluco@1541
   366
	Assert(sizeof(long) == sizeof(float));
faluco@1541
   367
	Assert(sizeof(float) == 4);
faluco@1541
   368
faluco@1541
   369
	void *v = &val;
faluco@1541
   370
	intVal = *reinterpret_cast<long *>(v);
faluco@1541
   371
	WriteUBitLong( intVal, 32 );
faluco@1541
   372
}
faluco@1541
   373
faluco@1541
   374
void bf_write::WriteBitVec3Coord( const Vector& fa )
faluco@1541
   375
{
faluco@1541
   376
	int		xflag, yflag, zflag;
faluco@1541
   377
faluco@1541
   378
	xflag = (fa[0] >= COORD_RESOLUTION) || (fa[0] <= -COORD_RESOLUTION);
faluco@1541
   379
	yflag = (fa[1] >= COORD_RESOLUTION) || (fa[1] <= -COORD_RESOLUTION);
faluco@1541
   380
	zflag = (fa[2] >= COORD_RESOLUTION) || (fa[2] <= -COORD_RESOLUTION);
faluco@1541
   381
faluco@1541
   382
	WriteOneBit( xflag );
faluco@1541
   383
	WriteOneBit( yflag );
faluco@1541
   384
	WriteOneBit( zflag );
faluco@1541
   385
faluco@1541
   386
	if ( xflag )
faluco@1541
   387
		WriteBitCoord( fa[0] );
faluco@1541
   388
	if ( yflag )
faluco@1541
   389
		WriteBitCoord( fa[1] );
faluco@1541
   390
	if ( zflag )
faluco@1541
   391
		WriteBitCoord( fa[2] );
faluco@1541
   392
}
faluco@1541
   393
faluco@1541
   394
void bf_write::WriteBitNormal( float f )
faluco@1541
   395
{
faluco@1541
   396
	int	signbit = (f <= -NORMAL_RESOLUTION);
faluco@1541
   397
faluco@1541
   398
	// NOTE: Since +/-1 are valid values for a normal, I'm going to encode that as all ones
faluco@1541
   399
	unsigned int fractval = abs( (int)(f*NORMAL_DENOMINATOR) );
faluco@1541
   400
faluco@1541
   401
	// clamp..
faluco@1541
   402
	if (fractval > NORMAL_DENOMINATOR)
faluco@1541
   403
		fractval = NORMAL_DENOMINATOR;
faluco@1541
   404
faluco@1541
   405
	// Send the sign bit
faluco@1541
   406
	WriteOneBit( signbit );
faluco@1541
   407
faluco@1541
   408
	// Send the fractional component
faluco@1541
   409
	WriteUBitLong( fractval, NORMAL_FRACTIONAL_BITS );
faluco@1541
   410
}
faluco@1541
   411
faluco@1541
   412
void bf_write::WriteBitVec3Normal( const Vector& fa )
faluco@1541
   413
{
faluco@1541
   414
	int		xflag, yflag;
faluco@1541
   415
faluco@1541
   416
	xflag = (fa[0] >= NORMAL_RESOLUTION) || (fa[0] <= -NORMAL_RESOLUTION);
faluco@1541
   417
	yflag = (fa[1] >= NORMAL_RESOLUTION) || (fa[1] <= -NORMAL_RESOLUTION);
faluco@1541
   418
faluco@1541
   419
	WriteOneBit( xflag );
faluco@1541
   420
	WriteOneBit( yflag );
faluco@1541
   421
faluco@1541
   422
	if ( xflag )
faluco@1541
   423
		WriteBitNormal( fa[0] );
faluco@1541
   424
	if ( yflag )
faluco@1541
   425
		WriteBitNormal( fa[1] );
faluco@1541
   426
	
faluco@1541
   427
	// Write z sign bit
faluco@1541
   428
	int	signbit = (fa[2] <= -NORMAL_RESOLUTION);
faluco@1541
   429
	WriteOneBit( signbit );
faluco@1541
   430
}
faluco@1541
   431
faluco@1541
   432
void bf_write::WriteBitAngles( const QAngle& fa )
faluco@1541
   433
{
faluco@1541
   434
	// FIXME:
faluco@1541
   435
	Vector tmp( fa.x, fa.y, fa.z );
faluco@1541
   436
	WriteBitVec3Coord( tmp );
faluco@1541
   437
}
faluco@1541
   438
faluco@1541
   439
void bf_write::WriteChar(int val)
faluco@1541
   440
{
faluco@1541
   441
	WriteSBitLong(val, sizeof(char) << 3);
faluco@1541
   442
}
faluco@1541
   443
faluco@1541
   444
void bf_write::WriteByte(int val)
faluco@1541
   445
{
faluco@1541
   446
	WriteUBitLong(val, sizeof(unsigned char) << 3);
faluco@1541
   447
}
faluco@1541
   448
faluco@1541
   449
void bf_write::WriteShort(int val)
faluco@1541
   450
{
faluco@1541
   451
	WriteSBitLong(val, sizeof(short) << 3);
faluco@1541
   452
}
faluco@1541
   453
faluco@1541
   454
void bf_write::WriteWord(int val)
faluco@1541
   455
{
faluco@1541
   456
	WriteUBitLong(val, sizeof(unsigned short) << 3);
faluco@1541
   457
}
faluco@1541
   458
faluco@1541
   459
void bf_write::WriteLong(long val)
faluco@1541
   460
{
faluco@1541
   461
	WriteSBitLong(val, sizeof(long) << 3);
faluco@1541
   462
}
faluco@1541
   463
faluco@1541
   464
void bf_write::WriteFloat(float val)
faluco@1541
   465
{
faluco@1541
   466
	WriteBits(&val, sizeof(val) << 3);
faluco@1541
   467
}
faluco@1541
   468
faluco@1541
   469
bool bf_write::WriteBytes( const void *pBuf, int nBytes )
faluco@1541
   470
{
faluco@1541
   471
	return WriteBits(pBuf, nBytes << 3);
faluco@1541
   472
}
faluco@1541
   473
faluco@1541
   474
bool bf_write::WriteString(const char *pStr)
faluco@1541
   475
{
faluco@1541
   476
	if(pStr)
faluco@1541
   477
	{
faluco@1541
   478
		do
faluco@1541
   479
		{
faluco@1541
   480
			WriteChar( *pStr );
faluco@1541
   481
			++pStr;
faluco@1541
   482
		} while( *(pStr-1) != 0 );
faluco@1541
   483
	}
faluco@1541
   484
	else
faluco@1541
   485
	{
faluco@1541
   486
		WriteChar( 0 );
faluco@1541
   487
	}
faluco@1541
   488
faluco@1541
   489
	return !IsOverflowed();
faluco@1541
   490
}
faluco@1541
   491
faluco@1541
   492
// ---------------------------------------------------------------------------------------- //
faluco@1541
   493
// bf_read
faluco@1541
   494
// ---------------------------------------------------------------------------------------- //
faluco@1541
   495
faluco@1541
   496
bf_read::bf_read()
faluco@1541
   497
{
faluco@1541
   498
	m_pData = NULL;
faluco@1541
   499
	m_nDataBytes = 0;
faluco@1541
   500
	m_nDataBits = -1; // set to -1 so we overflow on any operation
faluco@1541
   501
	m_iCurBit = 0;
faluco@1541
   502
	m_bOverflow = false;
faluco@1541
   503
	m_bAssertOnOverflow = true;
faluco@1541
   504
	m_pDebugName = NULL;
faluco@1541
   505
}
faluco@1541
   506
faluco@1541
   507
bf_read::bf_read( const void *pData, int nBytes, int nBits )
faluco@1541
   508
{
faluco@1541
   509
	m_bAssertOnOverflow = true;
faluco@1541
   510
	StartReading( pData, nBytes, 0, nBits );
faluco@1541
   511
}
faluco@1541
   512
faluco@1541
   513
bf_read::bf_read( const char *pDebugName, const void *pData, int nBytes, int nBits )
faluco@1541
   514
{
faluco@1541
   515
	m_bAssertOnOverflow = true;
faluco@1541
   516
	m_pDebugName = pDebugName;
faluco@1541
   517
	StartReading( pData, nBytes, 0, nBits );
faluco@1541
   518
}
faluco@1541
   519
faluco@1541
   520
void bf_read::StartReading( const void *pData, int nBytes, int iStartBit, int nBits )
faluco@1541
   521
{
faluco@1541
   522
	// Make sure we're dword aligned.
faluco@1541
   523
	Assert(((unsigned long)pData & 3) == 0);
faluco@1541
   524
faluco@1541
   525
	m_pData = (unsigned char*)pData;
faluco@1541
   526
	m_nDataBytes = nBytes;
faluco@1541
   527
faluco@1541
   528
	if ( nBits == -1 )
faluco@1541
   529
	{
faluco@1541
   530
		m_nDataBits = m_nDataBytes << 3;
faluco@1541
   531
	}
faluco@1541
   532
	else
faluco@1541
   533
	{
faluco@1541
   534
		Assert( nBits <= nBytes*8 );
faluco@1541
   535
		m_nDataBits = nBits;
faluco@1541
   536
	}
faluco@1541
   537
faluco@1541
   538
	m_iCurBit = iStartBit;
faluco@1541
   539
	m_bOverflow = false;
faluco@1541
   540
}
faluco@1541
   541
faluco@1541
   542
void bf_read::Reset()
faluco@1541
   543
{
faluco@1541
   544
	m_iCurBit = 0;
faluco@1541
   545
	m_bOverflow = false;
faluco@1541
   546
}
faluco@1541
   547
faluco@1541
   548
void bf_read::SetAssertOnOverflow( bool bAssert )
faluco@1541
   549
{
faluco@1541
   550
	m_bAssertOnOverflow = bAssert;
faluco@1541
   551
}
faluco@1541
   552
faluco@1541
   553
const char* bf_read::GetDebugName()
faluco@1541
   554
{
faluco@1541
   555
	return m_pDebugName;
faluco@1541
   556
}
faluco@1541
   557
faluco@1541
   558
void bf_read::SetDebugName( const char *pName )
faluco@1541
   559
{
faluco@1541
   560
	m_pDebugName = pName;
faluco@1541
   561
}
faluco@1541
   562
faluco@1541
   563
unsigned int bf_read::CheckReadUBitLong(int numbits)
faluco@1541
   564
{
faluco@1541
   565
	// Ok, just read bits out.
faluco@1541
   566
	int i, nBitValue;
faluco@1541
   567
	unsigned int r = 0;
faluco@1541
   568
faluco@1541
   569
	for(i=0; i < numbits; i++)
faluco@1541
   570
	{
faluco@1541
   571
		nBitValue = ReadOneBitNoCheck();
faluco@1541
   572
		r |= nBitValue << i;
faluco@1541
   573
	}
faluco@1541
   574
	m_iCurBit -= numbits;
faluco@1541
   575
	
faluco@1541
   576
	return r;
faluco@1541
   577
}
faluco@1541
   578
faluco@1541
   579
bool bf_read::ReadBits(void *pOutData, int nBits)
faluco@1541
   580
{
faluco@1541
   581
#if defined( BB_PROFILING )
faluco@1541
   582
	VPROF( "bf_write::ReadBits" );
faluco@1541
   583
#endif
faluco@1541
   584
faluco@1541
   585
	unsigned char *pOut = (unsigned char*)pOutData;
faluco@1541
   586
	int nBitsLeft = nBits;
faluco@1541
   587
faluco@1541
   588
	
faluco@1541
   589
	// Get output dword-aligned.
faluco@1541
   590
	while(((unsigned long)pOut & 3) != 0 && nBitsLeft >= 8)
faluco@1541
   591
	{
faluco@1541
   592
		*pOut = (unsigned char)ReadUBitLong(8);
faluco@1541
   593
		++pOut;
faluco@1541
   594
		nBitsLeft -= 8;
faluco@1541
   595
	}
faluco@1541
   596
faluco@1541
   597
	// Read dwords.
faluco@1541
   598
	while(nBitsLeft >= 32)
faluco@1541
   599
	{
faluco@1541
   600
		*((unsigned long*)pOut) = ReadUBitLong(32);
faluco@1541
   601
		pOut += sizeof(unsigned long);
faluco@1541
   602
		nBitsLeft -= 32;
faluco@1541
   603
	}
faluco@1541
   604
faluco@1541
   605
	// Read the remaining bytes.
faluco@1541
   606
	while(nBitsLeft >= 8)
faluco@1541
   607
	{
faluco@1541
   608
		*pOut = ReadUBitLong(8);
faluco@1541
   609
		++pOut;
faluco@1541
   610
		nBitsLeft -= 8;
faluco@1541
   611
	}
faluco@1541
   612
	
faluco@1541
   613
	// Read the remaining bits.
faluco@1541
   614
	if(nBitsLeft)
faluco@1541
   615
	{
faluco@1541
   616
		*pOut = ReadUBitLong(nBitsLeft);
faluco@1541
   617
	}
faluco@1541
   618
faluco@1541
   619
	return !IsOverflowed();
faluco@1541
   620
}
faluco@1541
   621
faluco@1541
   622
float bf_read::ReadBitAngle( int numbits )
faluco@1541
   623
{
faluco@1541
   624
	float fReturn;
faluco@1541
   625
	int i;
faluco@1541
   626
	float shift;
faluco@1541
   627
faluco@1541
   628
	shift = (float)( 1 << numbits );
faluco@1541
   629
faluco@1541
   630
	i = ReadUBitLong( numbits );
faluco@1541
   631
	fReturn = (float)i * (360.0 / shift);
faluco@1541
   632
faluco@1541
   633
	return fReturn;
faluco@1541
   634
}
faluco@1541
   635
faluco@1541
   636
unsigned int bf_read::PeekUBitLong( int numbits )
faluco@1541
   637
{
faluco@1541
   638
	unsigned int r;
faluco@1541
   639
	int i, nBitValue;
faluco@1541
   640
#ifdef BIT_VERBOSE
faluco@1541
   641
	int nShifts = numbits;
faluco@1541
   642
#endif
faluco@1541
   643
faluco@1541
   644
	bf_read savebf;
faluco@1541
   645
faluco@1541
   646
	savebf = *this;  // Save current state info
faluco@1541
   647
faluco@1541
   648
	r = 0;
faluco@1541
   649
	for(i=0; i < numbits; i++)
faluco@1541
   650
	{
faluco@1541
   651
		nBitValue = ReadOneBit();
faluco@1541
   652
faluco@1541
   653
		// Append to current stream
faluco@1541
   654
		if ( nBitValue )
faluco@1541
   655
		{
faluco@1541
   656
			r |= 1 << i;
faluco@1541
   657
		}
faluco@1541
   658
	}
faluco@1541
   659
	
faluco@1541
   660
	*this = savebf;
faluco@1541
   661
faluco@1541
   662
#ifdef BIT_VERBOSE
faluco@1541
   663
	Con_Printf( "PeekBitLong:  %i %i\n", nShifts, (unsigned int)r );
faluco@1541
   664
#endif
faluco@1541
   665
faluco@1541
   666
	return r;
faluco@1541
   667
}
faluco@1541
   668
faluco@1541
   669
// Append numbits least significant bits from data to the current bit stream
faluco@1541
   670
int bf_read::ReadSBitLong( int numbits )
faluco@1541
   671
{
faluco@1541
   672
	int r, sign;
faluco@1541
   673
faluco@1541
   674
	r = ReadUBitLong(numbits - 1);
faluco@1541
   675
faluco@1541
   676
	// Note: it does this wierdness here so it's bit-compatible with regular integer data in the buffer.
faluco@1541
   677
	// (Some old code writes direct integers right into the buffer).
faluco@1541
   678
	sign = ReadOneBit();
faluco@1541
   679
	if(sign)
faluco@1541
   680
		r = -((1 << (numbits-1)) - r);
faluco@1541
   681
faluco@1541
   682
	return r;
faluco@1541
   683
}
faluco@1541
   684
faluco@1541
   685
unsigned int bf_read::ReadUBitVar()
faluco@1541
   686
{
faluco@1541
   687
	int bits = 0; // how many bits are used to encode delta offset
faluco@1541
   688
faluco@1541
   689
		// how many bits do we use
faluco@1541
   690
	while ( ReadOneBit() == 0 )
faluco@1541
   691
		bits++;
faluco@1541
   692
faluco@1541
   693
	unsigned int data = (1<<bits)-1;
faluco@1541
   694
	
faluco@1541
   695
	// read the value
faluco@1541
   696
	if ( bits > 0)
faluco@1541
   697
		data += ReadUBitLong( bits );
faluco@1541
   698
faluco@1541
   699
	return data;
faluco@1541
   700
}
faluco@1541
   701
faluco@1541
   702
faluco@1541
   703
unsigned int bf_read::ReadBitLong(int numbits, bool bSigned)
faluco@1541
   704
{
faluco@1541
   705
	if(bSigned)
faluco@1541
   706
		return (unsigned int)ReadSBitLong(numbits);
faluco@1541
   707
	else
faluco@1541
   708
		return ReadUBitLong(numbits);
faluco@1541
   709
}
faluco@1541
   710
faluco@1541
   711
faluco@1541
   712
// Basic Coordinate Routines (these contain bit-field size AND fixed point scaling constants)
faluco@1541
   713
float bf_read::ReadBitCoord (void)
faluco@1541
   714
{
faluco@1541
   715
#if defined( BB_PROFILING )
faluco@1541
   716
	VPROF( "bf_write::ReadBitCoord" );
faluco@1541
   717
#endif
faluco@1541
   718
	int		intval=0,fractval=0,signbit=0;
faluco@1541
   719
	float	value = 0.0;
faluco@1541
   720
faluco@1541
   721
faluco@1541
   722
	// Read the required integer and fraction flags
faluco@1541
   723
	intval = ReadOneBit();
faluco@1541
   724
	fractval = ReadOneBit();
faluco@1541
   725
faluco@1541
   726
	// If we got either parse them, otherwise it's a zero.
faluco@1541
   727
	if ( intval || fractval )
faluco@1541
   728
	{
faluco@1541
   729
		// Read the sign bit
faluco@1541
   730
		signbit = ReadOneBit();
faluco@1541
   731
faluco@1541
   732
		// If there's an integer, read it in
faluco@1541
   733
		if ( intval )
faluco@1541
   734
		{
faluco@1541
   735
			// Adjust the integers from [0..MAX_COORD_VALUE-1] to [1..MAX_COORD_VALUE]
faluco@1541
   736
			intval = ReadUBitLong( COORD_INTEGER_BITS ) + 1;
faluco@1541
   737
		}
faluco@1541
   738
faluco@1541
   739
		// If there's a fraction, read it in
faluco@1541
   740
		if ( fractval )
faluco@1541
   741
		{
faluco@1541
   742
			fractval = ReadUBitLong( COORD_FRACTIONAL_BITS );
faluco@1541
   743
		}
faluco@1541
   744
faluco@1541
   745
		// Calculate the correct floating point value
faluco@1541
   746
		value = intval + ((float)fractval * COORD_RESOLUTION);
faluco@1541
   747
faluco@1541
   748
		// Fixup the sign if negative.
faluco@1541
   749
		if ( signbit )
faluco@1541
   750
			value = -value;
faluco@1541
   751
	}
faluco@1541
   752
faluco@1541
   753
	return value;
faluco@1541
   754
}
faluco@1541
   755
faluco@1541
   756
void bf_read::ReadBitVec3Coord( Vector& fa )
faluco@1541
   757
{
faluco@1541
   758
	int		xflag, yflag, zflag;
faluco@1541
   759
faluco@1541
   760
	// This vector must be initialized! Otherwise, If any of the flags aren't set, 
faluco@1541
   761
	// the corresponding component will not be read and will be stack garbage.
faluco@1541
   762
	fa.Init( 0, 0, 0 );
faluco@1541
   763
faluco@1541
   764
	xflag = ReadOneBit();
faluco@1541
   765
	yflag = ReadOneBit(); 
faluco@1541
   766
	zflag = ReadOneBit();
faluco@1541
   767
faluco@1541
   768
	if ( xflag )
faluco@1541
   769
		fa[0] = ReadBitCoord();
faluco@1541
   770
	if ( yflag )
faluco@1541
   771
		fa[1] = ReadBitCoord();
faluco@1541
   772
	if ( zflag )
faluco@1541
   773
		fa[2] = ReadBitCoord();
faluco@1541
   774
}
faluco@1541
   775
faluco@1541
   776
float bf_read::ReadBitNormal (void)
faluco@1541
   777
{
faluco@1541
   778
	// Read the sign bit
faluco@1541
   779
	int	signbit = ReadOneBit();
faluco@1541
   780
faluco@1541
   781
	// Read the fractional part
faluco@1541
   782
	unsigned int fractval = ReadUBitLong( NORMAL_FRACTIONAL_BITS );
faluco@1541
   783
faluco@1541
   784
	// Calculate the correct floating point value
faluco@1541
   785
	float value = (float)fractval * NORMAL_RESOLUTION;
faluco@1541
   786
faluco@1541
   787
	// Fixup the sign if negative.
faluco@1541
   788
	if ( signbit )
faluco@1541
   789
		value = -value;
faluco@1541
   790
faluco@1541
   791
	return value;
faluco@1541
   792
}
faluco@1541
   793
faluco@1541
   794
void bf_read::ReadBitVec3Normal( Vector& fa )
faluco@1541
   795
{
faluco@1541
   796
	int xflag = ReadOneBit();
faluco@1541
   797
	int yflag = ReadOneBit(); 
faluco@1541
   798
faluco@1541
   799
	if (xflag)
faluco@1541
   800
		fa[0] = ReadBitNormal();
faluco@1541
   801
	else
faluco@1541
   802
		fa[0] = 0.0f;
faluco@1541
   803
faluco@1541
   804
	if (yflag)
faluco@1541
   805
		fa[1] = ReadBitNormal();
faluco@1541
   806
	else
faluco@1541
   807
		fa[1] = 0.0f;
faluco@1541
   808
faluco@1541
   809
	// The first two imply the third (but not its sign)
faluco@1541
   810
	int znegative = ReadOneBit();
faluco@1541
   811
faluco@1541
   812
	float fafafbfb = fa[0] * fa[0] + fa[1] * fa[1];
faluco@1541
   813
	if (fafafbfb < 1.0f)
faluco@1541
   814
		fa[2] = sqrt( 1.0f - fafafbfb );
faluco@1541
   815
	else
faluco@1541
   816
		fa[2] = 0.0f;
faluco@1541
   817
faluco@1541
   818
	if (znegative)
faluco@1541
   819
		fa[2] = -fa[2];
faluco@1541
   820
}
faluco@1541
   821
faluco@1541
   822
void bf_read::ReadBitAngles( QAngle& fa )
faluco@1541
   823
{
faluco@1541
   824
	Vector tmp;
faluco@1541
   825
	ReadBitVec3Coord( tmp );
faluco@1541
   826
	fa.Init( tmp.x, tmp.y, tmp.z );
faluco@1541
   827
}
faluco@1541
   828
faluco@1541
   829
int bf_read::ReadChar()
faluco@1541
   830
{
faluco@1541
   831
	return ReadSBitLong(sizeof(char) << 3);
faluco@1541
   832
}
faluco@1541
   833
faluco@1541
   834
int bf_read::ReadByte()
faluco@1541
   835
{
faluco@1541
   836
	return ReadUBitLong(sizeof(unsigned char) << 3);
faluco@1541
   837
}
faluco@1541
   838
faluco@1541
   839
int bf_read::ReadShort()
faluco@1541
   840
{
faluco@1541
   841
	return ReadSBitLong(sizeof(short) << 3);
faluco@1541
   842
}
faluco@1541
   843
faluco@1541
   844
int bf_read::ReadWord()
faluco@1541
   845
{
faluco@1541
   846
	return ReadUBitLong(sizeof(unsigned short) << 3);
faluco@1541
   847
}
faluco@1541
   848
faluco@1541
   849
long bf_read::ReadLong()
faluco@1541
   850
{
faluco@1541
   851
	return ReadSBitLong(sizeof(long) << 3);
faluco@1541
   852
}
faluco@1541
   853
faluco@1541
   854
float bf_read::ReadFloat()
faluco@1541
   855
{
faluco@1541
   856
	float ret;
faluco@1541
   857
	Assert( sizeof(ret) == 4 );
faluco@1541
   858
	ReadBits(&ret, 32);
faluco@1541
   859
	return ret;
faluco@1541
   860
}
faluco@1541
   861
faluco@1541
   862
bool bf_read::ReadBytes(void *pOut, int nBytes)
faluco@1541
   863
{
faluco@1541
   864
	return ReadBits(pOut, nBytes << 3);
faluco@1541
   865
}
faluco@1541
   866
faluco@1541
   867
bool bf_read::ReadString( char *pStr, int maxLen, bool bLine, int *pOutNumChars )
faluco@1541
   868
{
faluco@1541
   869
	Assert( maxLen != 0 );
faluco@1541
   870
faluco@1541
   871
	bool bTooSmall = false;
faluco@1541
   872
	int iChar = 0;
faluco@1541
   873
	while(1)
faluco@1541
   874
	{
faluco@1541
   875
		char val = ReadChar();
faluco@1541
   876
		if ( val == 0 )
faluco@1541
   877
			break;
faluco@1541
   878
		else if ( bLine && val == '\n' )
faluco@1541
   879
			break;
faluco@1541
   880
faluco@1541
   881
		if ( iChar < (maxLen-1) )
faluco@1541
   882
		{
faluco@1541
   883
			pStr[iChar] = val;
faluco@1541
   884
			++iChar;
faluco@1541
   885
		}
faluco@1541
   886
		else
faluco@1541
   887
		{
faluco@1541
   888
			bTooSmall = true;
faluco@1541
   889
		}
faluco@1541
   890
	}
faluco@1541
   891
faluco@1541
   892
	// Make sure it's null-terminated.
faluco@1541
   893
	Assert( iChar < maxLen );
faluco@1541
   894
	pStr[iChar] = 0;
faluco@1541
   895
faluco@1541
   896
	if ( pOutNumChars )
faluco@1541
   897
		*pOutNumChars = iChar;
faluco@1541
   898
faluco@1541
   899
	return !IsOverflowed() && !bTooSmall;
faluco@1541
   900
}
faluco@1541
   901
faluco@1541
   902
faluco@1541
   903
char* bf_read::ReadAndAllocateString( bool *pOverflow )
faluco@1541
   904
{
faluco@1541
   905
	char str[2048];
faluco@1541
   906
	
faluco@1541
   907
	int nChars;
faluco@1541
   908
	bool bOverflow = !ReadString( str, sizeof( str ), false, &nChars );
faluco@1541
   909
	if ( pOverflow )
faluco@1541
   910
		*pOverflow = bOverflow;
faluco@1541
   911
faluco@1541
   912
	// Now copy into the output and return it;
faluco@1541
   913
	char *pRet = new char[ nChars + 1 ];
faluco@1541
   914
	for ( int i=0; i <= nChars; i++ )
faluco@1541
   915
		pRet[i] = str[i];
faluco@1541
   916
faluco@1541
   917
	return pRet;
faluco@1541
   918
}
faluco@1541
   919
faluco@1541
   920
	
faluco@1541
   921
bool bf_read::Seek(int iBit)
faluco@1541
   922
{
faluco@1541
   923
	if(iBit < 0)
faluco@1541
   924
	{
faluco@1541
   925
		SetOverflowFlag();
faluco@1541
   926
		m_iCurBit = m_nDataBits;
faluco@1541
   927
		return false;
faluco@1541
   928
	}
faluco@1541
   929
	else if(iBit > m_nDataBits)
faluco@1541
   930
	{
faluco@1541
   931
		SetOverflowFlag();
faluco@1541
   932
		m_iCurBit = m_nDataBits;
faluco@1541
   933
		return false;
faluco@1541
   934
	}
faluco@1541
   935
	else
faluco@1541
   936
	{
faluco@1541
   937
		m_iCurBit = iBit;
faluco@1541
   938
		return true;
faluco@1541
   939
	}
faluco@1541
   940
}
faluco@1541
   941
faluco@1541
   942
void bf_read::ExciseBits( int startbit, int bitstoremove )
faluco@1541
   943
{
faluco@1541
   944
	int endbit = startbit + bitstoremove;
faluco@1541
   945
	int remaining_to_end = m_nDataBits - endbit;
faluco@1541
   946
faluco@1541
   947
	bf_write temp;
faluco@1541
   948
	temp.StartWriting( (void *)m_pData, m_nDataBits << 3, startbit );
faluco@1541
   949
faluco@1541
   950
	Seek( endbit );
faluco@1541
   951
faluco@1541
   952
	for ( int i = 0; i < remaining_to_end; i++ )
faluco@1541
   953
	{
faluco@1541
   954
		temp.WriteOneBit( ReadOneBit() );
faluco@1541
   955
	}
faluco@1541
   956
faluco@1541
   957
	Seek( startbit );
faluco@1541
   958
	
faluco@1541
   959
	m_nDataBits -= bitstoremove;
faluco@1541
   960
	m_nDataBytes = m_nDataBits >> 3;
faluco@1541
   961
}