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.
509 lines
13 KiB
C++
509 lines
13 KiB
C++
#include "gosFXHeaders.hpp"
|
|
#include <MLR\MLRCardCloud.hpp>
|
|
|
|
static bool Disable_Fade;
|
|
|
|
static bool __stdcall CheckDisableFade() {return Disable_Fade;}
|
|
static void __stdcall EnableDisableFade() {Disable_Fade = !Disable_Fade;}
|
|
|
|
static bool Disable_Cast;
|
|
|
|
static bool __stdcall CheckDisableCast() {return Disable_Cast;}
|
|
static void __stdcall EnableDisableCast() {Disable_Cast = !Disable_Cast;}
|
|
|
|
//############################################################################
|
|
//######################## gosFX::Flare__Specification #############################
|
|
//############################################################################
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Flare__Specification::Flare__Specification(
|
|
Stuff::MemoryStream *stream,
|
|
int gfx_version
|
|
):
|
|
Card__Specification(FlareClassID, stream, gfx_version)
|
|
{
|
|
Check_Pointer(this);
|
|
Verify(m_class == FlareClassID);
|
|
if (gfx_version>=20)
|
|
*stream >> m_fadeInRate >> m_fadeOutRate >> m_rayCastTime;
|
|
else
|
|
{
|
|
m_fadeInRate = 4.0f;
|
|
m_fadeOutRate = 4.0f;
|
|
m_rayCastTime = 0.25f;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Flare__Specification::Flare__Specification():
|
|
Card__Specification(gosFX::FlareClassID)
|
|
{
|
|
Check_Pointer(this);
|
|
m_fadeInRate = 4.0f;
|
|
m_fadeOutRate = 4.0f;
|
|
m_rayCastTime = 0.25f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Flare__Specification::~Flare__Specification()
|
|
{
|
|
Check_Object(this);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Flare__Specification*
|
|
gosFX::Flare__Specification::Make(
|
|
Stuff::MemoryStream *stream,
|
|
int gfx_version
|
|
)
|
|
{
|
|
Check_Object(stream);
|
|
|
|
gos_PushCurrentHeap(Heap);
|
|
Flare__Specification *spec =
|
|
new gosFX::Flare__Specification(stream, gfx_version);
|
|
gos_PopCurrentHeap();
|
|
|
|
return spec;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Flare__Specification::Save(Stuff::MemoryStream *stream)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(stream);
|
|
BaseClass::Save(stream);
|
|
*stream << m_fadeInRate << m_fadeOutRate << m_rayCastTime;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Flare__Specification::BuildDefaults()
|
|
{
|
|
|
|
Check_Object(this);
|
|
BaseClass::BuildDefaults();
|
|
m_fadeInRate = 4.0f;
|
|
m_fadeOutRate = 4.0f;
|
|
m_rayCastTime = 0.25f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
bool
|
|
gosFX::Flare__Specification::IsDataValid(bool fix_data)
|
|
{
|
|
|
|
Check_Object(this);
|
|
return BaseClass::IsDataValid(fix_data);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Flare__Specification::Copy(Flare__Specification *spec)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(spec);
|
|
|
|
BaseClass::Copy(spec);
|
|
m_fadeInRate = spec->m_fadeInRate;
|
|
m_fadeOutRate = spec->m_fadeOutRate;
|
|
m_rayCastTime = spec->m_rayCastTime;
|
|
}
|
|
|
|
//############################################################################
|
|
//############################## gosFX::Flare ################################
|
|
//############################################################################
|
|
|
|
gosFX::Flare::ClassData*
|
|
gosFX::Flare::DefaultData = NULL;
|
|
|
|
static bool
|
|
stub_caster(Stuff::Line3D *line)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
gosFX::Flare::RayCastMethod
|
|
gosFX::Flare::RayCaster = stub_caster;
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Flare::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
FlareClassID,
|
|
"gosFX::Flare",
|
|
BaseClass::DefaultData,
|
|
(Effect::Factory)&Make,
|
|
(Specification::Factory)&Specification::Make
|
|
);
|
|
Register_Object(DefaultData);
|
|
|
|
Disable_Fade = false;
|
|
AddDebuggerMenuItem("Libraries\\gosFX\\Disable Flare Fade", CheckDisableFade, EnableDisableFade, 0 );
|
|
Disable_Cast = false;
|
|
AddDebuggerMenuItem("Libraries\\gosFX\\Disable Flare Cast Delay", CheckDisableCast, EnableDisableCast, 0 );
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Flare::TerminateClass()
|
|
{
|
|
Check_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Flare::Flare(
|
|
Specification *spec,
|
|
unsigned flags
|
|
):
|
|
Card(DefaultData, spec, flags)
|
|
{
|
|
Check_Object(spec);
|
|
|
|
m_fadeLevel = 0.0f;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Flare::~Flare()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
gosFX::Flare*
|
|
gosFX::Flare::Make(
|
|
Specification *spec,
|
|
unsigned flags
|
|
)
|
|
{
|
|
Check_Object(spec);
|
|
|
|
gos_PushCurrentHeap(Heap);
|
|
Flare *cloud = new gosFX::Flare(spec, flags);
|
|
gos_PopCurrentHeap();
|
|
|
|
return cloud;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Flare::Start(ExecuteInfo *info)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(info);
|
|
|
|
BaseClass::Start(info);
|
|
|
|
//
|
|
//------------------------------------------------
|
|
// Cast an initial ray to make sure its done right
|
|
//------------------------------------------------
|
|
//
|
|
Set_Statistic(Flare_Count, Flare_Count+1);
|
|
Specification *spec = GetSpecification();
|
|
m_timeTillCast = spec->m_rayCastTime;
|
|
Stuff::Line3D eye_line;
|
|
eye_line.m_origin = LastCameraPosition;
|
|
Stuff::Point3D to(m_localToWorld);
|
|
Stuff::Vector3D dir;
|
|
dir.Subtract(to, LastCameraPosition);
|
|
eye_line.m_length = dir.GetLength();
|
|
if (!Stuff::Small_Enough(eye_line.m_length))
|
|
{
|
|
Stuff::Scalar len = 1.0f / eye_line.m_length;
|
|
eye_line.m_direction.x = dir.x * len;
|
|
eye_line.m_direction.y = dir.y * len;
|
|
eye_line.m_direction.z = dir.z * len;
|
|
eye_line.m_length -= 0.5f;
|
|
Check_Pointer(RayCaster);
|
|
m_fadeTarget = ((*RayCaster)(&eye_line)) ? 0.0f : 1.0f;
|
|
m_fadeLevel = m_fadeTarget;
|
|
}
|
|
else
|
|
{
|
|
m_fadeTarget = 0.0f;
|
|
m_fadeLevel = 0.0f;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
bool
|
|
gosFX::Flare::Execute(ExecuteInfo *info)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(info);
|
|
GFX_LOGIC("Execute::Flare");
|
|
|
|
if (!IsExecuted())
|
|
return false;
|
|
|
|
//
|
|
//------------------------
|
|
// Do the effect animation
|
|
//------------------------
|
|
//
|
|
Stuff::Scalar step = static_cast<Stuff::Scalar>(info->m_time - m_lastRan);
|
|
if (!BaseClass::Execute(info))
|
|
return false;
|
|
|
|
//
|
|
//----------------------------------
|
|
// See if we need to test visibility
|
|
//----------------------------------
|
|
//
|
|
Set_Statistic(Flare_Count, Flare_Count+1);
|
|
Specification *spec = GetSpecification();
|
|
Check_Object(spec);
|
|
m_timeTillCast -= step;
|
|
if (m_timeTillCast <= 0.0f || Disable_Cast)
|
|
{
|
|
m_timeTillCast = spec->m_rayCastTime;
|
|
Stuff::Line3D eye_line;
|
|
eye_line.m_origin = LastCameraPosition;
|
|
Stuff::Point3D to(m_localToWorld);
|
|
Stuff::Vector3D dir;
|
|
dir.Subtract(to, LastCameraPosition);
|
|
eye_line.m_length = dir.GetLength();
|
|
if (!Stuff::Small_Enough(eye_line.m_length))
|
|
{
|
|
Stuff::Scalar len = 1.0f / eye_line.m_length;
|
|
eye_line.m_direction.x = dir.x * len;
|
|
eye_line.m_direction.y = dir.y * len;
|
|
eye_line.m_direction.z = dir.z * len;
|
|
eye_line.m_length -= 0.5f;
|
|
Check_Pointer(RayCaster);
|
|
m_fadeTarget = ((*RayCaster)(&eye_line)) ? 0.0f : 1.0f;
|
|
}
|
|
}
|
|
|
|
//
|
|
//-----------------------------------
|
|
// Adjust the fade level of the flare
|
|
//-----------------------------------
|
|
//
|
|
if (m_age == 0.0f)
|
|
m_fadeLevel = m_fadeTarget;
|
|
else if (m_fadeTarget < m_fadeLevel)
|
|
{
|
|
m_fadeLevel -= step * spec->m_fadeOutRate;
|
|
if (m_fadeLevel < m_fadeTarget || Disable_Fade)
|
|
m_fadeLevel = m_fadeTarget;
|
|
}
|
|
else if (m_fadeTarget > m_fadeLevel)
|
|
{
|
|
m_fadeLevel += step * spec->m_fadeInRate;
|
|
if (m_fadeLevel > m_fadeTarget || Disable_Fade)
|
|
m_fadeLevel = m_fadeTarget;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void gosFX::Flare::Draw(DrawInfo *info)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(info);
|
|
GFX_RENDER("Flare");
|
|
|
|
//
|
|
//------------------------------------------
|
|
// If the flare has faded out, don't draw it
|
|
//------------------------------------------
|
|
//
|
|
if (!m_fadeLevel)
|
|
return;
|
|
|
|
//
|
|
//----------------------------
|
|
// Set up the common draw info
|
|
//----------------------------
|
|
//
|
|
MidLevelRenderer::DrawEffectInformation dInfo;
|
|
dInfo.effect = m_cardCloud;
|
|
Specification *spec = GetSpecification();
|
|
Check_Object(spec);
|
|
dInfo.state.Combine(info->m_state, spec->m_state);
|
|
dInfo.clippingFlags = info->m_clippingFlags;
|
|
Stuff::LinearMatrix4D local_to_world;
|
|
local_to_world.Multiply(m_localToParent, *info->m_parentToWorld);
|
|
dInfo.effectToWorld = &local_to_world;
|
|
|
|
//
|
|
//---------------------
|
|
// Fill in the position
|
|
//---------------------
|
|
//
|
|
m_vertices[0].x = m_scale*m_halfX;
|
|
m_vertices[0].y = -m_scale*m_halfY;
|
|
m_vertices[0].z = 0.0f;
|
|
|
|
m_vertices[1].x = -m_scale*m_halfX;
|
|
m_vertices[1].y = -m_scale*m_halfY;
|
|
m_vertices[1].z = 0.0f;
|
|
|
|
m_vertices[2].x = -m_scale*m_halfX;
|
|
m_vertices[2].y = m_scale*m_halfY;
|
|
m_vertices[2].z = 0.0f;
|
|
|
|
m_vertices[3].x = m_scale*m_halfX;
|
|
m_vertices[3].y = m_scale*m_halfY;
|
|
m_vertices[3].z = 0.0f;
|
|
|
|
//
|
|
//----------------
|
|
// Animate the uvs
|
|
//----------------
|
|
//
|
|
Stuff::Scalar u = spec->m_UOffset.ComputeValue(m_age, m_seed);
|
|
Stuff::Scalar v = spec->m_VOffset.ComputeValue(m_age, m_seed);
|
|
Stuff::Scalar u2 = spec->m_USize.ComputeValue(m_age, m_seed);
|
|
Stuff::Scalar v2 = spec->m_VSize.ComputeValue(m_age, m_seed);
|
|
|
|
//
|
|
//--------------------------------------------------------------
|
|
// If we are animated, figure out the row/column to be displayed
|
|
//--------------------------------------------------------------
|
|
//
|
|
if (spec->m_animated)
|
|
{
|
|
BYTE columns =
|
|
Stuff::Truncate_Float_To_Byte(
|
|
spec->m_index.ComputeValue(m_age, m_seed)
|
|
);
|
|
BYTE rows = static_cast<BYTE>(columns / spec->m_width);
|
|
columns = static_cast<BYTE>(columns - rows*spec->m_width);
|
|
|
|
//
|
|
//---------------------------
|
|
// Now compute the end points
|
|
//---------------------------
|
|
//
|
|
u += u2*columns;
|
|
v += v2*rows;
|
|
}
|
|
u2 += u;
|
|
v2 += v;
|
|
|
|
m_uvs[0].x = u;
|
|
m_uvs[0].y = v2;
|
|
m_uvs[1].x = u2;
|
|
m_uvs[1].y = v2;
|
|
m_uvs[2].x = u2;
|
|
m_uvs[2].y = v;
|
|
m_uvs[3].x = u;
|
|
m_uvs[3].y = v;
|
|
|
|
//
|
|
//------------------
|
|
// Fill in the color
|
|
//------------------
|
|
//
|
|
m_color.red = m_fadeLevel*spec->m_red.ComputeValue(m_age, m_seed);
|
|
m_color.green = m_fadeLevel*spec->m_green.ComputeValue(m_age, m_seed);
|
|
m_color.blue = m_fadeLevel*spec->m_blue.ComputeValue(m_age, m_seed);
|
|
m_color.alpha = spec->m_alpha.ComputeValue(m_age, m_seed);
|
|
m_colors[0] = m_color;
|
|
m_colors[1] = m_color;
|
|
m_colors[2] = m_color;
|
|
m_colors[3] = m_color;
|
|
|
|
//
|
|
//--------------------------------------------------------------
|
|
// Check the orientation mode. The first case is XY orientation
|
|
//--------------------------------------------------------------
|
|
//
|
|
if (spec->m_alignZUsingX)
|
|
{
|
|
Stuff::Point3D
|
|
camera_in_world(info->m_clipper->GetCameraToWorldMatrix());
|
|
Stuff::Point3D card_in_world(local_to_world);
|
|
Stuff::Vector3D look_at;
|
|
look_at.Subtract(camera_in_world, card_in_world);
|
|
if (spec->m_alignZUsingY)
|
|
local_to_world.AlignLocalAxisToWorldVector(
|
|
look_at,
|
|
Stuff::Z_Axis,
|
|
Stuff::Y_Axis,
|
|
Stuff::X_Axis
|
|
);
|
|
else
|
|
local_to_world.AlignLocalAxisToWorldVector(
|
|
look_at,
|
|
Stuff::Z_Axis,
|
|
Stuff::X_Axis,
|
|
-1
|
|
);
|
|
}
|
|
|
|
//
|
|
//-------------------------------------------------------
|
|
// Each matrix needs to be aligned to the camera around Y
|
|
//-------------------------------------------------------
|
|
//
|
|
else if (spec->m_alignZUsingY)
|
|
{
|
|
Stuff::Point3D
|
|
camera_in_world(info->m_clipper->GetCameraToWorldMatrix());
|
|
Stuff::Point3D card_in_world(local_to_world);
|
|
Stuff::Vector3D look_at;
|
|
look_at.Subtract(camera_in_world, card_in_world);
|
|
local_to_world.AlignLocalAxisToWorldVector(
|
|
look_at,
|
|
Stuff::Z_Axis,
|
|
Stuff::Y_Axis,
|
|
-1
|
|
);
|
|
}
|
|
|
|
//
|
|
//---------------------
|
|
// Now just do the draw
|
|
//---------------------
|
|
//
|
|
info->m_clipper->DrawEffect(&dInfo);
|
|
BaseClass::BaseClass::Draw(info);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Flare::Kill()
|
|
{
|
|
Check_Object(this);
|
|
|
|
m_fadeTarget = 1.0f;
|
|
m_fadeLevel = 1.0f;
|
|
m_timeTillCast = 0.0f;
|
|
BaseClass::Kill();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
void
|
|
gosFX::Flare::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|