diff --git a/restoration/source410/BT/BTPLAYER.CPP b/restoration/source410/BT/BTPLAYER.CPP index 8470463e..a2f4b269 100644 --- a/restoration/source410/BT/BTPLAYER.CPP +++ b/restoration/source410/BT/BTPLAYER.CPP @@ -39,6 +39,22 @@ # include #endif +#if !defined(MECH_HPP) +# include +#endif + +#if !defined(RESOURCE_HPP) +# include +#endif + +#if !defined(HOSTMGR_HPP) +# include +#endif + +#if !defined(MISSION_HPP) +# include +#endif + // //############################################################################# // Shared data support @@ -278,14 +294,68 @@ void // //############################################################################# -// Vehicle creation -- pulls in the Mech subsystem (Mech::Make), not yet -// reconstructed. This is the current boot frontier. +// CreatePlayerVehicle Build the player's mech from the mission game-model +// 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 - 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 diff --git a/restoration/source410/BT/MECH.CPP b/restoration/source410/BT/MECH.CPP index dfcea78d..c96457f4 100644 --- a/restoration/source410/BT/MECH.CPP +++ b/restoration/source410/BT/MECH.CPP @@ -43,10 +43,31 @@ Mech::SharedData //############################################################################# // 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 diff --git a/restoration/source410/BT/MECH.NOTES.md b/restoration/source410/BT/MECH.NOTES.md new file mode 100644 index 00000000..19be8df8 --- /dev/null +++ b/restoration/source410/BT/MECH.NOTES.md @@ -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.