//===========================================================================// // File: btl4gau2.hpp // // Project: BattleTech Brick: Gauge Renderer Manager // // Contents: Cockpit instrument library, part 2 -- the COMPOSITE "panel" // // gauges that the BattleTech engineering / weapon-status HUD is // // assembled from. Where btl4gaug.cpp holds the primitive widgets // // (bars, dials, lamps, colour-mappers), btl4gau2.cpp holds the // // higher-level gauges that AGGREGATE those primitives into a single // // subsystem read-out: // // * SeekVoltageGraph -- energy-weapon seek-voltage curve // // * ConfigMapGauge -- joystick / config-manager state lamp // // * GeneratorCluster -- generator voltage + coolant + leak panel // // * PrepEngrScreen -- per-weapon engineering screen builder // // * SubsystemCluster +-> HeatSinkCluster // // +-> MyomerCluster // // +-> WeaponCluster +-> EnergyWeaponCluster // // +-> BallisticWeaponClu.// //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 02/22/96 CPB Initial coding. // //---------------------------------------------------------------------------// // Copyright (C) 1996, Virtual World Entertainment, Inc. All rights reserved // // PROPRIETARY AND CONFIDENTIAL // //===========================================================================// // // STAGED RECONSTRUCTION. No BTL4GAU2.HPP survived; recovered from the shipped // binary (BTL4OPT.EXE) and re-hosted onto the authentic 1995 engine headers // (MUNGA GAUGE/GAUGREND + MUNGA_L4 L4GAUGE) for the BC++4.52 build. // // Translation-unit extent (BTL4.MAK link order: // btl4mode -> btl4rdr -> btl4gaug -> btl4gau2 -> btl4gau3 -> btl4grnd -> ...): // first gau2 code @004c6798 (SeekVoltageGraph::SeekVoltageGraph) // last gau2 code @004c9b50 (BallisticWeaponCluster helpers) // plus VehicleSubSystems::Make @004cbaf0 // // Class names recovered from the CODE name-string pool around 0x519760 // (the gauge name list) and the per-instance identification strings: // "GeneratorCluster" 0x519a8c "PrepEngr" 0x519a9d // "ConfigMap" 0x519a38 "CoolingLoop" 0x519a42 "PowerSource" 0x519a4e // "GeneratorVoltage(scalar)" 0x519a73 "GeneratorVoltage(slotOf)" 0x519a5a // "EngrGraph" 0x519a2e "WeaponCluster ... " 0x519dcb // Field offsets in comments are the BINARY's byte offsets (e.g. "@0x90" == // this[0x24]); the recompiled objects are NOT byte-locked to them. // // Names flagged "(best-effort)" exist in the binary but their identification // string could not be tied to them unambiguously. // #if !defined(BTL4GAU2_HPP) # define BTL4GAU2_HPP # if !defined(SLOT_HPP) # include # endif # if !defined(L4GREND_HPP) # include # endif # if !defined(L4GAUGE_HPP) # include # endif # if !defined(BTL4GAUG_HPP) # include # endif # if !defined(HEAT_HPP) # include # endif // (see btl4gaug.hpp -- intentionally not pulled in; the // composite gauges reference subsystems by pointer/attribute, not by type.) // // Reconstruction type: the original referenced an "AttributeAccessor" handle // (a small object that samples one named subsystem attribute). Only its // address is used here (it is immediately reinterpreted as a Scalar*), so an // opaque forward declaration is sufficient for this translation unit. // class AttributeAccessor; //####################################################################### // SeekVoltageGraph -- the energy-weapon / myomer "seek voltage" response // graph on the engineering detail pages (the "POWER" box). // @004c6798 ctor / @004c68ac dtor / @004c6920 BecameActive / @004c6934 Execute. // vtable PTR_FUN_0051a1fc. Resolves the four SeekVoltage attribute // POINTERS off the weapon subsystem by NAME ("CurrentSeekVoltageIndex" / // "MinSeekVoltageIndex" / "MaxSeekVoltageIndex" / "SeekVoltage") and plots // the subsystem's voltage-response curve (binary vtbl slot 15 sampler: // Emitter @004bb42c / Myomers @004b8f94) over the top data box // (0x97,0x80)-(0x17d,0x13b): x = response(v)*230 (0..1 normalised sqrt // response), y = v/12000*187 (voltage axis), with per-gear tick marks (the // current gear drawn as a full L) and, when draw_cursor, a live 8x8 XOR // cursor at the subsystem's live voltage. When the subsystem is destroyed // (simulationState == 1) it shows a centred "destroyed" bitmap instead. // Its Execute's full-box CLEAR (@004c6be4) is what erases the sibling eng // pages' stale pixels on the shared Eng bit-plane -- the widget IS the // top-box eraser (Gitea #10 finding A). //####################################################################### class SeekVoltageGraph : public GraphicGauge { public: SeekVoltageGraph( // @004c6798 GaugeRate rate, ModeMask mode_mask, L4GaugeRenderer *renderer, int graphics_port_number, Entity *subsystem, AttributeAccessor *seek_voltage_pointer, const char *destroyed_image, Logical draw_cursor, const char *identification_string); ~SeekVoltageGraph(); // @004c68ac Logical TestInstance() const; void BecameActive(); // @004c6920 void Execute(); // @004c6934 protected: void ClearGraph(); // @004c6be4 (full-box erase) void DrawTicks(); // @004c6c6c (per-gear ticks, XOR) void DrawCursorBox(); // @004c6c30 (8x8 cursor, XOR) char *destroyedImage; // @0x90 this[0x24] int *currentSeekIndexPtr; // @0x94 this[0x25] attr ptr (or NULL) int *minSeekIndexPtr; // @0x98 this[0x26] attr ptr (or NULL) int *maxSeekIndexPtr; // @0x9C this[0x27] attr ptr (or NULL) Scalar *seekVoltageTablePtr; // @0xA0 this[0x28] attr ptr (array base) Scalar *liveVoltage; // @0xA4 this[0x29] the ctor's // seek_voltage_pointer ("OutputVoltage" // attr ptr / cluster seekValue cache) -- // Execute derefs it for the live cursor // (never NULL: ctor normalises a miss to // the file-scope unbound cell) Subsystem *subsystem; // @0xA8 this[0x2A] Scalar previousVoltage; // @0xAC this[0x2B] cached response at // 12000 V (9999 sentinel = force replot) Scalar xScale; // @0xB0 this[0x2C] =230.0f Scalar yScale; // @0xB4 this[0x2D] =187.0f int destroyedShown; // @0xB8 this[0x2E] Logical drawCursor; // @0xBC this[0x2F] int cursorX; // @0xC0 this[0x30] (-1 = no cursor drawn) int cursorY; // @0xC4 this[0x31] int tickIndexShown; // @0xC8 this[0x32] gear index the tick // highlight was last drawn at }; //####################################################################### // ConfigMapGauge -- the joystick / config-manager (control-mapper) state // lamp. @004c6d80 ctor / @004c6e54 dtor / @004c6ee0 LinkToEntity / // @004c6ef4 BecameActive / @004c6f1c Execute. vtable PTR_FUN_0051a1b8. // Owns a base joystick bitmap ("btjoy.pcc") plus four config-state pixmaps // (cm_off/cm_other/cm_only/cm_both .pcc) selected from a 4-entry table // (DAT_00518eb8) driven by the control-mapper state. Named "ConfigMap". //####################################################################### class ConfigMapGauge : public GraphicGauge { public: ConfigMapGauge( // @004c6d80 GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number, int x, int y, Entity *subsystem, const char *identification_string); ~ConfigMapGauge(); // @004c6e54 Logical TestInstance() const; // @004c6ee0 -- the GaugeBase::LinkToEntity OVERRIDE (vtbl slot 9, +0x24), // NOT a "SetColor": it stores the viewpoint entity into @0x94 and Execute // gates on it. GaugeRenderer::LinkToEntity (GAUGREND.CPP:3011) broadcasts // it to every gauge when the viewpoint binds -- THAT is what lights the // trigger-config joystick in the shipped game. (The old "SetColor, no // callers -> authentically dormant" claim was a mislabel.) void LinkToEntity(Entity *entity); // @004c6ee0 writes this[0x25] void BecameActive(); // @004c6ef4 void Execute(); // @004c6f1c protected: Entity *subsystem; // @0x90 this[0x24] (a Subsystem, stored // as the ctor's Entity* -- cast back // through Subsystem* before use) Entity *linkedEntity; // @0x94 this[0x25] (Execute gate) char *joystickImage; // @0x98 this[0x26] "btjoy.pcc" char *stateImage[4]; // @0x9C this[0x27..0x2A] int previousState[4]; // @0xAC this[0x2B..0x2E] Logical dirty; // @0xBC this[0x2F] }; //####################################################################### // Two small OneOfSeveral subclasses that drive the selected frame from a // subsystem value through a file-private GaugeConnection. // AnimatedSubsystemLamp @004c70a4 (vtable 0051a174) -- connection @004c3134 // AnimatedSourceLamp @004c7160 (vtable 0051a130) -- connection @004c31ec // Both chain OneOfSeveral::OneOfSeveral (@004c4d88, fromImageStrip=1) and // share dtor FUN_004c4e7c. Used for the cooling-loop / power-source lamps. // (Class names best-effort; the gauge is generic and reused with the // instance strings "CoolingLoop" and "PowerSource".) // // SHADOW-FIELD FIX (kept on re-host): 'selected' is INHERITED from // OneOfSeveral (@0xAC). A redeclared 'int selected;' here shadowed the // base at a higher offset -- the connection wrote the shadow while // OneOfSeveral::Execute read the base (always 0), freezing the lamp at // frame 0. Neither class declares its own copy. //####################################################################### class AnimatedSubsystemLamp : // (best-effort) public OneOfSeveral { public: AnimatedSubsystemLamp( // @004c70a4 GaugeRate, ModeMask, L4GaugeRenderer *, int, int x, int y, const char *image, int columns, int rows, void *subsystem, const char *identification_string); ~AnimatedSubsystemLamp(); // @004c7134 }; class AnimatedSourceLamp : // (best-effort) public OneOfSeveral { public: AnimatedSourceLamp( // @004c7160 GaugeRate, ModeMask, L4GaugeRenderer *, int, int x, int y, const char *image, int columns, int rows, void *source, const char *identification_string); ~AnimatedSourceLamp(); // @004c71f0 }; //####################################################################### // ScalarBarGauge -- a generator-voltage bar (derives from the engine // BarGraphBitMapScalar, L4GAUGE.HPP -- WipeGaugeScalar : GraphicGauge). // Two ctors, one vtable (0051a0e4), shared dtor @004c733c: // @004c721c "slotOf" variant -- AddConnection(GeneratorVoltageConnection // @004c3288) feeding the inherited currentValue from the // subsystem's resolved voltage source. // @004c72ac plain-Scalar variant -- a GaugeConnectionDirectOf // (engine template) from a DIRECT Scalar*. // Used with "GeneratorVoltage(slotOf)" / "GeneratorVoltage(scalar)". // // Its value slot @0xB4 (this[0x2D]) IS the inherited // WipeGaugeScalar::currentValue -- the connection writes it, so NO own // field is declared (declaring one would shadow / mis-align). // // BC++4.52 NOTE: the void* / Scalar* 15th-argument overload pair is // ambiguous for a literal 0/NULL argument -- every call site must pass a // TYPED pointer. //####################################################################### class ScalarBarGauge : public BarGraphBitMapScalar { public: ScalarBarGauge( // @004c721c (slotOf variant) GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number, int left, int bottom, int right, int top, const char *tile_image, int foreground_color, int background_color, WipeGaugeScalar::Direction direction, Scalar min, Scalar max, void *voltage_source, const char *identification_string); ScalarBarGauge( // @004c72ac (plain-Scalar variant) GaugeRate, ModeMask, L4GaugeRenderer *, int graphics_port_number, int left, int bottom, int right, int top, const char *tile_image, int foreground_color, int background_color, WipeGaugeScalar::Direction direction, Scalar min, Scalar max, Scalar *value_source, const char *identification_string); ~ScalarBarGauge(); // @004c733c }; //####################################################################### // GeneratorCluster -- the generator read-out panel (config keyword // "GeneratorCluster": engineering buttons 9-12, GeneratorA..D). // @004c7368 Make / @004c746c ctor / @004c7778 dtor. vtable PTR_FUN_0051a0a0. // A GraphicGauge that owns five child gauges, parented to its own port: // VertTwoPartBar (temperature) this[0x26] // ScalarBarGauge (voltage 0..12kV) this[0x27] // BitMapInverseWipe/Leak (coolant leak) this[0x28] // TwoState x2 (status lamps) this[0x29],this[0x2A] // Make resolves the named generator via FindSubsystem; warns // "Subsystem not found". //####################################################################### class GeneratorCluster : public GraphicGauge { public: // Registered config primitive "GeneratorCluster" (15 params; NO leading // rate token -- the panel rate is hard-wired 0xFFFF). static MethodDescription methodDescription; static Logical Make(int, Vector2DOf, Entity *, GaugeRenderer *); // @004c7368 GeneratorCluster( // @004c746c (BINARY param order) ModeMask, L4GaugeRenderer *, int owner_ID, int graphics_port_number, int x, int y, Subsystem *subsystem, const char *background_image, int extra_color, const char *temp_tile, int temp_bg_color, int temp_fill_color, const char *voltage_tile, int voltage_fg_color, const char *leak_image, int leak_color_b, const char *lampA_image, const char *lampB_image, int lamp_on_color, int lamp_off_color, const char *identification_string); ~GeneratorCluster(); // @004c7778 // A container panel MUST override BecameActive + Execute: the engine // base Gauge::Execute is Fail("not overridden") (GAUGE.CPP:598), and // the default BecameActive self-inactivates. The panel draws its // static background pixmap; the 5 self-registered child gauges draw // the dynamic content. void BecameActive(); void Execute(); protected: char *backgroundImage; // @0x90 this[0x24] interned .pcc (AddRef'd) int secondaryColor; // @0x94 this[0x25] = leak colorB (stored, unread) GraphicGauge *temperatureBar, // @0x98 this[0x26] VertTwoPartBar *voltageBar, // @0x9C this[0x27] ScalarBarGauge (@004c72ac variant) *leakGauge, // @0xA0 this[0x28] BitMapInverseWipe *lampA, // @0xA4 this[0x29] TwoState *lampB; // @0xA8 this[0x2A] TwoState Subsystem *subsystem; // @0xAC this[0x2B] int _reserved0xB0; // @0xB0 this[0x2C] (trailing pad -> binary sizeof 0xB4) }; //####################################################################### // PrepEngrScreen (config keyword "prepEngr") -- the per-engineering-screen // STATIC LABEL overlay. @004c7b30 Make / @004c7bf0 ctor / @004c7d14 dtor / // @004c7e48 BecameActive. vtable PTR_FUN_0051a06c. // // A GraphicGaugeBackground (paint-on-activation, NOT an Execute gauge -- // the same base/vtable shape as the engine's BackgroundBitmap: only the // dtor + BecameActive slots are overridden). Interns 7 status .pcc's // (font + 6 labels) and, when its MFD-Eng screen (1..12) activates, paints // the labels for the ONE subsystem whose aux screen == this screen, // dispatched by the subsystem's ClassID. // (FIX kept from the decode: mech/screenNumber were SWAPPED in the first // reconstruction, and the missing methodDescription parse-skipped all 12 // CFG lines.) //####################################################################### class PrepEngrScreen : public GraphicGaugeBackground { public: static MethodDescription methodDescription; // "prepEngr" static Logical Make(int, Vector2DOf, Entity *, GaugeRenderer *); // @004c7b30 PrepEngrScreen( // @004c7bf0 ModeMask, L4GaugeRenderer *, unsigned int owner_ID, int graphics_port_number, Entity *mech, int screen_number, const char *img0/*font*/, const char *img1, const char *img2, const char *img3, const char *img4, const char *img5, const char *img6, const char *identification_string = "PrepEngr"); ~PrepEngrScreen(); // @004c7d14 void BecameActive(); // @004c7e48 (the paint slot -- NOT Execute) protected: int screenNumber; // @0x6C this[0x1B] Entity *mech; // @0x70 this[0x1C] char *statusImage[7]; // @0x74 this[0x1D..0x23] (interned .pcc names) // binary sizeof == 0x90 (Make alloc); no offset locks (every read is // via named members). }; //####################################################################### // SubsystemCluster family -- the big composite panels. Each is a // GraphicGauge that builds a dozen child gauges into one cockpit instrument. // // SubsystemCluster @004c8140 (vtable 0051a020) -- base "engineering" // panel: HorizTwoPartBar + cooling/power loops + generator voltage + // OneOfSeveralInt + OneOfSeveralStates + 2x VertTwoPartBar + LeakGauge // + BackgroundBitmap. Uses the btXXloop / btXbus / evolt / btecmode / // eleak art. // // HeatSinkCluster @004c8a6c (vtable 00519fd4) : SubsystemCluster // adds 4 failure-annunciator TwoStates (btehfail/btepfail/btesfail) // and a NumericDisplayScalar. Execute @004c8db0 scales heatLoad by // 100 (_DAT_004c8df0) into the numeric read-out. // // MyomerCluster @004c8df4 (vtable 00519f88) : SubsystemCluster // adds a SeekVoltageGraph ("EngrGraph") + seek-step OneOfSeveralInt. // // WeaponCluster @004c8fc4 (vtable 00519f38) : SubsystemCluster // adds a SegmentArc270 (recharge dial, 0..360) + a ConfigMapGauge. // Reads "PercentDone". Execute @004c9290 toggles the warning lamp // past _DAT_004c92e0 (0.99). // // EnergyWeaponCluster @004c93b0 (vtable 00519ee8) : WeaponCluster // adds a SeekVoltageGraph ("EngrGraph", edestryd.pcc) and a // seek-step OneOfSeveralInt (bteseek.pcc). // BallisticWeaponCluster @004c9558 (vtable 00519e98) : WeaponCluster // adds 2x NumericDisplayInteger (ammo), jam/fire TwoStates // (btejam/btefire), NumericDisplayScalarTwoState, an eject // BitMapInverseWipeScalar (bteejtm), plus a GraphicsViewRecord // erase tracker (this[0x3F]). //####################################################################### class SubsystemCluster : public GraphicGauge { public: // @004c8140. Binary param order (rate/mode are hardcoded 0xFFFF / // ModeAlwaysActive in the base GraphicGauge ctor; the panel's two // bit-plane MODE masks are mfd_mode (MFD-port children) and eng_mode // (engineering-port children)). SubsystemCluster( // @004c8140 ModeMask mfd_mode, L4GaugeRenderer *renderer, int owner_ID, int mfd_port, int x, int y, Subsystem *subsystem, ModeMask eng_mode, const char *eng_port_name, const char *tile_image, const char *label, char **image_names, const char *identification_string); ~SubsystemCluster(); // @004c87dc Logical TestInstance() const; void BecameActive(); // (re-host addition: forces the first repaint) void Execute(); // @004c88e4 protected: BackgroundBitmap *background; BackgroundBitmap *titleBanner; // the authored 299x26 panel title // @0x90 this[0x24] BackgroundBitmap GraphicGauge *generatorVoltageBar, // @0x94 this[0x25] ScalarBarGauge (evolt) *temperatureBar, // @0x98 this[0x26] HorizTwoPartBar *coolingLoopA, // @0x9C this[0x27] AnimatedSubsystemLamp *coolingLoopB, // @0xA0 this[0x28] *powerSourceA, // @0xA4 this[0x29] AnimatedSourceLamp *powerSourceB, // @0xA8 this[0x2A] *vertBarA, // @0xAC this[0x2B] VertTwoPartBar *vertBarB, // @0xB0 this[0x2C] *modeLamp, // @0xB4 this[0x2D] OneOfSeveralInt *stateLamp, // @0xB8 this[0x2E] OneOfSeveralStates *leakGauge; // @0xBC this[0x2F] LeakGauge Subsystem *subsystem; // @0xC0 this[0x30] // POLARITY CORRECTED (PPC-dial fix, kept on re-host): the binary's // *(subsystem+0x40)==1 means the subsystem FAILED -- it lights the // destroyed-X TwoStates (the engine TwoState draws bright on NONZERO) // and selects the dead-panel look (GetDrawState 1 = black fill). The // old name `operating` had it backwards, inverting every consumer. Logical failedState; // @0xC4 this[0x31] 1 = subsystem destroyed int previousDrawState; // @0xC8 this[0x32] (Execute repaint key) // internal helpers (non-virtual) void DrawPanelFrame(int color); // @004c89c4 void ReleaseChildren(); // @004c8820 void SetChildrenEnable(int enable); // @004c8a28 public: int GetDrawState(); // @004c8990 (operational-state virtual, vtbl+0x48) }; class HeatSinkCluster : // @004c8a6c public SubsystemCluster { public: HeatSinkCluster( // @004c8a6c ModeMask mfd_mode, L4GaugeRenderer *, int owner_ID, int mfd_port, int x, int y, Subsystem *subsystem, Subsystem *hud, ModeMask eng_mode, const char *eng_port_name, const char *tile_image, const char *label, const char *fail_lamp_image, char **image_names, const char *identification_string); ~HeatSinkCluster(); // @004c8d18 void Execute(); // @004c8db0 protected: Subsystem *failSubsystem; // @0xCC this[0x33] Logical failFlag; // @0xD0 this[0x34] Scalar heatLoad; // @0xD4 this[0x35] (connection dst) Scalar heatLoadScaled; // @0xD8 this[0x36] GraphicGauge *heatFailLamp, // @0xDC this[0x37] TwoState *hsFailLamp, // @0xE0 this[0x38] TwoState (btehfail) *powerFailLamp, // @0xE4 this[0x39] TwoState (btepfail) *structFailLamp, // @0xE8 this[0x3A] TwoState (btesfail) *heatNumeric; // @0xEC this[0x3B] NumericDisplayScalar }; // // MyomerCluster @004c8df4 (vtable 00519f88) : SubsystemCluster -- the myomer // (muscle) panel. Adds a SeekVoltageGraph ("EngrGraph", edestryd.pcc) fed // by a GeneratorVoltageConnection (writes seekValue) + a seek-step // OneOfSeveralInt (bteseek.pcc). Execute = base. // class MyomerCluster : // @004c8df4 public SubsystemCluster { public: MyomerCluster( // @004c8df4 ModeMask mfd_mode, L4GaugeRenderer *, int owner_ID, int mfd_port, int x, int y, Subsystem *subsystem, ModeMask eng_mode, const char *eng_port_name, const char *tile_image, const char *label, char **image_names, const char *identification_string); ~MyomerCluster(); // @004c8f54 protected: Scalar seekValue; // @0xCC this[0x33] (connection dst) GraphicGauge *seekGraph, // @0xD0 this[0x34] SeekVoltageGraph *seekStepLamp; // @0xD4 this[0x35] OneOfSeveralInt }; class WeaponCluster : // @004c8fc4 public SubsystemCluster { public: WeaponCluster( // @004c8fc4 ModeMask mfd_mode, L4GaugeRenderer *, int owner_ID, int mfd_port, int x, int y, Subsystem *subsystem, ModeMask eng_mode, const char *eng_port_name, const char *tile_image, const char *label, const char *cluster_image, char **image_names, const char *identification_string); ~WeaponCluster(); // @004c91d4 void BecameActive(); // @004c9258 void Execute(); // @004c9290 virtual void DrawWarningLamp(int on); // @004c932c (virtual: BallisticWeaponCluster overrides) protected: char *clusterImage; // @0xCC this[0x33] (interned) GraphicGauge *rechargeArc; // @0xD0 this[0x34] SegmentArc270 ConfigMapGauge *configMap; // @0xD4 this[0x35] Scalar percentDone; // @0xD8 this[0x36] (connection dst) int warningCenterX; // @0xDC this[0x37] int warningCenterY; // @0xE0 this[0x38] int warningState; // @0xE4 this[0x39] }; class EnergyWeaponCluster : // @004c93b0 public WeaponCluster { public: EnergyWeaponCluster( // @004c93b0 ModeMask mfd_mode, L4GaugeRenderer *, int owner_ID, int mfd_port, int x, int y, Subsystem *subsystem, ModeMask eng_mode, const char *eng_port_name, const char *tile_image, const char *label, const char *cluster_image, char **image_names, const char *identification_string); ~EnergyWeaponCluster(); // @004c94dc protected: SeekVoltageGraph *seekGraph; // @0xE8 this[0x3A] GraphicGauge *seekStepLamp; // @0xEC this[0x3B] OneOfSeveralInt }; class BallisticWeaponCluster : // @004c9558 public WeaponCluster { public: BallisticWeaponCluster( // @004c9558 ModeMask mfd_mode, L4GaugeRenderer *, int owner_ID, int mfd_port, int x, int y, Subsystem *subsystem, ModeMask eng_mode, const char *eng_port_name, const char *tile_image, const char *label, const char *cluster_image, char **image_names, const char *font_a, const char *font_b, const char *identification_string); ~BallisticWeaponCluster(); // @004c9940 void BecameActive(); // @004c99cc void Execute(); // @004c9a38 void DrawWarningLamp(int on); // @004c9b50 (override: dot + ammo colour swap) Logical TestInstance() const; // @004c9adc protected: // // The live ammo cell the two round counters point at. The binary // pointed them at the resolved AmmoBin's count; the link is // protected, so Execute copies it here each frame -- the same // pattern this cluster already uses for jammed / reloadSeconds. // int ammoRounds; Logical jammed; // @0xE8 this[0x3A] Logical firing; // @0xEC this[0x3B] Logical reloading; // @0xF0 this[0x3C] int reloadStartTime; // @0xF4 this[0x3D] Scalar reloadSeconds; // @0xF8 this[0x3E] GraphicsViewRecord *ammoErase; // @0xFC this[0x3F] (bring-up NULL) GraphicGauge *ammoNumeric, // @0x100 this[0x40] NumericDisplayScalarTwoState *destroyedLamp, // @0x104 this[0x41] TwoState *jamLamp, // @0x108 this[0x42] TwoState (btejam) *fireLamp, // @0x10C this[0x43] TwoState (btefire) *ejectWipe, // @0x110 this[0x44] BitMapInverseWipeScalar (NULL) *ammoCountA, // @0x114 this[0x45] NumericDisplayInteger *ammoCountB; // @0x118 this[0x46] NumericDisplayInteger }; //####################################################################### // vehicleSubSystems -- the config primitive that builds the engineering- // screen (MFD) subsystem cluster panels. Make @004cbaf0 (methodDescription // @0x51c080, 8 typeString params = the 8 status strip bitmaps) is a per- // subsystem factory: it walks the mech roster (skipping slot 0), and for // each displayable subsystem builds the right cluster (HeatSink/Myomer/ // Energy/Ballistic) onto one of 12 auxiliary MFD positions. This holder // just carries the registered MethodDescription + the static Make // dispatcher (there is no instance). //####################################################################### class VehicleSubSystems { public: static MethodDescription methodDescription; static Logical Make( // @004cbaf0 int display_port_index, Vector2DOf position, Entity *entity, GaugeRenderer *gauge_renderer); }; #endif