added missing headers

This commit is contained in:
Magnus Auvinen 2009-10-29 12:14:31 +00:00
parent 878ede3080
commit e56feb597b
9 changed files with 786 additions and 0 deletions

45
src/base/tl/math.hpp Normal file
View file

@ -0,0 +1,45 @@
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
#ifndef BASE_MATH_H
#define BASE_MATH_H
#include <stdlib.h>
template <typename T>
inline T clamp(T val, T min, T max)
{
if(val < min)
return min;
if(val > max)
return max;
return val;
}
inline float sign(float f)
{
return f<0.0f?-1.0f:1.0f;
}
inline int round(float f)
{
if(f > 0)
return (int)(f+0.5f);
return (int)(f-0.5f);
}
template<typename T, typename TB>
inline T mix(const T a, const T b, TB amount)
{
return a + (b-a)*amount;
}
inline float frandom() { return rand()/(float)(RAND_MAX); }
const float pi = 3.1415926535897932384626433f;
template <typename T> inline T min(T a, T b) { return a<b?a:b; }
template <typename T> inline T max(T a, T b) { return a>b?a:b; }
template <typename T> inline T min(T a, T b, T c) { return min(min(a,b),c); }
template <typename T> inline T max(T a, T b, T c) { return max(max(a,b),c); }
#endif // BASE_MATH_H

163
src/base/tl/matrix.hpp Normal file
View file

@ -0,0 +1,163 @@
#ifndef TL_FILE_MATRIX_HPP
#define TL_FILE_MATRIX_HPP
/*
Looks like OpenGL
Column Major
/ m[0][0] m[1][0] m[2][0] m[3][0] \ / v[0] \
| | | |
| m[0][1] m[1][1] m[2][1] m[3][1] | | v[1] |
| | | |
M(v) = | m[0][2] m[1][2] m[2][2] m[3][2] | X | v[2] |
| | | |
\ m[0][3] m[1][3] m[2][3] m[3][3] / \ v[3] /
v[0] = x
v[1] = y
v[2] = z
v[3] = w or 1
+y
|
|
|_____ +x
/
/
+z
right = +x
up = +y
forward = -z
*/
template<class T>
class matrix4_base
{
public:
// [col][row]
T m[4][4];
//
inline matrix4_base()
{}
inline vector3_base<T> get_column3(const int i) const { return vector3_base<T>(m[i][0], m[i][1], m[i][2]); }
inline vector3_base<T> get_column4(const int i) const { return vector4_base<T>(m[i][0], m[i][1], m[i][2], m[i][3]); }
inline vector3_base<T> get_row3(const int i) const { return vector3_base<T>(m[0][i], m[1][i], m[2][i]); }
inline vector4_base<T> get_row4(const int i) const { return vector4_base<T>(m[0][i], m[1][i], m[2][i], m[3][i]); }
inline vector3_base<T> get_right() const { return get_row3(0); }
inline vector3_base<T> get_up() const { return get_row3(1); }
inline vector3_base<T> get_forward() const { return -get_row3(2); }
inline vector3_base<T> get_translation() const { return get_column3(3); }
//
void unit()
{
m[0][1] = m[0][2] = m[0][3] = 0;
m[1][0] = m[1][2] = m[1][3] = 0;
m[2][0] = m[2][1] = m[2][3] = 0;
m[3][0] = m[3][1] = m[3][2] = 0;
m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1;
}
//
vector3_base<T> operator *(const vector3_base<T> &v) const
{
vector3_base<T> r(0,0,0);
r.x += v.x*m[0][0] + v.y*m[1][0] + v.z*m[2][0] + m[3][0];
r.y += v.x*m[0][1] + v.y*m[1][1] + v.z*m[2][1] + m[3][1];
r.z += v.x*m[0][2] + v.y*m[1][2] + v.z*m[2][2] + m[3][2];
return r;
}
//
vector4_base<T> operator *(const vector4_base<T> &v) const
{
vector4_base<T> r(0,0,0,0);
r.x += v.x*m[0][0] + v.y*m[1][0] + v.z*m[2][0] + v.w*m[3][0];
r.y += v.x*m[0][1] + v.y*m[1][1] + v.z*m[2][1] + v.w*m[3][1];
r.z += v.x*m[0][2] + v.y*m[1][2] + v.z*m[2][2] + v.w*m[3][2];
r.w += v.x*m[0][3] + v.y*m[1][3] + v.z*m[2][3] + v.w*m[3][3];
return r;
}
//
matrix4_base operator *(const matrix4_base &other) const
{
matrix4_base r;
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
{
r.m[i][j] = 0;
for(int a = 0; a < 4; a++)
r.m[i][j] += m[a][j] * other.m[i][a];
}
return r;
}
//
// THIS PART IS KINDA UGLY BECAUSE MAT4 IS NOT IMMUTABLE
//
inline void set_row(const vector3_base<T>& v, const int row)
{
m[0][row] = v.x;
m[1][row] = v.y;
m[2][row] = v.z;
}
inline void set_column(const vector3_base<T>& v, const int col)
{
m[col][0] = v.x;
m[col][1] = v.y;
m[col][2] = v.z;
}
inline void set_translation(const vector3_base<T>& v) { set_column(v,3); }
//
void rot_x(T angle)
{
T sina = (T)sin(angle);
T cosa = (T)cos(angle);
unit();
m[1][1] = cosa; m[2][1] =-sina;
m[1][2] = sina; m[2][2] = cosa;
}
//
void rot_y(T angle)
{
T sina = (T)sin(-angle);
T cosa = (T)cos(-angle);
unit();
m[0][0] = cosa; m[2][0] =-sina;
m[0][2] = sina; m[2][2] = cosa;
}
//
void rot_z(T angle)
{
T sina = (T)sin(angle);
T cosa = (T)cos(angle);
unit();
m[0][0] = cosa; m[1][0] =-sina;
m[0][1] = sina; m[1][1] = cosa;
}
};
typedef matrix4_base<float> mat4;
#endif

