diff --git a/restoration/source410/BT/MECH.CPP b/restoration/source410/BT/MECH.CPP index 37808485..05f0f07c 100644 --- a/restoration/source410/BT/MECH.CPP +++ b/restoration/source410/BT/MECH.CPP @@ -100,7 +100,8 @@ const Mech::IndexEntry ATTRIBUTE_ENTRY(Mech, RadarAngularPosition, radarAngularPosition), ATTRIBUTE_ENTRY(Mech, LinearSpeed, currentBodySpeed), ATTRIBUTE_ENTRY(Mech, MaxRunSpeed, reverseStrideLength), - ATTRIBUTE_ENTRY(Mech, DuckState, duckState) + ATTRIBUTE_ENTRY(Mech, DuckState, duckState), + ATTRIBUTE_ENTRY(Mech, EyepointRotation, eyepointRotation) }; Mech::AttributeIndexSet diff --git a/restoration/source410/BT/MECH.HPP b/restoration/source410/BT/MECH.HPP index 26eacbdd..d6a2fe90 100644 --- a/restoration/source410/BT/MECH.HPP +++ b/restoration/source410/BT/MECH.HPP @@ -180,6 +180,16 @@ LinearSpeedAttributeID, MaxRunSpeedAttributeID, DuckStateAttributeID, + // + // The 3-D renderer reads this BY NAME: DPLRenderer::SetupCull + // (CODE/RP/MUNGA_L4/L4VIDEO.CPP:4990) fetches + // "EyepointRotation" off the viewpoint entity and, for a + // JointedMover, composes it with the siteeyepoint segment to + // build worldToEyeMatrix. Without it the engine Fails every + // frame. The member already existed -- only the publication + // was missing. + // + EyepointRotationAttributeID, NextAttributeID }; diff --git a/restoration/source410/BT_L4/BTL4VID.CPP b/restoration/source410/BT_L4/BTL4VID.CPP index 1c9c27aa..d292f74b 100644 --- a/restoration/source410/BT_L4/BTL4VID.CPP +++ b/restoration/source410/BT_L4/BTL4VID.CPP @@ -36,8 +36,41 @@ BTL4VideoRenderer::~BTL4VideoRenderer() { } +// +//############################################################################# +// LoadMissionImplementation -- called by Renderer::LoadMission (the authentic +// engine, CODE/RP/MUNGA/RENDERER.CPP:263) after it has set +// LoadingRendererStatus, stamped nextRenderTime and started the renderer with +// the RendererManager. This is where a GAME renderer builds the mission's +// scene content on the Division board. +// +// BRING-UP NO-OP (phase 1 of the btl4vid ladder). A no-op is a LEGAL body +// here, not a cheat: the engine's own VideoRenderer::LoadMissionImplementation +// (CODE/RP/MUNGA/VIDREND.CPP:259) is a bare Tell, and our GaugeRenderer +// (GAUGREND.CPP:3275) ships the same. The renderer therefore comes up and +// runs its frame loop with an EMPTY scene, which is exactly what we want to +// measure before writing any content. +// +// THE AUTHENTIC SHAPE, pinned by the surviving sibling header for Red +// Planet's renderer (CODE/RP/RP_L4/RPL4VID.HPP -- same engine, same board, +// same year; only the .CPP is missing there too): +// +// LoadMissionImplementation walks the mission's entities and calls +// MakeEntityRenderables(entity, model_resource, view_type) for each, +// which builds a dpl_DCS hierarchy through ReadSKLFile / +// RecurseSKLFile (the skeleton notation pages), with a material +// substitution list set up around it. +// +// The BT-specific renderables (BTReticleRenderable, BTTranslocationRenderable, +// the pending-wrecks map) come from the BT411 donor game/reconstructed/ +// btl4vid.cpp -- 3188 lines -- but NOTE that port restructured this hook and +// has no method under this name, so the CONTRACT above comes from the 1995 +// engine and only the CONTENT comes from the donor. +//############################################################################# +// void BTL4VideoRenderer::LoadMissionImplementation(Mission *) { - Fail("BTL4VideoRenderer::LoadMissionImplementation -- btl4vid.cpp not yet reconstructed"); + Check(this); + Tell("BTL4VideoRenderer::LoadMissionImplementation -- empty scene (bring-up)\n"); } diff --git a/restoration/source410/RENDER-ROADMAP.NOTES.md b/restoration/source410/RENDER-ROADMAP.NOTES.md index fff94e62..c93589bd 100644 --- a/restoration/source410/RENDER-ROADMAP.NOTES.md +++ b/restoration/source410/RENDER-ROADMAP.NOTES.md @@ -134,3 +134,46 @@ MakeVideoRenderer returns NULL unless DPLARG is set (BTL4APP.CPP:152), and no gauge conf sets it -- so no video renderer exists in those runs at all. That frame was almost certainly attract/loading art out of BTL4.RES. The evidence above is the real thing, and it came from setting DPLARG deliberately. + +-------------------------------------------------------------------------------- +TWO RUNGS CLIMBED -- the 3-D pipeline now runs end to end to the geometry load +-------------------------------------------------------------------------------- +RUNG 1: BTL4VideoRenderer::LoadMissionImplementation, Fail -> bring-up no-op. +A no-op is a LEGAL body, not a cheat: the engine's own +VideoRenderer::LoadMissionImplementation (CODE/RP/MUNGA/VIDREND.CPP:259) is a +bare Tell, and our working GaugeRenderer (GAUGREND.CPP:3275) ships the same. +The renderer comes up and runs its frame loop with an EMPTY scene, which is +what we wanted to measure before writing content. + +RUNG 2: Mech::EyepointRotation PUBLISHED. With the renderer live the engine +immediately Failed at + + l4video.cpp(5004): DPLRenderer::SetupCull jointed mover had no + EyepointRotation attribute + +SetupCull (CODE/RP/MUNGA_L4/L4VIDEO.CPP:4990) fetches "EyepointRotation" BY +NAME off the viewpoint entity and, for a JointedMover, composes it with the +"siteeyepoint" segment to build worldToEyeMatrix. Our mech already HAD +EulerAngles eyepointRotation with a getter (MECH.HPP) -- only the attribute +publication was missing. One enum id + one table row. (The siteeyepoint +check passed first time, so that segment was already streaming correctly.) + +WHERE IT STOPS NOW, and why that is not a defect: + + L4VIDEO.cpp couldn't load object buttee.bgf (x123, also dg100/mslr) + NULL instance + +ZERO Fails, zero exceptions -- the run reaches the full mech build (all 7 +weapons), constructs the renderer, boots the board (~907K VPX wire +transactions), loads the mission, runs the per-frame cull and gets all the way +into geometry loading. The models ARE present (VIDEO/GEO/BUTTEE.BGF etc, 879 +BGFs) and BTDPL.INI points at them (objectpath=. ideo\geo), but loading a +.BGF goes through the board to the EXTERNAL GL render bridge that the VPX HLE +tees over VPX_FIFOSOCK -- and that bridge was not running. "NULL instance" +comes from the prebuilt LIBDPL.LIB, i.e. the library refusing to instance an +object that never loaded. + +NEXT RUNG: run under the documented full rig (render-bridge/launch_pod.ps1, +see LAUNCH.md) so the bridge is up and geometry actually loads. Only then is +it worth writing real MakeEntityRenderables content -- until the bridge is in +the loop there is nothing to see even if the scene graph is correct.