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>
179 lines
5.9 KiB
C++
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
|