211
src/base/tl/quat.hpp Normal file
View file

@ -0,0 +1,211 @@
template<class T>
class quaternion_base
{
public:
T k[4];
/*void Unit()
{
k[0] = 0;
k[1] = 0;
k[2] = 0;
k[3] = 1;
}*/
inline quaternion_base(){}
inline quaternion_base(T x, T y, T z, T w)
{
k[0] = x;
k[1] = y;
k[2] = z;
k[3] = w;
}
inline quaternion_base(vector3_base<T> axis, T angle)
{
T sin_angle = sin(angle * (T)0.5);
T cos_angle = cos(angle * (T)0.5);
k[0] = axis.x * sin_angle;
k[1] = axis.y * sin_angle;
k[2] = axis.z * sin_angle;
k[3] = cos_angle;
}
T magnitude()
{
return sqrt(k[0] * k[0] + k[1] * k[1] + k[2] * k[2] + k[3] * k[3]);
}
matrix4_base<T> create_matrix() const
{
matrix4_base<T> mat;
T xx = k[0] * k[0];
T xy = k[0] * k[1];
T xz = k[0] * k[2];
T xw = k[0] * k[3];
T yy = k[1] * k[1];
T yz = k[1] * k[2];
T yw = k[1] * k[3];
T zz = k[2] * k[2];
T zw = k[2] * k[3];
mat.k[0][0] = 1 - 2 * (yy + zz);
mat.k[0][1] = 2 * (xy + zw);
mat.k[0][2] = 2 * (xz - yw);
mat.k[0][3] = 0;
mat.k[1][0] = 2 * (xy - zw);
mat.k[1][1] = 1 - 2 * (xx + zz);
mat.k[1][2] = 2 * (yz + xw);
mat.k[1][3] = 0;
mat.k[2][0] = 2 * (xz + yw);
mat.k[2][1] = 2 * (yz - xw);
mat.k[2][2] = 1 - 2 * (xx + yy);
mat.k[2][3] = 0;
mat.k[3][0] = 0;
mat.k[3][1] = 0;
mat.k[3][2] = 0;
mat.k[3][3] = 1;
}
/*
void CreateDOOM(T x, T y, T z)
{
k[0] = x;
k[1] = y;
k[2] = z;
T Term = 1 - (x * x) - (y * y) - (z * z);
if (Term < 0)
k[3] = 0;
else
k[3] = -sqrt(Term);
Normalize();
}
T DotProd(const TQuaternion<T>& Quat) const
{
return (k[0] * Quat.k[0] + k[1] * Quat.k[1] + k[2] * Quat.k[2] + k[3] * Quat.k[3]);
}
void Interpolate(const TQuaternion<T>& Quat, TQuaternion& Dest, T Scale)
{
T Separation = k[0] * Quat.k[0] + k[1] * Quat.k[1] + k[2] * Quat.k[2] + k[3] * Quat.k[3];
T Factor1,Factor2;
if (Separation > 1)
Separation = 1;
if (Separation < -1)
Separation = -1;
Separation = acos(Separation);
if (Separation == 0 || Separation == pi)
{
Factor1 = 1;
Factor2 = 0;
}
else
{
Factor1 = sin((1 - Scale)*Separation) / sin(Separation);
Factor2 = sin(Scale * Separation) / sin(Separation);
}
Dest.k[0] = k[0] * Factor1 + Quat.k[0] * Factor2;
Dest.k[1] = k[1] * Factor1 + Quat.k[1] * Factor2;
Dest.k[2] = k[2] * Factor1 + Quat.k[2] * Factor2;
Dest.k[3] = k[3] * Factor1 + Quat.k[3] * Factor2;
}
void Slerp(const TQuaternion<T>& Quat, TQuaternion& Dest, T Scale) const
{
T Sq1,Sq2;
T Dot = DotProd(Quat);
TQuaternion Temp;
if (Dot < 0.0f)
{
Dot = -Dot;
Temp.k[0] = -Quat.k[0];
Temp.k[1] = -Quat.k[1];
Temp.k[2] = -Quat.k[2];
Temp.k[3] = -Quat.k[3];
}
else
{
Temp = Quat;
}
if ((1.0 + Dot) > 0.00001)
{
if ((1.0 - Dot) > 0.00001)
{
T om = (T)acos(Dot);
T rsinom = (T)(1.0f / sin(om));
Sq1 = (T)sin(((T)1.0 - Scale) * om) * rsinom;
Sq2 = (T)sin(Scale * om) * rsinom;
}
else
{
Sq1 = (T)(1.0 - Scale);
Sq2 = Scale;
}
Dest.k[0] = Sq1 * k[0] + Sq2 * Temp[0];
Dest.k[1] = Sq1 * k[1] + Sq2 * Temp[1];
Dest.k[2] = Sq1 * k[2] + Sq2 * Temp[2];
Dest.k[3] = Sq1 * k[3] + Sq2 * Temp[3];
}
else
{
Sq1 = (T)sin(((T)1.0 - Scale) * (T)0.5 * pi);
Sq2 = (T)sin(Scale * (T)0.5 * pi);
Dest.k[0] = Sq1 * k[0] + Sq2 * Temp[1];
Dest.k[1] = Sq1 * k[1] + Sq2 * Temp[0];
Dest.k[2] = Sq1 * k[2] + Sq2 * Temp[3];
Dest.k[3] = Sq1 * k[3] + Sq2 * Temp[2];
}
}*/
// perators
T& operator [] (int i) { return k[i]; }
// quaternion multiply
quaternion_base operator *(const quaternion_base& other) const
{
// (w1 dot w2 - v1 dot v2, w1 dot v2 + w2 dot v1 + v1 cross v2)
quaternion_base r;
r.k[0] = k[3] * other.k[0] + k[0] * other.k[3] + k[1] * other.k[2] - k[2] * other.k[1];
r.k[1] = k[3] * other.k[1] + k[1] * other.k[3] + k[2] * other.k[0] - k[0] * other.k[2];
r.k[2] = k[3] * other.k[2] + k[2] * other.k[3] + k[0] * other.k[1] - k[1] * other.k[0];
r.k[3] = k[3] * other.k[3] - k[0] * other.k[0] - k[1] * other.k[1] - k[2] * other.k[2];
return normalize(r);
}
/*
bool operator == (const quaternion_base<T>& t) const { return ((k[0] == t.k[0]) && (k[1] == t.k[1]) && (k[2] == t.k[2]) && (k[3] == t.k[3])); }
bool operator != (const quaternion_base<T>& t) const { return ((k[0] != t.k[0]) || (k[1] != t.k[1]) || (k[2] != t.k[2]) || (k[3] != t.k[3])); }
void operator = (const quaternion_base<T>& other) { k[0] = other.k[0]; k[1] = other.k[1]; k[2] = other.k[2]; k[3] = other.k[3]; }
*/
/*void operator *= (const TQuaternion<T>& t) { TQuaternion Temp = Multiply(t); *this = Temp; }
TQuaternion operator * (const TQuaternion<T>& t) const { return Multiply(t); }
*/
};
template<typename T>
inline quaternion_base<T> normalize(const quaternion_base<T> &v)
{
T factor = 1.0f/v.magnitude();
return quaternion_base<T>(v.k[0]*factor, v.k[1]*factor,v. k[2]*factor,v. k[3]*factor);
}

