4.10 reconstruction: real spawn factory path -> Mech ctor frontier
BTPlayer::CreatePlayerVehicle reconstructed (faithful; BT411's BT_SPAWN_XZ/ BT_SPAWN_ENEMY bring-up scaffolding dropped): builds the Mech::MakeMessage from the mission game-model resource and hands it to MakeAndLinkViewpointEntity. Mech::Make = new Mech(creation_message); a staged Mech ctor chains the real JointedMover base (so the model skeleton/segments stream from BTL4.RES) then Fails. This validates the entire spawn factory chain live: CreatePlayerVehicle -> MakeAndLinkViewpointEntity -> registry -> Mech::Make -> new Mech -> JointedMover base ctor (streams the mech model) -> halts at the Mech ctor (mech.cpp:66). The Mech ctor (@004a1674, 5690 bytes -- the largest function in the game) plus the subsystem roster is the next MAJOR milestone, not a brick: it needs the full 1995 Mech member layout derived first (MECH.HPP is still reserved[331]; BT411's decomp uses raw offset pokes that can't compile fresh), the subsystem class hierarchy (only GAUSS/PPC/SENSOR survive in the 4.10 archive; the rest are the measured "917 missing functions"), and the segment-table walk. Plan + scope in MECH.NOTES.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,22 @@
|
|||||||
# include <dropzone.hpp>
|
# include <dropzone.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MECH_HPP)
|
||||||
|
# include <mech.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(RESOURCE_HPP)
|
||||||
|
# include <resource.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HOSTMGR_HPP)
|
||||||
|
# include <hostmgr.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MISSION_HPP)
|
||||||
|
# include <mission.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
// Shared data support
|
// Shared data support
|
||||||
@@ -278,14 +294,68 @@ void
|
|||||||
|
|
||||||
//
|
//
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
// Vehicle creation -- pulls in the Mech subsystem (Mech::Make), not yet
|
// CreatePlayerVehicle Build the player's mech from the mission game-model
|
||||||
// reconstructed. This is the current boot frontier.
|
// resource and bind it as the viewpoint entity. (An observer player gets a
|
||||||
|
// MUNGA camera ship from the base Player::CreatePlayerVehicle instead.)
|
||||||
|
//
|
||||||
|
// Constructs the Mech::MakeMessage and hands it to MakeAndLinkViewpointEntity,
|
||||||
|
// which routes through the registry to Mech::Make -> the Mech ctor (the mech
|
||||||
|
// subsystem, not yet reconstructed -- current boot frontier).
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
//
|
//
|
||||||
void
|
void
|
||||||
BTPlayer::CreatePlayerVehicle(Origin)
|
BTPlayer::CreatePlayerVehicle(Origin mech_location)
|
||||||
{
|
{
|
||||||
Fail("BTPlayer::CreatePlayerVehicle -- btplayer.cpp not yet reconstructed");
|
Check(this);
|
||||||
|
Check(application);
|
||||||
|
|
||||||
|
ResourceFile *resources = application->GetResourceFile();
|
||||||
|
Check(resources);
|
||||||
|
Check_Pointer(playerMission->GetGameModel());
|
||||||
|
|
||||||
|
HostManager *host_manager = application->GetHostManager();
|
||||||
|
Check(host_manager);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make any MUNGA-level vehicle (a camera ship for an observer player).
|
||||||
|
//
|
||||||
|
Player::CreatePlayerVehicle(mech_location);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the player still has no vehicle, build him a mech and link to it.
|
||||||
|
//
|
||||||
|
if (!playerVehicle)
|
||||||
|
{
|
||||||
|
ResourceDescription *mech_res =
|
||||||
|
resources->FindResourceDescription(
|
||||||
|
playerMission->GetGameModel(),
|
||||||
|
ResourceDescription::ModelListResourceType
|
||||||
|
);
|
||||||
|
Check(mech_res);
|
||||||
|
mech_res->Lock();
|
||||||
|
|
||||||
|
Mech::MakeMessage
|
||||||
|
create_player(
|
||||||
|
Mech::MakeMessageID,
|
||||||
|
sizeof(Mech::MakeMessage),
|
||||||
|
EntityID(host_manager->GetLocalHostID()),
|
||||||
|
(Entity::ClassID)MechClassID,
|
||||||
|
EntityID::Null,
|
||||||
|
mech_res->resourceID,
|
||||||
|
Mech::DefaultFlags,
|
||||||
|
mech_location,
|
||||||
|
Motion::Identity,
|
||||||
|
Motion::Identity,
|
||||||
|
playerMission->GetBadgeName(),
|
||||||
|
playerMission->GetColorName(),
|
||||||
|
((BTMission *)playerMission)->GetPatchName()
|
||||||
|
);
|
||||||
|
|
||||||
|
mech_res->Unlock();
|
||||||
|
|
||||||
|
playerVehicle = application->MakeAndLinkViewpointEntity(&create_player);
|
||||||
|
Register_Object(playerVehicle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -43,10 +43,31 @@ Mech::SharedData
|
|||||||
//#############################################################################
|
//#############################################################################
|
||||||
//
|
//
|
||||||
Mech*
|
Mech*
|
||||||
Mech::Make(MakeMessage *)
|
Mech::Make(MakeMessage *creation_message)
|
||||||
|
{
|
||||||
|
return new Mech(creation_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
// Mech ctor -- the heart of the entity (walks the model segment table and
|
||||||
|
// instantiates the full subsystem roster: power, heat, weapons, actuators,
|
||||||
|
// controls, tech, damage zones). This is the largest single function in the
|
||||||
|
// game and the current reconstruction frontier; see MECH.NOTES.md. Chains to
|
||||||
|
// the JointedMover base so the skeleton/segments stream before it Fails.
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
Mech::Mech(
|
||||||
|
MakeMessage *creation_message,
|
||||||
|
SharedData &shared_data
|
||||||
|
):
|
||||||
|
JointedMover(creation_message, shared_data)
|
||||||
|
{
|
||||||
|
Fail("Mech::Mech -- mech.cpp not yet reconstructed");
|
||||||
|
}
|
||||||
|
|
||||||
|
Mech::~Mech()
|
||||||
{
|
{
|
||||||
Fail("Mech::Make -- mech.cpp not yet reconstructed");
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# MECH.CPP / .HPP — reconstruction notes
|
||||||
|
|
||||||
|
**Status: `Mech::Make` (factory) reconstructed; the Mech constructor and the
|
||||||
|
entire mech subsystem are the CURRENT FRONTIER — the largest remaining
|
||||||
|
milestone in the reconstruction.**
|
||||||
|
|
||||||
|
## What is reconstructed
|
||||||
|
|
||||||
|
- `Mech::Make(MakeMessage *)` = `return new Mech(creation_message);` — the
|
||||||
|
factory the registry / `MakeAndLinkViewpointEntity` calls.
|
||||||
|
- The static shared data (ClassDerivations / DefaultData) — from the earlier
|
||||||
|
staging.
|
||||||
|
- A staged Mech ctor that chains the real `JointedMover` base ctor (so the
|
||||||
|
model skeleton/segments stream from BTL4.RES) and then Fails.
|
||||||
|
|
||||||
|
The spawn factory path is now validated live: `BTPlayer::CreatePlayerVehicle`
|
||||||
|
builds the `Mech::MakeMessage`, `Application::MakeAndLinkViewpointEntity` routes
|
||||||
|
it through the registry to `Mech::Make` -> `new Mech` -> the JointedMover base
|
||||||
|
ctor (real engine code, streams the mech model) -> the Mech ctor Fail. Boot
|
||||||
|
reaches `mech.cpp:66`.
|
||||||
|
|
||||||
|
## Why the Mech ctor is a milestone, not a brick
|
||||||
|
|
||||||
|
`Mech::Mech` is `@004a1674`, **5690 bytes** — the largest single function in the
|
||||||
|
game. It walks the model's segment table and instantiates the full subsystem
|
||||||
|
roster (power, heat, weapons, actuators, controls, tech, damage zones), and
|
||||||
|
primes ~150 members. Reconstructing it requires three things the tree does not
|
||||||
|
yet have:
|
||||||
|
|
||||||
|
1. **The complete 1995 Mech member layout as named fields.** MECH.HPP currently
|
||||||
|
carries `int reserved[331]` (1324 bytes) as a placeholder. BT411's Ghidra
|
||||||
|
reconstruction sidesteps the layout entirely by writing raw offset pokes
|
||||||
|
(`Wword(0x104)`, `*(void**)((char*)this + 0x388)`, `this[0x14a]`) — a
|
||||||
|
WinTesla-port technique that CANNOT compile into a fresh 1995 build, where
|
||||||
|
BC4.52 assigns offsets from the header declarations. So the layout must be
|
||||||
|
derived as real members first.
|
||||||
|
2. **The subsystem class hierarchy.** MechSubsystem + derived: sensor, generator
|
||||||
|
(gnrator), gyro, torso, HUD, myomers, plus the weapon subsystems (mechweap,
|
||||||
|
ppc, gauss, projweap, mislanch, ammobin...). Of these, only GAUSS, PPC,
|
||||||
|
SENSOR survive as source in the 4.10 archive (CODE/BT/BT); GNRATOR is a
|
||||||
|
partial .TCP. The rest are part of the measured "917 missing functions" and
|
||||||
|
come only from BT411's decomp.
|
||||||
|
3. **The segment-table walk** that reads the model resource and instantiates +
|
||||||
|
wires each subsystem.
|
||||||
|
|
||||||
|
BT411's mech reconstruction is ~12,255 lines across mech.cpp / mech2 / mech3 /
|
||||||
|
mech4 / mechsub alone, before the subsystem TUs — this is the bulk of the
|
||||||
|
remaining game.
|
||||||
|
|
||||||
|
## Reconstruction plan (for the dedicated mech milestone)
|
||||||
|
|
||||||
|
1. **Derive the Mech member layout.** Turn `reserved[331]` into named members.
|
||||||
|
Sources: BT411's offset comments (`this[0x14a]` gyroSubsystem, `+0x388`
|
||||||
|
target entity, etc.) give the binary offsets; the embedded member types
|
||||||
|
(NameFilter, AlarmIndicator, Slot/Socket, Reticle, Filter, CString,
|
||||||
|
StateIndicator) come from the surviving MUNGA headers. Cross-check total size
|
||||||
|
against the binary's `new Mech` allocation.
|
||||||
|
2. **Reconstruct MechSubsystem base + the subsystem roster**, backdating BT411
|
||||||
|
mechsub.cpp + the per-subsystem TUs; fold in the surviving 4.10 GAUSS/PPC/
|
||||||
|
SENSOR source where it exists (authoritative over the decomp).
|
||||||
|
3. **Reconstruct the Mech ctor** against the named layout: embedded-member
|
||||||
|
construction, the segment-table walk, subsystem instantiation + wiring.
|
||||||
|
4. Then the per-frame path (mech2 animation SM, mech3, mech4 locomotion/
|
||||||
|
targeting) and the damage/weapon handlers.
|
||||||
|
|
||||||
|
Until then the ctor Fails cleanly at the frontier; everything below it (engine,
|
||||||
|
app, network, mission, player, factory, jointed-mover base) runs real
|
||||||
|
reconstructed code.
|
||||||
Reference in New Issue
Block a user