170 lines
3.7 KiB
C
170 lines
3.7 KiB
C
//=======================================================================
|
|
// Copyright XashXT Group 2007 ©
|
|
// byteorder.h - byte order functions
|
|
//=======================================================================
|
|
#ifndef BYTEORDER_H
|
|
#define BYTEORDER_H
|
|
|
|
// byte order swap functions
|
|
_inline word WordSwap( word swap )
|
|
{
|
|
word *s = &swap;
|
|
|
|
__asm {
|
|
mov ebx, s
|
|
mov al, [ebx+1]
|
|
mov ah, [ebx ]
|
|
mov [ebx], ax
|
|
}
|
|
return *s;
|
|
}
|
|
|
|
#define ShortSwap(x) WordSwap((short)x)
|
|
|
|
_inline uint UintSwap( uint *swap )
|
|
{
|
|
uint *i = swap;
|
|
|
|
__asm {
|
|
mov ebx, i
|
|
mov eax, [ebx]
|
|
bswap eax
|
|
mov [ebx], eax
|
|
}
|
|
return *i;
|
|
}
|
|
|
|
#define LongSwap(x) UintSwap((uint *)&x)
|
|
#define FloatSwap(x) UintSwap((uint *)&x)
|
|
|
|
_inline double DoubleSwap( double swap )
|
|
{
|
|
#define dswap(x, y) t=b[x];b[x]=b[y];b[y]=b[x];
|
|
|
|
byte t, *b = ((byte *)&swap);
|
|
dswap(0,7);
|
|
dswap(1,6);
|
|
dswap(2,5);
|
|
dswap(3,4);
|
|
|
|
#undef dswap
|
|
|
|
return swap;
|
|
}
|
|
|
|
//============================================================================
|
|
// Endianess handling
|
|
//============================================================================
|
|
// using BSD-style defines: BYTE_ORDER is defined to either BIG_ENDIAN or LITTLE_ENDIAN
|
|
|
|
// Initializations
|
|
#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
|
|
#undef BYTE_ORDER
|
|
#undef LITTLE_ENDIAN
|
|
#undef BIG_ENDIAN
|
|
#define LITTLE_ENDIAN 1234
|
|
#define BIG_ENDIAN 4321
|
|
#endif
|
|
|
|
// If we still don't know the CPU endianess at this point, we try to guess
|
|
#ifndef BYTE_ORDER
|
|
#if defined(WIN32)
|
|
#define BYTE_ORDER LITTLE_ENDIAN
|
|
#else
|
|
#if defined(SUNOS)
|
|
#if defined(__i386) || defined(__amd64)
|
|
#define BYTE_ORDER LITTLE_ENDIAN
|
|
#else
|
|
#define BYTE_ORDER BIG_ENDIAN
|
|
#endif
|
|
#else
|
|
#warning "Unable to determine the CPU endianess. Defaulting to little endian"
|
|
#define BYTE_ORDER LITTLE_ENDIAN
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
|
// little endian
|
|
#define big_endian false
|
|
#define BigShort(l) ShortSwap(l)
|
|
#define LittleShort(l) (l)
|
|
#define BigLong(l) LongSwap(l)
|
|
#define LittleLong(l) (l)
|
|
#define BigFloat(l) FloatSwap(l)
|
|
#define LittleFloat(l) (l)
|
|
#define BigDouble(l) DoubleSwap(l)
|
|
#define LittleDouble(l) (l)
|
|
#else
|
|
// big endian
|
|
#define big_endian true
|
|
#define BigShort(l) (l)
|
|
#define LittleShort(l) ShortSwap(l)
|
|
#define BigLong(l) (l)
|
|
#define LittleLong(l) LongSwap(l)
|
|
#define BigFloat(l) (l)
|
|
#define LittleFloat(l) FloatSwap(l)
|
|
#define BigDouble(l) (l)
|
|
#define LittleDouble(l) DoubleSwap(l)
|
|
#endif
|
|
|
|
// extract from buffer
|
|
_inline unsigned long BuffBigLong( const byte *buf )
|
|
{
|
|
return (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|buf[3];
|
|
}
|
|
|
|
_inline unsigned short BuffBigShort( const byte *buf )
|
|
{
|
|
return (buf[0]<<8)|buf[1];
|
|
}
|
|
|
|
_inline float BuffBigFloat( const byte *buf )
|
|
{
|
|
return BuffBigLong( buf );
|
|
}
|
|
|
|
_inline double BuffBigDouble( const byte *buf )
|
|
{
|
|
return (buf[0]<<64)|(buf[1]<<56)|(buf[2]<<40)|(buf[3]<<32)|(buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|buf[7];
|
|
}
|
|
|
|
_inline unsigned long BuffLittleLong( const byte *buf )
|
|
{
|
|
return (buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|buf[0];
|
|
}
|
|
|
|
_inline unsigned short BuffLittleShort( const byte *buf )
|
|
{
|
|
return (buf[1]<<8)|buf[0];
|
|
}
|
|
|
|
_inline float BuffLittleFloat( const byte *buf )
|
|
{
|
|
return BuffLittleLong( buf );
|
|
}
|
|
|
|
_inline signed __int64 BuffLittleLong64( const byte *buf )
|
|
{
|
|
return (buf[7]<<64)|(buf[6]<<56)|(buf[5]<<40)|(buf[4]<<32)|(buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|buf[0];
|
|
}
|
|
|
|
/*
|
|
=============
|
|
SwapBlock
|
|
|
|
generic lump swaping
|
|
=============
|
|
*/
|
|
_inline void SwapBlock( int *block, int sizeOfBlock )
|
|
{
|
|
int i;
|
|
|
|
sizeOfBlock >>= 2;
|
|
|
|
for( i = 0; i < sizeOfBlock; i++ )
|
|
block[i] = LittleLong( block[i] );
|
|
}
|
|
|
|
|
|
#endif//BYTEORDER_H
|