#ifndef __C_MY3D_HELPER_H_INCLUDED__
#define __C_MY3D_HELPER_H_INCLUDED__
#include <irrTypes.h>
namespace irr
{
namespace scene
{
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
#elif defined( __GNUC__ )
# define PACK_STRUCT __attribute__((packed))
#else
# error compiler not supported
#endif
struct SMyVector3
{ SMyVector3 () {;}
SMyVector3 (f32 __X, f32 __Y, f32 __Z)
: X(__X), Y(__Y), Z(__Z) {}
f32 X, Y, Z;
} PACK_STRUCT;
struct SMyVector2
{ SMyVector2 () {;}
SMyVector2(f32 __X, f32 __Y)
: X(__X), Y(__Y) {}
f32 X, Y;
} PACK_STRUCT;
struct SMyVertex
{ SMyVertex () {;}
SMyVertex (SMyVector3 _Coord, SMyColor _Color, SMyVector3 _Normal)
:Coord(_Coord), Color(_Color), Normal(_Normal) {;}
SMyVector3 Coord;
SMyColor Color;
SMyVector3 Normal;
} PACK_STRUCT;
struct SMyTVertex
{ SMyTVertex () {;}
SMyTVertex (SMyVector2 _TCoord)
: TCoord(_TCoord) {;}
SMyVector2 TCoord;
} PACK_STRUCT;
struct SMyFace
{ SMyFace() {;}
SMyFace(u32 __A, u32 __B, u32 __C)
: A(__A), B(__B), C(__C) {}
u32 A, B, C;
} PACK_STRUCT;
struct SMyFileHeader
{ u32 MyId;
u16 Ver;
} PACK_STRUCT;
struct SMySceneHeader
{ SMyColor BackgrColor;
SMyColor AmbientColor;
s32 MaterialCount;
s32 MeshCount;
} PACK_STRUCT;
struct SMyMeshHeader
{ c8 Name[256];
u32 MatIndex;
u32 TChannelCnt;
} PACK_STRUCT;
struct SMyTexDataHeader
{ c8 Name[256];
u32 ComprMode;
u32 PixelFormat;
u32 Width;
u32 Height;
} PACK_STRUCT;
struct SMyPixelColor24
{ SMyPixelColor24() {;}
SMyPixelColor24(u8 __r, u8 __g, u8 __b)
: r(__r), g(__g), b(__b) {}
u8 r, g, b;
} PACK_STRUCT;
struct SMyPixelColor16
{ SMyPixelColor16() {;}
SMyPixelColor16(s16 _argb): argb(_argb) {;}
SMyPixelColor16(u8 r, u8 g, u8 b)
{ argb = ((r&0x1F)<<10) | ((g&0x1F)<<5) | (b&0x1F);
}
s16 argb;
} PACK_STRUCT;
struct SMyRLEHeader
{ SMyRLEHeader() {}
u32 nEncodedBytes;
u32 nDecodedBytes;
} PACK_STRUCT;
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
}
}
namespace irr
{
namespace core
{
int rle_encode (
unsigned char *in_buf, int in_buf_size,
unsigned char *out_buf, int out_buf_size
);
unsigned long process_comp(
unsigned char *buf, int buf_size,
unsigned char *out_buf, int out_buf_size
);
void process_uncomp(
unsigned char, unsigned char *out_buf, int out_buf_size
);
void flush_outbuf(
unsigned char *out_buf, int out_buf_size
);
unsigned long get_byte (
unsigned char *ch,
unsigned char *in_buf, int in_buf_size,
unsigned char *out_buf, int out_buf_size
);
void put_byte(
unsigned char ch, unsigned char *out_buf, int out_buf_size
);
const unsigned long LIMIT = 1; const unsigned long NON_MATCH = 2; const unsigned long EOD_FOUND = 3; const unsigned long EOD = 0x00454f44;
static int nDecodedBytes=0;
static int nCodedBytes=0;
static int nReadedBytes=0;
static unsigned char tmpbuf[4];
static int tmpbuf_cnt;
static unsigned char outbuf[128];
static int outbuf_cnt;
int rle_encode (
unsigned char *in_buf, int in_buf_size,
unsigned char *out_buf, int out_buf_size
)
{
unsigned long ret_code;
unsigned char ch;
nCodedBytes=0;
nReadedBytes=0;
tmpbuf_cnt = 0;
outbuf_cnt = 0;
while (1)
{
if (get_byte(&ch, in_buf, in_buf_size,
out_buf, out_buf_size) == (int)EOD)
break;
tmpbuf[++tmpbuf_cnt] = (unsigned char) ch;
if (tmpbuf_cnt == 3)
{
if ((tmpbuf[1] == tmpbuf[2]) && (tmpbuf[2] == tmpbuf[3]))
{
ret_code = process_comp(in_buf, in_buf_size, out_buf, out_buf_size);
if (ret_code == (int)EOD_FOUND)
break;
if (ret_code == (int)NON_MATCH)
tmpbuf_cnt=1;
else
tmpbuf_cnt=0;
}
else
{
process_uncomp(tmpbuf[1], out_buf, out_buf_size);
if (tmpbuf[2] == tmpbuf[3])
{
tmpbuf[1]=tmpbuf[3];
tmpbuf_cnt=2;
}
else
{
process_uncomp(tmpbuf[2], out_buf, out_buf_size);
tmpbuf[1]=tmpbuf[3];
tmpbuf_cnt=1;
}
}
}
}
flush_outbuf(out_buf, out_buf_size);
return nCodedBytes;
}
unsigned long process_comp(
unsigned char *buf, int buf_size,
unsigned char *out_buf, int out_buf_size)
{
register int len = 3;
unsigned char ch;
flush_outbuf(out_buf, out_buf_size);
while (get_byte(&ch, buf, buf_size, out_buf, out_buf_size) != (int)EOD)
{
if (ch != tmpbuf[1])
{
put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size);
put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size);
tmpbuf[1]=(unsigned char) ch;
return NON_MATCH;
}
len++;
if (len == 128)
{
put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size);
put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size);
return LIMIT;
}
}
put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size);
put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size);
return EOD_FOUND;
}
void process_uncomp(
unsigned char char1, unsigned char *out_buf, int out_buf_size
)
{
outbuf[outbuf_cnt++] = char1;
if (outbuf_cnt == 128)
flush_outbuf(out_buf, out_buf_size);
}
void flush_outbuf(unsigned char *out_buf, int out_buf_size)
{
register int pos=0;
if(!outbuf_cnt)
return;
put_byte((unsigned char)(outbuf_cnt - 1), out_buf, out_buf_size);
for ( ; outbuf_cnt; outbuf_cnt--)
put_byte((unsigned char)outbuf[pos++], out_buf, out_buf_size);
}
void put_byte(unsigned char ch, unsigned char *out_buf, int out_buf_size)
{
if (nCodedBytes<=(out_buf_size-1))
{ out_buf[nCodedBytes++]=ch;
out_buf[nCodedBytes]=0;
}
}
unsigned long get_byte(
unsigned char *ch,
unsigned char *in_buf, int in_buf_size,
unsigned char *out_buf, int out_buf_size
)
{
if (nReadedBytes>=in_buf_size)
{
if (tmpbuf_cnt == 1)
process_uncomp(tmpbuf[1], out_buf, out_buf_size);
else
{
if (tmpbuf_cnt == 2)
{
process_uncomp(tmpbuf[1], out_buf, out_buf_size);
process_uncomp(tmpbuf[2], out_buf, out_buf_size);
}
}
nReadedBytes =0;
return EOD;
}
(*ch) = (unsigned char)in_buf[nReadedBytes++];
return 0;
}
int rle_decode (
unsigned char *in_buf, int in_buf_size,
unsigned char *out_buf, int out_buf_size
)
{
nDecodedBytes=0;
nReadedBytes=0;
int ch, i;
while (1)
{
if (nReadedBytes>=in_buf_size)
break;
else
ch=in_buf[nReadedBytes];
nReadedBytes++;
if (ch > 127)
{
i = ch - 127;
if (nReadedBytes>=in_buf_size)
break;
else
ch=in_buf[nReadedBytes];
nReadedBytes++;
for ( ; i ; i--)
{
if (nDecodedBytes<out_buf_size)
out_buf[nDecodedBytes] = ch;
nDecodedBytes++;
}
}
else
{
i = ch + 1;
for ( ; i ; i--)
{
if (nReadedBytes>=in_buf_size)
break;
else
ch=in_buf[nReadedBytes];
nReadedBytes++;
if (nDecodedBytes<out_buf_size)
out_buf[nDecodedBytes] = ch;
nDecodedBytes++;
}
}
}
return nDecodedBytes;
}
}
}
#endif