BT410 5.3.106: MISSION REVIEW LINKS -- the playback app, the winners circle, and the last Fail() in main

BTL4PB.CPP reconstructed against its AUTHENTIC surviving header (BTL4PB.HPP)
from the binary's 0x4d3b74-0x4d40d8 cluster, cross-checked against the
surviving RP411 twin -- and the review/camera launch in BTL4.CPP's main() is
real code now.  btl4.lib 11 -> 12 members, link clean, zero unresolved: the
linker pulled the entire playback chain for the first time.

The launch decode closed on two identifications:

  The `if (spool_file)` guard in the decomp means the manager getter is
  GetStoredSpoolFile -- the empty-spool getter cannot fail, so a review pod
  with no recorded battle simply starts nothing, which is the right field
  behaviour.

  The camera app's ctor (FUN_0047c3fc) sits in the ENGINE range with the
  (ResourceFile*, ApplicationID) shape: the camera pod's recorder IS the
  engine's own L4SpoolingApplication -- restored one commit ago -- started
  with ApplicationID 1 == BTL4.  BT shipped no camera app of its own.

What the playback app does, all binary-anchored: BTSpoolerTask pumps
recorded packets through DispatchPacket -> the client's own
ReceiveNetworkPacket; RunMission synchronises the clock (timeBias = Now -
the recorded run packet's stamp); the frame loop runs controls ONLY in
interactive review (mode 2), then update/interest/renderer/intercom; and
StopMission plays the WINNERS CIRCLE -- release the spool, park each
player's mech on the dropzone named "win1".."winN" by finishing rank,
freeze it (DoNothing performance), and tilt the camera up 45 degrees over
the tableau.

DOS-authentic ctor shape throughout: the binary's base call is (resource,
0x3eb, DefaultData) -- no windowing parameters ever existed in 4.10; the
RP411 twin's HINSTANCE/HWND threading is port drift, dropped.

Also fixed from 5.3.105's debt: L4PlaybackNetworkManager chains
NetworkManager::DefaultData -- the 1995 header declares no statics of its
own; the RP411 self-reference was drift too.

One [T3] in source: the idle frame's renderer service (the descendant's
ExecuteIdle) has no 1995 entry point; pre-egg the idle frame spins.

RUNTIME TEST PENDING, stated plainly: exercising review needs a
camera/review egg and a recorded spool on the rig (CAMERA-REVIEW-NOTES.md
has the roles).  The normal pod path regressed clean (mode gate untouched).

