//===========================================================================// // 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 # 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 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