65
src/base/tl/stream.hpp Normal file
View file

@ -0,0 +1,65 @@
#ifndef TL_FILE_STREAM_HPP
#define TL_FILE_STREAM_HPP
class input_stream
{
public:
virtual ~input_stream() {}
virtual size_t read(void *data, size_t size) = 0;
virtual size_t size() = 0;
};
class output_stream
{
public:
virtual ~output_stream() {}
virtual size_t write(const void *data, size_t size) = 0;
};
// input wrapping
// RAII style
class file_backend
{
private:
file_backend(const file_backend &other) { /* no copy allowed */ }
protected:
IOHANDLE file_handle;
explicit file_backend(const char *filename, int flags)
{
file_handle = io_open(filename, flags);
}
~file_backend()
{
if(file_handle)
io_close(file_handle);
}
public:
bool is_open() const { return file_handle != 0; }
};
class file_reader : public input_stream, public file_backend
{
public:
explicit file_reader(const char *filename)
: file_backend(filename, IOFLAG_READ)
{}
virtual size_t read(void *data, size_t size) { return io_read(file_handle, data, size); }
virtual size_t size() { return io_length(file_handle); }
};
class file_writer : public output_stream, public file_backend
{
public:
explicit file_writer(const char *filename)
: file_backend(filename, IOFLAG_WRITE)
{}
virtual size_t write(const void *data, size_t size) { return io_write(file_handle, data, size); }
};
#endif

