Files
BT411/engine/MUNGA/BOXSOLID.h
T
arcattackandClaude Opus 4.8 7b7d465e5e Initial commit: bt411 -- standalone Windows BattleTech (Tesla 4.10 port)
Clean, self-contained extraction of the BattleTech-specific work from the
reverse-engineering workspace -- engine + game + content + build, with nothing
from Red Planet or the raw archive dumps. Builds green (Win32) and runs the
single-player drive->animate->target->fire->damage->destroy loop out of the box.

Layout:
  engine/   MUNGA + MUNGA_L4 shared 2007 engine, carrying our BT render/loader
            work (bgfload/L4D3D/L4VIDEO: BSL bit-slice decode, LOD/ground/shadow
            models) + image codec; the minimal rp/ headers the audio HAL needs
  game/     reconstructed BT logic + surviving-original BT source + fwd shims
            + WinMain launcher
  content/  full runtime tree (BTL4.RES, VIDEO/, GAUGE/, AUDIO/, eggs, BTDPL.INI)
  docs/     format specs + reconstruction ledgers
  reference/ raw Ghidra pseudocode (recon source-of-truth) + decomp exporter
  tools/    MP console emulator + map/resource scanners

One top-level CMake builds munga_engine lib + bt410_l4 game lib + btl4.exe.
All paths relativized (186 fwd shims + ~437 CMake abs paths -> repo-relative);
DXSDK is the one external, overridable via -DDXSDK. Verified: builds to a
byte-identical 2.27MB exe and runs combat (TARGET DESTROYED, 0 crashes) against
the bundled content.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 21:03:40 -05:00

977 lines
21 KiB
C++

