Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS

Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
This commit is contained in:
Cyd
2026-06-24 21:28:16 -05:00
commit 2b8ca921cb
66341 changed files with 7923174 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,657 @@
//===========================================================================//
// File: affnmtrx.hh //
// Project: MUNGA Brick: Math Library //
// Contents: Interface specifications for Affine matrices //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 11/20/94 JMA Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#pragma once
#include "Stuff.hpp"
#include "Point3D.hpp"
namespace Stuff {class AffineMatrix4D;}
#if !defined(Spew)
void
Spew(
const char* group,
const Stuff::AffineMatrix4D& matrix
);
#endif
namespace Stuff {
class Origin3D;
class EulerAngles;
class UnitQuaternion;
class YawPitchRoll;
//~~~~~~~~~~~~~~~~~~~~~~~~~~ AffineMatrix4D ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class AffineMatrix4D
{
public:
static const AffineMatrix4D
Identity;
Scalar
entries[12];
//
// Constructors
//
AffineMatrix4D()
{}
AffineMatrix4D&
BuildIdentity();
explicit AffineMatrix4D(int)
{BuildIdentity();}
AffineMatrix4D(const AffineMatrix4D &m)
{*this = m;}
explicit AffineMatrix4D(const Origin3D &p)
{*this = p;}
explicit AffineMatrix4D(const Matrix4D &m)
{*this = m;}
explicit AffineMatrix4D(const EulerAngles &angles)
{*this = angles;}
explicit AffineMatrix4D(const YawPitchRoll &angles)
{*this = angles;}
explicit AffineMatrix4D(const UnitQuaternion &q)
{*this = q;}
explicit AffineMatrix4D(const Point3D &p)
{*this = p;}
//
// Assignment Operators
//
AffineMatrix4D&
operator=(const AffineMatrix4D &m)
{
Check_Pointer(this); Check_Object(&m);
memcpy(entries, m.entries, sizeof(m.entries)); return *this;
}
AffineMatrix4D&
operator=(const Origin3D &p);
AffineMatrix4D&
operator=(const Matrix4D &m);
AffineMatrix4D&
operator=(const EulerAngles &angles);
AffineMatrix4D&
operator=(const YawPitchRoll &angles);
AffineMatrix4D&
operator=(const UnitQuaternion &q);
AffineMatrix4D&
operator=(const Point3D &p);
AffineMatrix4D&
BuildRotation(const EulerAngles &angles);
AffineMatrix4D&
BuildRotation(const YawPitchRoll &angles);
AffineMatrix4D&
BuildRotation(const UnitQuaternion &q);
AffineMatrix4D&
BuildRotation(const Vector3D &angles);
AffineMatrix4D&
BuildTranslation(const Point3D &p)
{
Check_Pointer(this); Check_Object(&p);
(*this)(W_Axis, X_Axis) = p.x;
(*this)(W_Axis, Y_Axis) = p.y;
(*this)(W_Axis, Z_Axis) = p.z;
return *this;
}
AffineMatrix4D&
BuildLookAt(const YawPitchRange& rotation);
AffineMatrix4D&
BuildLookFrom(const YawPitchRange& rotation);
//
// Comparison operators
//
friend bool
Close_Enough(
const AffineMatrix4D &m1,
const AffineMatrix4D &m2,
Scalar e=SMALL
);
bool
operator==(const AffineMatrix4D& a) const
{return Close_Enough(*this,a,SMALL);}
bool
operator!=(const AffineMatrix4D& a) const
{return !Close_Enough(*this,a,SMALL);}
//
// Index operators
//
Scalar&
operator()(size_t row,size_t column)
{
Check_Pointer(this);
Verify(static_cast<unsigned>(row) <= W_Axis);
Verify(static_cast<unsigned>(column) <= Z_Axis);
return entries[(column<<2)+row];
}
const Scalar&
operator ()(size_t row,size_t column) const
{
Check_Pointer(this);
Verify(static_cast<unsigned>(row) <= W_Axis);
Verify(static_cast<unsigned>(column) <= Z_Axis);
return entries[(column<<2)+row];
}
//
// Axis Manipulation functions
//
void
GetLocalForwardInWorld(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_FORWARD_SIGN((*this)(FORWARD_AXIS, X_Axis));
v->y = APPLY_FORWARD_SIGN((*this)(FORWARD_AXIS, Y_Axis));
v->z = APPLY_FORWARD_SIGN((*this)(FORWARD_AXIS, Z_Axis));
}
void
GetWorldForwardInLocal(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_FORWARD_SIGN((*this)(X_Axis, FORWARD_AXIS));
v->y = APPLY_FORWARD_SIGN((*this)(Y_Axis, FORWARD_AXIS));
v->z = APPLY_FORWARD_SIGN((*this)(Z_Axis, FORWARD_AXIS));
}
void
GetLocalBackwardInWorld(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_BACKWARD_SIGN((*this)(BACKWARD_AXIS, X_Axis));
v->y = APPLY_BACKWARD_SIGN((*this)(BACKWARD_AXIS, Y_Axis));
v->z = APPLY_BACKWARD_SIGN((*this)(BACKWARD_AXIS, Z_Axis));
}
void
GetWorldBackwardInLocal(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_BACKWARD_SIGN((*this)(X_Axis, BACKWARD_AXIS));
v->y = APPLY_BACKWARD_SIGN((*this)(Y_Axis, BACKWARD_AXIS));
v->z = APPLY_BACKWARD_SIGN((*this)(Z_Axis, BACKWARD_AXIS));
}
void
GetLocalRightInWorld(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_RIGHT_SIGN((*this)(RIGHT_AXIS, X_Axis));
v->y = APPLY_RIGHT_SIGN((*this)(RIGHT_AXIS, Y_Axis));
v->z = APPLY_RIGHT_SIGN((*this)(RIGHT_AXIS, Z_Axis));
}
void
GetWorldRightInLocal(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_RIGHT_SIGN((*this)(X_Axis, RIGHT_AXIS));
v->y = APPLY_RIGHT_SIGN((*this)(Y_Axis, RIGHT_AXIS));
v->z = APPLY_RIGHT_SIGN((*this)(Z_Axis, RIGHT_AXIS));
}
void
GetLocalLeftInWorld(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_LEFT_SIGN((*this)(LEFT_AXIS, X_Axis));
v->y = APPLY_LEFT_SIGN((*this)(LEFT_AXIS, Y_Axis));
v->z = APPLY_LEFT_SIGN((*this)(LEFT_AXIS, Z_Axis));
}
void
GetWorldLeftInLocal(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_LEFT_SIGN((*this)(X_Axis, LEFT_AXIS));
v->y = APPLY_LEFT_SIGN((*this)(Y_Axis, LEFT_AXIS));
v->z = APPLY_LEFT_SIGN((*this)(Z_Axis, LEFT_AXIS));
}
void
GetLocalUpInWorld(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_UP_SIGN((*this)(UP_AXIS, X_Axis));
v->y = APPLY_UP_SIGN((*this)(UP_AXIS, Y_Axis));
v->z = APPLY_UP_SIGN((*this)(UP_AXIS, Z_Axis));
}
void
GetWorldUpInLocal(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_UP_SIGN((*this)(X_Axis, UP_AXIS));
v->y = APPLY_UP_SIGN((*this)(Y_Axis, UP_AXIS));
v->z = APPLY_UP_SIGN((*this)(Z_Axis, UP_AXIS));
}
void
GetLocalDownInWorld(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_DOWN_SIGN((*this)(DOWN_AXIS, X_Axis));
v->y = APPLY_DOWN_SIGN((*this)(DOWN_AXIS, Y_Axis));
v->z = APPLY_DOWN_SIGN((*this)(DOWN_AXIS, Z_Axis));
}
void
GetWorldDownInLocal(Vector3D *v) const
{
Check_Object(this); Check_Pointer(v);
v->x = APPLY_DOWN_SIGN((*this)(X_Axis, DOWN_AXIS));
v->y = APPLY_DOWN_SIGN((*this)(Y_Axis, DOWN_AXIS));
v->z = APPLY_DOWN_SIGN((*this)(Z_Axis, DOWN_AXIS));
}
//
// Matrix Multiplication
//
inline AffineMatrix4D&
Multiply(
const AffineMatrix4D& Source1,
const AffineMatrix4D& Source2
)
{
Check_Pointer(this);
Check_Object(&Source1);
Check_Object(&Source2);
Verify(this != &Source1);
Verify(this != &Source2);
#if USE_ASSEMBLER_CODE
Scalar *f = entries;
_asm {
mov edx, Source1.entries
push esi
mov esi, Source2.entries
mov eax, f
fld dword ptr [edx] // s1[0][0]
fmul dword ptr [esi] // s2[0][0] M0,1
fld dword ptr [edx+010h] // s1[0][1]
fmul dword ptr [esi+4] // s2[1][0] M0,2
fld dword ptr [edx+020h] // s1[0][2]
fmul dword ptr [esi+8] // s2[2][0] M0,3
fxch st(2)
faddp st(1),st // A0,1
fld dword ptr [edx+4] // s1[1][0]
fmul dword ptr [esi] // s2[0][0] M1,1
fxch st(2)
faddp st(1),st // A0,2
fld dword ptr [edx+14h] // s1[1][1]
fmul dword ptr [esi+4] // s2[1][0] M1,2
fxch st(1)
fstp dword ptr [eax] // [0][0] S0
fld dword ptr [edx+24h] // s1[1][2]
fmul dword ptr [esi+8] // s2[2][0] M1,3
fxch st(2)
faddp st(1),st // A1,1
fld dword ptr [edx+8] // s1[2][0]
fmul dword ptr [esi] // s2[0][0] M2,1
fxch st(2)
faddp st(1),st // A1,2
fld dword ptr [edx+018h] // s1[2][1]
fmul dword ptr [esi+4] // s2[1][0] M2,2
fxch st(1)
fstp dword ptr [eax+4] // [1][0] S1
fld dword ptr [edx+28h] // s1[2][2]
fmul dword ptr [esi+8] // s2[2][0] M2,3
fxch st(2)
faddp st(1),st // A2,1
fld dword ptr [edx+0ch] // s1[3][0]
fmul dword ptr [esi] // s2[0][0] M3,1
fxch st(2)
faddp st(1),st // A2,2
fld dword ptr [edx+1ch] // s1[3][1]
fmul dword ptr [esi+4] // s2[1][0] M3,2
fxch st(1)
fstp dword ptr [eax+8] // [2][0] S2
fld dword ptr [edx+2ch] // s1[3][2]
fmul dword ptr [esi+8] // s2[2][0] M3,3
fxch st(2)
faddp st(1),st // A3,1
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
fld dword ptr [edx] // s1[0][0]
fmul dword ptr [esi+010h] // s2[0][1] M0,1
fxch st(2)
faddp st(1),st // A3,2
fld dword ptr [edx+010h] // s1[0][1]
fmul dword ptr [esi+014h] // s2[1][1] M0,2
fxch st(1)
fadd dword ptr [esi+0Ch] // s2[3][0] A3,3
fld dword ptr [edx+020h] // s1[0][2]
fmul dword ptr [esi+018h] // s2[2][1] M0,3
fxch st(1)
fstp dword ptr [eax+0Ch] // [3][0] S3
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
fxch st(2)
faddp st(1),st // A0,1
fld dword ptr [edx+4] // s1[1][0]
fmul dword ptr [esi+010h] // s2[0][1] M1,1
fxch st(2)
faddp st(1),st // A0,2
fld dword ptr [edx+014h] // s1[1][1]
fmul dword ptr [esi+014h] // s2[1][1] M1,2
fxch st(1)
fstp dword ptr [eax+010h] // [0][1] S0
fld dword ptr [edx+024h] // s1[1][2]
fmul dword ptr [esi+018h] // s2[2][1] M1,3
fxch st(2)
faddp st(1),st // A1,1
fld dword ptr [edx+8] // s1[2][0]
fmul dword ptr [esi+010h] // s2[0][1] M2,1
fxch st(2)
faddp st(1),st // A1,2
fld dword ptr [edx+018h] // s1[2][1]
fmul dword ptr [esi+014h] // s2[1][1] M2,2
fxch st(1)
fstp dword ptr [eax+014h] // [1][1] S1
fld dword ptr [edx+028h] // s1[2][2]
fmul dword ptr [esi+018h] // s2[2][1] M2,3
fxch st(2)
faddp st(1),st // A2,1
fld dword ptr [edx+0ch] // s1[3][0]
fmul dword ptr [esi+010h] // s2[0][1] M3,1
fxch st(2)
faddp st(1),st // A2,2
fld dword ptr [edx+01ch] // s1[3][1]
fmul dword ptr [esi+014h] // s2[1][1] M3,2
fxch st(1)
fstp dword ptr [eax+018h] // [2][1] S2
fld dword ptr [edx+02ch] // s1[3][2]
fmul dword ptr [esi+018h] // s2[2][1] M3,3
fxch st(2)
faddp st(1),st // A3,1
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
fld dword ptr [edx] // s1[0][0]
fmul dword ptr [esi+020h] // s2[0][2] M0,1
fxch st(2)
faddp st(1),st // A3,2
fld dword ptr [edx+010h] // s1[0][1]
fmul dword ptr [esi+024h] // s2[1][2] M0,2
fxch st(1)
fadd dword ptr [esi+01Ch] // s2[3][1] A3,3
fld dword ptr [edx+020h] // s1[0][2]
fmul dword ptr [esi+028h] // s2[2][2] M0,3
fxch st(1)
fstp dword ptr [eax+01Ch] // [3][1] S3
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
fxch st(2)
faddp st(1),st // A0,1
fld dword ptr [edx+4] // s1[1][0]
fmul dword ptr [esi+020h] // s2[0][2] M1,1
fxch st(2)
faddp st(1),st // A0,2
fld dword ptr [edx+014h] // s1[1][1]
fmul dword ptr [esi+024h] // s2[1][2] M1,2
fxch st(1)
fstp dword ptr [eax+020h] // [0][2] S0
fld dword ptr [edx+024h] // s1[1][2]
fmul dword ptr [esi+028h] // s2[2][2] M1,3
fxch st(2)
faddp st(1),st // A1,1
fld dword ptr [edx+8] // s1[2][0]
fmul dword ptr [esi+020h] // s2[0][2] M2,1
fxch st(2)
faddp st(1),st // A1,2
fld dword ptr [edx+018h] // s1[2][1]
fmul dword ptr [esi+024h] // s2[1][2] M2,2
fxch st(1)
fstp dword ptr [eax+024h] // [1][2] S1
fld dword ptr [edx+028h] // s1[2][2]
fmul dword ptr [esi+028h] // s2[2][2] M2,3
fxch st(2)
faddp st(1),st // A2,1
fld dword ptr [edx+0ch] // s1[3][0]
fmul dword ptr [esi+020h] // s2[0][2] M3,1
fxch st(2)
faddp st(1),st // A2,2
fld dword ptr [edx+01ch] // s1[3][1]
fmul dword ptr [esi+024h] // s2[1][2] M3,2
fxch st(1)
fstp dword ptr [eax+028h] // [2][2] S2
fld dword ptr [edx+02ch] // s1[3][2]
fmul dword ptr [esi+028h] // s2[2][2] M3,3
fxch st(2)
faddp st(1),st // A3,1
faddp st(1),st // A3,2
fadd dword ptr [esi+02Ch] // s2[3][2] A3,3
fstp dword ptr [eax+02Ch] // [3][2] S3
pop esi
}
#else
(*this)(0,0) =
Source1(0,0)*Source2(0,0)
+ Source1(0,1)*Source2(1,0)
+ Source1(0,2)*Source2(2,0);
(*this)(1,0) =
Source1(1,0)*Source2(0,0)
+ Source1(1,1)*Source2(1,0)
+ Source1(1,2)*Source2(2,0);
(*this)(2,0) =
Source1(2,0)*Source2(0,0)
+ Source1(2,1)*Source2(1,0)
+ Source1(2,2)*Source2(2,0);
(*this)(3,0) =
Source1(3,0)*Source2(0,0)
+ Source1(3,1)*Source2(1,0)
+ Source1(3,2)*Source2(2,0)
+ Source2(3,0);
(*this)(0,1) =
Source1(0,0)*Source2(0,1)
+ Source1(0,1)*Source2(1,1)
+ Source1(0,2)*Source2(2,1);
(*this)(1,1) =
Source1(1,0)*Source2(0,1)
+ Source1(1,1)*Source2(1,1)
+ Source1(1,2)*Source2(2,1);
(*this)(2,1) =
Source1(2,0)*Source2(0,1)
+ Source1(2,1)*Source2(1,1)
+ Source1(2,2)*Source2(2,1);
(*this)(3,1) =
Source1(3,0)*Source2(0,1)
+ Source1(3,1)*Source2(1,1)
+ Source1(3,2)*Source2(2,1)
+ Source2(3,1);
(*this)(0,2) =
Source1(0,0)*Source2(0,2)
+ Source1(0,1)*Source2(1,2)
+ Source1(0,2)*Source2(2,2);
(*this)(1,2) =
Source1(1,0)*Source2(0,2)
+ Source1(1,1)*Source2(1,2)
+ Source1(1,2)*Source2(2,2);
(*this)(2,2) =
Source1(2,0)*Source2(0,2)
+ Source1(2,1)*Source2(1,2)
+ Source1(2,2)*Source2(2,2);
(*this)(3,2) =
Source1(3,0)*Source2(0,2)
+ Source1(3,1)*Source2(1,2)
+ Source1(3,2)*Source2(2,2)
+ Source2(3,2);
#endif
return *this;
};
AffineMatrix4D&
operator*=(const AffineMatrix4D& m)
{AffineMatrix4D temp(*this); return Multiply(temp,m);}
//
// Matrix Inversion
//
AffineMatrix4D&
Invert(const AffineMatrix4D& Source);
AffineMatrix4D&
Invert()
{AffineMatrix4D src(*this); return Invert(src);}
//
// Scaling, Rotation and Translation
//
AffineMatrix4D&
Multiply(const AffineMatrix4D &m,const Vector3D &v);
AffineMatrix4D&
operator*=(const Vector3D &v)
{AffineMatrix4D m(*this); return Multiply(m,v);}
AffineMatrix4D&
Multiply(const AffineMatrix4D &m,const UnitQuaternion &q);
AffineMatrix4D&
operator*=(const UnitQuaternion &q)
{AffineMatrix4D m(*this); return Multiply(m,q);}
AffineMatrix4D&
Multiply(const AffineMatrix4D &m,const Point3D &p);
AffineMatrix4D&
operator*=(const Point3D& p)
{AffineMatrix4D m(*this); return Multiply(m,p);}
//
// Miscellaneous Functions
//
Scalar
Determinant() const;
AffineMatrix4D&
Solve();
//
// Support functions
//
#if !defined(Spew)
friend void
::Spew(
const char* group,
const AffineMatrix4D& matrix
);
#endif
void
TestInstance() const
{}
static bool
TestClass();
};
inline Point3D&
Point3D::operator=(const AffineMatrix4D& m)
{
Check_Pointer(this); Check_Object(&m);
x = m(W_Axis, X_Axis);
y = m(W_Axis, Y_Axis);
z = m(W_Axis, Z_Axis);
Check_Object(this);
return *this;
}
}
namespace MemoryStreamIO {
inline Stuff::MemoryStream&
Read(
Stuff::MemoryStream *stream,
Stuff::AffineMatrix4D *output
)
{return stream->ReadBytes(output, sizeof(*output));}
inline Stuff::MemoryStream&
Write(
Stuff::MemoryStream *stream,
const Stuff::AffineMatrix4D *input
)
{return stream->WriteBytes(input, sizeof(*input));}
}
@@ -0,0 +1,28 @@
//===========================================================================//
// File: affnmtrx.cc //
// Project: MUNGA Brick: Math Library //
// Contents: Implementation details for the Affine matrices //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 11/20/94 JMA Initial coding. //
// 12/01/94 JMA Made compatible with SGI CC //
//---------------------------------------------------------------------------//
// Copyright (C) 1994, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "StuffHeaders.hpp"
//
//###########################################################################
//###########################################################################
//
bool
AffineMatrix4D::TestClass()
{
SPEW((GROUP_STUFF_TEST, "Starting AffineMatrix4D Test..."));
SPEW((GROUP_STUFF_TEST, " AffineMatrix4D::TestClass() stubbed out!"));
return false;
}
+156
View File
@@ -0,0 +1,156 @@
//===========================================================================//
// File: angle.cc //
// Project: MUNGA Brick: Math Library //
// Contents: Implementation details for angle classes //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 11/19/94 JMA Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "StuffHeaders.hpp"
//
//#############################################################################
//#############################################################################
//
Scalar
Radian::Normalize(Scalar Value)
{
Scalar temp = static_cast<Scalar>(fmod(Value,Two_Pi));
if (temp > Pi)
{
temp -= Two_Pi;
}
else if (temp <= -Pi)
{
temp += Two_Pi;
}
return temp;
}
//
//#############################################################################
//#############################################################################
//
Radian&
Radian::Normalize()
{
Check_Object(this);
angle = static_cast<Scalar>(fmod(angle,Two_Pi));
if (angle > Pi) {
angle -= Two_Pi;
}
else if (angle < -Pi) {
angle += Two_Pi;
}
return *this;
}
//
//#############################################################################
//#############################################################################
//
Radian&
Radian::Lerp(const Radian &a,const Radian &b,Scalar t)
{
Scalar a1,a2;
Check_Pointer(this);
Check_Object(&a);
Check_Object(&b);
a1 = Radian::Normalize(a.angle);
a2 = Radian::Normalize(b.angle);
if (a2-a1 > Pi) {
a2 -= Two_Pi;
}
else if (a2-a1 < -Pi) {
a2 += Two_Pi;
}
angle = Stuff::Lerp(a1, a2, t);
return *this;
}
#if 0
SinCosPair&
SinCosPair::operator=(const Radian &radian)
{
Check_Pointer(this);
Check_Object(&radian);
#if USE_ASSEMBLER_CODE
Scalar *f = &sine;
_asm {
push ebx
push edx
mov ebx, f
mov edx, radian.angle
fld dword ptr [edx]
fsincos
fstp dword ptr [ebx + 4]
fstp dword ptr [ebx]
pop edx
pop ebx
}
#else
cosine = cos(radian);
sine = sin(radian);
#endif
Check_Object(this);
return *this;
}
#endif
//
//#############################################################################
//#############################################################################
//
#if !defined(Spew)
void
Spew(
const char* group,
const Radian& angle
)
{
Check_Object(&angle);
SPEW((group, "%f rad+", angle.angle));
}
//
//#############################################################################
//#############################################################################
//
void
Spew(
const char* group,
const Degree& angle
)
{
Check_Object(&angle);
SPEW((group, "%f deg+", angle.angle));
}
//
//#############################################################################
//#############################################################################
//
void
Spew(
const char* group,
const SinCosPair& angle
)
{
Check_Object(&angle);
SPEW((group, "{%f,%f}+", angle.cosine, angle.sine));
}
#endif
+358
View File
@@ -0,0 +1,358 @@
//===========================================================================//
// File: angle.hh //
// Project: MUNGA Brick: Math Library //
// Contents: Interface specification for angle classes //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 11/18/94 JMA Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#pragma once
#include "Stuff.hpp"
#include "Scalar.hpp"
namespace Stuff {
class Radian;
class Degree;
class SinCosPair;
}
#if !defined(Spew)
void
Spew(
const char* group,
const Stuff::Radian& angle
);
void
Spew(
const char* group,
const Stuff::Degree& angle
);
void
Spew(
const char* group,
const Stuff::SinCosPair& angle
);
#endif
namespace Stuff {
class Degree;
class SinCosPair;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Radian ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Radian
{
public:
Scalar
angle;
//
// Constructors
//
Radian()
{}
Radian(Scalar a)
{angle = a;}
Radian(const Radian &a)
{angle = a.angle;}
explicit Radian(const Degree &degree)
{*this = degree;}
explicit Radian(const SinCosPair &pair)
{*this = pair;}
//
// Assignment operators
//
Radian&
operator=(Scalar angle)
{
Check_Pointer(this);
this->angle = angle; return *this;
}
Radian&
operator=(const Radian &radian)
{
Check_Pointer(this); Check_Object(&radian);
angle = radian.angle; return *this;
}
Radian&
operator=(const Degree &degree);
Radian&
operator=(const SinCosPair &pair);
//
// Casting
//
operator Scalar() const
{Check_Object(this); return angle;}
//
// These comparator functions are not designed to make exact comparisons
// of Scalaring point numbers, but rather to compare them to within some
// specified error threshold
//
bool
operator!() const
{Check_Object(this); return Small_Enough(angle);}
bool
operator==(const Radian &r) const
{Check_Object(this); Check_Object(&r); return Close_Enough(angle,r.angle);}
bool
operator==(float r) const
{Check_Object(this); return Close_Enough(angle,r);}
bool
operator!=(const Radian &r) const
{Check_Object(this); Check_Object(&r); return !Close_Enough(angle,r.angle);}
bool
operator!=(float r) const
{Check_Object(this); return !Close_Enough(angle,r);}
//
// Math operators
//
Radian&
Negate(Scalar r)
{Check_Pointer(this); angle = -r; return *this;}
Radian&
Add(Scalar r1,Scalar r2)
{Check_Pointer(this); angle = r1 + r2; return *this;}
Radian&
operator+=(Scalar r)
{Check_Object(this); angle += r; return *this;}
Radian&
Subtract(Scalar r1,Scalar r2)
{Check_Pointer(this); angle = r1 - r2; return *this;}
Radian&
operator-=(Scalar r)
{Check_Object(this); angle -= r; return *this;}
Radian&
Multiply(Scalar r1,Scalar r2)
{Check_Pointer(this); angle = r1 * r2; return *this;}
Radian&
operator*=(Scalar r)
{Check_Object(this); angle *= r; return *this;}
Radian&
Divide(Scalar r1,Scalar r2)
{
Check_Pointer(this); Verify(!Small_Enough(r2));
angle = r1 / r2; return *this;
}
Radian&
operator/=(Scalar r)
{Check_Object(this); Verify(!Small_Enough(r)); angle /= r; return *this;}
//
// Template support
//
Radian&
Lerp(
const Radian &a,
const Radian &b,
Scalar t
);
//
// Support functions
//
static Scalar
Normalize(Scalar Value);
Radian&
Normalize();
#if !defined(Spew)
friend void
::Spew(
const char* group,
const Radian& angle
);
#endif
void
TestInstance() const
{}
static bool
TestClass();
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Degree ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Degree
{
public:
Scalar
angle;
//
// constructors
//
Degree()
{}
Degree(Scalar a)
{angle = a;}
Degree(const Degree &a)
{angle = a.angle;}
explicit Degree(const Radian &radian)
{*this = radian;}
//
// Assignment operators
//
Degree&
operator=(const Degree &degree)
{Check_Object(this); Check_Object(&degree); angle = degree.angle; return *this;}
Degree&
operator=(Scalar angle)
{Check_Object(this); this->angle = angle; return *this;}
Degree&
operator=(const Radian &radian)
{
Check_Object(this); Check_Object(&radian);
angle = radian.angle * Degrees_Per_Radian; return *this;
}
//
// Support functions
//
#if !defined(Spew)
friend void
::Spew(
const char* group,
const Degree& angle
);
#endif
void
TestInstance() const
{}
static bool
TestClass();
};
inline Radian&
Radian::operator=(const Degree& degree)
{
Check_Pointer(this); Check_Object(&degree);
angle = degree.angle * Radians_Per_Degree; return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SinCosPair ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class SinCosPair
{
public:
Scalar
sine,
cosine;
//
// Constructors
//
SinCosPair()
{}
SinCosPair(Scalar sin, Scalar cos)
{Check_Pointer(this); sine = sin; cosine = cos; Check_Object(this);}
SinCosPair(const SinCosPair &pair)
{
Check_Pointer(this); Check_Object(&pair);
sine = pair.sine; cosine = pair.cosine;
}
explicit SinCosPair(const Radian &radian)
{*this = radian;}
//
// Assignment operators
//
SinCosPair&
operator=(const SinCosPair &pair)
{
Check_Pointer(this); Check_Object(&pair);
sine = pair.sine; cosine = pair.cosine; return *this;
}
SinCosPair&
operator=(const Radian &radian)
{
Check_Pointer(this);
Check_Object(&radian);
#if USE_ASSEMBLER_CODE
Scalar *f = &sine;
_asm {
push ebx
push edx
mov ebx, f
mov edx, radian.angle
fld dword ptr [edx]
fsincos
fstp dword ptr [ebx + 4]
fstp dword ptr [ebx]
pop edx
pop ebx
}
#else
cosine = cos(radian);
sine = sin(radian);
#endif
Check_Object(this);
return *this;
}
//
// Support functions
//
#if !defined(Spew)
friend void
::Spew(
const char* group,
const SinCosPair& angle
);
#endif
void
TestInstance() const
{}
static bool
TestClass();
};
inline Radian&
Radian::operator=(const SinCosPair& pair)
{
Check_Pointer(this); Check_Object(&pair);
angle = Arctan(pair.sine, pair.cosine); return *this;
}
}
namespace MemoryStreamIO {
inline Stuff::MemoryStream&
Read(
Stuff::MemoryStream* stream,
Stuff::Radian *output
)
{return stream->ReadBytes(output, sizeof(*output));}
inline Stuff::MemoryStream&
Write(
Stuff::MemoryStream* stream,
const Stuff::Radian *input
)
{return stream->WriteBytes(input, sizeof(*input));}
}
@@ -0,0 +1,182 @@
//===========================================================================//
// File: angle.tst //
// Project: MUNGA Brick: Math Library //
// Contents: Tests for angle classes //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 11/19/94 JMA Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "StuffHeaders.hpp"
//
//#############################################################################
//#############################################################################
//
bool
Radian::TestClass()
{
SPEW((GROUP_STUFF_TEST, "Starting Radian Test..."));
const Radian a(1.25f);
Radian
b,c;
Verify(a);
c = 0.0f;
Verify(!c);
Verify(Normalize(3.1f) == 3.1f);
Verify(Normalize(-3.1f) == -3.1f);
Scalar f = Normalize(Pi+Pi_Over_2);
Verify(Close_Enough(f,Pi_Over_2 - Pi));
f = Normalize(-Pi-Pi_Over_2);
Verify(Close_Enough(f,Pi - Pi_Over_2));
c = a;
#if 0
Verify(c == a);
Verify(c.angle == a);
Verify(c == a.angle);
#endif
b.Negate(c);
#if 0
Verify(b == -c.angle);
#endif
#if 0
b = -c;
d.Add(b,c);
Verify(d == b.angle + c.angle);
Verify(a+b == a.angle + b.angle);
Verify(a+c == a.angle + c.angle);
Verify(a+1.25f == a.angle+1.25f);
Verify(1.25f+c == 1.25f+c.angle);
c = 1.5f;
d.Subtract(c,a);
Verify(d == c.angle - a.angle);
Verify(c-a == c.angle - a.angle);
Verify(c-1.25f == c.angle - 1.25f);
Verify(1.5f-a == 1.5f - a.angle);
Verify(c-b == c.angle - b.angle);
c = 2.5f;
d.Multiply(a,c);
Verify(d == a.angle * c.angle);
Verify(a*c == a.angle * c.angle);
Verify(1.25f*c == 1.25f * c.angle);
Verify(a*2.5f == a.angle * 2.5f);
Verify(a*b == a.angle * b.angle);
c = 2.0f;
d.Divide(a,c);
Verify(d == a.angle / c.angle);
Verify(a/c == a.angle / c.angle);
Verify(1.25f/c == 1.25f / c.angle);
Verify(a/2.0f == a.angle / 2.0f);
Verify(a/b == a.angle / b.angle);
b = a;
b += c;
b.Normalize();
Verify(b == 3.25f - TWO_PI);
b += 2.0f;
b.Normalize();
Verify(b == 5.25f - TWO_PI);
b -= c;
b.Normalize();
Verify(b == 3.25f - TWO_PI);
b -= 2.0f;
b.Normalize();
Verify(b == 1.25f);
b *= c;
b.Normalize();
Verify(b == 1.25f*2.0f);
b *= 2.0f;
b.Normalize();
Verify(b == 1.25f*2.0f*2.0f - TWO_PI);
b = a*c;
b.Normalize();
Verify(b == 1.25f*2.0f);
b /= 2.0f;
b.Normalize();
Verify(b == 1.25f);
b = -3.0f*PI_OVER_4;
c = 3.0f*PI_OVER_4;
Verify(Lerp(b,c,0.25f) < b);
Verify(Normalize(Lerp(b,c,0.75f)) > c);
#endif
return true;
}
//
//#############################################################################
//#############################################################################
//
bool
Degree::TestClass()
{
SPEW((GROUP_STUFF_TEST, "Starting Degree test..."));
const Degree a(Degrees_Per_Radian);
Degree
b,c;
Radian
r(1.0f),s;
s = a;
Verify(r == s);
b = r;
s = b;
#if 0
Verify(r == s);
#endif
c = Degrees_Per_Radian;
s = c;
#if 0
Verify(r == s);
#endif
b = c;
s = b;
#if 0
Verify(r == s);
#endif
return true;
}
//
//#############################################################################
//#############################################################################
//
bool
SinCosPair::TestClass()
{
SPEW((GROUP_STUFF_TEST, "Starting SinCos test..."));
Radian
s,r(Pi_Over_2);
SinCosPair a;
a = r;
Verify(Close_Enough(a.sine,1.0f));
Verify(Small_Enough(a.cosine));
s = a;
Verify(s == r);
return true;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,39 @@
//=======================================================================//
// File: debugoff.hpp //
// Project: Architecture //
// Author: J.M. Albertson //
// 4-12-95 CPB added Str_Cat macro //
//-----------------------------------------------------------------------//
// Copyright (C) 1994, Virtual World Entertainments, All Rights reserved //
// PROPRIETARY AND CONFIDENTIAL //
//=======================================================================//
#pragma warning (disable:4786)
#pragma once
#undef Verify
#undef Warn
#undef Check_Signature
#undef Check_Pointer
#undef Mem_Copy
#undef Str_Copy
#undef Str_Cat
#undef Check
#undef Cast_Pointer
#undef Cast_Object
#undef Spew
#define Verify(c) ((void)0)
#define Warn(c) ((void)0)
#define Check_Pointer(p) ((void)0)
#define Mem_Copy(destination, source, length, available)\
memcpy(destination, source, length)
#define Str_Copy(destination, source, available)\
strcpy(destination, source)
#define Str_Cat(destination, source, available)\
strcat(destination, source)
#define Check_Object(p) ((void)0)
#define Check_Signature(p) ((void)0)
#define Cast_Pointer(type, ptr) reinterpret_cast<type>(ptr)
#define Cast_Object(type, ptr) static_cast<type>(ptr)
#define Spew(x,y) ((void)0)
@@ -0,0 +1,133 @@
//=======================================================================//
// File: debug3on.hpp //
// Project: Architecture //
// Author: J.M. Albertson //
// 4-12-95 CPB added Str_Cat macro //
//-----------------------------------------------------------------------//
// Copyright (C) 1994, Virtual World Entertainments, All Rights reserved //
// PROPRIETARY AND CONFIDENTIAL //
//=======================================================================//
#pragma warning (disable:4786)
#pragma once
#undef Verify
#undef Warn
#undef Check_Pointer
#undef Check_Signature
#undef Check
#undef Cast_Pointer
#undef Cast_Object
#undef Mem_Copy
#undef Str_Copy
#undef Str_Cat
#undef Spew
#define Verify(c)\
do {if (Stuff::ArmorLevel>0 && !(c)) PAUSE(("Failed " #c));} while(0)
#define Warn(c)\
do {\
if (Stuff::ArmorLevel>0 && (c)) SPEW((0, #c));\
} while(0)
#define Check_Pointer(p) Verify((p) && reinterpret_cast<int>(p)!=Stuff::SNAN_NEGATIVE_LONG)
template <class T> T
Cast_Pointer_Function(T p)
{
if (ArmorLevel>0)
Check_Pointer(p);
return p;
}
#define Cast_Pointer(type, ptr) Stuff::Cast_Pointer_Function(reinterpret_cast<type>(ptr))
#define Mem_Copy(destination, source, length, available)\
do {\
Check_Pointer(destination);\
Check_Pointer(source);\
Verify((length) <= (available));\
Verify(\
abs(\
reinterpret_cast<char*>(destination)\
- reinterpret_cast<const char*>(source)\
) >= length\
);\
memcpy(destination, source, length);\
} while (0)
#define Str_Copy(destination, source, available)\
do {\
Check_Pointer(destination);\
Check_Pointer(source);\
Verify((strlen(source) + 1) <= (available));\
Verify(abs(destination - source) >= (strlen(source) + 1));\
strcpy(destination, source);\
} while (0)
#define Str_Cat(destination, source, available)\
do {\
Check_Pointer(destination);\
Check_Pointer(source);\
Verify((strlen(destination) + strlen(source) + 1) <= (available));\
strcat(destination, source);\
} while (0)
#define Check_Signature(p) Stuff::Is_Signature_Bad(p)
template <class T> void
Check_Object_Function(T *p)
{
switch (ArmorLevel)
{
case 1:
Check_Pointer(p);
break;
case 2:
Check_Signature(p);
break;
case 3:
case 4:
Check_Signature(p);
p->TestInstance();
break;
}
}
#define Check_Object(p) Stuff::Check_Object_Function(p)
//
// Cast_Object will only work for polymorphic objects,
// non-polymorphic objects use Cast_Pointer
//
template <class T> T
Cast_Object_Function(T p)
{
switch (ArmorLevel)
{
case 1:
Check_Pointer(p);
break;
case 2:
Check_Signature(p);
break;
case 3:
Check_Signature(p);
p->TestInstance();
break;
case 4:
Check_Signature(p);
p->TestInstance();
Verify(dynamic_cast<T>(p) != NULL);
break;
}
return p;
}
#define Cast_Object(type, ptr) Stuff::Cast_Object_Function(static_cast<type>(ptr))
@@ -0,0 +1,131 @@
#pragma once
#ifndef AUTO_CONTAINER_HPP
#define AUTO_CONTAINER_HPP
#pragma warning (disable:4786) // this is necessary to avoid "truncated to 255 characters in debug info" message
#include "Auto_Ptr.hpp"
#include "Noncopyable.hpp"
namespace Stuff
{
template <class pointed_to, class container_type>
class Auto_Container
: public Noncopyable
{
public:
virtual ~Auto_Container();
typedef pointed_to* value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef container_type::iterator iterator;
typedef container_type::const_iterator const_iterator;
typedef size_t size_type;
iterator begin() { return (m_Container.begin()); }
const_iterator begin() const { return (m_Container.begin()); }
iterator end() { return (m_Container.end()); }
const_iterator end() const { return (m_Container.end()); }
size_type size() const { return (m_Container.size()); }
bool empty() const { return (m_Container.empty()); }
size_type max_size() const { return (m_Container.max_size()); }
void swap(container_type& other_container) { m_Container.swap(other_container); }
reference at(size_type pos) { return (m_Container.at(pos)); }
const_reference at(size_type pos) const { return (m_Container.at(pos)); }
reference operator[](size_type pos) { return (m_Container[pos]); }
const_reference operator[](size_type pos) const { return (m_Container[pos]); }
void clear() { erase(begin(),end()); }
reference back() { return (m_Container.back()); }
const_reference back() const { return (m_Container.back()); }
reference front() { return (m_Container.front()); }
const_reference front() const { return (m_Container.front()); }
iterator erase(iterator it)
{
iterator rv = m_Container.erase(it);
delete (*rv);
return (rv);
}
iterator erase(iterator first, iterator last)
{
{for (iterator i = first;
i != last;
++i)
{
delete (*i);
}}
return (m_Container.erase(first,last));
}
Auto_Ptr<pointed_to> remove(iterator it)
{
Auto_Ptr<pointed_to> rv(*it);
m_Container.erase(it);
return (rv);
}
Auto_Ptr<pointed_to> pop_back()
{
Auto_Ptr<pointed_to> rv(m_Container.back());
m_Container.pop_back();
return (rv);
}
void push_back(Auto_Ptr<pointed_to>& x)
{
m_Container.push_back(x.ReleaseAndNull());
}
iterator insert(iterator it, Auto_Ptr<pointed_to>& x)
{
return (m_Container.insert(it,x.ReleaseAndNull()));
}
const container_type& GetContainer() const
{
return (m_Container);
}
void MoveTo(Auto_Container<pointed_to,container_type>& dest)
{
while (empty() == false)
{
value_type value = m_Container.back();
dest.m_Container.push_back(value);
m_Container.pop_back();
}
}
protected:
container_type m_Container;
};
};
template <class pointed_to, class container_type>
Stuff::Auto_Container<pointed_to,container_type>::~Auto_Container()
{
clear();
}
#endif // AUTO_CONTAINER_HPP
@@ -0,0 +1,293 @@
#pragma once
#ifndef Auto_Ptr_HPP
#define Auto_Ptr_HPP
#include "Stuff.hpp"
namespace Stuff
{
// Auto_Ptr<>: similar to the STL auto_ptr<> class, but better! :)
// An Auto_Ptr<> is a pointer that "owns" the object pointed to.
// When the Auto_Ptr<> is deleted, it will also delete the object
// if it still owns the pointer. Auto_Ptr<> also handles the transfer
// of ownership between Auto_Ptrs via the == operators.
// This version of Auto_Ptr<> is slightly more memory-efficient as it
// stores the ownership bits in the unused bits of the pointer data member.
// It also allows you to specify whether or not to use array deletion;
// this also is stored in the extra bits of the pointer.
template <class T>
class Auto_Ptr
{
public:
Auto_Ptr();
explicit Auto_Ptr(T* ptr, bool delete_as_array = DELETE_NORMAL);
Auto_Ptr(Auto_Ptr const& src);
~Auto_Ptr();
enum deletion_type
{
DELETE_AS_ARRAY = true,
DELETE_NORMAL = false
};
Auto_Ptr<T> Assimilate(T* ptr, bool delete_as_array = DELETE_NORMAL);
Auto_Ptr<T> Assimilate(Auto_Ptr<T>& src);
T* GetPointer() const;
T* Release() const;
T* ReleaseAndNull();
Auto_Ptr<T>& operator=(Auto_Ptr<T> const& src);
operator bool() const;
T& operator*() const;
T* operator->() const;
void Swap(Auto_Ptr<T>& src);
void Delete();
private:
bool IsOwner() const;
bool IsArray() const;
void SetAsOwner(bool fOwn) const;
void SetAsArray(bool fArray);
void Set(T* ptr, bool fIsOwner, bool fIsArray);
mutable union
{
T *m_ptr;
mutable int unsigned m_bits;
};
enum
{
OWNER_MASK = 1,
ARRAY_MASK = 2,
POINTER_MASK = ~3
};
};
template<class T>
inline bool operator==(const Auto_Ptr<T>& a,
const Auto_Ptr<T>& b)
{
return (a.GetPointer() == b.GetPointer());
}
template<class T>
inline bool operator==(const T* a,
const Auto_Ptr<T>& b)
{
return (a == b.GetPointer());
}
template<class T>
inline bool operator==(const Auto_Ptr<T>& a,
const T* b)
{
return (a.GetPointer() == b);
}
}; // namespace Stuff
template <class T>
Stuff::Auto_Ptr<T>::Auto_Ptr()
: m_ptr(0)
{
Verify(sizeof(T*) == sizeof(unsigned int));
}
template <class T>
Stuff::Auto_Ptr<T>::Auto_Ptr(T* ptr, bool delete_as_array)
{
Verify(sizeof(T *) == sizeof(unsigned int));
Set(ptr,true,delete_as_array);
}
template <class T>
Stuff::Auto_Ptr<T>::Auto_Ptr(Auto_Ptr const& src)
{
Verify(sizeof(T*) == sizeof(unsigned int));
m_ptr = src.m_ptr;
src.SetAsOwner(false);
}
template <class T>
Stuff::Auto_Ptr<T>::~Auto_Ptr()
{
Delete();
}
template <class T>
Stuff::Auto_Ptr<T> Stuff::Auto_Ptr<T>::Assimilate(T* ptr, bool delete_as_array)
{
Auto_Ptr<T> temp(*this);
Set(ptr,true,delete_as_array);
return (temp);
}
template <class T>
Stuff::Auto_Ptr<T> Stuff::Auto_Ptr<T>::Assimilate(Auto_Ptr<T>& src)
{
Auto_Ptr<T> temp;
if (&src != this)
{
temp = *this;
m_ptr = src.m_ptr;
src.SetAsOwner(false);
}
return (temp);
}
template <class T>
T* Stuff::Auto_Ptr<T>::GetPointer() const
{
return ((T*)(m_bits & POINTER_MASK));
}
template <class T>
T* Stuff::Auto_Ptr<T>::Release() const
{
SetAsOwner(false);
return (GetPointer());
}
template <class T>
T* Stuff::Auto_Ptr<T>::ReleaseAndNull()
{
T* rv = GetPointer();
m_ptr = 0;
return (rv);
}
template <class T>
Stuff::Auto_Ptr<T>& Stuff::Auto_Ptr<T>::operator=(Auto_Ptr<T> const& src)
{
if (&src != this)
{
Delete();
m_ptr = src.m_ptr;
src.SetAsOwner(false);
}
return (*this);
}
template <class T>
Stuff::Auto_Ptr<T>::operator bool() const
{
return (GetPointer() != 0);
}
template <class T>
T& Stuff::Auto_Ptr<T>::operator*() const
{
return (*GetPointer());
}
template <class T>
T* Stuff::Auto_Ptr<T>::operator->() const
{
return (GetPointer());
}
template <class T>
void Stuff::Auto_Ptr<T>::Swap(Auto_Ptr<T>& src)
{
if (this != &src)
{
T* temp_ptr = src.m_ptr;
src.m_ptr = m_ptr;
m_ptr = temp_ptr;
}
}
template <class T>
void Stuff::Auto_Ptr<T>::Delete()
{
if (IsOwner())
{
if (IsArray())
{
m_bits &= POINTER_MASK;
delete [] m_ptr;
}
else
{
m_bits &= POINTER_MASK;
delete m_ptr;
}
}
m_ptr = 0;
}
template <class T>
bool Stuff::Auto_Ptr<T>::IsOwner() const
{
return ((m_bits & OWNER_MASK) == OWNER_MASK);
}
template <class T>
bool Stuff::Auto_Ptr<T>::IsArray() const
{
return ((m_bits & ARRAY_MASK) == ARRAY_MASK);
}
template <class T>
void Stuff::Auto_Ptr<T>::SetAsOwner(bool fOwn) const
{
if (fOwn == true)
{
m_bits |= OWNER_MASK;
}
else
{
m_bits &= ~OWNER_MASK;
}
}
template <class T>
void Stuff::Auto_Ptr<T>::SetAsArray(bool fArray)
{
if (fArray == true)
{
m_bits |= ARRAY_MASK;
}
else
{
m_bits &= ~ARRAY_MASK;
}
}
template <class T>
void Stuff::Auto_Ptr<T>::Set(T* ptr, bool fIsOwner, bool fIsArray)
{
m_ptr = ptr;
Verify((m_bits & POINTER_MASK) == m_bits);
if (fIsOwner == true)
{
m_bits |= OWNER_MASK;
}
if (fIsArray == true)
{
m_bits |= ARRAY_MASK;
}
}
#endif // Auto_Ptr_HPP
@@ -0,0 +1,399 @@
//===========================================================================//
// File: average.hpp //
// Project: MUNGA Brick: Renderer //
// Contents: //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- -----------------------------------------------------------//
// 12/14/94 ECH Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#pragma once
#include "Stuff.hpp"
namespace Stuff {
//##########################################################################
//########################### AverageOf ##############################
//##########################################################################
template <class T> class AverageOf
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
public:
//
//-----------------------------------------------------------------------
// Constructor, Destructor, Testing
//-----------------------------------------------------------------------
//
AverageOf();
AverageOf(
size_t size,
T initial=(T)0
);
~AverageOf();
void
TestInstance() const
{Check_Pointer(array); Verify(next < size);}
//
//-----------------------------------------------------------------------
// SetSize
//-----------------------------------------------------------------------
//
void
SetSize(
size_t size,
T initial=(T)0
);
//
//-----------------------------------------------------------------------
// GetSize
//-----------------------------------------------------------------------
//
size_t
GetArraySize()
{
return size;
}
//
//-----------------------------------------------------------------------
// Add
//-----------------------------------------------------------------------
//
void
Add(T value);
//
//-----------------------------------------------------------------------
// CalculateSum
//-----------------------------------------------------------------------
//
T
CalculateSum();
//
//-----------------------------------------------------------------------
// CalculateAverage
//-----------------------------------------------------------------------
//
T
CalculateAverage();
//
//-----------------------------------------------------------------------
// CalculateOlympicAverage
//-----------------------------------------------------------------------
//
T
CalculateOlympicAverage();
//
//-----------------------------------------------------------------------
// Calculate Trend of Average
//-----------------------------------------------------------------------
//
Scalar
CalculateTrend();
//
//-----------------------------------------------------------------------
// Return the lowest value in the array, or,
// Return the highest value in the array
//-----------------------------------------------------------------------
//
T
CalculateLowerBound();
T
CalculateUpperBound();
private:
//
//-----------------------------------------------------------------------
// Private data
//-----------------------------------------------------------------------
//
size_t size;
size_t next;
T *array;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AverageOf templates ~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T>
AverageOf<T>::AverageOf()
{
array = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T>
AverageOf<T>::AverageOf(
size_t the_size,
T initial
)
{
array = NULL;
SetSize(the_size, initial);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T> void
AverageOf<T>::SetSize(
size_t the_size,
T initial
)
{
if (array != NULL)
{
Unregister_Pointer(array);
delete[] array;
}
size = the_size;
array = new T[size];
Register_Pointer(array);
next = 0;
for (size_t i = 0; i < size; i++)
{
Check_Pointer(array);
Verify(i < size);
array[i] = initial;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T>
AverageOf<T>::~AverageOf()
{
Unregister_Pointer(array);
delete[] array;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T> void
AverageOf<T>::Add(T value)
{
Check_Object(this);
Check_Pointer(array);
Verify(next < size);
array[next] = value;
++next;
if (next >= size)
{
Verify(next == size);
next = 0;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T> T
AverageOf<T>::CalculateAverage()
{
Check_Object(this);
size_t i;
T accumulate;
for (i = 0, accumulate = (T)0; i < size; i++)
{
Check_Pointer(array);
Verify(i < size);
accumulate += array[i];
}
Verify(!Small_Enough(static_cast<Scalar>(size)));
return (accumulate / static_cast<T>(size));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T> T
AverageOf<T>::CalculateSum()
{
Check_Object(this);
size_t i;
T accumulate;
for (i = 0, accumulate = (T)0; i < size; i++)
{
Check_Pointer(array);
Verify(i < size);
accumulate += array[i];
}
return accumulate;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T> T
AverageOf<T>::CalculateOlympicAverage()
{
Check_Object(this);
size_t i;
T accumulate, min_value, max_value;
Verify(0 < size);
min_value = array[0];
max_value = array[0];
for (i = 0, accumulate = (T)0; i < size; i++)
{
Check_Pointer(array);
Verify(i < size);
accumulate += array[i];
min_value = Min(array[i], min_value);
max_value = Max(array[i], max_value);
}
accumulate -= min_value;
accumulate -= max_value;
Verify(!Small_Enough(static_cast<Scalar>(size - 2)));
return (accumulate / static_cast<T>(size - 2));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T> Scalar
AverageOf<T>::CalculateTrend()
{
Check_Object(this);
size_t i;
Scalar f = 0.0f;
Scalar fx = 0.0f;
Scalar x1 = static_cast<Scalar>(size);
Scalar x2 = x1*x1/2.0f;
Scalar x3 = x2 + x1*x1*x1/3.0f + x1/6.0f;
x2 += x1/2.0f;
i = next;
Scalar t = 1.0f;
do
{
f += array[i];
fx += t*array[i];
t += 1.0f;
if (++i == size)
{
i = 0;
}
} while (i != next);
return (x1*fx - x2*f) / (x1*x3 - x2*x2);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T> T
AverageOf<T>::CalculateLowerBound()
{
Check_Object(this);
size_t i;
T min_value;
Verify(0 < size);
min_value = array[0];
for (i = 0; i < size; i++)
{
Check_Pointer(array);
Verify(i < size);
min_value = Min(array[i], min_value);
}
return min_value;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T> T
AverageOf<T>::CalculateUpperBound()
{
Check_Object(this);
size_t i;
T max_value;
Verify(0 < size);
max_value = array[0];
for (i = 0; i < size; i++)
{
Check_Pointer(array);
Verify(i < size);
max_value = Max(array[i], max_value);
}
return max_value;
}
//##########################################################################
//######################## StaticAverageOf ###########################
//##########################################################################
template <class T> class StaticAverageOf
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
public:
//
//-----------------------------------------------------------------------
// Constructor, Destructor, Testing
//-----------------------------------------------------------------------
//
StaticAverageOf()
{size = (size_t)(T)0; total = (T)0;}
~StaticAverageOf()
{}
void
TestInstance() const
{}
//
//-----------------------------------------------------------------------
// Add
//-----------------------------------------------------------------------
//
void
Add(T value)
{Check_Object(this); size++; total += value;}
//
//-----------------------------------------------------------------------
// CalculateAverage
//-----------------------------------------------------------------------
//
T
CalculateAverage()
{Check_Object(this); return (size == 0) ? ((T)0) : (total / (T)size);}
//
//-----------------------------------------------------------------------
// GetSize
//-----------------------------------------------------------------------
//
size_t
GetSize()
{Check_Object(this); return size;}
private:
//
//-----------------------------------------------------------------------
// Private data
//-----------------------------------------------------------------------
//
size_t size;
T total;
};
}
+387
View File
@@ -0,0 +1,387 @@
//===========================================================================//
// File: m_chain.cc //
// Project: MUNGA Brick: Connection Engine //
// Contents: Implementation details of chains and their iterators //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 09/29/94 ECH Initial coding. //
// 10/20/94 JMA Fixed style stuff. Merged with CHNITR.HPP, and added //
// operator functions to iterator //
// 10/23/94 ECH Added greater deletion safety //
// 10/28/94 JMA Made compatible with SGI CC //
// 11/03/94 ECH Made compatible with BC4.0 //
// 12/12/94 ECH Changed release handling //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
#include "StuffHeaders.hpp"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainLink ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MemoryBlock*
ChainLink::s_AllocatedMemory = NULL;
//
//#############################################################################
//#############################################################################
//
void
ChainLink::InitializeClass(size_t block_count)
{
Verify(!s_AllocatedMemory);
s_AllocatedMemory =
new MemoryBlock(
sizeof(ChainLink),
block_count,
block_count>>2,
"Stuff::ChainLink",
g_ConnectionEngineHeap
);
}
//
//#############################################################################
//#############################################################################
//
void
ChainLink::TerminateClass()
{
delete s_AllocatedMemory;
s_AllocatedMemory = NULL;
}
//
//#############################################################################
// ~ChainLink
//#############################################################################
//
ChainLink::~ChainLink()
{
Check_Object(this);
Check_Object(m_chain);
//
//------------------------
// Unlink the forward link
//------------------------
//
if (m_nextChainLink)
{
Check_Object(m_nextChainLink);
m_nextChainLink->m_prevChainLink = m_prevChainLink;
}
else
{
Verify(m_chain->m_tail == this);
m_chain->m_tail = m_prevChainLink;
}
//
//-------------------------
// Unlink the backward link
//-------------------------
//
if (m_prevChainLink)
{
Check_Object(m_prevChainLink);
m_prevChainLink->m_nextChainLink = m_nextChainLink;
}
else
{
Verify(m_chain->m_head == this);
m_chain->m_head = m_nextChainLink;
}
//
//------------------------------------------
// Remove this link from any plug references
//------------------------------------------
//
m_nextChainLink = NULL;
m_prevChainLink = NULL;
ReleaseFromPlug();
}
//
//#############################################################################
// ChainLink
//#############################################################################
//
ChainLink::ChainLink(
Chain *m_chain,
Plug *plug,
ChainLink *next_link,
ChainLink *prev_link
):
m_chain(m_chain),
m_plug(plug)
{
//
//-------------------------
// ChainLink into existing m_chain
//-------------------------
//
AddToPlug(plug);
m_nextChainLink = next_link;
m_prevChainLink = prev_link;
if (prev_link)
{
Check_Object(prev_link);
prev_link->m_nextChainLink = this;
}
if (next_link)
{
Check_Object(next_link);
next_link->m_prevChainLink = this;
}
}
//
//#############################################################################
// ReleaseFromPlug
//#############################################################################
//
void
ChainLink::ReleaseFromPlug()
{
Check_Object(this);
//
//-----------------------------------------------------
// Remove this link from the plugs current set of links
//-----------------------------------------------------
//
Check_Object(m_plug);
ChainLink *link = m_plug->m_chainLinkHead;
Check_Object(link);
if (link == this)
{
if (m_nextPlugLink != this)
m_plug->m_chainLinkHead = m_nextPlugLink;
else
{
m_nextPlugLink = m_plug->m_chainLinkHead = NULL;
return;
}
}
while (link->m_nextPlugLink != this)
{
Check_Object(this);
link = link->m_nextPlugLink;
}
link->m_nextPlugLink = m_nextPlugLink;
m_nextPlugLink = NULL;
}
//
//#############################################################################
// AddToPlug
//#############################################################################
//
void
ChainLink::AddToPlug(Plug *plug)
{
Check_Object(this);
Check_Object(plug);
if (!plug->m_chainLinkHead)
m_nextPlugLink = this;
else
{
Check_Object(plug->m_chainLinkHead);
m_nextPlugLink = plug->m_chainLinkHead->m_nextPlugLink;
plug->m_chainLinkHead->m_nextPlugLink = this;
}
plug->m_chainLinkHead = this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//#############################################################################
// ~Chain
//#############################################################################
//
Chain::~Chain()
{
Check_Object(this);
ChainLink *link = m_head;
while (link)
{
Check_Object(link);
ChainLink *next = link->m_nextChainLink;
Check_Object(link);
delete link;
link = next;
}
}
//
//#############################################################################
// AddImplementation
//#############################################################################
//
void
Chain::AddPlug(Plug *plug)
{
Check_Object(this);
m_tail = new ChainLink(this, plug, NULL, m_tail);
if (!m_head)
m_head = m_tail;
}
//
//###########################################################################
// IsPlugMember
//###########################################################################
//
void
Chain::DeletePlugs()
{
ChainLink *link = m_head;
while (link)
{
Check_Object(link);
ChainLink *next = link->m_nextChainLink;
Check_Object(link);
Check_Object(link->GetPlug());
delete link->GetPlug();
link = next;
}
}
//
//###########################################################################
// GetNthImplementation
//###########################################################################
//
void*
Chain::GetNthItem(unsigned index)
{
Check_Object(this);
unsigned count = 0;
for (ChainLink *link = m_head; link != NULL; link = link->m_nextChainLink)
{
Check_Object(link);
if (count == index)
return link->m_plug;
count++;
}
return NULL;
}
//
//###########################################################################
// GetSize
//###########################################################################
//
unsigned
Chain::GetSize()
{
Check_Object(this);
unsigned count=0;
for (ChainLink *link = m_head; link != NULL; link = link->m_nextChainLink)
{
Check_Object(link);
count++;
}
return count;
}
//
//#############################################################################
// InsertChainLink
//#############################################################################
//
ChainLink*
Chain::InsertChainLink(
Plug *plug,
ChainLink *current_link
)
{
Check_Object(this);
Check_Object(plug);
Check_Object(current_link);
ChainLink *new_link =
new ChainLink(
this,
plug,
current_link,
current_link->m_prevChainLink
);
Register_Object(new_link);
if (!new_link->m_prevChainLink)
{
Verify(m_head == current_link);
m_head = new_link;
}
return new_link;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainIterator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//###########################################################################
// GetNthImplementation
//###########################################################################
//
void*
ChainIterator::GetNthItem(unsigned index)
{
Check_Object(this);
unsigned count = 0;
for (
ChainLink *link = m_chain->m_head;
link != NULL;
link = link->m_nextChainLink
)
{
Check_Object(link);
if (count == index)
{
m_currentLink = link;
return m_currentLink->m_plug;
}
count++;
}
return NULL;
}
//
//###########################################################################
// Remove
//###########################################################################
//
void
ChainIterator::Remove()
{
Check_Object(this);
ChainLink *oldLink = m_currentLink;
Check_Object(m_currentLink);
m_currentLink = m_currentLink->m_nextChainLink;
Check_Object(oldLink);
delete oldLink;
}
//
//###########################################################################
// InsertImplementation
//###########################################################################
//
void
ChainIterator::InsertPlug(Plug *plug)
{
Check_Object(this);
m_currentLink =
m_chain->InsertChainLink(plug, m_currentLink);
Check_Object(m_currentLink);
}
+455
View File
@@ -0,0 +1,455 @@
//===========================================================================//
// File: chain.hh //
// Project: MUNGA Brick: Connection Engine //
// Contents: Interface specification of Chains and their iterators //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 09/29/94 ECH Initial coding. //
// 10/20/94 JMA Fixed style stuff. Merged with CHNITR.HPP, and added //
// operator functions to iterator //
// 10/23/94 ECH Added greater deletion safety //
// 10/28/94 JMA Made compatible with SGI CC //
// 11/03/94 ECH Made compatible with BC4.0 //
// 12/12/94 ECH Changed release handling //
// 06/07/96 ECH Implemented socket based remove functionality //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
#pragma once
#include "Stuff.hpp"
#include "MemoryBlock.hpp"
namespace Stuff {
class Chain;
class ChainIterator;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainLink ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class ChainLink
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
public:
friend class Chain;
friend class ChainIterator;
friend class Plug;
static void
InitializeClass(size_t block_count);
static void
TerminateClass();
public:
void
TestInstance()
{}
//
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//
Chain*
GetChain()
{return m_chain;}
Plug*
GetPlug()
{return m_plug;}
protected:
~ChainLink();
explicit ChainLink(
Chain *chain,
Plug *plug,
ChainLink *nextChainLink,
ChainLink *prevChainLink
);
//
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//
void
ReleaseFromPlug();
void
AddToPlug(Plug *plug);
Plug
*m_plug;
ChainLink
*m_nextChainLink,
*m_prevChainLink;
Chain
*m_chain;
ChainLink
*m_nextPlugLink;
static MemoryBlock
*s_AllocatedMemory;
void*
operator new(size_t)
{return s_AllocatedMemory->New();}
void
operator delete(void *where)
{s_AllocatedMemory->Delete(where);}
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class _declspec(novtable) Chain
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
friend class ChainLink;
friend class ChainIterator;
public:
//
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Public interface
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//
//
//--------------------------------------------------------------------
// Constructor, Destructor and testing
//--------------------------------------------------------------------
//
explicit Chain(void *data=NULL)
{m_head = m_tail = NULL;}
~Chain();
void
TestInstance()
{}
static bool
TestClass();
static bool
ProfileClass();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Socket methods
//
public:
//
//-----------------------------------------------------------------------
// DeletePlugs - For each plug in the socket, the routine unregisters it
// and then deletes it.
//-----------------------------------------------------------------------
//
void
AddPlug(Plug *plug);
//
//-----------------------------------------------------------------------
// RemovePlug - Remove a plug from this socket, untyped access.
//-----------------------------------------------------------------------
//
void
DeletePlugs();
void
RemovePlug(Plug *plug)
{
Check_Object(this);
Check_Object(plug);
plug->RemoveChain(this);
}
//
//-----------------------------------------------------------------------
// IsPlugMember - Determine if the plug is a member of this socket.
//-----------------------------------------------------------------------
//
void*
GetNthItem(unsigned index);
bool
IsPlugMember(Plug *plug)
{
Check_Object(this);
Check_Object(plug);
return plug->IsChainMember(this);
}
//
//-----------------------------------------------------------------------
// IsEmpty - Returns true if the socket contains no plugs.
//-----------------------------------------------------------------------
//
unsigned
GetSize();
bool
IsEmpty()
{Check_Object(this); return (m_head == NULL);}
protected:
//
//--------------------------------------------------------------------
// Private methods
//--------------------------------------------------------------------
//
ChainLink*
InsertChainLink(
Plug *plug,
ChainLink *current_link
);
//
//--------------------------------------------------------------------
// Private data
//--------------------------------------------------------------------
//
ChainLink
*m_head,
*m_tail;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T> class ChainOf:
public Chain
{
public:
//
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Public interface
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//
explicit ChainOf(void *node=NULL)
{}
//
//--------------------------------------------------------------------
// Socket methods (see Socket for full listing)
//--------------------------------------------------------------------
//
void
Add(T plug)
{Chain::AddPlug(Cast_Pointer(Plug*, plug));}
void
Remove(T plug)
{Chain::RemovePlug(Cast_Pointer(Plug*, plug));}
T
GetNth(unsigned index)
{return (T)Chain::GetNthItem(index);}
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainIterator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class _declspec(novtable) ChainIterator
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
public:
//
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Public interface
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//
//
//--------------------------------------------------------------------
// Constructors, Destructor and testing
//--------------------------------------------------------------------
//
explicit ChainIterator(Chain *chain):
m_chain(chain)
{Check_Object(chain); m_currentLink = chain->m_head;}
ChainIterator(const ChainIterator &iterator):
m_chain(iterator.m_chain)
{Check_Object(&iterator); m_currentLink = iterator.m_currentLink;}
virtual ChainIterator*
MakeClone()=0;
void
TestInstance() const
{}
//
//--------------------------------------------------------------------
// Iterator methods (see Iterator for full listing)
//--------------------------------------------------------------------
//
ChainIterator&
First()
{
Check_Object(this);
m_currentLink = m_chain->m_head;
return *this;
}
ChainIterator&
Last()
{
Check_Object(this);
m_currentLink = m_chain->m_tail;
return *this;
}
ChainIterator&
Next()
{
Check_Object(this);
Check_Object(m_currentLink);
m_currentLink = m_currentLink->m_nextChainLink;
return *this;
}
ChainIterator&
Previous()
{
Check_Object(this);
Check_Object(m_currentLink);
m_currentLink = m_currentLink->m_prevChainLink;
return *this;
}
void*
ReadAndNextItem()
{
if (m_currentLink != NULL)
{
Check_Object(m_currentLink);
Plug *plug = m_currentLink->m_plug;
m_currentLink = m_currentLink->m_nextChainLink;
return plug;
}
return NULL;
}
void*
ReadAndPreviousItem()
{
if (m_currentLink != NULL)
{
Check_Object(m_currentLink);
Plug *plug = m_currentLink->m_plug;
m_currentLink = m_currentLink->m_prevChainLink;
return plug;
}
return NULL;
}
void*
GetCurrentItem()
{
Check_Object(this);
if (m_currentLink != NULL)
{
Check_Object(m_currentLink);
return m_currentLink->m_plug;
}
return NULL;
}
unsigned
GetSize()
{Check_Object(this); return m_chain->GetSize();}
void*
GetNthItem(unsigned index);
ChainIterator&
operator++()
{return Next();}
ChainIterator&
operator--()
{return Previous();}
Plug*
ReadAndNextPlug()
{return static_cast<Plug*>(ReadAndNextItem());}
Plug*
GetCurrentPlug()
{return static_cast<Plug*>(GetCurrentItem());}
void
DeletePlugs()
{Check_Object(m_chain); m_chain->DeletePlugs();}
void
Remove();
void
InsertPlug(Plug*);
protected:
//
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Protected data
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//
Chain
*m_chain;
ChainLink
*m_currentLink;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainIteratorOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <class T> class ChainIteratorOf:
public ChainIterator
{
public:
//
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Public interface
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//
//
//--------------------------------------------------------------------
// Constructors and Destructor
//--------------------------------------------------------------------
//
explicit ChainIteratorOf(ChainOf<T> *chain):
ChainIterator(chain)
{}
explicit ChainIteratorOf(const ChainIteratorOf<T> &iterator):
ChainIterator(iterator)
{}
ChainIterator*
MakeClone()
{return new(g_Heap) ChainIteratorOf<T>(*this);}
//
//--------------------------------------------------------------------
// Iterator methods (see Iterator for full listing)
//--------------------------------------------------------------------
//
T
ReadAndNext()
{return (T)ChainIterator::ReadAndNextItem();}
T
ReadAndPrevious()
{return (T)ChainIterator::ReadAndPreviousItem();}
T
GetCurrent()
{return (T)ChainIterator::GetCurrentItem();}
T
GetNth(unsigned index)
{return (T)ChainIterator::GetNthItem(index);}
void
Insert(T plug)
{ChainIterator::InsertPlug(Cast_Object(Plug*,plug));}
operator T()
{return ChainIterator::GetCurrent();}
};
}
@@ -0,0 +1,537 @@
//===========================================================================//
// File: chain.tst //
// Project: MUNGA Brick: Connection Library //
// Contents: Verify function for chain class //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 09/29/94 ECH Initial coding. //
// 10/28/94 JMA Made compatible with SGI CC //
// 11/03/94 ECH Made compatible with BC4.0 //
// 11/04/94 JMA Made compatible with GNU C++ //
// 11/04/94 ECH Merged changes
//---------------------------------------------------------------------------//
// Copyright (C) 1994, Virtual World Entertainment, Inc. All Rights reserved //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
#include "StuffHeaders.hpp"
#include <GameOS\ToolOS.hpp>
#define TEST_COUNT 50
class ChainTestPlug:
public Plug
{
public:
long value;
ChainTestPlug(long value);
~ChainTestPlug();
};
class ChainTestNode:
public Plug
{
public:
int receivedCommand;
ChainOf<ChainTestPlug*> chain1;
ChainOf<ChainTestPlug*> chain2;
ChainTestNode();
~ChainTestNode();
bool RunProfile();
bool RunTest();
};
ChainTestPlug::ChainTestPlug(long value):
Plug(DefaultData)
{
this->value = value;
}
ChainTestPlug::~ChainTestPlug()
{
}
ChainTestNode::ChainTestNode():
Plug(DefaultData),
chain1(NULL),
chain2(NULL)
{
receivedCommand = 0;
}
ChainTestNode::~ChainTestNode()
{
}
//
//###########################################################################
// ProfileClass
//###########################################################################
//
bool
Chain::ProfileClass()
{
ChainTestNode testNode;
#if defined(_ARMOR)
Time startTicks = gos_GetHiResTime();
#endif
Test_Message("Chain::ProfileClass\n");
testNode.RunProfile();
SPEW((
GROUP_STUFF_TEST,
"Chain::ProfileClass elapsed = %f",
gos_GetHiResTime() - startTicks
));
return true;
}
//
//###########################################################################
// TestClass
//###########################################################################
//
bool
Chain::TestClass()
{
SPEW((GROUP_STUFF_TEST, "Starting Chain test..."));
ChainTestNode testNode;
testNode.RunTest();
return true;
}
//
//###########################################################################
// RunProfile
//###########################################################################
//
bool
ChainTestNode::RunProfile()
{
ChainTestPlug *testPlug1;
unsigned i;
Time startTicks;
//
//--------------------------------------------------------------------
// Run timing tests
//--------------------------------------------------------------------
//
/*
* Create plugs and add to both sockets
*/
startTicks = gos_GetHiResTime();
for (i = 0; i < TEST_COUNT; i++)
{
testPlug1 = new ChainTestPlug(i);
Register_Object( testPlug1 );
chain1.Add(testPlug1);
chain2.Add(testPlug1);
}
SPEW((
GROUP_STUFF_TEST,
"ChainTestNode::RunTest Create = %f",
gos_GetHiResTime() - startTicks
));
/*
* Iterate over both sockets
*/
startTicks = gos_GetHiResTime();
{
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
ChainIteratorOf<ChainTestPlug*> iterator2(&chain2);
Verify( iterator1.GetSize() == TEST_COUNT );
Verify( iterator2.GetSize() == TEST_COUNT );
i = 0;
while ((testPlug1 = iterator1.ReadAndNext()) != NULL)
{
Verify( testPlug1->value == i );
i++;
}
Verify( i == TEST_COUNT );
i = 0;
while ((testPlug1 = iterator2.ReadAndNext()) != NULL)
{
Verify( testPlug1->value == i );
i++;
}
Verify( i == TEST_COUNT );
}
SPEW((
GROUP_STUFF_TEST,
"ChainTestNode::RunTest Iterate = %f",
gos_GetHiResTime() - startTicks
));
/*
* Destroy from chain1, verify with chain2
*/
startTicks = gos_GetHiResTime();
{
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
ChainIteratorOf<ChainTestPlug*> iterator2(&chain2);
Verify( iterator1.GetSize() == TEST_COUNT );
Verify( iterator2.GetSize() == TEST_COUNT );
#if defined(_ARMOR)
i = 0;
#endif
while ((testPlug1 = iterator1.ReadAndNext()) != NULL)
{
Verify( testPlug1->value == i++ );
Unregister_Object( testPlug1 );
delete(testPlug1);
}
Verify( i == TEST_COUNT );
Verify( iterator1.GetSize() == 0 );
Verify( iterator2.GetSize() == 0 );
}
SPEW((
GROUP_STUFF_TEST,
"ChainTestNode::RunTest Destroy = %f",
gos_GetHiResTime() - startTicks
));
return true;
}
//
//###########################################################################
// RunTest
//###########################################################################
//
bool
ChainTestNode::RunTest()
{
ChainTestPlug *testPlug1, *testPlug2;
unsigned i;
// Time startTicks;
//
//--------------------------------------------------------------------
// Stress tests
//--------------------------------------------------------------------
//
/*
* Create plugs and add to both sockets
*/
for (i = 0; i < TEST_COUNT; i++)
{
testPlug1 = new ChainTestPlug(i);
Register_Object( testPlug1 );
chain1.Add(testPlug1);
chain2.Add(testPlug1);
}
/*
* Verify first and last
*/
{
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
ChainIteratorOf<ChainTestPlug*> iterator2(&chain2);
Verify( iterator1.GetSize() == TEST_COUNT );
Verify( iterator2.GetSize() == TEST_COUNT );
iterator1.First();
iterator2.First();
testPlug1 = iterator1.GetCurrent();
testPlug2 = iterator2.GetCurrent();
Verify( testPlug1 == testPlug2 );
Verify( testPlug1 == iterator1.GetNth(0) );
Verify( testPlug1 == iterator2.GetNth(0) );
iterator1.Last();
iterator2.Last();
testPlug1 = iterator1.GetCurrent();
testPlug2 = iterator2.GetCurrent();
Verify( testPlug1 == testPlug2 );
Verify( testPlug1 == iterator1.GetNth(TEST_COUNT - 1) );
Verify( testPlug1 == iterator2.GetNth(TEST_COUNT - 1) );
}
/*
* Verify next and prev
*/
{
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
ChainIteratorOf<ChainTestPlug*> iterator2(&chain2);
Verify( iterator1.GetSize() == TEST_COUNT );
Verify( iterator2.GetSize() == TEST_COUNT );
i = 0;
while ((testPlug1 = iterator1.GetCurrent()) != NULL)
{
testPlug2 = iterator2.GetCurrent();
Verify( testPlug1 == testPlug2 );
Verify( testPlug1->value == i );
Verify( testPlug2->value == i );
iterator1.Next();
iterator2.Next();
i++;
}
Verify( i == TEST_COUNT );
iterator1.Last();
iterator2.Last();
i = TEST_COUNT - 1;
while ((testPlug1 = iterator1.GetCurrent()) != NULL)
{
testPlug2 = iterator2.GetCurrent();
Verify( testPlug1 == testPlug2 );
Verify( testPlug1->value == i );
Verify( testPlug2->value == i );
iterator1.Previous();
iterator2.Previous();
i--;
}
Verify( i == -1 );
}
/*
* Verify read next and read prev
*/
{
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
ChainIteratorOf<ChainTestPlug*> iterator2(&chain2);
Verify( iterator1.GetSize() == TEST_COUNT );
Verify( iterator2.GetSize() == TEST_COUNT );
i = 0;
while ((testPlug1 = iterator1.ReadAndNext()) != NULL)
{
testPlug2 = iterator2.ReadAndNext();
Verify( testPlug1 == testPlug2 );
Verify( testPlug1->value == i );
Verify( testPlug2->value == i );
i++;
}
Verify( i == TEST_COUNT );
iterator1.Last();
iterator2.Last();
i = TEST_COUNT - 1;
while ((testPlug1 = iterator1.ReadAndPrevious()) != NULL)
{
testPlug2 = iterator2.ReadAndPrevious();
Verify( testPlug1 == testPlug2 );
Verify( testPlug1->value == i );
Verify( testPlug2->value == i );
i--;
}
Verify( i == -1 );
}
/*
* Verify nth
*/
{
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
ChainIteratorOf<ChainTestPlug*> iterator2(&chain2);
Verify( iterator1.GetSize() == TEST_COUNT );
Verify( iterator2.GetSize() == TEST_COUNT );
for (i = 0; i < TEST_COUNT; i++)
{
testPlug1 = iterator1.GetNth(i);
testPlug2 = iterator2.GetNth(i);
Verify( testPlug1 == testPlug2 );
Verify( testPlug1->value == i );
Verify( testPlug2->value == i );
}
}
/*
* Verify Remove
*/
{
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
ChainIteratorOf<ChainTestPlug*> iterator2(&chain2);
Verify( iterator1.GetSize() == TEST_COUNT );
Verify( iterator2.GetSize() == TEST_COUNT );
i = 0;
while ((testPlug1 = iterator1.GetCurrent()) != NULL)
{
Verify( testPlug1->value == i );
if (i % 2 == 0)
{
iterator1.Remove();
}
else
{
iterator1.Next();
chain1.Remove(testPlug1);
}
testPlug2 = iterator2.GetNth(0);
Verify( testPlug2->value == i );
Verify( testPlug1 == testPlug2 );
Unregister_Object( testPlug2 );
delete(testPlug2);
i++;
}
Verify( i == TEST_COUNT );
Verify( iterator1.GetSize() == 0 );
Verify( iterator2.GetSize() == 0 );
}
/*
* Verify insert
*/
{
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
Verify( iterator1.GetSize() == 0 );
for (i = 0; i < TEST_COUNT; i += 2)
{
testPlug1 = new ChainTestPlug(i);
Register_Object(testPlug1);
chain1.Add(testPlug1);
}
for (i = 1; i < TEST_COUNT; i += 2)
{
testPlug1 = new ChainTestPlug(i);
Register_Object(testPlug1);
iterator1.First();
while ((testPlug2 = iterator1.GetCurrent()) != NULL)
{
if (i < testPlug2->value)
{
iterator1.Insert(testPlug1);
break;
}
iterator1.Next();
}
if (testPlug2 == NULL)
{
chain1.Add(testPlug1);
}
}
Verify( iterator1.GetSize() == TEST_COUNT );
for (i = 1; i < TEST_COUNT; i++)
{
testPlug1 = iterator1.GetNth(i);
testPlug2 = iterator1.GetNth(i-1);
Verify(testPlug2->value < testPlug1->value);
}
}
{
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
while ((testPlug1 = iterator1.GetCurrent()) != NULL)
{
Unregister_Object(testPlug1);
delete(testPlug1);
iterator1.First();
}
}
/*
* Verify random deletion
*/
{
/*
* Add plugs to both sockets
*/
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
ChainIteratorOf<ChainTestPlug*> iterator2(&chain2);
Verify( iterator1.GetSize() == 0 );
Verify( iterator2.GetSize() == 0 );
for (i = 0; i < TEST_COUNT; i++)
{
testPlug1 = new ChainTestPlug(i);
Register_Object( testPlug1 );
chain1.Add(testPlug1);
chain2.Add(testPlug1);
}
}
{
int size, index;
ChainIteratorOf<ChainTestPlug*> iterator1(&chain1);
ChainIteratorOf<ChainTestPlug*> iterator2(&chain2);
Verify( iterator1.GetSize() == TEST_COUNT );
Verify( iterator2.GetSize() == TEST_COUNT );
i = 0;
while((size = iterator1.GetSize()) != 0)
{
index = Random::GetLessThan(size);
testPlug1 = iterator1.GetNth(index);
iterator1.Remove();
testPlug2 = iterator2.GetNth(index);
Verify( testPlug1 == testPlug2 );
Unregister_Object( testPlug2 );
delete(testPlug2);
i++;
}
Verify( i == TEST_COUNT );
Verify( iterator1.GetSize() == 0 );
Verify( iterator2.GetSize() == 0 );
}
return true;
}
+277
View File
@@ -0,0 +1,277 @@
//===========================================================================//
// File: color.cpp //
// Title: Definition of Color classes. //
// Project: MUNGA Brick: Utility Library //
// Contents: Implementation details for color classes //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 11/12/95 GDU Initial coding. //
// 01/24/97 KEO Added Unassigned and change operator== to use Close_Enough //
//---------------------------------------------------------------------------//
// Copyright (c) 1994-1996 Virtual World Entertainment, Inc. //
// Copyright (c) 1996-1997 Fasa Interactive Technologies, Inc. //
// All rights reserved worldwide. //
// This unpublished source code is PROPRIETARY and CONFIDENTIAL. //
//===========================================================================//
#include "StuffHeaders.hpp"
//~~~~~~~~~~~~~~~~~~~~~~~~~~ RGBColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const RGBColor
RGBColor::Unassigned(-1.0f, -1.0f, -1.0f);
const RGBColor
RGBColor::White(1.0f, 1.0f, 1.0f);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (friend)
bool
Stuff::Close_Enough(
const RGBColor &c1,
const RGBColor &c2,
Scalar e // = SMALL
)
{
Check_Object(&c1);
Check_Object(&c2);
return
Close_Enough(c1.red, c2.red, e)
&& Close_Enough(c1.green, c2.green, e)
&& Close_Enough(c1.blue, c2.blue, e);
}
//
//###########################################################################
//###########################################################################
//
RGBColor&
RGBColor::operator=(const HSVColor &color)
{
Check_Object(this);
Check_Object(&color);
Verify(color.saturation >= 0.0 && color.saturation <= 1.0f);
//
//----------------
// Check for black
//----------------
//
if (color.saturation <= SMALL)
{
red = green = blue = 0.0f;
return *this;
}
//
//-----------------------------
// find the sextant for the hue
//-----------------------------
//
Verify(color.hue >= 0.0 && color.hue <= 1.0f);
Scalar hue = (color.hue == 1.0f) ? 0.0f : color.hue;
hue *= 6.0f;
int sextant = Truncate_Float_To_Byte(hue);
Verify(static_cast<unsigned>(sextant) < 6);
Scalar remainder = hue - static_cast<Scalar>(sextant);
//
//--------------------
// Build the RGB color
//--------------------
//
Verify(color.value >= 0.0f && color.value <= 1.0f);
Scalar a = color.value * (1.0f - color.saturation);
Verify(a >= 0.0f && a < 1.0f);
switch (sextant)
{
case 0:
red = color.value;
green = color.value * (1.0f - color.saturation * (1.0f - remainder));
Verify(green >= 0.0f && green <= 1.0f);
blue = a;
break;
case 1:
red = color.value * (1.0f - color.saturation * remainder);
Verify(red >= 0.0f && red <= 1.0f);
green = color.value;
blue = a;
break;
case 2:
red = a;
green = color.value;
blue = color.value * (1.0f - color.saturation * (1.0f - remainder));
Verify(blue >= 0.0f && blue <= 1.0f);
break;
case 3:
red = a;
green = color.value * (1.0f - color.saturation * remainder);
Verify(green >= 0.0f && green <= 1.0f);
blue = color.value;
break;
case 4:
red = color.value * (1.0f - color.saturation * (1.0f - remainder));
Verify(red >= 0.0f && red <= 1.0f);
green = a;
blue = color.value;
break;
case 5:
red = color.value;
green = a;
blue = color.value * (1.0f - color.saturation * remainder);
Verify(blue >= 0.0f && blue <= 1.0f);
break;
}
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~ RGBAColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const RGBAColor
RGBAColor::Unassigned(-1.0f, -1.0f, -1.0f, -1.0f);
const RGBAColor
RGBAColor::White(1.0f, 1.0f, 1.0f, 1.0f);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (friend)
bool
Stuff::Close_Enough(
const RGBAColor &c1,
const RGBAColor &c2,
Scalar e // = SMALL
)
{
Check_Object(&c1);
Check_Object(&c2);
return
Close_Enough(c1.red, c2.red, e)
&& Close_Enough(c1.green, c2.green, e)
&& Close_Enough(c1.blue, c2.blue, e)
&& Close_Enough(c1.alpha, c2.alpha, e);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~ HSVColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const HSVColor
HSVColor::Unassigned(-1.0f, -1.0f, -1.0f);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (friend)
bool
Stuff::Close_Enough(
const HSVColor &c1,
const HSVColor &c2,
Scalar e // = SMALL
)
{
Check_Object(&c1);
Check_Object(&c2);
return
Close_Enough(c1.hue, c2.hue, e)
&& Close_Enough(c1.saturation, c2.saturation, e)
&& Close_Enough(c1.value, c2.value, e);
}
//
//###########################################################################
//###########################################################################
//
HSVColor&
HSVColor::operator=(const RGBColor &color)
{
Check_Object(this);
Check_Object(&color);
Verify(color.red >= 0.0f && color.red <= 1.0f);
Verify(color.green >= 0.0f && color.green <= 1.0f);
Verify(color.blue >= 0.0f && color.blue <= 1.0f);
//
//--------------------
// Set the color value
//--------------------
//
value = Max(color.red, Max(color.green, color.blue));
//
//-------------------------
// Set the saturation value
//-------------------------
//
Scalar delta = value - Min(color.red, Min(color.green, color.blue));
if (value > SMALL)
{
saturation = delta / value;
Verify(saturation > 0.0f && saturation <= 1.0f);
}
else
{
saturation = 0.0f;
}
//
//------------
// Set the hue
//------------
//
if (saturation <= SMALL)
{
hue = 0.0f;
}
else
{
Verify(delta > SMALL);
if (color.red == value)
{
hue = (color.green - color.blue) / delta;
}
else if (color.green == value)
{
hue = 2.0f + (color.blue - color.red) / delta;
}
else
{
hue = 4.0f + (color.red - color.green) / delta;
}
if (hue < 0.0f)
{
hue += 6.0f;
}
hue *= 1.0f/6.0f;
Verify(hue >= 0.0f && hue <= 1.0f);
}
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~ HSVAColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const HSVAColor
HSVAColor::Unassigned(-1.0f, -1.0f, -1.0f, -1.0f);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (friend)
bool
Stuff::Close_Enough(
const HSVAColor &c1,
const HSVAColor &c2,
Scalar e // = SMALL
)
{
Check_Object(&c1);
Check_Object(&c2);
return
Close_Enough(c1.hue, c2.hue, e)
&& Close_Enough(c1.saturation, c2.saturation, e)
&& Close_Enough(c1.value, c2.value, e)
&& Close_Enough(c1.alpha, c2.alpha, e);
}
+520
View File
@@ -0,0 +1,520 @@
//===========================================================================//
// File: color.hpp //
// Title: Declaration of Color classes. //
// Project: Tool Architecture II //
// Author: Jerry Edsall & Ken Olsen (based on work by J.M. Albertson) //
// Purpose: Stores color information. //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 12/15/94 KEO Added RGBAColor class. //
// 11/12/95 GDU Added MUNGA signatures and stream IO, moved to MUNGA //
// 01/03/97 KEO Added RGBColor::operator*(). //
// 01/24/97 KEO Added Unassigned and change operator== to use Close_Enough //
//---------------------------------------------------------------------------//
// Copyright (c) 1994-1996 Virtual World Entertainment, Inc. //
// Copyright (c) 1996-1997 Fasa Interactive Technologies, Inc. //
// All rights reserved worldwide. //
// This unpublished source code is PROPRIETARY and CONFIDENTIAL. //
//===========================================================================//
#pragma once
#include "Stuff.hpp"
#include "MemoryStream.hpp"
#include "Scalar.hpp"
#include "Vector3D.hpp"
namespace Stuff {
class RGBColor;
class RGBAColor;
class HSVColor;
class HSVAColor;
}
#if !defined(Spew)
void
Spew(
const char* group,
const Stuff::RGBColor &color
);
void
Spew(
const char* group,
const Stuff::RGBAColor &color
);
void
Spew(
const char* group,
const Stuff::HSVColor &color
);
void
Spew(
const char* group,
const Stuff::HSVAColor &color
);
#endif
namespace Stuff {
//##########################################################################
//############## RGBColor ############################################
//##########################################################################
class RGBColor
{
friend class RGBAColor;
public:
static const RGBColor
Unassigned;
static const RGBColor
White;
Scalar
red,
green,
blue;
RGBColor()
{red = green = blue = -1.0f;}
RGBColor(
Scalar r,
Scalar g,
Scalar b
)
{red = r; green = g; blue = b;}
friend bool
Close_Enough(
const RGBColor &c1,
const RGBColor &c2,
Scalar e = SMALL
);
bool
operator==(const RGBColor &color) const
{Check_Object(this); return Close_Enough(*this, color, SMALL);}
bool
operator!=(const RGBColor &color) const
{Check_Object(this); return !Close_Enough(*this, color, SMALL);}
RGBColor&
operator=(const RGBColor &color)
{
Check_Object(this); Check_Object(&color);
red = color.red; green = color.green; blue = color.blue;
return *this;
}
RGBColor&
operator=(const HSVColor &color);
void
TestInstance() const
{}
Scalar
Infrared() const
{Check_Object(this); return 0.3f*red + 0.5f*green + 0.2f*blue;}
RGBColor&
Combine(
const RGBColor& c1,
Scalar t1,
const RGBColor& c2,
Scalar t2
)
{
Check_Pointer(this); Check_Object(&c1); Check_Object(&c2);
red = c1.red*t1 + c2.red*t2; green = c1.green*t1 + c2.green*t2;
blue = c1.blue*t1 + c2.blue*t2; return *this;
}
RGBColor&
Lerp(
const RGBColor& c1,
const RGBColor& c2,
Scalar t
)
{
Check_Pointer(this); Check_Object(&c1); Check_Object(&c2);
red = c1.red + t*(c2.red-c1.red);
green = c1.green + t*(c2.green-c1.green);
blue = c1.blue + t*(c2.blue-c1.blue);
return *this;
}
//
// Support functions
//
#if !defined(Spew)
friend void
::Spew(
const char* group,
const RGBColor &color
);
#endif
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~ RGBColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//##########################################################################
//############## RGBAColor ###########################################
//##########################################################################
class RGBAColor:
public RGBColor
{
public:
static const RGBAColor
Unassigned;
static const RGBAColor
White;
Scalar
alpha;
RGBAColor():
RGBColor()
{alpha = -1.0f;}
RGBAColor(
Scalar r,
Scalar g,
Scalar b,
Scalar a
):
RGBColor(r, g, b)
{alpha = a;}
friend bool
Close_Enough(
const RGBAColor &c1,
const RGBAColor &c2,
Scalar e = SMALL
);
bool
operator==(const RGBAColor &color) const
{return Close_Enough(*this, color, SMALL);}
bool
operator!=(const RGBAColor &color) const
{return !Close_Enough(*this, color, SMALL);}
RGBAColor&
operator=(const RGBAColor &color)
{
Check_Object(this); Check_Object(&color);
red = color.red; green = color.green; blue = color.blue;
alpha = color.alpha;
return *this;
}
RGBAColor&
operator=(const HSVAColor &color);
RGBAColor&
Combine(
const RGBAColor& c1,
Scalar t1,
const RGBAColor& c2,
Scalar t2
)
{
Check_Pointer(this); Check_Object(&c1); Check_Object(&c2);
red = c1.red*t1 + c2.red*t2; green = c1.green*t1 + c2.green*t2;
blue = c1.blue*t1 + c2.blue*t2;
alpha = c1.alpha*t1 + c2.alpha*t2; return *this;
}
RGBAColor&
Lerp(
const RGBAColor& c1,
const RGBAColor& c2,
Scalar t
)
{
Check_Pointer(this); Check_Object(&c1); Check_Object(&c2);
red = c1.red + t*(c2.red-c1.red);
green = c1.green + t*(c2.green-c1.green);
blue = c1.blue + t*(c2.blue-c1.blue);
alpha = c1.alpha + t*(c2.alpha-c1.alpha);
return *this;
}
//
// Support functions
//
#if !defined(Spew)
friend void
::Spew(
const char* group,
const RGBAColor &color
);
#endif
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~ RGBAColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//##########################################################################
//############## HSVColor ############################################
//##########################################################################
class HSVColor
{
friend class HSVAColor;
public:
static const HSVColor
Unassigned;
Scalar
hue,
saturation,
value;
HSVColor()
{hue = saturation = value = -1.0f;}
HSVColor(
Scalar h,
Scalar s,
Scalar v
)
{hue = h; saturation = s; value = v;}
friend bool
Close_Enough(
const HSVColor &c1,
const HSVColor &c2,
Scalar e = SMALL
);
bool
operator==(const HSVColor &color) const
{Check_Object(this); return Close_Enough(*this, color, SMALL);}
bool
operator!=(const HSVColor &color) const
{Check_Object(this); return !Close_Enough(*this, color, SMALL);}
HSVColor&
operator=(const RGBColor &color);
HSVColor&
operator=(const HSVColor &color)
{
Check_Object(this); Check_Object(&color);
hue = color.hue; saturation = color.saturation;
value = color.value; return *this;
}
void
TestInstance() const
{}
HSVColor&
Combine(
const HSVColor& c1,
Scalar t1,
const HSVColor& c2,
Scalar t2
)
{
Check_Pointer(this); Check_Object(&c1); Check_Object(&c2);
hue = c1.hue*t1 + c2.hue*t2;
saturation = c1.saturation*t1 + c2.saturation*t2;
value = c1.value*t1 + c2.value*t2;
return *this;
}
HSVColor&
Lerp(
const HSVColor& c1,
const HSVColor& c2,
Scalar t
)
{
Check_Pointer(this); Check_Object(&c1); Check_Object(&c2);
hue = c1.hue + t*(c2.hue-c1.hue);
saturation = c1.saturation + t*(c2.saturation-c1.saturation);
value = c1.value + t*(c2.value-c1.value);
return *this;
}
//
// Support functions
//
#if !defined(Spew)
friend void
::Spew(
const char* group,
const HSVColor &color
);
#endif
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~ HSVColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//##########################################################################
//############## HSVAColor ###########################################
//##########################################################################
class HSVAColor:
public HSVColor
{
public:
static const HSVAColor
Unassigned;
Scalar
alpha;
HSVAColor():
HSVColor()
{alpha = -1.0f;}
HSVAColor(
Scalar h,
Scalar s,
Scalar v,
Scalar a
):
HSVColor(h, s, v)
{alpha = a;}
friend bool
Close_Enough(
const HSVAColor &c1,
const HSVAColor &c2,
Scalar e = SMALL
);
bool
operator==(const HSVAColor &color) const
{return Close_Enough(*this, color, SMALL);}
bool
operator!=(const HSVAColor &color) const
{return !Close_Enough(*this, color, SMALL);}
HSVAColor&
operator=(const RGBAColor &color)
{
Check_Object(this); Check_Object(&color);
HSVColor::operator=(color); alpha = color.alpha;
return *this;
}
HSVAColor&
operator=(const HSVAColor &color)
{
Check_Object(this); Check_Object(&color);
hue = color.hue; saturation = color.saturation;
value = color.value; alpha = color.alpha; return *this;
}
HSVAColor&
Combine(
const HSVAColor& c1,
Scalar t1,
const HSVAColor& c2,
Scalar t2
)
{
Check_Pointer(this); Check_Object(&c1); Check_Object(&c2);
hue = c1.hue*t1 + c2.hue*t2;
saturation = c1.saturation*t1 + c2.saturation*t2;
value = c1.value*t1 + c2.value*t2;
alpha = c1.alpha*t1 + c2.alpha*t2;
return *this;
}
HSVAColor&
Lerp(
const HSVAColor& c1,
const HSVAColor& c2,
Scalar t
)
{
Check_Pointer(this); Check_Object(&c1); Check_Object(&c2);
hue = c1.hue + t*(c2.hue-c1.hue);
saturation = c1.saturation + t*(c2.saturation-c1.saturation);
value = c1.value + t*(c2.value-c1.value);
alpha = c1.alpha + t*(c2.alpha-c1.alpha);
return *this;
}
//
// Support functions
//
#if !defined(Spew)
friend void
::Spew(
const char* group,
const HSVAColor &color
);
#endif
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~ HSVAColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
inline RGBAColor&
RGBAColor::operator=(const HSVAColor &color)
{
Check_Object(this);
Check_Object(&color);
RGBColor::operator=(color);
alpha = color.alpha;
return *this;
}
}
namespace MemoryStreamIO {
inline Stuff::MemoryStream&
Read(
Stuff::MemoryStream* stream,
Stuff::RGBColor *output
)
{return stream->ReadBytes(output, sizeof(*output));}
inline Stuff::MemoryStream&
Write(
Stuff::MemoryStream* stream,
const Stuff::RGBColor *input
)
{return stream->WriteBytes(input, sizeof(*input));}
inline Stuff::MemoryStream&
Read(
Stuff::MemoryStream* stream,
Stuff::RGBAColor *output
)
{return stream->ReadBytes(output, sizeof(*output));}
inline Stuff::MemoryStream&
Write(
Stuff::MemoryStream* stream,
const Stuff::RGBAColor *input
)
{return stream->WriteBytes(input, sizeof(*input));}
inline Stuff::MemoryStream&
Read(
Stuff::MemoryStream* stream,
Stuff::HSVColor *output
)
{return stream->ReadBytes(output, sizeof(*output));}
inline Stuff::MemoryStream&
Write(
Stuff::MemoryStream* stream,
const Stuff::HSVColor *input
)
{return stream->WriteBytes(input, sizeof(*input));}
inline Stuff::MemoryStream&
Read(
Stuff::MemoryStream* stream,
Stuff::HSVAColor *output
)
{return stream->ReadBytes(output, sizeof(*output));}
inline Stuff::MemoryStream&
Write(
Stuff::MemoryStream* stream,
const Stuff::HSVAColor *input
)
{return stream->WriteBytes(input, sizeof(*input));}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,167 @@
#pragma once
#include "Stuff.hpp"
namespace Stuff {
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// **************************** DATABASE API **************************** //
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
class Record;
class RecordHandle;
class Database;
class DatabaseHandle;
class RecordHandle
{
public:
DatabaseHandle *m_databaseHandle;
WORD m_ID;
const char *m_name;
__int64 m_timeStamp;
DWORD m_length;
const void *m_data;
const Record *m_record;
#if defined(_ARMOR)
RecordHandle();
~RecordHandle();
#endif
//
// Add - Adds a record to the database and returns a unique ID that can be used to access the record.
// The record can be found by the RecordID returned or the RecordName
// The info fields will be changed to point at the database's copy of the field
//
void Add();
//
// Replace - Overwrites a record based on the RecordID passed.
// The record can be found by the RecordID returned or the RecordName
// The info fields will be changed to point at the database's copy of the field
//
void Replace();
//
// Delete - Removes the record with the given RecordID.
//
void Delete();
//
// FindID - Returns a pointer to the Data contained in the record with the ID specified, also fills in a pointer to the original name.
// True is returned if a record is found
//
bool FindID(bool load);
//
// FindName - Returns a pointer to the Data contained in the record with the Name specified, also fills in a pointer to the record ID number.
// True is returned if a record is found
// The info fields will be changed to point at the database's copy of the field
//
bool FindName(bool load);
//
// This function must be called before the data will be loaded (note that data is automatically loaded if loaded by ID rather than name)
//
void LoadData();
//
// This function will unload any loaded data for the record
//
void UnloadData();
DWORD GetRealRecordSize();
//
// This function will unload any loaded data for the record BUT IT WILL NOT DELETE THE ACTUAL DATA ITSELF!!!!
//
void AbandonData();
int GetDiskOffset();
//
// Return the current record information and moves the current record to the next record.
// If there is a current record, True will be returned.
//
void First();
bool ReadAndNext();
void TestInstance() const;
};
class DatabaseHandle
{
friend class Database;
friend class Record;
friend class RecordHandle;
public:
Database *m_dataBase;
DatabaseHandle(
const char* filename,
bool read_only,
DWORD content_version
);
DatabaseHandle(
const char* filename,
MemoryStream *stream,
DWORD content_version
);
~DatabaseHandle();
void Save();
void ScatterSave();
void SaveAs(const char* filename);
void Save(BYTE* buffer, DWORD length);
void SpewLoadedRecords();
void UnloadRecords();
//
// GetNumberOfRecords - Returns the number of records in the database
//
WORD GetNumberOfRecords();
void TestInstance() const;
// it does not store the crc on purpose
// that way a hacker can't find the number easily...
__int64 CalculateCRC(int key);
__int64 CalculateDateCRC();
MString
GetFileName()
{return m_fileName;}
HGOSFILE
GetFileHandle()
{return m_fileHandle;}
DWORD
GetFileLength()
{return m_fileLength;}
protected:
__int64 m_currentCRC;
MString m_fileName;
HGOSFILE m_fileHandle;
BYTE *m_fileAddress;
DWORD m_fileLength;
DWORD m_MMHandle;
DWORD m_contentVersion;
HGOSHEAP m_heap;
bool
m_dirtyFlag,
m_readOnly;
};
extern HGOSHEAP g_DatabaseHeap;
}
@@ -0,0 +1,466 @@
//===========================================================================//
// File: extntbox.cc //
// Project: MUNGA Brick: Math Library //
// Contents: Implementation details of bounding box class //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 01/07/95 JMA Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1994,1995 Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "StuffHeaders.hpp"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ExtentBox::ExtentBox(
const Vector3D &min,
const Vector3D &max
)
{
Check_Pointer(this);
Check_Object(&min);
Check_Object(&max);
if (min.x <= max.x)
{
minX = min.x;
maxX = max.x;
}
else
{
minX = max.x;
maxX = min.x;
}
if (min.y <= max.y)
{
minY = min.y;
maxY = max.y;
}
else
{
minY = max.y;
maxY = min.y;
}
if (min.z <= max.z)
{
minZ = min.z;
maxZ = max.z;
}
else
{
minZ = max.z;
maxZ = min.z;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ExtentBox::ExtentBox(const ExtentBox &box)
{
Check_Pointer(this);
Check_Object(&box);
minX = box.minX;
maxX = box.maxX;
minY = box.minY;
maxY = box.maxY;
minZ = box.minZ;
maxZ = box.maxZ;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ExtentBox::ExtentBox(const OBB &obb)
{
Check_Pointer(this);
Check_Object(&obb);
Verify(obb.axisExtents.x >= 0.0f);
Verify(obb.axisExtents.y >= 0.0f);
Verify(obb.axisExtents.z >= 0.0f);
Stuff::Scalar len =
Fabs(obb.localToParent(0,0))*obb.axisExtents.x
+ Fabs(obb.localToParent(1,0))*obb.axisExtents.y
+ Fabs(obb.localToParent(2,0))*obb.axisExtents.z;
minX = obb.localToParent(3,0) - len;
maxX = obb.localToParent(3,0) + len;
len =
Fabs(obb.localToParent(0,1))*obb.axisExtents.x
+ Fabs(obb.localToParent(1,1))*obb.axisExtents.y
+ Fabs(obb.localToParent(2,1))*obb.axisExtents.z;
minY = obb.localToParent(3,1) - len;
maxY = obb.localToParent(3,1) + len;
len =
Fabs(obb.localToParent(0,2))*obb.axisExtents.x
+ Fabs(obb.localToParent(1,2))*obb.axisExtents.y
+ Fabs(obb.localToParent(2,2))*obb.axisExtents.z;
minZ = obb.localToParent(3,2) - len;
maxZ = obb.localToParent(3,2) + len;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ExtentBox::ComputeBounds(ReadOnlyArrayOf<Point3D> &points)
{
Check_Object(&points);
minX = maxX = points[0].x;
minY = maxY = points[0].y;
minZ = maxZ = points[0].z;
for (int i=1; i<points.GetLength(); ++i)
{
if (points[i].x < minX)
minX = points[i].x;
else if (points[i].x > maxX)
maxX = points[i].x;
if (points[i].y < minY)
minY = points[i].y;
else if (points[i].y > maxY)
maxY = points[i].y;
if (points[i].z < minZ)
minZ = points[i].z;
else if (points[i].z > maxZ)
maxZ = points[i].z;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ExtentBox&
ExtentBox::Intersect(
const ExtentBox &box_1,
const ExtentBox &box_2
)
{
Check_Pointer(this);
Check_Object(&box_1);
Check_Object(&box_2);
Verify(box_1.minX <= box_2.maxX);
Verify(box_1.maxX >= box_2.minX);
Verify(box_1.minY <= box_2.maxY);
Verify(box_1.maxY >= box_2.minY);
Verify(box_1.minZ <= box_2.maxZ);
Verify(box_1.maxZ >= box_2.minZ);
minX = Max(box_1.minX, box_2.minX);
maxX = Min(box_1.maxX, box_2.maxX);
minY = Max(box_1.minY, box_2.minY);
maxY = Min(box_1.maxY, box_2.maxY);
minZ = Max(box_1.minZ, box_2.minZ);
maxZ = Min(box_1.maxZ, box_2.maxZ);
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ExtentBox&
ExtentBox::Union(
const ExtentBox &box_1,
const ExtentBox &box_2
)
{
Check_Pointer(this);
Check_Object(&box_1);
Check_Object(&box_2);
minX = Min(box_1.minX, box_2.minX);
maxX = Max(box_1.maxX, box_2.maxX);
minY = Min(box_1.minY, box_2.minY);
maxY = Max(box_1.maxY, box_2.maxY);
minZ = Min(box_1.minZ, box_2.minZ);
maxZ = Max(box_1.maxZ, box_2.maxZ);
Check_Object(this);
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ExtentBox&
ExtentBox::Union(
const ExtentBox &box,
const Vector3D &point
)
{
Check_Pointer(this);
Check_Object(&box);
Check_Object(&point);
minX = Min(box.minX, point.x);
maxX = Max(box.maxX, point.x);
minY = Min(box.minY, point.y);
maxY = Max(box.maxY, point.y);
minZ = Min(box.minZ, point.z);
maxZ = Max(box.maxZ, point.z);
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Vector3D*
ExtentBox::Constrain(Vector3D *point) const
{
Check_Object(this);
Check_Object(point);
Clamp(point->x,minX,maxX);
Clamp(point->y,minY,maxY);
Clamp(point->z,minZ,maxZ);
return point;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ExtentBox::Contains(const Vector3D &point) const
{
Check_Object(this);
Check_Object(&point);
return
minX <= point.x && maxX >= point.x
&& minY <= point.y && maxY >= point.y
&& minZ <= point.z && maxZ >= point.z;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ExtentBox::Contains(const ExtentBox &box) const
{
Check_Object(this);
Check_Object(&box);
return
minX <= box.minX && maxX >= box.maxX
&& minY <= box.minY && maxY >= box.maxY
&& minZ <= box.minZ && maxZ >= box.maxZ;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ExtentBox::Intersects(const ExtentBox &box) const
{
Check_Object(this);
Check_Object(&box);
return
minX <= box.maxX && maxX >= box.minX
&& minY <= box.maxY && maxY >= box.minY
&& minZ <= box.maxZ && maxZ >= box.minZ;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ExtentBox::GetCenterpoint(Point3D *point) const
{
Check_Object(this);
Check_Pointer(point);
point->x = 0.5f * (minX + maxX);
point->y = 0.5f * (minY + maxY);
point->z = 0.5f * (minZ + maxZ);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ExtentBox::TestInstance() const
{
Verify(minX<=maxX && minY<=maxY && minZ<=maxZ);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
#if !defined(Spew)
void
Spew(
const char* group,
const ExtentBox &box
)
{
Check_Object(&box);
SPEW((
group,
"[%f..%f,%f..%f,%f..%f]+",
box.minX,
box.maxX,
box.minY,
box.maxY,
box.minZ,
box.maxZ
));
}
#endif
//~~~~~~~~~~~~~~~~~~~~~~~~~~ ExtentBox functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Stuff::Use_Scalar_In_Sorted_Array(
DynamicArrayOf<Scalar> *values,
Scalar value,
unsigned *max_index,
unsigned block_size,
Scalar threshold
)
{
Check_Object(values);
Check_Pointer(max_index);
//
//-------------------------------------------------------------
// First, look to see if the table contains the specified value
//-------------------------------------------------------------
//
unsigned bottom = 0;
unsigned top = *max_index;
while (top > bottom)
{
unsigned middle = (top + bottom - 1) >> 1;
if (Close_Enough((*values)[middle], value, threshold))
{
return;
}
else if ((*values)[middle] > value)
{
top = middle;
}
else
{
bottom = middle + 1;
}
}
Verify(top == bottom);
//
//-----------------------------------------------------------------------
// Since we got here, a new value must be added to the table. First make
// room in the table
//-----------------------------------------------------------------------
//
if (*max_index == values->GetLength())
{
values->SetLength(*max_index + block_size);
}
unsigned to_move = *max_index - bottom;
Verify(to_move <= *max_index);
if (to_move > 0)
{
memmove(
&(*values)[bottom+1],
&(*values)[bottom],
to_move * sizeof(value)
);
}
++(*max_index);
(*values)[bottom] = value;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Stuff::Find_Planes_Of_Boxes(
DynamicArrayOf<Plane> *planes,
const DynamicArrayOf<ExtentBox> &boxes
)
{
Check_Object(planes);
Check_Object(&boxes);
//
//------------------------------------------------------------
// Figure out all the unique axis components used by the boxes
//------------------------------------------------------------
//
DynamicArrayOf<Scalar>
xs,
ys,
zs;
unsigned
max_x = 0,
max_y = 0,
max_z = 0,
count = boxes.GetLength(),
i;
Verify(count > 0);
for (i=0; i<count; ++i)
{
Use_Scalar_In_Sorted_Array(&xs, boxes[i].minX, &max_x, 10);
Use_Scalar_In_Sorted_Array(&xs, boxes[i].maxX, &max_x, 10);
Use_Scalar_In_Sorted_Array(&ys, boxes[i].minY, &max_y, 10);
Use_Scalar_In_Sorted_Array(&ys, boxes[i].maxY, &max_y, 10);
Use_Scalar_In_Sorted_Array(&zs, boxes[i].minZ, &max_z, 10);
Use_Scalar_In_Sorted_Array(&zs, boxes[i].maxZ, &max_z, 10);
}
//
//------------------------------------------------
// There will be a plane for each unique component
//------------------------------------------------
//
count = max_x + max_y + max_z;
planes->SetLength(count);
//
//------------------------
// Generate the Y-Z planes
//------------------------
//
Plane *plane = &(*planes)[0];
for (i=0; i<max_x; ++i)
{
Verify(static_cast<unsigned>(plane - &(*planes)[0]) < count);
plane->normal.x = 1.0f;
plane->normal.y = 0.0f;
plane->normal.z = 0.0f;
plane->offset = xs[i];
++plane;
}
//
//------------------------
// Generate the X-Z planes
//------------------------
//
for (i=0; i<max_y; ++i)
{
Verify(static_cast<unsigned>(plane - &(*planes)[0]) < count);
plane->normal.x = 0.0f;
plane->normal.y = 1.0f;
plane->normal.z = 0.0f;
plane->offset = ys[i];
++plane;
}
//
//------------------------
// Generate the X-Y planes
//------------------------
//
for (i=0; i<max_z; ++i)
{
Verify(static_cast<unsigned>(plane - &(*planes)[0]) < count);
plane->normal.x = 0.0f;
plane->normal.y = 0.0f;
plane->normal.z = 1.0f;
plane->offset = zs[i];
++plane;
}
}
@@ -0,0 +1,148 @@
//===========================================================================//
// File: extntbox.hh //
// Project: MUNGA Brick: Math Library //
// Contents: Interface specification of bounding box class //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 01/07/95 JMA Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995 Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#pragma once
#include "Stuff.hpp"
#include "Scalar.hpp"
#include "MArray.hpp"
#include "Plane.hpp"
namespace Stuff {class ExtentBox;}
#if !defined(Spew)
void
Spew(
const char* group,
const Stuff::ExtentBox& box
);
#endif
namespace Stuff {
class Vector3D;
class Point3D;
class NotationFile;
class OBB;
//~~~~~~~~~~~~~~~~~~~~~~~~~ ExtentBox ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class ExtentBox
{
public:
Scalar
minX,
maxX,
minY,
maxY,
minZ,
maxZ;
ExtentBox() {}
ExtentBox(
const Vector3D &min,
const Vector3D &max
);
ExtentBox(const ExtentBox &box);
explicit ExtentBox(const OBB& obb);
const Scalar&
operator[](int index) const
{Check_Object(this); return (&minX)[index];}
Scalar&
operator[](int index)
{Check_Object(this); return (&minX)[index];}
void
ComputeBounds(ReadOnlyArrayOf<Point3D> &points);
Scalar
GetVolume() const
{Check_Object(this); return (maxX-minX)*(maxY-minY)*(maxZ-minZ);}
ExtentBox&
Intersect(
const ExtentBox &box_1,
const ExtentBox &box_2
);
ExtentBox&
Union(
const ExtentBox &box_1,
const ExtentBox &box_2
);
ExtentBox&
Union(
const ExtentBox &box_1,
const Vector3D &point
);
Vector3D*
Constrain(Vector3D *point) const;
bool
Contains(const Vector3D &point) const;
bool
Contains(const ExtentBox &box) const;
bool
Intersects(const ExtentBox &box) const;
void
GetCenterpoint(Point3D *point) const;
void
TestInstance() const;
static bool
TestClass();
#if !defined(Spew)
friend void
::Spew(
const char* group,
const ExtentBox& box
);
#endif
};
//~~~~~~~~~~~~~~~~~~~~~~~~~ ExtentBox functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
Use_Scalar_In_Sorted_Array(
DynamicArrayOf<Scalar> *values,
Scalar value,
unsigned *max_index,
unsigned block_size,
Scalar threshold = SMALL
);
void
Find_Planes_Of_Boxes(
DynamicArrayOf<Plane> *planes,
const DynamicArrayOf<ExtentBox> &boxes
);
}
namespace MemoryStreamIO {
inline Stuff::MemoryStream&
Read(
Stuff::MemoryStream* stream,
Stuff::ExtentBox *output
)
{return stream->ReadBytes(output, sizeof(*output));}
inline Stuff::MemoryStream&
Write(
Stuff::MemoryStream* stream,
const Stuff::ExtentBox *input
)
{return stream->WriteBytes(input, sizeof(*input));}
}
@@ -0,0 +1,554 @@
#include "StuffHeaders.hpp"
#include <mbstring.h>
#define __mbschr(s,c) (char*)_mbschr((const unsigned char*)(s),(c))
#if !defined(TOOLOS_HPP)
#include <GameOS\ToolOS.hpp>
#endif
//#############################################################################
//############################# Directory ###############################
//#############################################################################
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Directory::Directory(
const char *find_files,
bool directories
):
fileEntries(NULL,NULL),
folderEntries(NULL,NULL)
{
Check_Pointer(find_files);
//
//------------------------------------------------
// Isolate the search path that we are looking for
//------------------------------------------------
//
MString new_directory_string = find_files;
currentDirectoryString = find_files;
currentDirectoryString.IsolateDirectory();
//
//---------------------------------------------------------
// Now look for the files and add each entry into the chain
//---------------------------------------------------------
//
const char* file_name = gos_FindFiles(new_directory_string);
while (file_name)
{
MString file_name_string = file_name;
DirectoryEntry *entry = new(g_Heap) DirectoryEntry(file_name_string);
Check_Object(entry);
fileEntries.AddValue(entry,file_name_string);
file_name = gos_FindFilesNext();
}
gos_FindFilesClose();
fileWalker = new(g_Heap) SortedChainIteratorOf<DirectoryEntry*,MString>(&fileEntries);
Check_Object(fileWalker);
//
//---------------------------------------------------
// Look through the directories if we are supposed to
//---------------------------------------------------
//
folderWalker = NULL;
if (directories)
{
file_name = gos_FindDirectories(new_directory_string);
while (file_name)
{
MString file_name_string = file_name;
DirectoryFolder *entry = new(g_Heap) DirectoryFolder(file_name_string);
Check_Object(entry);
folderEntries.AddValue(entry,file_name_string);
file_name = gos_FindDirectoriesNext();
}
gos_FindDirectoriesClose();
folderWalker = new(g_Heap) SortedChainIteratorOf<DirectoryFolder*,MString>(&folderEntries);
Check_Object(folderWalker);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Directory::~Directory(void)
{
Check_Object(this);
Check_Object(fileWalker);
fileWalker->DeletePlugs();
Check_Object(fileWalker);
delete fileWalker;
if (folderWalker != NULL)
{
Check_Object(folderWalker);
folderWalker->DeletePlugs();
Check_Object(folderWalker);
delete folderWalker;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const char* Directory::GetCurrentFileName(void)
{
Check_Object(this);
Check_Object(fileWalker);
DirectoryEntry *entry;
if ((entry = fileWalker->GetCurrent()) != NULL)
{
Check_Object(entry);
return entry->GetItem();
}
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void Directory::AdvanceCurrentFile(void)
{
Check_Object(this);
Check_Object(fileWalker);
fileWalker->Next();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const char * Directory::GetCurrentFolderName( void )
{
Check_Object(this);
if (folderWalker == NULL)
STOP(("Directory class was instantiated without directory support:\n Set the <directories> parameter to true to enable."));
Check_Object(folderWalker);
DirectoryFolder *entry;
if ((entry = folderWalker->GetCurrent()) != NULL)
{
Check_Object(entry);
return entry->GetItem();
}
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void Directory::AdvanceCurrentFolder( void )
{
Check_Object(this);
if (folderWalker == NULL)
STOP(("Directory class was instantiated without directory support:\n Set the <directories> parameter to true to enable."));
Check_Object(folderWalker);
folderWalker->Next();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const char* Directory::GetNewestFile(void)
{
Check_Object(this);
Check_Object(fileWalker);
SortedChainIteratorOf<DirectoryEntry*, MString> file_walker(&fileEntries);
DirectoryEntry *entry;
DirectoryEntry *newest_entry;
__int64 new_file_time;
newest_entry = file_walker.GetCurrent();
if(newest_entry)
{
MString file_name = currentDirectoryString;
file_name += newest_entry->GetItem();
new_file_time = gos_FileTimeStamp((const char *)file_name);
while((entry = file_walker.ReadAndNext()) != NULL)
{
Check_Object(entry);
file_name = currentDirectoryString;
file_name += entry->GetItem();
__int64 current_file_time = gos_FileTimeStamp((const char *)file_name);
if(current_file_time > new_file_time)
{
newest_entry = entry;
new_file_time = current_file_time;
}
}
return newest_entry->GetItem();
}
return NULL;
}
//#############################################################################
//########################### FileStream ################################
//#############################################################################
FileStream::ClassData* FileStream::DefaultData = NULL;
HGOSHEAP FileStream::s_Heap = NULL;
const char * FileStream::WhiteSpace = " \t\n";
char FileStream::RedirectedName[256];
bool
FileStream::IsRedirected=false,
FileStream::IgnoreReadOnlyFlag=false;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::InitializeClass()
{
Verify(!s_Heap);
s_Heap = gos_CreateMemoryHeap("File Buffers", 0, Stuff::g_LibraryHeap);
Check_Pointer(s_Heap);
Verify(!DefaultData);
DefaultData =
new ClassData(
FileStreamClassID,
"Stuff::FileStream",
MemoryStream::DefaultData
);
Check_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::TerminateClass()
{
Check_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
Check_Pointer(s_Heap);
gos_DestroyMemoryHeap(s_Heap);
s_Heap = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileStream::FileStream():
MemoryStream(DefaultData, NULL, 0)
{
fileName = NULL;
isOpen = false;
fileHandle = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileStream::FileStream(
const char* file_name,
WriteStatus writable
):
MemoryStream(DefaultData, NULL, 0)
{
fileName = NULL;
isOpen = false;
Open(file_name, writable);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileStream::~FileStream()
{
Close();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::Open(
const char* file_name,
WriteStatus writable
)
{
Check_Object(this);
Check_Pointer(file_name);
writeEnabled = writable;
currentPosition = streamStart = highWaterByte = NULL;
streamSize = 0;
fileHandle = NULL;
//
//------------------------------------------------
// If this is a readonly file, have gos read it in
//------------------------------------------------
//
if (writeEnabled == ReadOnly)
{
if (IsRedirected)
{
void (__stdcall *old_hook)(const char*, BYTE**, DWORD*) = Environment.HookGetFile;
Environment.HookGetFile = NULL;
gos_PushCurrentHeap(s_Heap);
gos_GetFile(RedirectedName, &streamStart, &streamSize);
gos_PopCurrentHeap();
Environment.HookGetFile = old_hook;
fileName = _strdup(RedirectedName);
}
else
{
gos_PushCurrentHeap(s_Heap);
gos_GetFile(file_name, &streamStart, &streamSize);
gos_PopCurrentHeap();
if (IsRedirected)
fileName = _strdup(RedirectedName);
else
fileName = _strdup(file_name);
}
isOpen = true;
currentPosition = streamStart;
highWaterByte = currentPosition;
}
//
//-----------------------------------------------
// Write only flags go through standard file open
//-----------------------------------------------
//
else
{
writeEnabled = writable;
if (IgnoreReadOnlyFlag)
{
bool (__stdcall *old_hook)(const char*) = Environment.HookDoesFileExist;
Environment.HookDoesFileExist = NULL;
if (gos_DoesFileExist(file_name))
gos_FileSetReadWrite(file_name);
Environment.HookDoesFileExist = old_hook;
}
gos_OpenFile(
&fileHandle,
file_name,
READWRITE
);
isOpen = true;
streamSize = 0xFFFFFFFFU;
fileName = _strdup(file_name);
}
//
//--------------------------
// Try and open the filename
//--------------------------
//
IsRedirected = false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::Close()
{
Check_Object(this);
//
//---------------------------------
// If the file was opened, close it
//---------------------------------
//
if (fileHandle)
{
gos_CloseFile(fileHandle);
fileHandle = NULL;
}
else if (streamStart != NULL)
gos_Free(streamStart);
//
//----------------
// Delete the name
//----------------
//
isOpen = false;
if (fileName)
{
Check_Pointer(fileName);
free(fileName);
fileName = NULL;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void FileStream::SetPointer(DWORD index)
{
Check_Object(this);
Verify(IsFileOpened());
MemoryStream::SetPointer(index);
if (writeEnabled == WriteOnly)
gos_SeekFile(fileHandle, FROMSTART, reinterpret_cast<DWORD>(currentPosition));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream& FileStream::AdvancePointer(DWORD index)
{
Check_Object(this);
Verify(IsFileOpened());
MemoryStream::AdvancePointer(index);
if (writeEnabled == WriteOnly)
gos_SeekFile(fileHandle, FROMSTART, reinterpret_cast<DWORD>(currentPosition));
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream& FileStream::RewindPointer(DWORD index)
{
Check_Object(this);
Verify(IsFileOpened());
MemoryStream::RewindPointer(index);
if (writeEnabled == WriteOnly)
gos_SeekFile(fileHandle, FROMSTART, reinterpret_cast<DWORD>(currentPosition));
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream& FileStream::ReadBytes(
void *ptr,
DWORD number_of_bytes
)
{
Check_Object(this);
Verify(IsFileOpened());
Verify(writeEnabled == ReadOnly);
return MemoryStream::ReadBytes(ptr, number_of_bytes);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream& FileStream::WriteBytes(
const void *ptr,
DWORD number_of_bytes
)
{
Check_Object(this);
Verify(IsFileOpened());
Verify(writeEnabled == WriteOnly);
DWORD written =
gos_WriteFile(
fileHandle,
Cast_Pointer(BYTE*, const_cast<void*>(ptr)),
number_of_bytes
);
Verify(written == number_of_bytes);
currentPosition += written;
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool FileStream::IsFileOpened()
{
Check_Object(this);
return isOpen;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool Stuff::CreateDirectories(const char *directory_path)
{
if (directory_path == NULL)
return false;
Check_Pointer(directory_path);
const char *start_position = directory_path;
const char *current_position = directory_path;
if (*current_position != '\\')
{
if ((current_position + 1) != NULL)
{
if((current_position + 2) != NULL)
{
if ( *(current_position + 1) == ':' && *(current_position + 2) == '\\')
{
current_position += 2;
}
}
}
}
if (*current_position != '\\')
return false;
while((current_position != NULL))
{
//make a substring with the path...
const char *next_slash;
next_slash = __mbschr( current_position + 1, '\\' );
char *new_string = NULL;
if (next_slash == NULL)
{
//copy the whole string
int length = strlen(start_position)+1;
new_string = new(g_Heap) char[length];
Check_Pointer(new_string);
Str_Copy(new_string, start_position, length);
}
else
{
if (next_slash - current_position == 0)
{
return false;
}
if (next_slash - current_position == 1)
{
return false;
}
//copy the sub string
int length = next_slash - start_position;
new_string = new(g_Heap) char[length+1];
Check_Pointer(new_string);
strncpy(new_string, start_position, length);
new_string[length] = NULL;
}
Verify(new_string != NULL);
if (!gos_DoesFileExist(new_string))
{
gos_CreateDirectory(new_string);
}
Check_Pointer(new_string);
delete new_string;
current_position = next_slash;
}
return true;
}
@@ -0,0 +1,160 @@
//===========================================================================//
// File: filestrm.hpp //
// Project: MUNGA Brick: Resource Manager //
// Contents: Implementation Details of resource management //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
//---------------------------------------------------------------------------//
// Copyright (C) 1996, Virtual World Entertainment, Inc. //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
#pragma once
#include "Stuff.hpp"
#include "MemoryStream.hpp"
namespace Stuff {
class FileStreamManager;
class FileStream;
//##########################################################################
//########################## Directory ###############################
//##########################################################################
class Directory
#if defined(_ARMOR)
: public Stuff::Signature
#endif
{
public:
Directory(
const char *find_files,
bool find_directories=false
);
~Directory();
void TestInstance() const
{}
const char* GetCurrentFileName();
void AdvanceCurrentFile();
const char* GetCurrentFolderName();
void AdvanceCurrentFolder();
const char* GetNewestFile();
public:
int fileOk;
Stuff::MString currentDirectoryString;
typedef Stuff::PlugOf<Stuff::MString> DirectoryEntry;
typedef Stuff::PlugOf<Stuff::MString> DirectoryFolder;
Stuff::SortedChainOf<DirectoryFolder*, Stuff::MString> folderEntries;
Stuff::SortedChainOf<DirectoryEntry*, Stuff::MString> fileEntries;
Stuff::SortedChainIteratorOf<DirectoryFolder*, Stuff::MString> *folderWalker;
Stuff::SortedChainIteratorOf<DirectoryEntry*, Stuff::MString> *fileWalker;
};
//##########################################################################
//######################## FileStream ################################
//##########################################################################
class FileStream:
public MemoryStream
{
friend class FileStreamManager;
public:
static void InitializeClass();
static void TerminateClass();
static ClassData *DefaultData;
static const char *WhiteSpace;
static HGOSHEAP s_Heap;
void TestInstance() const;
static bool TestClass();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructors
//
public:
enum WriteStatus {
ReadOnly,
WriteOnly
};
FileStream();
explicit FileStream(
const char* file_name,
WriteStatus writable = ReadOnly
);
~FileStream();
void Open(
const char* file_name = NULL,
WriteStatus writable = ReadOnly
);
void Close();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Status functions
//
public:
void* GetPointer() const
{Check_Object(this); Verify(writeEnabled == ReadOnly); return currentPosition;}
void SetPointer(void *)
{
STOP((
"No implementation possible for FileStream::SetPointer(void*)"
));
}
void SetPointer(DWORD index);
MemoryStream& AdvancePointer(DWORD count);
MemoryStream& RewindPointer(DWORD count);
MemoryStream& ReadBytes(
void *ptr,
DWORD number_of_bytes
);
MemoryStream& WriteBytes(
const void *ptr,
DWORD number_of_bytes
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// File functions
//
public:
virtual bool IsFileOpened();
const char* GetFileName()
{Check_Object(this); return fileName;}
enum SeekType {
FromBeginning,
FromEnd
};
static char RedirectedName[256];
static bool IsRedirected;
static void IgnoreReadOnly(bool flag)
{IgnoreReadOnlyFlag = flag;}
protected:
WriteStatus writeEnabled;
char *fileName;
HGOSFILE fileHandle;
bool isOpen;
static bool IgnoreReadOnlyFlag;
};
bool
CreateDirectories(const char *directories);
}
@@ -0,0 +1,265 @@
//===========================================================================//
// File: filestrmmgr.cpp //
// Project: MUNGA Brick: Resource Manager //
// Contents: Implementation Details of resource management //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
//---------------------------------------------------------------------------//
// Copyright (C) 1996, Virtual World Entertainment, Inc. //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
#include "StuffHeaders.hpp"
#include <GameOS\ToolOS.hpp>
//#############################################################################
//########################## FileDependencies ###########################
//#############################################################################
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileDependencies::FileDependencies():
Plug(DefaultData)
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileDependencies::~FileDependencies()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileDependencies&
FileDependencies::operator=(const FileDependencies &dependencies)
{
Check_Pointer(this);
Check_Object(&dependencies);
m_fileNameStream.Rewind();
int len = dependencies.m_fileNameStream.GetBytesUsed();
if (len)
{
MemoryStream scanner(
static_cast<BYTE*>(dependencies.m_fileNameStream.GetPointer())-len,
len
);
m_fileNameStream.AllocateBytes(len);
m_fileNameStream << scanner;
}
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
FileDependencies::AddDependency(FileStream *stream)
{
Check_Object(this);
Check_Object(stream);
//
//---------------------
// Get the new filename
//---------------------
//
const char* new_file = stream->GetFileName();
Check_Pointer(new_file);
//
//---------------------------------------------------
// Make a new memorystream that wraps our current one
//---------------------------------------------------
//
BYTE *end = Cast_Pointer(BYTE*, m_fileNameStream.GetPointer());
int len = m_fileNameStream.GetBytesUsed();
MemoryStream scanner(end-len, len);
//
//--------------------------------------
// See if the new file is already inside
//--------------------------------------
//
while (scanner.GetBytesRemaining() > 0)
{
const char* old_name = Cast_Pointer(const char*, scanner.GetPointer());
int len = strlen(old_name);
if (!_stricmp(new_file, old_name))
return;
scanner.AdvancePointer(len+1);
}
m_fileNameStream.WriteBytes(new_file, strlen(new_file)+1);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
FileDependencies::AddDependency(const char* new_file)
{
Check_Object(this);
//
//---------------------------------------------------
// Make a new memorystream that wraps our current one
//---------------------------------------------------
//
BYTE *end = Cast_Pointer(BYTE*, m_fileNameStream.GetPointer());
int len = m_fileNameStream.GetBytesUsed();
MemoryStream scanner(end-len, len);
//
//--------------------------------------
// See if the new file is already inside
//--------------------------------------
//
while (scanner.GetBytesRemaining() > 0)
{
const char* old_name = Cast_Pointer(const char*, scanner.GetPointer());
int len = strlen(old_name);
if (!_stricmp(new_file, old_name))
return;
scanner.AdvancePointer(len+1);
}
m_fileNameStream.WriteBytes(new_file, strlen(new_file)+1);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
FileDependencies::AddDependencies(MemoryStream *dependencies)
{
Check_Object(this);
Check_Object(dependencies);
int old_len = m_fileNameStream.GetBytesUsed();
dependencies->Rewind();
while (dependencies->GetBytesRemaining() > 0)
{
const char* new_name =
Cast_Pointer(const char*, dependencies->GetPointer());
int new_len = strlen(new_name);
//
//---------------------------------------------------
// Make a new memorystream that wraps our current one
//---------------------------------------------------
//
BYTE *end = static_cast<BYTE*>(m_fileNameStream.GetPointer());
MemoryStream scanner(end-m_fileNameStream.GetBytesUsed(), old_len);
//
//--------------------------------------
// See if the new file is already inside
//--------------------------------------
//
while (scanner.GetBytesRemaining() > 0)
{
const char* old_name = Cast_Pointer(const char*, scanner.GetPointer());
int len = strlen(old_name);
if (!_stricmp(old_name, new_name))
break;
scanner.AdvancePointer(len+1);
}
if (!scanner.GetBytesRemaining())
m_fileNameStream.WriteBytes(new_name, new_len+1);
dependencies->AdvancePointer(new_len+1);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
FileDependencies::AddDependencies(const FileDependencies *dependencies)
{
Check_Object(this);
Check_Object(dependencies);
AddDependencies((MemoryStream*)&dependencies->m_fileNameStream);
}
//#############################################################################
//######################### FileStreamManager ###########################
//#############################################################################
FileStreamManager*
FileStreamManager::Instance = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileStreamManager::FileStreamManager():
compareCache(NULL, true)
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
FileStreamManager::~FileStreamManager()
{
PurgeFileCompareCache();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
FileStreamManager::CompareModificationDate(
const MString &file_name,
__int64 time_stamp
)
{
Check_Object(this);
Check_Object(&file_name);
//
//------------------------------
// Check the compare cache first
//------------------------------
//
FileStatPlug *stat_plug;
if ((stat_plug = compareCache.Find(file_name)) != NULL)
{
Check_Object(stat_plug);
Check_Pointer(stat_plug->GetPointer());
if (*stat_plug->GetPointer() > time_stamp)
return true;
return false;
}
//
//-------------------------------------------------------------
// Get the statistics about the file. If the file isn't there,
// return false == "file older than time stamp"
//-------------------------------------------------------------
//
__int64 file_stats = gos_FileTimeStamp(file_name);
if (file_stats == -1)
return false;
//
//-------------
// Add to cache
//-------------
//
stat_plug = new(g_Heap) FileStatPlug(file_stats);
Register_Object(stat_plug);
compareCache.AddValue(stat_plug, file_name);
//
// Return, "is file newer than time stamp"?
//
if (file_stats > time_stamp)
return true;
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
FileStreamManager::PurgeFileCompareCache()
{
Check_Object(this);
compareCache.DeletePlugs();
}

Some files were not shown because too many files have changed in this diff Show More