198
src/base/tl/vector.hpp Normal file
View file

@ -0,0 +1,198 @@
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
#ifndef TL_FILE_VECTOR_HPP
#define TL_FILE_VECTOR_HPP
#include <math.h>
// ------------------------------------
template<typename T>
class vector2_base
{
public:
union { T x,u; };
union { T y,v; };
vector2_base() {}
vector2_base(float nx, float ny)
{
x = nx;
y = ny;
}
vector2_base operator -() const { return vector2_base(-x, -y); }
vector2_base operator -(const vector2_base &v) const { return vector2_base(x-v.x, y-v.y); }
vector2_base operator +(const vector2_base &v) const { return vector2_base(x+v.x, y+v.y); }
vector2_base operator *(const T v) const { return vector2_base(x*v, y*v); }
const vector2_base &operator =(const vector2_base &v) { x = v.x; y = v.y; return *this; }
const vector2_base &operator +=(const vector2_base &v) { x += v.x; y += v.y; return *this; }
const vector2_base &operator -=(const vector2_base &v) { x -= v.x; y -= v.y; return *this; }
const vector2_base &operator *=(const T v) { x *= v; y *= v; return *this; }
bool operator ==(const vector2_base &v) const { return x == v.x && y == v.y; } //TODO: do this with an eps instead
operator const T* () { return &x; }
};
template<typename T>
inline T length(const vector2_base<T> &a)
{
return sqrtf(a.x*a.x + a.y*a.y);
}
template<typename T>
inline T distance(const vector2_base<T> a, const vector2_base<T> &b)
{
return length(a-b);
}
template<typename T>
inline T dot(const vector2_base<T> a, const vector2_base<T> &b)
{
return a.x*b.x + a.y*b.y;
}
template<typename T>
inline vector2_base<T> normalize(const vector2_base<T> &v)
{
T l = (T)(1.0f/sqrtf(v.x*v.x + v.y*v.y));
return vector2_base<T>(v.x*l, v.y*l);
}
typedef vector2_base<float> vec2;
typedef vector2_base<bool> bvec2;
typedef vector2_base<int> ivec2;
template<typename T>
inline vector2_base<T> closest_point_on_line(vector2_base<T> line_point0, vector2_base<T> line_point1, vector2_base<T> target_point)
{
vector2_base<T> c = target_point - line_point0;
vector2_base<T> v = (line_point1 - line_point0);
v = normalize(v);
T d = length(line_point0-line_point1);
T t = dot(v, c)/d;
return mix(line_point0, line_point1, clamp(t, (T)0, (T)1));
/*
if (t < 0) t = 0;
if (t > 1.0f) return 1.0f;
return t;*/
}
// ------------------------------------
template<typename T>
class vector3_base
{
public:
union { T x,r,h; };
union { T y,g,s; };
union { T z,b,v,l; };
vector3_base() {}
vector3_base(float nx, float ny, float nz)
{
x = nx;
y = ny;
z = nz;
}
const vector3_base &operator =(const vector3_base &v) { x = v.x; y = v.y; z = v.z; return *this; }
vector3_base operator -(const vector3_base &v) const { return vector3_base(x-v.x, y-v.y, z-v.z); }
vector3_base operator -() const { return vector3_base(-x, -y, -z); }
vector3_base operator +(const vector3_base &v) const { return vector3_base(x+v.x, y+v.y, z+v.z); }
vector3_base operator *(const T v) const { return vector3_base(x*v, y*v, z*v); }
vector3_base operator *(const vector3_base &v) const { return vector3_base(x*v.x, y*v.y, z*v.z); }
vector3_base operator /(const T v) const { return vector3_base(x/v, y/v, z/v); }
const vector3_base &operator +=(const vector3_base &v) { x += v.x; y += v.y; z += v.z; return *this; }
const vector3_base &operator -=(const vector3_base &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
const vector3_base &operator *=(const T v) { x *= v; y *= v; z *= v; return *this; }
bool operator ==(const vector3_base &v) const { return x == v.x && y == v.y && z == v.z; } //TODO: do this with an eps instead
operator const T* () { return &x; }
};
template<typename T>
inline T length(const vector3_base<T> &a)
{
return sqrtf(a.x*a.x + a.y*a.y + a.z*a.z);
}
template<typename T>
inline T distance(const vector3_base<T> &a, const vector3_base<T> &b)
{
return length(a-b);
}
template<typename T>
inline T dot(const vector3_base<T> &a, const vector3_base<T> &b)
{
return a.x*b.x + a.y*b.y + a.z*b.z;
}
template<typename T>
inline vector3_base<T> normalize(const vector3_base<T> &v)
{
T l = (T)(1.0f/sqrtf(v.x*v.x + v.y*v.y + v.z*v.z));
return vector3_base<T>(v.x*l, v.y*l, v.z*l);
}
template<typename T>
inline vector3_base<T> cross(const vector3_base<T> &a, const vector3_base<T> &b)
{
return vector3_base<T>(
a.y*b.z - a.z*b.y,
a.z*b.x - a.x*b.z,
a.x*b.y - a.y*b.x);
}
typedef vector3_base<float> vec3;
typedef vector3_base<bool> bvec3;
typedef vector3_base<int> ivec3;
// ------------------------------------
template<typename T>
class vector4_base
{
public:
union { T x,r; };
union { T y,g; };
union { T z,b; };
union { T w,a; };
vector4_base() {}
vector4_base(float nx, float ny, float nz, float nw)
{
x = nx;
y = ny;
z = nz;
w = nw;
}
vector4_base operator +(const vector4_base &v) const { return vector4_base(x+v.x, y+v.y, z+v.z, w+v.w); }
vector4_base operator -(const vector4_base &v) const { return vector4_base(x-v.x, y-v.y, z-v.z, w-v.w); }
vector4_base operator -() const { return vector4_base(-x, -y, -z, -w); }
vector4_base operator *(const vector4_base &v) const { return vector4_base(x*v.x, y*v.y, z*v.z, w*v.w); }
vector4_base operator *(const T v) const { return vector4_base(x*v, y*v, z*v, w*v); }
const vector4_base &operator =(const vector4_base &v) { x = v.x; y = v.y; z = v.z; w = v.w; return *this; }
const vector4_base &operator +=(const vector4_base &v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
const vector4_base &operator -=(const vector4_base &v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; }
const vector4_base &operator *=(const T v) { x *= v; y *= v; z *= v; w *= v; return *this; }
bool operator ==(const vector4_base &v) const { return x == v.x && y == v.y && z == v.z && w == v.w; } //TODO: do this with an eps instead
operator const T* () { return &x; }
};
typedef vector4_base<float> vec4;
typedef vector4_base<bool> bvec4;
typedef vector4_base<int> ivec4;
#endif

View file

@ -0,0 +1,17 @@
class IEngine
{
public:
virtual ~IEngine() {}
virtual class IGraphics *Graphics() = 0;
};
class IGameClient
{
public:
virtual ~IGameClient() {}
};
extern IGameClient *CreateGameClient(IEngine *pEngine);

View file

@ -0,0 +1,10 @@
class IEditor
{
public:
virtual ~IEditor() {}
virtual void Init(class IGraphics *pGraphics) = 0;
virtual void UpdateAndRender() = 0;
};
extern IEditor *CreateEditor();

View file

@ -0,0 +1,69 @@
#include "../e_if_gfx.h"
class IGraphics
{
protected:
int m_ScreenWidth;
int m_ScreenHeight;
public:
virtual ~IGraphics() {}
int ScreenWidth() const { return m_ScreenWidth; }
int ScreenHeight() const { return m_ScreenHeight; }
float ScreenAspect() const { return (float)ScreenWidth()/(float)ScreenHeight(); }
virtual void Clear(float r, float g, float b) = 0;
virtual void ClipEnable(int x, int y, int w, int h) = 0;
virtual void ClipDisable() = 0;
virtual void MapScreen(float tl_x, float tl_y, float br_x, float br_y) = 0;
virtual void GetScreen(float *tl_x, float *tl_y, float *br_x, float *br_y) = 0;
virtual void BlendNone() = 0;
virtual void BlendNormal() = 0;
virtual void BlendAdditive() = 0;
virtual int LoadPNG(IMAGE_INFO *pImg, const char *pFilename) =0;
virtual int UnloadTexture(int Index) = 0;
virtual int LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags) = 0;
virtual int LoadTexture(const char *pFilename, int StoreFormat, int Flags) = 0;
virtual void TextureSet(int TextureID) = 0;
virtual void LinesBegin() = 0;
virtual void LinesEnd() = 0;
virtual void LinesDraw(float x0, float y0, float x1, float y1) = 0;
virtual void QuadsBegin() = 0;
virtual void QuadsEnd() = 0;
virtual void QuadsSetRotation(float Angle) = 0;
virtual void QuadsSetSubset(float tl_u, float tl_v, float br_u, float br_v) = 0;
virtual void QuadsSetSubsetFree(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) = 0;
virtual void QuadsDraw(float x, float y, float w, float h) = 0;
virtual void QuadsDrawTL(float x, float y, float w, float h) = 0;
virtual void QuadsDrawFreeform(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) = 0;
virtual void QuadsText(float x, float y, float Size, float r, float g, float b, float a, const char *pText) = 0;
virtual void SetColorVertex(int i, float r, float g, float b, float a) = 0;
virtual void SetColor(float r, float g, float b, float a) = 0;
virtual void TakeScreenshot() = 0;
};
class IEngineGraphics : public IGraphics
{
public:
virtual bool Init() = 0;
virtual void Shutdown() = 0;
virtual void Swap() = 0;
virtual void Minimize() = 0;
virtual void Maximize() = 0;
virtual int WindowActive() = 0;
virtual int WindowOpen() = 0;
};
extern IEngineGraphics *CreateEngineGraphics();

8
src/engine/message.h Normal file
View file

@ -0,0 +1,8 @@
class CMessage
{
public:
virtual bool Pack(void *pData, unsigned MaxDataSize);
virtual bool Unpack(const void *pData, unsigned DataSize);
};