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.
638 lines
13 KiB
C++
638 lines
13 KiB
C++
#pragma once
|
|
#define MLR_GOSVERTEX_HPP
|
|
|
|
#include <MLR\MLR.hpp>
|
|
#include <Stuff\Scalar.hpp>
|
|
#include <GameOS\GameOS.hpp>
|
|
|
|
namespace MidLevelRenderer {
|
|
|
|
//##########################################################################
|
|
//#################### GOSVertex ##############################
|
|
//##########################################################################
|
|
|
|
class GOSVertex :
|
|
public gos_VERTEX
|
|
{
|
|
public:
|
|
GOSVertex();
|
|
|
|
static Stuff::Scalar
|
|
farClipReciprocal;
|
|
|
|
inline GOSVertex&
|
|
operator=(const GOSVertex& V)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
x = V.x;
|
|
y = V.y;
|
|
z = V.z;
|
|
rhw = V.rhw;
|
|
argb = V.argb;
|
|
frgb = V.frgb;
|
|
u = V.u;
|
|
v = V.v;
|
|
|
|
return *this;
|
|
};
|
|
|
|
inline GOSVertex&
|
|
operator=(const Stuff::Vector4D& v)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
Verify(!Stuff::Small_Enough(v.w));
|
|
|
|
// Tell_Value(v);
|
|
|
|
rhw = 1.0f / v.w;
|
|
|
|
x = v.x * rhw;
|
|
Verify(x>=0.0f && x<=1.0f);
|
|
|
|
y = v.y * rhw;
|
|
Verify(y>=0.0f && y<=1.0f);
|
|
|
|
z = v.z * rhw;
|
|
Verify(z>=0.0f && z<1.0f);
|
|
|
|
return *this;
|
|
}
|
|
|
|
inline GOSVertex&
|
|
operator=(const Stuff::RGBAColor& c)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
// DEBUG_STREAM << "c = <" << c.alpha << ", " << c.red << ", ";
|
|
// DEBUG_STREAM << c.green << ", " << c.blue << ">" << endl;
|
|
|
|
float f;
|
|
f = c.alpha * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
argb = Stuff::Round_Float_To_Byte (f);
|
|
|
|
f = c.red * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
|
|
|
|
f = c.green * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
|
|
|
|
f = c.blue * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
argb = (argb << 8) | Stuff::Round_Float_To_Byte (f);
|
|
|
|
// DEBUG_STREAM << "0x" << hex << argb << dec << endl;
|
|
|
|
return *this;
|
|
}
|
|
|
|
inline GOSVertex&
|
|
operator=(const DWORD c)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
argb = c;
|
|
|
|
return *this;
|
|
}
|
|
|
|
inline GOSVertex&
|
|
operator=(const Stuff::Vector2DOf<Stuff::Scalar>& uv)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
u = uv[0];
|
|
v = uv[1];
|
|
|
|
return *this;
|
|
}
|
|
|
|
inline void
|
|
GOSTransformNoClip(
|
|
const Stuff::Point3D &v,
|
|
const Stuff::Matrix4D &m,
|
|
const Stuff::Scalar *uv
|
|
#if FOG_HACK
|
|
, int foggy
|
|
#endif
|
|
);
|
|
|
|
inline void
|
|
GOSTransformNoClipNoUV(
|
|
const Stuff::Point3D &v,
|
|
const Stuff::Matrix4D &m
|
|
#if FOG_HACK
|
|
, int foggy
|
|
#endif
|
|
);
|
|
|
|
#if FOG_HACK
|
|
static BYTE GOSVertex::fogTable[Limits::Max_Number_Of_FogStates][1024];
|
|
|
|
static void
|
|
SetFogTableEntry(int entry, Stuff::Scalar fogNearClip, Stuff::Scalar fogFarClip, Stuff::Scalar fogDensity);
|
|
#endif
|
|
|
|
protected:
|
|
};
|
|
|
|
struct ViewportScalars
|
|
{
|
|
static Stuff::Scalar MulX;
|
|
static Stuff::Scalar MulY;
|
|
static Stuff::Scalar AddX;
|
|
static Stuff::Scalar AddY;
|
|
};
|
|
|
|
void SetViewportScalars(Stuff::Scalar top=1.0f, Stuff::Scalar left=1.0f, Stuff::Scalar bottom=0.0f, Stuff::Scalar right=0.0f);
|
|
void ClearZBuffer();
|
|
|
|
const float float_cheat = 12582912.0f/256.0f;
|
|
const float One_Over_256 = 1.0f/256.0f;
|
|
|
|
#pragma warning (disable : 4725)
|
|
|
|
void
|
|
GOSVertex::GOSTransformNoClip(
|
|
const Stuff::Point3D &_v,
|
|
const Stuff::Matrix4D &m,
|
|
const Stuff::Scalar *uv
|
|
#if FOG_HACK>0
|
|
, int foggy
|
|
#endif
|
|
)
|
|
{
|
|
GOSTransformNoClipNoUV(_v, m
|
|
#if FOG_HACK>0
|
|
, foggy
|
|
#endif
|
|
);
|
|
|
|
#ifdef UV_CHECK
|
|
Verify( MLRState::GetHasMaxUVs() ? (uv[0]<MLRState::GetMaxUV() && uv[0]>-MLRState::GetMaxUV()) : 1 );
|
|
Verify( MLRState::GetHasMaxUVs() ? (uv[1]<MLRState::GetMaxUV() && uv[1]>-MLRState::GetMaxUV()) : 1 );
|
|
#endif
|
|
|
|
u = uv[0];
|
|
v = uv[1];
|
|
}
|
|
|
|
void
|
|
GOSVertex::GOSTransformNoClipNoUV(
|
|
const Stuff::Point3D &_v,
|
|
const Stuff::Matrix4D &m
|
|
#if FOG_HACK>0
|
|
, int foggy
|
|
#endif
|
|
)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(&_v);
|
|
Check_Object(&m);
|
|
|
|
#if USE_ASSEMBLER_CODE
|
|
Stuff::Scalar *f = &x;
|
|
_asm {
|
|
mov edx, m
|
|
|
|
mov eax, _v
|
|
|
|
fld dword ptr [eax] // v.x
|
|
fld dword ptr [eax+4] // v.y
|
|
fld dword ptr [eax+8] // v.z
|
|
|
|
mov eax, f
|
|
|
|
fld dword ptr [edx+34h] // m[1][3]
|
|
fmul st, st(2) // v.y
|
|
|
|
fld dword ptr [edx+38h] // m[2][3]
|
|
fmul st, st(2) // v.z
|
|
|
|
fxch st(1)
|
|
fadd dword ptr [edx+3Ch] // m[3][3]
|
|
|
|
fld dword ptr [edx+30h] // m[0][3]
|
|
fmul st, st(5) // v.x
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
fld dword ptr [edx+14h] // m[1][1]
|
|
fmul st, st(4) // v.y
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
fld dword ptr [edx+18h] // m[2][1]
|
|
fmul st, st(3) // v.z
|
|
|
|
fxch st(1)
|
|
fstp dword ptr [eax+0Ch] // w
|
|
|
|
fadd dword ptr [edx+1Ch] // m[3][1]
|
|
|
|
fld dword ptr [edx+10h] // m[0][1]
|
|
fmul st, st(5) // v.x
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
fld dword ptr [edx+24h] // m[1][2]
|
|
fmul st, st(4) // v.y
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
fld dword ptr [edx+28h] // m[2][2]
|
|
fmul st, st(3) // v.z
|
|
|
|
fxch st(1)
|
|
fstp dword ptr [eax+4] // y
|
|
|
|
fadd dword ptr [edx+2Ch] // m[3][2]
|
|
|
|
fld dword ptr [edx+20h] // m[0][2]
|
|
fmul st, st(5) // v.x
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
fld dword ptr [edx+4] // m[1][0]
|
|
fmul st, st(4) // v.y
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
fld dword ptr [edx+8] // m[2][0]
|
|
fmul st, st(3) // v.z
|
|
|
|
fxch st(1)
|
|
fstp dword ptr [eax+8] // z
|
|
|
|
fadd dword ptr [edx+0Ch] // m[3][0]
|
|
|
|
fld dword ptr [edx] // m[0][0]
|
|
fmul st, st(5) // v.x
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
faddp st(1),st
|
|
|
|
// fld1
|
|
|
|
// fdivrp st(1),st
|
|
|
|
// get rid of x, y, z
|
|
fstp st(1)
|
|
fstp st(1)
|
|
fstp st(1)
|
|
|
|
fstp dword ptr [eax] // x
|
|
|
|
}
|
|
#else
|
|
x = v.x*m(0,0) + v.y*m(1,0) + v.z*m(2,0) + m(3,0);
|
|
y = v.x*m(0,1) + v.y*m(1,1) + v.z*m(2,1) + m(3,1);
|
|
z = v.x*m(0,2) + v.y*m(1,2) + v.z*m(2,2) + m(3,2);
|
|
rhw = v.x*m(0,3) + v.y*m(1,3) + v.z*m(2,3) + m(3,3);
|
|
#endif
|
|
|
|
#if 0 //USE_ASSEMBLER_CODE
|
|
_asm {
|
|
; gos_vertices[0].w = 1.0f/coords[offset].w;
|
|
|
|
mov ecx, f
|
|
fld1
|
|
|
|
fdiv dword ptr [ecx+0Ch]
|
|
|
|
fst dword ptr [ecx+0Ch]
|
|
|
|
; gos_vertices[0].x = coords[offset].x * gos_vertices[0].w;
|
|
fld st(0)
|
|
fmul dword ptr [ecx]
|
|
fstp dword ptr [ecx]
|
|
|
|
; gos_vertices[0].y = coords[offset].y * gos_vertices[0].w;
|
|
fld dword ptr [ecx+4]
|
|
fmul st,st(1)
|
|
fstp dword ptr [ecx+4]
|
|
; gos_vertices[0].z = coords[offset].z * gos_vertices[0].w;
|
|
|
|
; fld dword ptr [ecx+8]
|
|
fmul dword ptr [ecx+8]
|
|
|
|
fstp dword ptr [ecx+8]
|
|
; fstp st(0)
|
|
}
|
|
#else
|
|
#if FOG_HACK
|
|
if(foggy)
|
|
{
|
|
*((BYTE *)&frgb + 3) =
|
|
fogTable[foggy-1][Stuff::Truncate_Float_To_Word(rhw)];
|
|
}
|
|
else
|
|
{
|
|
*((BYTE *)&frgb + 3) = 0xff;
|
|
}
|
|
#endif
|
|
|
|
rhw = 1.0f/rhw;
|
|
|
|
x = x * rhw;
|
|
y = y * rhw;
|
|
z = z * rhw;
|
|
#endif
|
|
|
|
Verify(rhw > Stuff::SMALL);
|
|
|
|
Verify(x >= 0.0f);
|
|
Verify(y >= 0.0f);
|
|
Verify(z >= 0.0f);
|
|
|
|
Verify(x <= 1.0f);
|
|
Verify(y <= 1.0f);
|
|
Verify(z < 1.0f);
|
|
|
|
x = x*ViewportScalars::MulX + ViewportScalars::AddX;
|
|
y = y*ViewportScalars::MulY + ViewportScalars::AddY;
|
|
}
|
|
|
|
// create a dword color out of 4 rgba floats
|
|
inline DWORD
|
|
GOSCopyColor( const Stuff::RGBAColor *color )
|
|
{
|
|
Stuff::Scalar f;
|
|
#if USE_ASSEMBLER_CODE
|
|
DWORD argb;
|
|
|
|
_asm {
|
|
fld float_cheat
|
|
|
|
mov esi, dword ptr [color]
|
|
|
|
fld dword ptr [esi + 0Ch]
|
|
|
|
mov ecx, dword ptr [esi + 0Ch]
|
|
|
|
fadd st, st(1)
|
|
|
|
rcl ecx, 1
|
|
sbb eax, eax
|
|
xor eax, -1
|
|
|
|
fstp f
|
|
xor ecx, ecx
|
|
|
|
mov ebx, f
|
|
and ebx, eax
|
|
|
|
test ebx, 0000ff00h
|
|
|
|
seta cl
|
|
|
|
xor eax, eax
|
|
sub eax, ecx
|
|
|
|
or ebx, eax
|
|
and ebx, 000000ffh
|
|
|
|
mov argb, ebx
|
|
|
|
fld dword ptr [esi]
|
|
|
|
mov ecx, dword ptr [esi]
|
|
|
|
fadd st, st(1)
|
|
rcl ecx, 1
|
|
sbb eax, eax
|
|
xor eax, -1
|
|
|
|
fstp f
|
|
xor ecx, ecx
|
|
|
|
mov ebx, f
|
|
and ebx, eax
|
|
|
|
test ebx, 0000ff00h
|
|
|
|
seta cl
|
|
|
|
xor eax, eax
|
|
sub eax, ecx
|
|
|
|
or ebx, eax
|
|
and ebx, 000000ffh
|
|
|
|
mov ecx, argb
|
|
shl ecx, 8
|
|
|
|
or ecx, ebx
|
|
mov argb, ecx
|
|
|
|
fld dword ptr [esi+4]
|
|
|
|
mov ecx, dword ptr [esi+4]
|
|
|
|
fadd st, st(1)
|
|
rcl ecx, 1
|
|
sbb eax, eax
|
|
xor eax, -1
|
|
|
|
fstp f
|
|
xor ecx, ecx
|
|
|
|
mov ebx, f
|
|
and ebx, eax
|
|
|
|
test ebx, 0000ff00h
|
|
|
|
seta cl
|
|
|
|
xor eax, eax
|
|
sub eax, ecx
|
|
|
|
or ebx, eax
|
|
and ebx, 000000ffh
|
|
|
|
mov ecx, argb
|
|
shl ecx, 8
|
|
|
|
or ecx, ebx
|
|
mov argb, ecx
|
|
|
|
; fld dword ptr [esi+8]
|
|
|
|
mov ecx, dword ptr [esi+8]
|
|
|
|
fadd dword ptr [esi+8]
|
|
rcl ecx, 1
|
|
sbb eax, eax
|
|
xor eax, -1
|
|
|
|
fstp f
|
|
xor ecx, ecx
|
|
|
|
mov ebx, f
|
|
and ebx, eax
|
|
|
|
test ebx, 0000ff00h
|
|
|
|
seta cl
|
|
|
|
xor eax, eax
|
|
sub eax, ecx
|
|
|
|
or ebx, eax
|
|
and ebx, 000000ffh
|
|
|
|
mov ecx, argb
|
|
shl ecx, 8
|
|
|
|
or ecx, ebx
|
|
mov argb, ecx
|
|
}
|
|
|
|
#else
|
|
f = color->alpha * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
argb = Stuff::Positive_Float_To_Byte (f);
|
|
|
|
f = colors->red * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
argb = (gos_vertices[0].argb << 8) | Stuff::Positive_Float_To_Byte (f);
|
|
|
|
f = colors->green * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
argb = (gos_vertices[0].argb << 8) | Stuff::Positive_Float_To_Byte (f);
|
|
|
|
f = colors->blue * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
argb = (gos_vertices[0].argb << 8) | Stuff::Positive_Float_To_Byte (f);
|
|
|
|
#endif
|
|
return argb;
|
|
}
|
|
|
|
inline void
|
|
DWORD2Color(Stuff::RGBAColor& to, DWORD from)
|
|
{
|
|
to.blue = (from & 0xff) * One_Over_256;
|
|
|
|
from = from>>8;
|
|
|
|
to.green = (from & 0xff) * One_Over_256;
|
|
|
|
from = from>>8;
|
|
|
|
to.red = (from & 0xff) * One_Over_256;
|
|
|
|
from = from>>8;
|
|
|
|
to.alpha = (from & 0xff) * One_Over_256;
|
|
}
|
|
|
|
inline DWORD
|
|
Color_DWORD_Lerp (
|
|
DWORD _from,
|
|
DWORD _to,
|
|
Stuff::Scalar _lerp
|
|
)
|
|
{
|
|
Stuff::RGBAColor from, to, lerp;
|
|
|
|
from.blue = (_from & 0xff) * One_Over_256;
|
|
|
|
_from = _from>>8;
|
|
|
|
from.green = (_from & 0xff) * One_Over_256;
|
|
|
|
_from = _from>>8;
|
|
|
|
from.red = (_from & 0xff) * One_Over_256;
|
|
|
|
_from = _from>>8;
|
|
|
|
from.alpha = (_from & 0xff) * One_Over_256;
|
|
|
|
// ====
|
|
|
|
to.blue = (_to & 0xff) * One_Over_256;
|
|
|
|
_to = _to>>8;
|
|
|
|
to.green = (_to & 0xff) * One_Over_256;
|
|
|
|
_to = _to>>8;
|
|
|
|
to.red = (_to & 0xff) * One_Over_256;
|
|
|
|
_to = _to>>8;
|
|
|
|
to.alpha = (_to & 0xff) * One_Over_256;
|
|
|
|
lerp.Lerp(from, to, _lerp);
|
|
|
|
return GOSCopyColor(&lerp);
|
|
}
|
|
|
|
inline BYTE
|
|
BYTE_Lerp(
|
|
BYTE from,
|
|
BYTE to,
|
|
Stuff::Scalar lerp
|
|
)
|
|
{
|
|
return Stuff::Round_Float_To_Byte(from + lerp*(to-from));
|
|
}
|
|
|
|
//######################################################################################################################
|
|
// the lines below will produce following functions:
|
|
//
|
|
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, int);
|
|
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, int);
|
|
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, int);
|
|
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const Vector2DScalar*, int);
|
|
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, const Vector2DScalar*, int);
|
|
// bool GOSCopyData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, const Vector2DScalar*, int);
|
|
//
|
|
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, int, int, int);
|
|
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, int, int, int);
|
|
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, int, int, int);
|
|
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const Vector2DScalar*, int, int, int);
|
|
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const DWORD*, const Vector2DScalar*, int, int, int);
|
|
// bool GOSCopyTriangleData(GOSVertex*, const Stuff::Vector4D*, const RGBAColor*, const Vector2DScalar*, int, int, int);
|
|
//#######################################################################################################################
|
|
|
|
#define I_SAY_YES_TO_COLOR
|
|
#define I_SAY_YES_TO_TEXTURE
|
|
#define I_SAY_YES_TO_DWORD_COLOR
|
|
#include <MLR\GOSVertexManipulation.hpp>
|
|
|
|
#undef I_SAY_YES_TO_DWORD_COLOR
|
|
#include <MLR\GOSVertexManipulation.hpp>
|
|
|
|
#undef I_SAY_YES_TO_COLOR
|
|
#include <MLR\GOSVertexManipulation.hpp>
|
|
|
|
#define I_SAY_YES_TO_COLOR
|
|
#undef I_SAY_YES_TO_TEXTURE
|
|
#include <MLR\GOSVertexManipulation.hpp>
|
|
|
|
#define I_SAY_YES_TO_DWORD_COLOR
|
|
#include <MLR\GOSVertexManipulation.hpp>
|
|
|
|
#undef I_SAY_YES_TO_COLOR
|
|
#include <MLR\GOSVertexManipulation.hpp>
|
|
|
|
#define MLR_GOSVERTEXMANIPULATION_HPP
|
|
|
|
}
|