The Fail() census moves: BTL4.CPP and SEQCTL.CPP are now stub-free; 22
stubs remain across 15 files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-08-03 15:54:31 -05:00
co-authored by Claude Fable 5
parent f85e5f5bcd
commit d2be54a3b9
4 changed files with 647 additions and 157 deletions
+128 -91
View File
@@ -1,91 +1,128 @@
//===========================================================================//
// File: btl4.cpp //
// Project: BattleTech Brick: BattleTech LBE Application //
// Contents: Application launcher (main) //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include <btl4.hpp>
#pragma hdrstop
#if !defined(BTL4APP_HPP)
# include <btl4app.hpp>
#endif
#if !defined(APPMGR_HPP)
# include <appmgr.hpp>
#endif
#if !defined(BTL4VER_HPP)
# include <btl4ver.hpp>
#endif
//##########################################################################
//#################### BTL4Application Globals #######################
//##########################################################################
extern const char* const ProgName;
const char* const ProgName = "btl4";
static Byte
version[3] =
{MAJOR_DATA_VERSION, RELEASE_VERSION, MINOR_DATA_VERSION};
//
//#############################################################################
// main
//#############################################################################
//
int
main(int argc, char *argv[])
{
DEBUG_STREAM << "BattleTech v4.10" << endl;
if (!L4Application::ParseCommandLine(argc, argv, L4Application::ParseToken))
{
return 1;
}
StreamableResourceFile
resources("btl4.res", version);
ApplicationManager
*application_manager = NULL;
if (L4Application::GetMissionReviewMode() < 1)
{
application_manager =
new ApplicationManager(GetTicksPerSecond());
Application
*application = new BTL4Application(&resources);
application_manager->StartApplication(application);
}
else
{
//
//-------------------------------------------------------------------
// Mission review / live-camera launch (missionReviewMode >= 1):
// a MissionReviewApplicationManager with a SPOOLSIZE-byte packet
// spool plus BTL4PlaybackApplication -- those bricks are not yet
// reconstructed (see BTL4.NOTES.md for the decompiled structure).
//-------------------------------------------------------------------
//
Fail("btl4.cpp -- mission review/camera launch not yet reconstructed");
return 1;
}
application_manager->RunMissions();
delete application_manager;
return Exit_Code;
}
//===========================================================================//
// File: btl4.cpp //
// Project: BattleTech Brick: BattleTech LBE Application //
// Contents: Application launcher (main) //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include <btl4.hpp>
#pragma hdrstop
#if !defined(BTL4APP_HPP)
# include <btl4app.hpp>
#endif
#if !defined(APPMGR_HPP)
# include <appmgr.hpp>
#endif
#if !defined(BTL4VER_HPP)
# include <btl4ver.hpp>
#endif
#if !defined(BTL4PB_HPP)
# include <btl4pb.hpp> // BTL4PlaybackApplication -- the review app
#endif
#if !defined(SPOOLER_HPP)
# include <spooler.hpp> // MissionReviewApplicationManager / SpoolFile
#endif
//##########################################################################
//#################### BTL4Application Globals #######################
//##########################################################################
extern const char* const ProgName;
const char* const ProgName = "btl4";
static Byte
version[3] =
{MAJOR_DATA_VERSION, RELEASE_VERSION, MINOR_DATA_VERSION};
//
//#############################################################################
// main
//#############################################################################
//
int
main(int argc, char *argv[])
{
DEBUG_STREAM << "BattleTech v4.10" << endl;
if (!L4Application::ParseCommandLine(argc, argv, L4Application::ParseToken))
{
return 1;
}
StreamableResourceFile
resources("btl4.res", version);
ApplicationManager
*application_manager = NULL;
if (L4Application::GetMissionReviewMode() < 1)
{
application_manager =
new ApplicationManager(GetTicksPerSecond());
Application
*application = new BTL4Application(&resources);
application_manager->StartApplication(application);
}
else
{
//
//-------------------------------------------------------------------
// Mission review / live-camera launch (mode 1 = camera, 2 = review).
//
// The manager owns SPOOLSIZE-byte packet spools (default 8MB); a
// STORED spool starts the playback application over it, and camera
// mode additionally starts the engine's spooling application -- the
// recorder -- as a second app (the binary's FUN_0047c3fc ctor is
// L4SpoolingApplication's, ApplicationID 1 == BTL4).
//-------------------------------------------------------------------
//
int
spool_size =
(getenv("SPOOLSIZE") != NULL)
? atoi(getenv("SPOOLSIZE"))
: 0x800000;
DEBUG_STREAM << "Spool size = " << spool_size << endl;
MissionReviewApplicationManager
*review_manager =
new MissionReviewApplicationManager(
GetTicksPerSecond(),
(L4Application::GetMissionReviewMode() != 2) ? 2 : 1,
spool_size
);
application_manager = review_manager;
SpoolFile
*spool_file = review_manager->GetStoredSpoolFile();
if (spool_file != NULL)
{
review_manager->StartApplication(
new BTL4PlaybackApplication(&resources, spool_file));
}
if (L4Application::GetMissionReviewMode() == 1)
{
review_manager->StartApplication(
new L4SpoolingApplication(&resources, (ApplicationID)1));
}
}
application_manager->RunMissions();
delete application_manager;
return Exit_Code;
}
+70 -65
View File
@@ -1,65 +1,70 @@
# BTL4.CPP — reconstruction notes
**Status: RECONSTRUCTED (normal launch path); review/camera branch staged with Fail().**
The 4.10 main TU. No original survives anywhere in the archive (OPT.MAK links
`btl4.obj` as a bare object next to the libs — it was never a lib member).
## Evidence base
1. **Ghidra decomp of the 4.11 binary**`C:\VWE\BT411\reference\decomp\all\part_000.c`,
`FUN_0040109c` (the 524-byte function the Borland startup calls = `main`).
The 4.10 and 4.11 binaries share the same string pool layout for this TU.
2. **String pool of the original 4.10 `BTL4OPT.EXE`** (ALPHA_1/REL410/BT), file
offset ~917884: `"btl4" "HEAPSIZE" "BattleTech v4.10" "btl4.res" "SPOOLSIZE"
"Spool size = "` — banner text and resource name byte-exact.
3. **Surviving 1995 launcher-style TU** `CODE/RP/RP_L4/RPL4TOOL.CPP` — house
style for `main(int, char*[])` and the `ProgName` global pattern.
4. **BT411's win32 launcher** `game/btl4main.cpp` (adapted from RP's RPL4.CPP)
independently reconstructs the same skeleton and pins `version[3] = {1,0,6}`
against the RESOURCE.cpp version check.
## Decoded decomp → source mapping
| decomp | source |
|---|---|
| `FUN_004dbb24(&cout, "BattleTech v4.10", 0); FUN_004d9c38(&cout)` | `DEBUG_STREAM << "BattleTech v4.10" << endl` |
| `FUN_0047b2ec(argc, argv, &LAB_0047af8c)` | `L4Application::ParseCommandLine(argc, argv, L4Application::ParseToken)` |
| `FUN_00407218(stack84, "btl4.res", &DAT_004e0070, 3)` | `StreamableResourceFile resources("btl4.res", version)` (match_level=3 is the declared default) |
| `DAT_004e0070` = 3 bytes | `version[3]` = `{MAJOR_DATA_VERSION, RELEASE_VERSION, MINOR_DATA_VERSION}` = {1,0,6} from BTL4VER.HPP |
| `DAT_004fd550 < 1` | `L4Application::GetMissionReviewMode() < 1` (inline static accessor) |
| `new(0x28) FUN_0044f29c(this, DAT_0052140c)` | `new ApplicationManager(GetTicksPerSecond())` (inline friend accessor, TIME.HPP:49) — DAT_0052140c is set to 28.0f by `SystemClock::SystemClock()` (L4TIME.CPP:93) when `L4TIMER=FAST` |
| `new(0xd4) FUN_004d34c4(this, &resources, 0x3EB, &DAT_0051e8d8)` | `new BTL4Application(&resources)` — 0x3EB/`DefaultData` are the declared default args (BTL4APP.HPP:34) |
| `FUN_0044f318(mgr, app)` | `application_manager->StartApplication(application)` |
| `FUN_0044f344(mgr)` | `application_manager->RunMissions()` |
| vcall slot 0 (mgr, 3) | `delete application_manager` |
| `return DAT_004efc98` | `return Exit_Code` (APP.HPP:542) |
## Review/camera branch (NOT yet reconstructed — staged Fail)
Decomp structure for `missionReviewMode >= 1` (mode 1 = camera, 2 = review per
emulator/CAMERA-REVIEW-NOTES.md):
```
spool_size = getenv("SPOOLSIZE") ? atoi(...) : 0x800000; // "Spool size = " printed
mgr = new(0x38) MissionReviewApplicationManager(ticksPerSecond,
(mode != 2) ? 2 : 1, spool_size);
spool_file = <mgr getter, FUN_0044fa14>;
if (spool_file)
mgr->StartApplication(new(0xd8) BTL4PlaybackApplication(&resources, spool_file));
if (mode == 1)
mgr->StartApplication(new(0xd8) <camera app, FUN_0047c3fc>(&resources, 1));
```
Class declarations survive: `BTL4PlaybackApplication` (CODE/BT/BT_L4/BTL4PB.HPP),
spooler bricks in CODE/RP/MUNGA_L4/L4SPLR.HPP (`MissionReviewApplicationManager`
referenced there). Their .CPP bodies are not staged, so the branch Fails loudly
instead of linking half a subsystem.
## Deliberate differences from the binary
- `HEAPSIZE` string sits in the pool between ProgName and the banner but is not
referenced from the decompiled main — it likely belongs to the runtime heap
init, not this TU. Not reproduced.
- `Register_Object`/`Start_Registering` debug bookkeeping is absent from the
optimized binary (DEBUG_LEVEL=0 compiles it out), so it is not written here.
# BTL4.CPP — reconstruction notes
**Status: FULLY RECONSTRUCTED (2026-08-03) — both launch paths. The review/camera branch links against the real BTL4PB + L4SPLR bricks; no Fail() remains in this TU.**
The 4.10 main TU. No original survives anywhere in the archive (OPT.MAK links
`btl4.obj` as a bare object next to the libs — it was never a lib member).
## Evidence base
1. **Ghidra decomp of the 4.11 binary**`C:\VWE\BT411\reference\decomp\all\part_000.c`,
`FUN_0040109c` (the 524-byte function the Borland startup calls = `main`).
The 4.10 and 4.11 binaries share the same string pool layout for this TU.
2. **String pool of the original 4.10 `BTL4OPT.EXE`** (ALPHA_1/REL410/BT), file
offset ~917884: `"btl4" "HEAPSIZE" "BattleTech v4.10" "btl4.res" "SPOOLSIZE"
"Spool size = "` — banner text and resource name byte-exact.
3. **Surviving 1995 launcher-style TU** `CODE/RP/RP_L4/RPL4TOOL.CPP` — house
style for `main(int, char*[])` and the `ProgName` global pattern.
4. **BT411's win32 launcher** `game/btl4main.cpp` (adapted from RP's RPL4.CPP)
independently reconstructs the same skeleton and pins `version[3] = {1,0,6}`
against the RESOURCE.cpp version check.
## Decoded decomp → source mapping
| decomp | source |
|---|---|
| `FUN_004dbb24(&cout, "BattleTech v4.10", 0); FUN_004d9c38(&cout)` | `DEBUG_STREAM << "BattleTech v4.10" << endl` |
| `FUN_0047b2ec(argc, argv, &LAB_0047af8c)` | `L4Application::ParseCommandLine(argc, argv, L4Application::ParseToken)` |
| `FUN_00407218(stack84, "btl4.res", &DAT_004e0070, 3)` | `StreamableResourceFile resources("btl4.res", version)` (match_level=3 is the declared default) |
| `DAT_004e0070` = 3 bytes | `version[3]` = `{MAJOR_DATA_VERSION, RELEASE_VERSION, MINOR_DATA_VERSION}` = {1,0,6} from BTL4VER.HPP |
| `DAT_004fd550 < 1` | `L4Application::GetMissionReviewMode() < 1` (inline static accessor) |
| `new(0x28) FUN_0044f29c(this, DAT_0052140c)` | `new ApplicationManager(GetTicksPerSecond())` (inline friend accessor, TIME.HPP:49) — DAT_0052140c is set to 28.0f by `SystemClock::SystemClock()` (L4TIME.CPP:93) when `L4TIMER=FAST` |
| `new(0xd4) FUN_004d34c4(this, &resources, 0x3EB, &DAT_0051e8d8)` | `new BTL4Application(&resources)` — 0x3EB/`DefaultData` are the declared default args (BTL4APP.HPP:34) |
| `FUN_0044f318(mgr, app)` | `application_manager->StartApplication(application)` |
| `FUN_0044f344(mgr)` | `application_manager->RunMissions()` |
| vcall slot 0 (mgr, 3) | `delete application_manager` |
| `return DAT_004efc98` | `return Exit_Code` (APP.HPP:542) |
## Review/camera branch (NOT yet reconstructed — staged Fail)
Decomp structure for `missionReviewMode >= 1` (mode 1 = camera, 2 = review per
emulator/CAMERA-REVIEW-NOTES.md):
```
spool_size = getenv("SPOOLSIZE") ? atoi(...) : 0x800000; // "Spool size = " printed
mgr = new(0x38) MissionReviewApplicationManager(ticksPerSecond,
(mode != 2) ? 2 : 1, spool_size);
spool_file = <mgr getter, FUN_0044fa14>;
if (spool_file)
mgr->StartApplication(new(0xd8) BTL4PlaybackApplication(&resources, spool_file));
if (mode == 1)
mgr->StartApplication(new(0xd8) <camera app, FUN_0047c3fc>(&resources, 1));
```
RECONSTRUCTED 2026-08-03: the branch is real. BTL4PB.CPP reconstructs the
playback app against its authentic surviving header; L4SPLR.CPP back-dates the
RP411 descendant onto the authentic 1995 engine header (see each sidecar). Two
identifications closed it: the `if (spool_file)` guard means the getter is
GetStoredSpoolFile (the empty-spool getter cannot fail), and the camera app's
ctor FUN_0047c3fc sits in the engine range with the (ResourceFile*,
ApplicationID) shape — the camera app IS the engine's L4SpoolingApplication,
started with ApplicationID 1 == BTL4. RUNTIME TEST PENDING: needs a
camera/review egg and a recorded spool on the rig (CAMERA-REVIEW-NOTES.md).
## Deliberate differences from the binary
- `HEAPSIZE` string sits in the pool between ProgName and the banner but is not
referenced from the decompiled main — it likely belongs to the runtime heap
init, not this TU. Not reproduced.
- `Register_Object`/`Start_Registering` debug bookkeeping is absent from the
optimized binary (DEBUG_LEVEL=0 compiles it out), so it is not written here.
+444
View File
@@ -0,0 +1,444 @@
//===========================================================================//
// File: btl4pb.cpp //
// Project: BattleTech Brick: BattleTech LBE Application //
// Contents: BTL4PlaybackApplication -- the mission-review application, and //
// BTSpoolerTask, the pump that replays recorded NetworkPackets //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
//
// RECONSTRUCTED against the AUTHENTIC surviving header (BTL4PB.HPP) from the
// shipped binary's 0x4d3b74-0x4d40d8 cluster, cross-checked against the
// surviving RP411 descendant RPL4PB.cpp (a line-for-line structural twin).
// The binary's own base-ctor call (FUN_004d34c4(this, resource, 0x3eb,
// DefaultData)) confirms the DOS ctor shape this file uses -- no windowing
// parameters ever existed in 4.10.
//
#include <btl4.hpp>
#pragma hdrstop
#if !defined(BTL4PB_HPP)
# include <btl4pb.hpp>
#endif
#if !defined(MISSION_HPP)
# include <mission.hpp>
#endif
#if !defined(L4NET_HPP)
# include <l4net.hpp>
#endif
#if !defined(UPDATE_HPP)
# include <update.hpp>
#endif
#if !defined(RENDERER_HPP)
# include <renderer.hpp>
#endif
#if !defined(ICOM_HPP)
# include <icom.hpp>
#endif
#if !defined(DROPZONE_HPP)
# include <dropzone.hpp>
#endif
#if !defined(DIRECTOR_HPP)
# include <director.hpp>
#endif
#if !defined(NTTMGR_HPP)
# include <nttmgr.hpp>
#endif
#if !defined(MECH_HPP)
# include <mech.hpp>
#endif
#if !defined(L4VIDEO_HPP)
# include <l4video.hpp>
#endif
#if !defined(L4CTRL_HPP)
# include <l4ctrl.hpp>
#endif
//#############################################################################
//########################## BTSpoolerTask ##############################
//#############################################################################
//
// @004d3b74 / @004d3bb8 -- chain-only construction; the task adds no data.
//
BTSpoolerTask::BTSpoolerTask()
{
}
BTSpoolerTask::~BTSpoolerTask()
{
Check_Fpu();
}
//
//#############################################################################
// @004d3b90 / @004d3ba8 -- the pump's two callbacks forward to the running
// playback application.
//#############################################################################
//
void
BTSpoolerTask::DispatchPacket(NetworkPacket *packet)
{
BTL4PlaybackApplication
*playback_app =
Cast_Object(BTL4PlaybackApplication *, application);
playback_app->DispatchPacket(packet);
Check_Fpu();
}
long
BTSpoolerTask::GetTimeBias()
{
BTL4PlaybackApplication
*playback_app =
Cast_Object(BTL4PlaybackApplication *, application);
return playback_app->GetTimeBias();
}
//#############################################################################
//####################### BTL4PlaybackApplication #######################
//#############################################################################
const Receiver::HandlerEntry
BTL4PlaybackApplication::MessageHandlerEntries[] =
{
MESSAGE_ENTRY(BTL4PlaybackApplication, RunMission), // @004d3ef8
MESSAGE_ENTRY(BTL4PlaybackApplication, StopMission) // @004d3f44
};
BTL4PlaybackApplication::MessageHandlerSet
BTL4PlaybackApplication::MessageHandlers(
ELEMENTS(BTL4PlaybackApplication::MessageHandlerEntries),
BTL4PlaybackApplication::MessageHandlerEntries,
BTL4Application::MessageHandlers
);
Derivation
BTL4PlaybackApplication::ClassDerivations(
BTL4Application::ClassDerivations,
"BTL4PlaybackApplication" // @0051f182
);
BTL4PlaybackApplication::SharedData
BTL4PlaybackApplication::DefaultData( // @0051ee5c
BTL4PlaybackApplication::ClassDerivations,
BTL4PlaybackApplication::MessageHandlers
);
//
//#############################################################################
// @004d3be4 -- the binary's base call is (resource, 0x3eb, DefaultData): the
// L4ApplicationClassID, no windowing. The spool lands in the inherited
// spoolFile slot.
//#############################################################################
//
BTL4PlaybackApplication::BTL4PlaybackApplication(
ResourceFile *resource_file,
SpoolFile *spool_file
):
BTL4Application(resource_file, L4ApplicationClassID, DefaultData)
{
spoolFile = spool_file;
timeBias = 0;
Check_Fpu();
}
BTL4PlaybackApplication::~BTL4PlaybackApplication()
{
Check_Fpu();
}
Logical
BTL4PlaybackApplication::TestInstance() const
{
return IsDerivedFrom(ClassDerivations);
}
//
//#############################################################################
// @004d3c14 -- playback drives the spool-fed network manager, not a live one.
//#############################################################################
//
NetworkManager *
BTL4PlaybackApplication::MakeNetworkManager()
{
Check_Fpu();
return new L4PlaybackNetworkManager;
}
//
//#############################################################################
// @004d3c34
//#############################################################################
//
void
BTL4PlaybackApplication::Initialize()
{
Check(this);
L4Application::InitializeTillConsole();
}
//
//#############################################################################
// @004d3c44 -- the playback task pipeline: our own spool pump first, then the
// stock event / gauge / cycle / audio tasks.
//#############################################################################
//
void
BTL4PlaybackApplication::LoadBackgroundTasks()
{
Check(this);
ApplicationTask
*application_task;
application_task = new BTSpoolerTask;
Register_Object(application_task);
backgroundTasks->AddTask(application_task);
application_task = new ProcessEventTask;
Register_Object(application_task);
backgroundTasks->AddTask(application_task);
application_task = new GaugeRendererTask;
Register_Object(application_task);
backgroundTasks->AddTask(application_task);
application_task = new CompleteCyclesTask;
Register_Object(application_task);
backgroundTasks->AddTask(application_task);
application_task = new AudioRendererTask;
Register_Object(application_task);
backgroundTasks->AddTask(application_task);
Check_Fpu();
}
//
//#############################################################################
// @004d3d40 -- the mission-review frame loop. Idle until frames execute;
// controls only in INTERACTIVE review (mode 2); then the update, interest,
// renderer and intercom managers; and while running, keep the game clock
// current from the recorded start.
//#############################################################################
//
Logical
BTL4PlaybackApplication::ExecuteForeground(
Time start_of_frame,
Scalar frame_duration
)
{
SET_FOREGROUND_PROCESSING();
Check(this);
if (!executeFrames || GetApplicationState() == WaitingForEgg)
{
//
// [T3] The binary services a renderer idle slot here (the RP411
// descendant names it ExecuteIdle); no such entry exists in the
// 1995 renderer headers, and pre-egg there is nothing to draw --
// the idle frame simply spins. Revisit if the review screen shows
// stale video before the egg arrives.
//
CLEAR_FOREGROUND_PROCESSING();
return executeFrames && !Exit_Code;
}
Time
frame_ticks;
frame_ticks = frame_duration;
if (GetMissionReviewMode() == 2)
{
Check(controlsManager);
((LBE4ControlsManager *)controlsManager)->Execute();
}
SET_UPDATE_MANAGER();
Check(updateManager);
updateManager->Execute(start_of_frame);
CLEAR_UPDATE_MANAGER();
Check(rendererManager);
rendererManager->UpdateInterestOrigins(start_of_frame);
Check(interestManager);
interestManager->Execute();
SET_RENDERER_MANAGER();
Check(rendererManager);
rendererManager->Execute(start_of_frame, frame_ticks, frame_ticks);
CLEAR_RENDERER_MANAGER();
Check(intercomManager);
intercomManager->Execute();
if (GetApplicationState() == RunningMission)
{
secondsRemainingInGame =
currentMission->GetGameLength() - (Now() - gameStarted);
}
CLEAR_FOREGROUND_PROCESSING();
Check_Fpu();
return executeFrames && !Exit_Code;
}
//
//#############################################################################
// Inherited-shape background task (the OPT build emitted no BT override; the
// body matches the L4 base, kept for the header's declaration).
//#############################################################################
//
void
BTL4PlaybackApplication::ExecuteBackgroundTask()
{
Check(this);
if (ProcessOneEvent(HighEventPriority))
{
return;
}
Check(backgroundTasks);
backgroundTasks->Execute();
}
//
//#############################################################################
// @004d3ecc -- route a recorded packet to its client.
//#############################################################################
//
void
BTL4PlaybackApplication::DispatchPacket(NetworkPacket *packet)
{
Check(this);
NetworkManager
*net_mgr = GetNetworkManager();
Check(net_mgr);
NetworkClient
*client = net_mgr->GetNetworkClientPointer(packet->clientID);
Check(client);
client->ReceiveNetworkPacket(packet, &packet->messageData);
Check_Fpu();
}
//
//#############################################################################
// @004d3ef8 -- first launch synchronises the playback clock: the bias is the
// difference between NOW and the recorded RunMission packet's timestamp, and
// every replayed packet is re-timed by it.
//#############################################################################
//
void
BTL4PlaybackApplication::RunMissionMessageHandler(RunMissionMessage *message)
{
Check(this);
if (GetApplicationState() == WaitingForLaunch)
{
SpoolFile
*spool = GetSpoolFile();
Check(spool);
NetworkPacket
*packet = (NetworkPacket *)spool->GetPointer();
timeBias = Now().ticks - packet->timeStamp.ticks;
spool->NextPacket();
}
BTL4Application::RunMissionMessageHandler(message);
Check_Fpu();
}
//
//#############################################################################
// @004d3f44 -- the WINNERS CIRCLE. When the recorded mission ends, release
// the spool, park every player's mech on the dropzone matching its finishing
// rank ("win1".."winN"), freeze them, refresh the name bitmaps and tilt the
// camera up 45 degrees for the final tableau.
//#############################################################################
//
static char
winners_spot[] = "win?"; // @0051ee63
void
BTL4PlaybackApplication::StopMissionMessageHandler(StopMissionMessage *message)
{
MissionReviewApplicationManager
*app_mgr = GetApplicationManager();
Check(app_mgr);
SpoolFile
*spool = GetSpoolFile();
if (spool)
{
app_mgr->ReleaseSpoolFile(spool);
spoolFile = NULL;
EntityManager
*entity_manager = application->GetEntityManager();
EntityGroup
*dropzones = entity_manager->FindGroup("DropZones");
char
*place = winners_spot + 3;
Player
*player;
int
rank;
for (
rank = 0;
(player = CameraDirector::FindPlayerByRank(rank)) != NULL;
++rank
)
{
*place = (char)('1' + rank);
ChainIteratorOf<Node *>
iterator(dropzones->groupMembers);
DropZone
*dropzone;
while ((dropzone = (DropZone *)iterator.ReadAndNext()) != NULL)
{
if (!strcmp(dropzone->GetDropZoneName(), winners_spot))
{
break;
}
}
if (!dropzone)
{
continue;
}
Mech
*mech = (Mech *)player->GetPlayerVehicle();
if (mech->GetClassID() == RegisteredClass::MechClassID)
{
mech->Reset(dropzone->localOrigin, False);
mech->SetPerformance(
(Mech::Performance)&Simulation::DoNothing);
mech->FlushEvents();
}
}
DPLRenderer
*dpl_renderer = (DPLRenderer *)GetVideoRenderer();
Check(dpl_renderer);
dpl_renderer->SortAndReloadNameBitmaps();
dpl_renderer->SetViewAngle(Degree(45.0f));
}
BTL4Application::StopMissionMessageHandler(message);
Check_Fpu();
}
+5 -1
View File
@@ -202,8 +202,12 @@ void
//###################### L4PlaybackNetworkManager #########################
//#############################################################################
//
// The 1995 header declares no statics of its own (the DefaultData reference
// in the RP411 descendant was later-era drift); chain the base's.
//
L4PlaybackNetworkManager::L4PlaybackNetworkManager():
NetworkManager(L4PlaybackNetworkManager::DefaultData)
NetworkManager(NetworkManager::DefaultData)
{
}