Files
BT411/game/reconstructed/mechtech.hpp
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

263 lines
9.4 KiB
C++

//===========================================================================//
// File: mechtech.hpp //
// Project: BattleTech Brick: Entity Manager //
// Contents: MechTech -- the mech's subsystem-monitor / diagnostics //
// ("technician") subsystem. Watches every damageable MechSubsystem//
// on the mech and drives the cockpit status / MFD readouts. //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. All Rights reserved //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
//
// GROUND TRUTH. This header reproduces the surviving source header
// 410SRC/Telsa40/Rel410/CODE/BT/BT/MECHTECH.HPP
// verbatim (it is authoritative for the public interface). The only
// additions are the "@0x.." byte-offset annotations and the provenance
// notes below, recovered by cross-referencing the shipped binary. See
// mechtech.cpp for the per-method @ADDR evidence.
//
// Binary identity (corrects the placeholder labels emitted by mech.cpp):
// MechTech ClassID 0xBDC (NOT 0xBD6)
// ctor @004ad228 (mech.cpp called this
// "HeatableSubsystem")
// dtor @004ad1b8
// vtable @0050e3a0 (12 slots; only the dtor is
// overridden, the rest inherit
// Subsystem's MUNGA base @0x41xxxx)
// DefaultData (SharedData) @0050e270
// ClassDerivations (Derivation) @0050e280
// instance size 0x104
//
// NOTE: mech.cpp's switch labelled 0xBD6 / @004b7f94 "MechTech"; that
// class is actually the HUD torso-horizon gimbal display (parses
// "FlickerRate"/"HorizontalMovementPerSecond"/"HorizontalLimit",
// vtable @00511510) and is unrelated to MechTech.
//
// "MechTech::SubsystemMonitors" and "AlarmModel" survive as literals at
// @0050e2f3 / @0050e322 in the binary's .rdata.
//
#if !defined(MECHTECH_HPP)
# define MECHTECH_HPP
# if !defined(MECHSUB_HPP)
# include <mechsub.hpp>
# endif
//##########################################################################
//###################### MechTech::StatusInfo ########################
//##########################################################################
//
// One per (subsystem, TechStatusType) cell. 16 bytes (0x10); the
// SubsystemMonitor ctor (@004ad124) zero-inits all four words of each
// entry and the per-frame monitor (@004ad33c) reads/writes them.
//
struct MechTech__StatusInfo SIGNATURED
{
public:
int
currentStatus, // +0x00 last reported status bit for this cell
wooHooed; // +0x04 a "woo hoo!" alert is currently latched
Time
startTime, // +0x08 when the alert began
wooHooEnd; // +0x0C when the latched alert expires
};
//##########################################################################
//###############3### MechTech::SubsystemMonitor #####################
//##########################################################################
//
// One monitor per watched MechSubsystem. Layout (@004ad124):
// Plug base +0x00 (0x0C bytes)
// StatusInfo statusArray[7] +0x0C .. +0x7B
// MechSubsystem* monitoredSubsystem +0x7C
// => sizeof(SubsystemMonitor) == 0x80
// Allocated from the static MemoryBlock at @0050e248.
//
struct MechTech__SubsystemMonitor:
public Plug
{
friend class MechTech;
//##########################################################################
// Memory Allocation Support
//
private:
static MemoryBlock AllocatedMemory; // @0050e248
void*
operator new(size_t)
{return AllocatedMemory.New();} // FUN_00402f74(0x50e248)
void
operator delete(void *where)
{AllocatedMemory.Delete(where);} // FUN_00402f98(0x50e248)
public:
MechTech__StatusInfo statusArray[MechSubsystem::TechStatusTypeCount]; // +0x0C (TechStatusTypeCount == 7)
MechSubsystem *monitoredSubsystem; // +0x7C
MechTech__SubsystemMonitor(MechSubsystem *subsystem); // @004ad124
~MechTech__SubsystemMonitor(); // @004ad180
};
//##########################################################################
//##################### MechTech::ModelResource ######################
//##########################################################################
//
// Streamed resource record (sizeof == 0x40, classID 0xBDC), parsed by
// CreateStreamedSubsystem @004ad48c. Only "AlarmModel" is read from the
// notation file; the three wooHoo scalars default to 0.
//
struct MechTech__SubsystemResource:
public Subsystem::SubsystemResource
{
ResourceDescription::ResourceID
alarmModel; // +0x30 "AlarmModel" (resolved .mod id, -1 = none)
Scalar
wooHooMinimumDuration, // +0x34
wooHooDurationRange, // +0x38
wooHooChance; // +0x3C
};
//##########################################################################
//############################ MechTech ##############################
//##########################################################################
class MechTech:
public Subsystem
{
//##########################################################################
// Shared Data Support
//
public:
static Derivation ClassDerivations; // @0050e280
static SharedData DefaultData; // @0050e270
static Receiver::MessageHandlerSet MessageHandlers;
static AttributeIndexSet AttributeIndex;
//##########################################################################
// BT segment / status-sink compatibility shims.
//
// CROSS-FAMILY: the per-segment "copy/template" + "damageable" flags and the
// cockpit status-message sink logically belong on the shared Mech / Subsystem
// bases and the HUD message brick. Until they are exposed, they are backed
// locally here so this module compiles. See report "CROSS-FAMILY NEEDS".
//
#if !defined(BT_SEGMENT_FLAG_CONSTS)
# define BT_SEGMENT_FLAG_CONSTS
enum {
SegmentCopyMask = 0x0C, // (flags & 0xC): 0 == primary, 4 == damaged copy
SegmentLiveFlag = 0x01,
MasterHeatSinkFlag = 0x0100
};
#endif
enum {
SegmentDamageableFlag = 0x08, // segment bit 0x8 == damageable
DormantInstanceFlag = 0x02 // this[10] |= 2 -- copy/template instance
};
public:
Word
GetSegmentFlags() const { return segmentFlags; }
protected:
Word segmentFlags; // @this[0x28] segment flags (Mech-supplied)
//##########################################################################
// Attribute Support
//
public:
typedef MechTech__StatusInfo StatusInfo;
typedef MechTech__SubsystemMonitor SubsystemMonitor;
typedef MechTech__SubsystemResource SubsystemResource;
//##########################################################################
// Construction and Destruction Support
//
public:
~MechTech(); // @004ad1b8
static Logical
CreateStreamedSubsystem( // @004ad48c
NotationFile *model_file,
const char* model_name,
const char* subsystem_name,
SubsystemResource *subsystem_resource,
NotationFile *subsystem_file,
const ResourceDirectories *directories,
ResourceFile *resource_file
);
MechTech( // @004ad228
Mech *entity,
int subsystem_id,
SubsystemResource *model,
SharedData &shared_data = DefaultData
);
Logical
TestInstance() const; // @004ad470 (IsDerivedFrom ClassDerivations)
//##########################################################################
// Model support
//
public:
typedef void
(MechTech::*Performance)(Scalar time_slice);
void
SetPerformance(Performance performance)
{
Check(this);
activePerformance = (Simulation::Performance)performance;
}
ChainOf<SubsystemMonitor*> subsystemMonitors; // @0xE4 (this[0x39])
Scalar
wooHooMinimumDuration, // @0xF4 (this[0x3D]) <- resource +0x34
wooHooDurationRange, // @0xF8 (this[0x3E]) <- resource +0x38
wooHooChance; // @0xFC (this[0x3F]) <- resource +0x3C
ResourceDescription::ResourceID
alarmModel; // @0x100 (this[0x40]) <- resource +0x30
void
TechnicalAssistance(Scalar time_slice); // @004ad33c (the Performance)
Mech*
GetEntity()
{return (Mech*)Subsystem::GetEntity();}
//##########################################################################
// Status reporting support.
//
// CROSS-FAMILY: in the shipped binary these route through the running
// Application/World status sink (DAT_004efc94 + 0x38) and the HUD message
// builders (FUN_004366b8 / FUN_00436688 / FUN_004364e4), which live in the
// (not-yet-reconstructed) cockpit-message brick. Declared here with stub
// bodies so MechTech compiles; see report "CROSS-FAMILY NEEDS".
//
public:
Time
GetTime() const; // engine current time (Now())
protected:
void*
StatusMessageSink(); // *(DAT_004efc94 + 0x38)
void
ReportStatusCleared( // FUN_004366b8 + FUN_004364e4
void *sink,
Mech *owner,
MechSubsystem *sub,
int type
);
void
ReportStatusSet( // FUN_00436688 + FUN_004364e4
void *sink,
Mech *owner,
MechSubsystem *sub,
int type,
ResourceDescription::ResourceID alarm_model
);
};
#endif