mirror of
https://github.com/tribes2/engine.git
synced 2026-01-21 12:14:46 +00:00
176 lines
5 KiB
C++
176 lines
5 KiB
C++
//-----------------------------------------------------------------------------
|
|
// V12 Engine
|
|
//
|
|
// Copyright (c) 2001 GarageGames.Com
|
|
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef _BITSTREAM_H_
|
|
#define _BITSTREAM_H_
|
|
|
|
//Includes
|
|
#ifndef _PLATFORM_H_
|
|
#include "Platform/platform.h"
|
|
#endif
|
|
#ifndef _STREAM_H_
|
|
#include "Core/stream.h"
|
|
#endif
|
|
|
|
//-------------------------------------- Some caveats when using this class:
|
|
// - Get/setPosition semantics are changed
|
|
// to indicate bit position rather than
|
|
// byte position.
|
|
//
|
|
|
|
class Point3F;
|
|
class MatrixF;
|
|
class HuffmanProcessor;
|
|
|
|
class BitStream : public Stream
|
|
{
|
|
protected:
|
|
U8 *dataPtr;
|
|
S32 bitNum;
|
|
S32 bufSize;
|
|
bool error;
|
|
S32 maxReadBitNum;
|
|
S32 maxWriteBitNum;
|
|
char *stringBuffer;
|
|
|
|
friend class HuffmanProcessor;
|
|
public:
|
|
static BitStream *getPacketStream(U32 writeSize = 0);
|
|
static void sendPacketStream(const NetAddress *addr);
|
|
|
|
void setBuffer(void *bufPtr, S32 bufSize, S32 maxSize = 0);
|
|
U8* getBuffer() { return dataPtr; }
|
|
U8* getBytePtr();
|
|
|
|
U32 getReadByteSize();
|
|
|
|
S32 getCurPos() const;
|
|
void setCurPos(const U32);
|
|
|
|
BitStream(void *bufPtr, S32 bufSize, S32 maxWriteSize = -1) { setBuffer(bufPtr, bufSize,maxWriteSize); stringBuffer = NULL; }
|
|
void clear();
|
|
|
|
void setStringBuffer(char buffer[256]);
|
|
void writeInt(S32 value, S32 bitCount);
|
|
S32 readInt(S32 bitCount);
|
|
|
|
void writeSignedInt(S32 value, S32 bitCount);
|
|
S32 readSignedInt(S32 bitCount);
|
|
|
|
void writeRangedU32(U32 value, U32 rangeStart, U32 rangeEnd);
|
|
U32 readRangedU32(U32 rangeStart, U32 rangeEnd);
|
|
|
|
// read and write floats... floats are 0 to 1 inclusive, signed floats are -1 to 1 inclusive
|
|
|
|
F32 readFloat(S32 bitCount);
|
|
F32 readSignedFloat(S32 bitCount);
|
|
|
|
void writeFloat(F32 f, S32 bitCount);
|
|
void writeSignedFloat(F32 f, S32 bitCount);
|
|
|
|
// writes a normalized vector
|
|
void writeNormalVector(const Point3F& vec, S32 bitCount);
|
|
void readNormalVector(Point3F *vec, S32 bitCount);
|
|
|
|
// Uses the above method to reduce the precision of a normal vector so the server can
|
|
// determine exactly what is on the client. (Pre-dumbing the vector before sending
|
|
// to the client can result in precision errors...)
|
|
static Point3F dumbDownNormal(const Point3F& vec, S32 bitCount);
|
|
|
|
|
|
// writes a normalized vector using alternate method
|
|
void writeNormalVector(const Point3F& vec, S32 angleBitCount, S32 zBitCount);
|
|
void readNormalVector(Point3F *vec, S32 angleBitCount, S32 zBitCount);
|
|
|
|
// writes an affine transform (full precision version)
|
|
void writeAffineTransform(const MatrixF&);
|
|
void readAffineTransform(MatrixF*);
|
|
|
|
void writeBits(S32 bitCount, const void *bitPtr);
|
|
void readBits(S32 bitCount, void *bitPtr);
|
|
bool writeFlag(bool val);
|
|
bool readFlag();
|
|
|
|
void setBit(S32 bitCount, bool set);
|
|
bool testBit(S32 bitCount);
|
|
|
|
bool isFull() { return bitNum > (bufSize << 3); }
|
|
bool isValid() { return !error; }
|
|
|
|
bool _read (const U32 size,void* d);
|
|
bool _write(const U32 size,const void* d);
|
|
|
|
void readString(char stringBuf[256]);
|
|
void writeString(const char *stringBuf, S32 maxLen=255);
|
|
|
|
bool hasCapability(const Capability) const { return true; }
|
|
U32 getPosition() const;
|
|
bool setPosition(const U32 in_newPosition);
|
|
U32 getStreamSize();
|
|
};
|
|
|
|
class ResizeBitStream : public BitStream
|
|
{
|
|
U32 mMinSpace;
|
|
public:
|
|
ResizeBitStream(U32 minSpace = 1500, U32 initialSize = 0);
|
|
void validate();
|
|
~ResizeBitStream();
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
//-------------------------------------- INLINES
|
|
//
|
|
inline S32 BitStream::getCurPos() const
|
|
{
|
|
return bitNum;
|
|
}
|
|
|
|
inline void BitStream::setCurPos(const U32 in_position)
|
|
{
|
|
AssertFatal(in_position < (U32)(bufSize << 3), "Out of range bitposition");
|
|
bitNum = S32(in_position);
|
|
}
|
|
|
|
inline bool BitStream::readFlag()
|
|
{
|
|
if(bitNum > maxReadBitNum)
|
|
{
|
|
error = true;
|
|
AssertFatal(false, "Out of range read");
|
|
return false;
|
|
}
|
|
S32 mask = 1 << (bitNum & 0x7);
|
|
bool ret = (*(dataPtr + (bitNum >> 3)) & mask) != 0;
|
|
bitNum++;
|
|
return ret;
|
|
}
|
|
|
|
inline void BitStream::writeRangedU32(U32 value, U32 rangeStart, U32 rangeEnd)
|
|
{
|
|
AssertFatal(value >= rangeStart && value <= rangeEnd, "Out of bounds value!");
|
|
AssertFatal(rangeEnd >= rangeStart, "error, end of range less than start");
|
|
|
|
U32 rangeSize = rangeEnd - rangeStart + 1;
|
|
U32 rangeBits = getBinLog2(getNextPow2(rangeSize));
|
|
|
|
writeInt(S32(value - rangeStart), S32(rangeBits));
|
|
}
|
|
|
|
inline U32 BitStream::readRangedU32(U32 rangeStart, U32 rangeEnd)
|
|
{
|
|
AssertFatal(rangeEnd >= rangeStart, "error, end of range less than start");
|
|
|
|
U32 rangeSize = rangeEnd - rangeStart + 1;
|
|
U32 rangeBits = getBinLog2(getNextPow2(rangeSize));
|
|
|
|
U32 val = U32(readInt(S32(rangeBits)));
|
|
return val + rangeStart;
|
|
}
|
|
|
|
#endif //_BITSTREAM_H_
|