Files
TeslaRel410/restoration/source410/BT/TORSO.HPP
T
CydandClaude Fable 5 4168f1ad4d BT410 5.3.47: the whole authored watcher set is published -- cockpit renders in the pod
Ladder rungs, each run-verified on the pod rig: ReportLeak (HeatSink),
GeneratorOn (Generator -- member existed, publication missing),
ConfigureActivePress (MechSubsystem -- likewise), AmmoState +
FireCountdownStarted + the rest of the AmmoBin table.

THE PINNED RANGE IS NOW THE AUTHENTIC SHAPE.  Publishing ReportLeak on
HeatSink and ConfigureActivePress on MechSubsystem shifts the chain down two,
and MechWeapon's bridge to its binary-pinned PercentDone (0x12) collapses
from THREE guessed pads to ONE -- which is exactly the arithmetic the shipped
string pool predicts (MechSubsystem 1, HeatableSubsystem 3, HeatSink 6,
PoweredSubsystem 5).  Three pads of guesswork replaced by a real attribute
and a real base-class row.  HeatableSubsystem and Torso rebase onto
MechSubsystem::AttributeIndex; MechControlsMapper does not (it derives from
Subsystem directly).

Types were chosen deliberately this time, per the AudioWatcher families the
engine instantiates (Motion / Hinge / Scalar / StateIndicator): every *State
name resolves to a StateIndicator, ReportLeak is a Scalar.

RESULT: the pod run now gets past every authored watcher and DRAWS THE FULL
COCKPIT -- sensor cluster, myomers, cooling, the weapon panels, kills/deaths
-- with the board booted and audio running.  It then exits without flushing
its redirected stdout, so the exit reason is not yet known; next step is a
run with the redirect removed so the console is readable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 08:09:56 -05:00

179 lines
5.9 KiB
C++

//===========================================================================//
// File: torso.hpp //
// Project: BattleTech Brick: Mech subsystems //
// Contents: Torso -- the torso twist / weapon-elevation subsystem //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#if !defined(TORSO_HPP)
# define TORSO_HPP
# if !defined(POWERSUB_HPP)
# include <powersub.hpp>
# endif
//##################### Forward Class Declarations #######################
class Mech;
class Joint;
//###########################################################################
//##################### Torso Model Resource ###########################
//###########################################################################
struct Torso__SubsystemResource:
public PowerWatcher::SubsystemResource
{
Scalar horizontalRotationPerSecond;
Scalar verticalRotationPerSecond;
Scalar horizontalLimitRight;
Scalar horizontalLimitLeft;
Scalar verticalLimitTop;
Scalar verticalLimitBottom;
char torsoHorizontalJoint[32];
char torsoHorizontalShadowJoint[32];
Logical torsoHorizontalEnabled;
Scalar buttonAccelerationPerSecond;
Scalar buttonAccelerationStartValue;
};
//###########################################################################
//############################### Torso ################################
//###########################################################################
//
// Drives torso twist (horizontal) and weapon elevation (vertical). The
// tuning rates/limits come from the resource; the live twist/elevation state
// and the resolved skeleton joints are advanced by the per-frame
// TorsoSimulation (staged) once the Mech skeleton link is live.
//
class Torso:
public PowerWatcher
{
public:
static Derivation ClassDerivations;
static SharedData DefaultData;
typedef void
(Torso::*Performance)(Scalar time_slice);
void
SetPerformance(Performance performance)
{
Check(this);
activePerformance = (Simulation::Performance)performance;
}
static Logical
TestClass(Mech &);
Logical
TestInstance() const;
Scalar
CurrentTwist() const { Check(this); return currentTwist; }
Scalar
CurrentElevation() const { Check(this); return currentElevation; }
Logical
GetHorizontalEnabled() const{ Check(this); return horizontalEnabled; }
//
// Analog aim inputs (written by MechControlsMapper::InterpretControls;
// consumed by TorsoSimulation to slew the twist/elevation each frame).
//
void
SetAnalogElevationAxis(Scalar axis) { Check(this); analogElevationAxis = axis; }
void
SetAnalogTwistAxis(Scalar axis) { Check(this); analogTwistAxis = axis; }
void
TorsoSimulation(Scalar time_slice);
void
TorsoCopySimulation(Scalar time_slice);
public:
typedef Torso__SubsystemResource SubsystemResource;
Torso(
Mech *owner,
int subsystem_ID,
SubsystemResource *subsystem_resource,
SharedData &shared_data = DefaultData
);
~Torso();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute publication. The shipped string pool lists this class's
// attribute names contiguously after the class name "Torso":
//
// RotationOfTorsoVertical RotationOfTorsoHorizontal
// HorizontalLimitRight HorizontalLimitLeft
// SpeedOfTorsoVertical SpeedOfTorsoHorizontal
//
// (the TorsoUp/Down/Left/Right/Center that follow are MESSAGES, not
// attributes). All six map onto members we already carry. An
// authored AttributeWatcher binds SpeedOfTorsoHorizontal.
//
// The chain -- PowerWatcher -> HeatWatcher -> MechSubsystem -- publishes
// nothing of its own, so these start at Subsystem::NextAttributeID.
//
public:
enum {
RotationOfTorsoVerticalAttributeID = MechSubsystem::NextAttributeID,
RotationOfTorsoHorizontalAttributeID,
HorizontalLimitRightAttributeID,
HorizontalLimitLeftAttributeID,
SpeedOfTorsoVerticalAttributeID,
SpeedOfTorsoHorizontalAttributeID,
//
// Bound by an authored watcher (BTL4.RES pairs it as
// Torso/MotionState). Appended at the END of this leaf class's
// own range, so no downstream id moves.
//
MotionStateAttributeID,
NextAttributeID
};
static const IndexEntry AttributePointers[];
static AttributeIndexSet AttributeIndex;
protected:
int isDamagedCopy;
int statusFlags;
Logical horizontalEnabled;
Scalar baseTwistRate;
Scalar baseElevationRate;
Scalar horizontalLimitRight;
Scalar horizontalLimitLeft;
Scalar verticalLimitTop;
Scalar verticalLimitBottom;
Scalar twistCenterHigh;
Scalar twistCenterLow;
Scalar elevationCenter;
Scalar elevationHalfBottom;
Scalar buttonAccelerationPerSecond;
Scalar buttonAccelerationStart;
int buttonRampActive;
Scalar buttonRamp;
Joint *horizontalJointNode;
Joint *horizontalShadowJointNode;
Scalar currentTwist;
Scalar currentElevation;
Scalar analogElevationAxis;
Scalar analogTwistAxis;
//
// MUST BE A StateIndicator. The authored watcher for a *State
// name is an AudioStateWatcher, which is AudioWatcherOf<StateIndicator>
// and whose ctor immediately runs
// Cast_Object(StateIndicator*, attributePointer)->AddAudioWatcher(this)
// (AUDWTHR.CPP:891). Point it at a plain int and that call goes
// through garbage -- the pod dies on the extender.
//
StateIndicator motionState; // authored watcher
//
// Twist/elevation dynamics accumulators advanced by TorsoSimulation.
// Reserved until the per-frame sim is reconstructed (phase 5).
//
Scalar dynamicsState[22];
};
#endif