#pragma once
#include "bndgbox.h"
#include "boxtree.h"
#include "boxlist.h"
#include "resource.h"
struct BoxedSolidResource;
class BoxedSolidCollision;
class BoxedSolidCollisionList;
class Simulation;
class NotationFile;
class Normal;
//##########################################################################
//########################### BoxedSolid #############################
//##########################################################################
class BoxedSolid:
public TaggedBoundingBox
{
public:
enum Type {
BlockType=0,
SphereType=1,
ConeType=2,
ReducibleBlockType=3,
RampType=4,
RampFacingNegativeZType=4,
RampFacingNegativeXType,
RampFacingPositiveZType,
RampFacingPositiveXType,
InvertedRampType=8,
InvertedRampFacingNegativeZType=8,
InvertedRampFacingNegativeXType,
InvertedRampFacingPositiveZType,
InvertedRampFacingPositiveXType,
WedgeType=12,
WedgeFacingNegativeZAndPositiveXType=12,
WedgeFacingNegativeZAndNegativeXType,
WedgeFacingPositiveZAndNegativeXType,
WedgeFacingPositiveZAndPositiveXType,
XAxisCylinderType=16,
YAxisCylinderType=17,
ZAxisCylinderType=18,
RightHandedTileType=19,
LeftHandedTileType=20,
SolidTypeCount
}
solidType;
enum Material {
StoneMaterial = 0,
GravelMaterial,
ConcreteMaterial,
SteelMaterial,
WoodMaterial,
RockMaterial,
OurCraftMaterial,
OtherCraftMaterial,
MaterialCount
}
materialType;
BoxedSolid(
const ExtentBox &extents,
Type type,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
BoxedSolid(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedSolid();
static BoxedSolid*
MakeBoxedSolid(
BoxedSolidResource *resource,
Simulation *owner,
BoxedSolid *next_solid
);
virtual Logical
VerifyCollision(BoxedSolidCollision &collision);
virtual Logical
ProcessCollision(
BoxedSolidCollision &collision,
const Vector3D &velocity,
BoxedSolidCollisionList *last_collisions,
Normal *normal,
Scalar *penetration
);
Logical
TestInstance() const;
static Logical
TestClass();
Simulation*
GetOwningSimulation()
{Check(this); return (Simulation*)GetTagPointer();}
BoxedSolid*
GetNextSolid()
{Check(this); return nextSolid;}
protected:
BoxedSolid
*nextSolid;
};
//##########################################################################
//####################### BoxedSolidCollision ########################
//##########################################################################
class BoxedSolidCollision:
public BoundingBoxCollision
{
public:
BoxedSolid*
GetTreeVolume()
{Check(this); return (BoxedSolid*)treeVolume;}
Logical
Occludes(
BoxedSolidCollision &collision,
const Vector3D &velocity
);
};
//##########################################################################
//##################### BoxedSolidCollisionList ######################
//##########################################################################
class BoxedSolidCollisionList:
public BoundingBoxCollisionList
{
protected:
int phantomCollisions;
public:
BoxedSolidCollisionList(int max_length = 10):
BoundingBoxCollisionList(max_length)
{Reset();}
void
Reset()
{phantomCollisions = 0; BoundingBoxCollisionList::Reset();}
BoxedSolidCollision&
operator[](int index)
{
Check(this); Verify((unsigned)index < maxCollisions);
return ((BoxedSolidCollision*)listStart)[index];
}
int
GetRealCollisions()
{Check(this); return GetCollisionCount() - phantomCollisions;}
void
ReduceCollisionList(const Vector3D &velocity);
};
//##########################################################################
//####################### BoxedSolidResource #########################
//##########################################################################
struct BoxedSolidResource
{
size_t recordLength;
ExtentBox
solidExtents,
sliceExtents;
BoxedSolid::Type solidType;
BoxedSolid::Material materialType;
void
Instance(
const BoxedSolidResource &source,
const Origin& origin
);
static ResourceDescription::ResourceID
CreateBoxedSolidStream(
const char *entry_data,
ResourceFile *file,
const ResourceDirectories *resource_directories,
Logical convert_boxes = False
);
};
//##########################################################################
//########################### BoxedSphere ############################
//##########################################################################
class BoxedSphere:
public BoxedSolid
{
public:
BoxedSphere(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedSphere();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//############################ BoxedCone #############################
//##########################################################################
class BoxedCone:
public BoxedSolid
{
public:
BoxedCone(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedCone();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//####################### BoxedReducibleBlock ########################
//##########################################################################
class BoxedReducibleBlock:
public BoxedSolid
{
public:
BoxedReducibleBlock(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedReducibleBlock();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//###################### BoxedRampFacingNegativeZ ####################
//##########################################################################
class BoxedRampFacingNegativeZ:
public BoxedSolid
{
public:
BoxedRampFacingNegativeZ(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedRampFacingNegativeZ();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//#################### BoxedRampFacingPositiveX ######################
//##########################################################################
class BoxedRampFacingPositiveX:
public BoxedSolid
{
public:
BoxedRampFacingPositiveX(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedRampFacingPositiveX();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//#################### BoxedRampFacingPositiveZ ######################
//##########################################################################
class BoxedRampFacingPositiveZ:
public BoxedSolid
{
public:
BoxedRampFacingPositiveZ(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedRampFacingPositiveZ();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//#################### BoxedRampFacingNegativeX ######################
//##########################################################################
class BoxedRampFacingNegativeX:
public BoxedSolid
{
public:
BoxedRampFacingNegativeX(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedRampFacingNegativeX();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//################## BoxedInvertedRampFacingNegativeZ ################
//##########################################################################
class BoxedInvertedRampFacingNegativeZ:
public BoxedSolid
{
public:
BoxedInvertedRampFacingNegativeZ(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedInvertedRampFacingNegativeZ();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//################## BoxedInvertedRampFacingNegativeX ################
//##########################################################################
class BoxedInvertedRampFacingNegativeX:
public BoxedSolid
{
public:
BoxedInvertedRampFacingNegativeX(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedInvertedRampFacingNegativeX();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//################## BoxedInvertedRampFacingPositiveZ ################
//##########################################################################
class BoxedInvertedRampFacingPositiveZ:
public BoxedSolid
{
public:
BoxedInvertedRampFacingPositiveZ(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedInvertedRampFacingPositiveZ();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//################## BoxedInvertedRampFacingPositiveX ################
//##########################################################################
class BoxedInvertedRampFacingPositiveX:
public BoxedSolid
{
public:
BoxedInvertedRampFacingPositiveX(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedInvertedRampFacingPositiveX();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//############## BoxedWedgeFacingNegativeZAndPositiveX ###############
//##########################################################################
class BoxedWedgeFacingNegativeZAndPositiveX:
public BoxedSolid
{
public:
BoxedWedgeFacingNegativeZAndPositiveX(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedWedgeFacingNegativeZAndPositiveX();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//############## BoxedWedgeFacingPositiveZAndPositiveX ###############
//##########################################################################
class BoxedWedgeFacingPositiveZAndPositiveX:
public BoxedSolid
{
public:
BoxedWedgeFacingPositiveZAndPositiveX(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedWedgeFacingPositiveZAndPositiveX();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//############## BoxedWedgeFacingPositiveZAndNegativeX ###############
//##########################################################################
class BoxedWedgeFacingPositiveZAndNegativeX:
public BoxedSolid
{
public:
BoxedWedgeFacingPositiveZAndNegativeX(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedWedgeFacingPositiveZAndNegativeX();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//############## BoxedWedgeFacingNegativeZAndNegativeX ###############
//##########################################################################
class BoxedWedgeFacingNegativeZAndNegativeX:
public BoxedSolid
{
public:
BoxedWedgeFacingNegativeZAndNegativeX(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedWedgeFacingNegativeZAndNegativeX();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//####################### BoxedXAxisCylinder #########################
//##########################################################################
class BoxedXAxisCylinder:
public BoxedSolid
{
public:
BoxedXAxisCylinder(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedXAxisCylinder();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//####################### BoxedYAxisCylinder #########################
//##########################################################################
class BoxedYAxisCylinder:
public BoxedSolid
{
public:
BoxedYAxisCylinder(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedYAxisCylinder();
Logical
VerifyCollision(BoxedSolidCollision &collision);
Logical
ProcessCollision(
BoxedSolidCollision &collision,
const Vector3D &velocity,
BoxedSolidCollisionList *last_collisions,
Normal *normal,
Scalar *penetration
);
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//####################### BoxedZAxisCylinder #########################
//##########################################################################
class BoxedZAxisCylinder:
public BoxedSolid
{
public:
BoxedZAxisCylinder(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid
);
~BoxedZAxisCylinder();
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//##################### RightHandedTile #######################
//##########################################################################
class RightHandedTile:
public BoxedSolid
{
public:
RightHandedTile(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid,
Scalar *cornerHeights,
Type type=RightHandedTileType
);
~RightHandedTile();
Scalar
cornerHeight[4];
Logical
IntersectsBounded(const ExtentBox &extents);
Logical
ContainsBounded(const Point3D &point);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//######################## LeftHandedTile #########################
//##########################################################################
class LeftHandedTile:
public RightHandedTile
{
public:
LeftHandedTile(
const ExtentBox &extents,
Material material,
Simulation *owner,
BoxedSolid *next_solid,
Scalar *cornerHeights
);
~LeftHandedTile();
Logical
IntersectsBounded(const ExtentBox &extents);
Scalar
FindDistanceBelowBounded(const Point3D &point);
Logical
HitByBounded(
Line *line,
Scalar enters,
Scalar leaves
);
Logical
TestInstance() const;
};
//##########################################################################
//####################### TerrainTileResource ########################
//##########################################################################
struct TileResource:
public BoxedSolidResource
{
Scalar
cornerHeight[4];
void
Instance(
const TileResource &source,
const Origin& origin
);
};
//##########################################################################
//######################## BoxedSolidTree ############################
//##########################################################################
class BoxedSolidTree:
public BoundingBoxTree
{
//##########################################################################
// Construction and Destruction
//
public:
BoxedSolidTree()
{}
~BoxedSolidTree()
{}
//##########################################################################
// Tree Traversal Functions
//
public:
BoxedSolid*
FindBoundingBoxContaining(const Point3D &point)
{
return
(BoxedSolid*)
BoundingBoxTree::FindBoundingBoxContaining(point);
}
BoxedSolid*
FindBoundingBoxUnder(
const Point3D &point,
Scalar *height
)
{
return
(BoxedSolid*)
BoundingBoxTree::FindBoundingBoxUnder(point, height);
}
BoxedSolid*
FindBoundingBoxHitBy(Line *line)
{return (BoxedSolid*)BoundingBoxTree::FindBoundingBoxHitBy(line);}
};
//##########################################################################
//######################## BoxedSolidList ############################
//##########################################################################
class BoxedSolidList:
public BoundingBoxList
{
//##########################################################################
// Construction and Destruction
//
public:
BoxedSolidList() {}
~BoxedSolidList() {}
//##########################################################################
// Tree Traversal Functions
//
public:
int
AddBoxedSolids(NotationFile *notation_file);
BoxedSolid*
FindBoundingBoxContaining(const Point3D &point)
{
return
(BoxedSolid*)
BoundingBoxList::FindBoundingBoxContaining(point);
}
BoxedSolid*
FindBoundingBoxUnder(
const Point3D &point,
Scalar *height
)
{
return
(BoxedSolid*)
BoundingBoxList::FindBoundingBoxUnder(point, height);
}
BoxedSolid*
FindBoundingBoxHitBy(Line *line)
{return (BoxedSolid*)BoundingBoxList::FindBoundingBoxHitBy(line);}
void
Reduce();
};