source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived

- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
  is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
  Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
  (extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
  BT game source (never mixed into CODE/). Round 1-3 state:
  * 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
    (BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
    since 1996.
  * BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
    its binary-recorded line 400 exactly.
  * BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
    (Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
    TeamScore=12 flagged [T4]).
  * MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
    (VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
    the period compiler is the drift detector).
  * Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
    (per-TU verification sweep under authentic OPT.MAK flags).
  * README: corrected roadmap - MECH.HPP is the capstone grown with the mech
    TU reconstructions; BTREG.CPP green = the header-family milestone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-19 07:33:26 -05:00
co-authored by Claude Fable 5
parent 599b2388a1
commit 63312e07f9
5913 changed files with 756089 additions and 0 deletions
+190
View File
@@ -0,0 +1,190 @@
//===========================================================================//
// File: cnslmsgs.hpp //
// Project: MUNGA Brick: //
// Contents: Console messages //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- -----------------------------------------------------------//
// 06/02/95 ECH Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#if !defined(BTCNSL_HPP)
# define BTCNSL_HPP
# if !defined(CONSOLE_HPP)
# include <console.hpp>
# endif
enum
{
ConsolePlayerMechKilledMessageID = 9,
ConsolePlayerMechDamagedMessageID = 10,
ConsoleBTTeamScoreUpdateMessageID = 12,
ConsolePlayerMechScoreUpdateMessageID = 13,
ConsolePlayerMechDeathWithoutHonorMessageID = 15
};
//##########################################################################
//################ ConsolePlayerMechKilledMessage ####################
//##########################################################################
class ConsolePlayerMechKilledMessage:
public NetworkClient::Message
{
public:
ConsolePlayerMechKilledMessage(
HostID player_host_ID,
HostID killer_host_ID
);
HostID
GetPlayerHostID()
{return playerHostID;}
HostID
GetKillerHostID()
{return killerHostID;}
private:
HostID
playerHostID;
HostID
killerHostID;
};
//##########################################################################
//############## ConsolePlayerMechScoreUpdateMessage #################
//##########################################################################
class ConsolePlayerMechScoreUpdateMessage:
public NetworkClient::Message
{
public:
ConsolePlayerMechScoreUpdateMessage(
HostID player_host_ID,
int score
);
HostID
GetPlayerHostID()
{return playerHostID;}
int
GetPlayerScore()
{return playerScore;}
private:
HostID
playerHostID;
int
playerScore;
};
//##########################################################################
//############### ConsoleBTTeamScoreUpdateMessage ####################
//##########################################################################
class ConsoleBTTeamScoreUpdateMessage:
public NetworkClient::Message
{
public:
ConsoleBTTeamScoreUpdateMessage(
int team_ID,
int score
);
int
GetTeamID()
{return teamID;}
int
GetTeamScore()
{return teamScore;}
private:
int
teamID;
int
teamScore;
};
//##########################################################################
//############### ConsolePlayerMechDamagedMessage ####################
//##########################################################################
class ConsolePlayerMechDamagedMessage:
public NetworkClient::Message
{
public:
ConsolePlayerMechDamagedMessage(
HostID player_host_ID,
HostID damager_host_ID,
int loss,
int damage_zone_index,
Logical damage_zone_destroyed,
int points_transfered,
int weapon_index
);
HostID
GetPlayerHostID()
{return playerHostID;}
HostID
GetDamagerHostID()
{return damagerHostID;}
int
GetDamageLoss()
{return damageLoss;}
int
GetPointsTransfered()
{return pointsTransfered;}
int
GetDamageZoneIndex()
{return damageZoneIndex;}
Logical
GetDamageZoneDestroyed()
{return damageZoneDestroyed;}
int
GetWeaponIndex()
{return weaponIndex;}
private:
HostID
playerHostID;
HostID
damagerHostID;
int
damageLoss;
int
pointsTransfered;
int
damageZoneIndex;
Logical
damageZoneDestroyed;
int
weaponIndex;
};
//##########################################################################
//########### ConsolePlayerMechDeathWithoutHonorMessage ##############
//##########################################################################
class ConsolePlayerMechDeathWithoutHonorMessage:
public NetworkClient::Message
{
public:
ConsolePlayerMechDeathWithoutHonorMessage(
HostID player_host_ID
);
HostID
GetPlayerHostID()
{return playerHostID;}
private:
HostID
playerHostID;
};
#endif
+25
View File
@@ -0,0 +1,25 @@
# BTCNSL.HPP — reconstruction notes (2026-07-19)
The header for the SURVIVING BTCNSL.CPP (whose own banner is the stale clone "cnslmsgs.cpp" —
the HPP banner mirrors it). Class shapes/member order recovered from BTCNSL.CPP itself; layout
cross-checked against the binary's ctors.
**THE WIRE IDs ARE BINARY-PROVEN [T1] — a discovery with cross-project value** (the TeslaSuite
console port spec still lists BT's in-match message set as "confirm"):
| message | ID | evidence |
|---|---|---|
| ConsolePlayerMechKilled | **9** | ctor @4c18f4 (`[1]=9`, size 0x14, 2 HostID fields) [T1 value / T3 name-pairing by source order] |
| ConsolePlayerMechDamaged | **10** | ctor @4c1944 (`[1]=10`, size 0x28, the unique 7-field payload; field ORDER = player, damager, loss, pointsTransfered, zoneIndex, zoneDestroyed, weaponIndex — decomp param mapping matches the CPP's member order) [T1] |
| ConsoleBTTeamScoreUpdate | **12 ⚠ [T4 GUESS]** | ctor NOT FOUND in the image (gap 4c19a0-4c19fc holds an unrelated helper); 12 fills the gap pattern around the engine-reserved IDs (CONSOLE.HPP: 0,1,7,11,14) — VERIFY against a live console session or the original Mac console binary before trusting on the wire |
| ConsolePlayerMechScoreUpdate | **13** | ctor @4c191c (`[1]=0xd`, size 0x14) [T1 value / T3 pairing] |
| ConsolePlayerMechDeathWithoutHonor | **15** | ctor @4c198c (`[1]=0xf`, size 0x10, single HostID) [T1] |
The 9↔13 pairing (Killed vs ScoreUpdate — both 2-int payloads) follows binary emission order =
source order [T3]; a live console decode would upgrade it. NetworkClient::Message header =
{length, messageID, flags(1=Reliable)} = 12 bytes before payload [T1].
Compile-proven: BTCNSL.CPP (original) and BTTEAM.CPP (original, constructs
ConsoleBTTeamScoreUpdateMessage — signature validated by a surviving consumer) both build
against this header. The port headers' `...VTV...` typedef aliases are port-only
accommodations and are intentionally ABSENT here.
+44
View File
@@ -0,0 +1,44 @@
//===========================================================================//
// File: btscnrl.hpp //
// Project: MUNGA //
// Contents: BT Scenario Role Specific Data //
//------------------- -------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 05/06/96 GDU Initial coding //
//---------------------------------------------------------------------------//
// Copyright (C) 1996, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#if !defined(BTSCNRL_HPP)
# define BTSCNRL_HPP
# if !defined(SCNROLE_HPP)
# include <scnrole.hpp>
# endif
//##########################################################################
//###################### BTScenarioRole ##############################
//##########################################################################
class BTScenarioRole:
public ScenarioRole
{
public:
typedef ScenarioRole__ModelResource ModelResource;
BTScenarioRole(
const CString &role_name,
const CString &model_file
):
ScenarioRole(role_name, model_file)
{}
BTScenarioRole(const CString &role_name):
ScenarioRole(role_name)
{}
};
#endif
+10
View File
@@ -0,0 +1,10 @@
# BTSCNRL.HPP — reconstruction notes (2026-07-19)
Header for the surviving (near-empty) BTSCNRL.CPP — the TU only includes <bt.hpp> +
<btscnrl.hpp>, so the header is a thin `BTScenarioRole : ScenarioRole` specialisation.
Basis: BT412's reconstruction, de-modernized: `explicit` REMOVED (not in BC4.52's C++),
`ScenarioRole__ModelResource` kept (the double-underscore nested-class workaround is the
PERIOD idiom — the surviving engine SCNROLE.HPP uses it itself); ctor pair mirrors
SCNROLE.HPP:144-149. Banner cloned from BTSCNRL.CPP (05/06/96 GDU).
Compile-proven via the original BTSCNRL.CPP. [T1 shapes / T3 that no additional members
existed — nothing in the image or any consumer suggests any]
+486
View File
@@ -0,0 +1,486 @@
//===========================================================================//
// File: rp4lbe4.cc //
// Project: MUNGA Brick: Red Planet LBE Application //
// Contents: //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// //
//---------------------------------------------------------------------------//
// Copyright (C) 1994, 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(BTREG_HPP)
# include <btreg.hpp>
#endif
#if !defined(BTL4VID_HPP)
# include <btl4vid.hpp>
#endif
#if !defined(BTL4ARND_HPP)
# include <btl4arnd.hpp>
#endif
#if !defined(BTL4GRND_HPP)
# include <btl4grnd.hpp>
#endif
#if !defined(BTL4MODE_HPP)
# include <btl4mode.hpp>
#endif
#if !defined(BTL4MSSN_HPP)
# include <btl4mssn.hpp>
#endif
#if !defined(MECH_HPP)
# include <mech.hpp>
#endif
#if !defined(CAMSHIP_HPP)
# include <camship.hpp>
#endif
#if !defined(L4MPPR_HPP)
# include <l4mppr.hpp>
#endif
#if !defined(L4CTRL_HPP)
# include <l4ctrl.hpp>
#endif
//
//#############################################################################
//#############################################################################
//
const Receiver::HandlerEntry
BTL4Application::MessageHandlerEntries[]=
{
MESSAGE_ENTRY(BTL4Application, RunMission),
MESSAGE_ENTRY(BTL4Application, StopMission)
};
BTL4Application::MessageHandlerSet
BTL4Application::MessageHandlers(
ELEMENTS(BTL4Application::MessageHandlerEntries),
BTL4Application::MessageHandlerEntries,
L4Application::MessageHandlers
);
//
//#############################################################################
//#############################################################################
//
Derivation
BTL4Application::ClassDerivations(
L4Application::ClassDerivations,
"BTL4Application"
);
BTL4Application::SharedData
BTL4Application::DefaultData(
BTL4Application::ClassDerivations,
BTL4Application::MessageHandlers
);
//
//#############################################################################
//#############################################################################
//
BTL4Application::BTL4Application(
ResourceFile *resource_file,
ClassID class_ID,
SharedData &shared_data
):
L4Application(
resource_file,
BTL4,
class_ID,
shared_data
)
{
DEBUG_STREAM << "BTL4Application::BTL4Application" << endl;
}
//
//#############################################################################
//#############################################################################
//
BTL4Application::~BTL4Application()
{
}
//
//#############################################################################
// MakeRegistry
//#############################################################################
//
Registry*
BTL4Application::MakeRegistry()
{
Check(this);
return new BTRegistry(GetResourceFile());
}
//
//#############################################################################
// MakeVideoRenderer
//#############################################################################
//
VideoRenderer*
BTL4Application::MakeVideoRenderer()
{
Check(this);
//
// Only build a video renderer when there is a division card
//
if (!divisionParameters)
{
return NULL;
}
return
new BTL4VideoRenderer(
DefaultRendererRate,
MaxRendererComplexity,
DefaultRendererPriority,
VisualInterestType,
1
);
}
//
//#############################################################################
// MakeAudioRenderer
//#############################################################################
//
AudioRenderer*
BTL4Application::MakeAudioRenderer()
{
Check(this);
//
// Both sound cards must be present
//
if (!getenv("AWE_FRONT") || !getenv("AWE_REAR"))
{
return NULL;
}
return
new BTL4AudioRenderer(
GetFrameRate(),
GetMissionReviewMode()
);
}
//
//#############################################################################
// MakeModeManager
//#############################################################################
//
ModeManager*
BTL4Application::MakeModeManager()
{
Check(this);
return new BTL4ModeManager(BTL4ModeManager::ModeInitial);
}
//
//#############################################################################
// MakeControlsManager
//#############################################################################
//
ControlsManager*
BTL4Application::MakeControlsManager()
{
Check(this);
LBE4ControlsManager
*controls_manager = new LBE4ControlsManager;
Check_Pointer(controls_manager);
//
// Route the PC keyboard to the application's key-command handler
//
controls_manager->keyboardGroup[LBE4ControlsManager::KeyboardPC].Add(
ModeManager::ModeAlwaysActive,
this,
KeyCommandMessageID,
this
);
return controls_manager;
}
//
//#############################################################################
// MakeGaugeRenderer
//#############################################################################
//
GaugeRenderer*
BTL4Application::MakeGaugeRenderer()
{
Check(this);
//
// Only build the gauge renderer on a machine with gauge hardware
//
if (!getenv("L4GAUGE"))
{
return NULL;
}
return new BTL4GaugeRenderer;
}
//
//#############################################################################
// MakeMission
//#############################################################################
//
Mission*
BTL4Application::MakeMission(
NotationFile *notation_file,
ResourceFile *resources
)
{
Check(this);
return new BTL4Mission(notation_file, resources);
}
//
//#############################################################################
// MakeViewpointEntity
//#############################################################################
//
Entity*
BTL4Application::MakeViewpointEntity(Entity::MakeMessage *message)
{
Check(this);
LBE4ControlsManager
*controls_manager = GetControlsManager();
Entity
*viewing_entity = NULL;
char
*primary_mapping_name = NULL;
switch (message->classToCreate)
{
case CameraShipClassID:
//===============================================================
// Create Camera ship
//===============================================================
{
CameraShip
*viewing_camera =
CameraShip::Make((CameraShip::MakeMessage*)message);
Check(viewing_camera);
viewing_entity = viewing_camera;
//------------------------------------------------------------
// Create the controls mapping subsystem resource
//------------------------------------------------------------
CameraControlsMapper::SubsystemResource
control_subsystem_resource;
Str_Copy(
control_subsystem_resource.subsystemName,
"ControlsMapper",
sizeof(control_subsystem_resource.subsystemName)
);
control_subsystem_resource.classID = TrivialSubsystemClassID;
control_subsystem_resource.subsystemModelSize =
sizeof(control_subsystem_resource);
CameraControlsMapper
*camera_mapper;
switch (controls_manager->primaryControlType)
{
case LBE4ControlsManager::PrimaryThrustMaster:
camera_mapper =
new CameraThrustmasterMapper(
viewing_camera,
0,
&control_subsystem_resource
);
primary_mapping_name = "Thrustmaster";
break;
case LBE4ControlsManager::PrimaryRIO:
camera_mapper =
new CameraRIOMapper(
viewing_camera,
0,
&control_subsystem_resource
);
primary_mapping_name = "L4";
break;
default:
camera_mapper =
new CameraL4Mapper(
viewing_camera,
0,
&control_subsystem_resource
);
break;
}
//------------------------------------------------------------
// Attach the mapping subsystem to the entity
//------------------------------------------------------------
viewing_camera->SetMappingSubsystem(camera_mapper);
}
break;
case MechClassID:
//===============================================================
// Create Mech
//===============================================================
{
Mech
*viewing_mech = Mech::Make((Mech::MakeMessage*)message);
Check(viewing_mech);
viewing_entity = viewing_mech;
//------------------------------------------------------------
// Control deadbanding
//------------------------------------------------------------
controls_manager->SetJoystickDeadBand(0.05f);
controls_manager->SetThrottleDeadBand(0.05f);
controls_manager->SetPedalsDeadBand(0.05f);
MechControlsMapper
*mech_mapper;
switch (controls_manager->primaryControlType)
{
case LBE4ControlsManager::PrimaryThrustMaster:
mech_mapper =
new MechThrustmasterMapper(
viewing_mech,
0,
"ControlsMapper"
);
primary_mapping_name = "Thrustmaster";
break;
case LBE4ControlsManager::PrimaryRIO:
mech_mapper =
new MechRIOMapper(
viewing_mech,
0,
"ControlsMapper"
);
primary_mapping_name = "L4";
break;
default:
DEBUG_STREAM << "*****Mech has no controls mapping!*****";
Fail("BTL4Application::MakeViewpointEntity");
mech_mapper = NULL;
break;
}
//------------------------------------------------------------
// Attach the mapping subsystem to the entity
//------------------------------------------------------------
viewing_mech->SetMappingSubsystem(mech_mapper);
viewing_mech->StartCollisionAssistant();
}
break;
}
//-------------------------------------------------------------------
// Load the control mappings for the entity
//-------------------------------------------------------------------
if (primary_mapping_name)
{
ResourceDescription
*description =
application->GetResourceFile()->SearchList(
viewing_entity->GetResourceID(),
ControlMappingsListResourceType
);
if (description)
{
description =
GetResourceFile()->SearchList(
description->resourceID,
primary_mapping_name
);
if (description)
{
description->Lock();
GetControlsManager()->CreateStreamedMappings(
viewing_entity,
(int*)description->resourceAddress
);
description->Unlock();
}
}
}
//-------------------------------------------------------------------
// Configure the gauges for the entity
//-------------------------------------------------------------------
if (GetGaugeRenderer())
{
GetGaugeRenderer()->ConfigureForModel("Init", viewing_entity);
}
return viewing_entity;
}
//
//#############################################################################
// RunMissionMessageHandler
//#############################################################################
//
void
BTL4Application::RunMissionMessageHandler(RunMissionMessage *message)
{
DEBUG_STREAM << "BTL4Application::RunMissionMessageHandler" << endl;
GetModeManager()->AddModeMask(BTL4ModeManager::ModePlasmaDisplay);
DEBUG_STREAM << "Turning Plasma Score Display On" << endl;
L4Application::RunMissionMessageHandler(message);
}
//
//#############################################################################
// StopMissionMessageHandler
//#############################################################################
//
void
BTL4Application::StopMissionMessageHandler(StopMissionMessage *message)
{
GetModeManager()->RemoveModeMask(BTL4ModeManager::ModePlasmaDisplay);
L4Application::StopMissionMessageHandler(message);
DEBUG_STREAM << "Turning Plasma Score Display Off" << endl;
}
@@ -0,0 +1,69 @@
# BTL4APP.CPP — reconstruction notes (2026-07-18)
**Status: 12/12 functions reconstructed; the binary's `Fail()` line constraint (BTL4APP.CPP:400)
is met exactly.** Source basis: decomp `BT411/reference/decomp/all/part_014.c:8052-8425`,
port semantic map `BT411/game/reconstructed/btl4app.cpp`, surviving headers BTL4APP.HPP /
L4APP.HPP / BTL4MODE.HPP / BTL4ARND.HPP / BTREG.HPP / L4CTRL.HPP / CONTROLS.HPP / MODE.HPP /
APPMSG.HPP / RPL4VID.HPP / RENDERER.HPP / LATTICE.HPP, idiom exemplars AUDSRC.CPP /
BTL4ARND.CPP / L4MPPR.CPP / BTMSSN.CPP.
## Address map (source order = binary emission order) [T1]
| line | function | @addr | size |
|---|---|---|---|
| 100 | ctor | 4d34c4 | 72 |
| 116 | dtor | 4d350c | 44 |
| 125 | MakeRegistry | 4d3538 | 44 |
| 138 | MakeVideoRenderer | 4d3564 | 76 |
| 165 | MakeAudioRenderer | 4d35b0 | 100 |
| 189 | MakeModeManager | 4d3614 | 48 |
| 202 | MakeControlsManager | 4d3644 | 72 |
| 228 | MakeGaugeRenderer | 4d368c | 56 |
| 249 | MakeMission | 4d36c4 | 48 |
| 264 | MakeViewpointEntity | 4d36f4 | 824 (anchor; Fail @ line 400 ✅) |
| 461 | RunMissionMessageHandler | 4d3a2c | 104 |
| 476 | StopMissionMessageHandler | 4d3a94 | 224 |
Note the CPP emission order differs from BTL4APP.HPP's declaration order (ModeManager before
ControlsManager before GaugeRenderer in the binary) — the binary order wins. [T1]
## Decoded constants — all resolve to named 1995 expressions [T1]
- ctor base arg `1` = `BTL4` (`enum ApplicationID {RPL4, BTL4, BTW4}`, APPMSG.HPP:47 — note
the unreleased **BTW4** slot).
- `0x50421` = `BTL4ModeManager::ModeInitial`; `0x400000` = `ModePlasmaDisplay`; the +8/+4
writes = `ModeManager::AddModeMask/RemoveModeMask` inlines (MODE.HPP:56-70, byte-exact).
- `2`/`4` = `LBE4ControlsManager::{PrimaryThrustMaster, PrimaryRIO}` (L4CTRL.HPP IOType).
- `-1` mode mask = `ModeManager::ModeAlwaysActive` (MODE.HPP); keyboard registration =
`ControlsUpdateManager<ControlsKey>::Add(ModeMask, Receiver*, MessageID, Plug*)`
(CONTROLS.HPP:319; the vtbl+0x14 call on `keyboardGroup[KeyboardPC]` @manager+0x1a0).
- Video ctor 5-tuple = `(DefaultRendererRate, MaxRendererComplexity, DefaultRendererPriority,
VisualInterestType, 1)` — signature from RPL4VID.HPP; the two leading globals are
DAT_004e8238/DAT_004e823c (extern consts, RENDERER.HPP:38/41). ⚠ the PORT's btl4app.cpp
maps these to the WRONG positions (globals as args 4-5) — flagged for back-porting.
- Audio ctor = `(GetFrameRate(), GetMissionReviewMode())` — BTL4ARND.HPP:95 proves arg2 is
`Logical mission_review_mode`; DAT_004fd550 = `L4Application::missionReviewMode` static.
`GetFrameRate` naming for FUN_0044e19c is [T3] (port identification, not header-proven).
- All string literals byte-verified via section_dump (51ebd6…51ed40), including
`"*****Mech has no controls mapping!*****"` and the camera/mech `"Thrustmaster"`/`"L4"`
mapping names.
## Judgment calls (flagged, not proven)
- **Banner** copies the stale `rp4lbe4.cc` RP-clone banner because the surviving BTL4APP.HPP
carries the matching stale `rp4lbe4.hh` banner — the pair was cloned from RP together. [T4]
- Include list & order mirror the port's reconstruction, trimmed to 1995 headers. [T4]
- `switch` vs `if/else` for the two class cases compiles identically at -O; switch chosen to
match VWE style elsewhere. [T4]
- Camera-case mapper resource = stack `SubsystemResource` (decomp-proven: 32-byte name copy,
classID 0xf, modelSize 0x30); mech-case mappers take a **CString name** (decomp-proven:
CString ctor + refcount at the call) with `ClassID`/`SharedData` DEFAULTED (0x7dc,
&DefaultData passed by the compiler). [T1 shape / T3 default-arg reading]
- `mech_mapper = NULL;` after `Fail()` reflects the decomp's `puVar3 = 0` (Fail returns in
OPT?); kept. [T1]
- `description->resourceAddress` / `ControlMappingsListResourceType` (== 6) member/constant
names follow the port's ResourceDescription reading; verify against the 1995 RESITEM/RES
headers when that TU is done. [T3]
- Two `Check*` lines were omitted in MakeViewpointEntity to meet the line-400 constraint;
Check macros are invisible in OPT builds so the choice is evidence-neutral, but WHICH
lines the original spent is unknown — revisit if a Borland build ever line-checks. [T4]
## Line-constraint ledger
`BTL4APP.CPP:400` = the only Fail in the TU ✅ met exactly.
+775
View File
@@ -0,0 +1,775 @@
#if !defined(APP_HPP)
# define APP_HPP
# if !defined(NETWORK_HPP)
# include <network.hpp>
# endif
# if !defined(EVENT_HPP)
# include <event.hpp>
# endif
# if !defined(STATE_HPP)
# include <state.hpp>
# endif
# if !defined(CSTR_HPP)
# include <cstr.hpp>
# endif
#if defined(TRACE_FOREGROUND_PROCESSING)
extern BitTrace Foreground_Processing;
#define SET_FOREGROUND_PROCESSING() Foreground_Processing.Set()
#define CLEAR_FOREGROUND_PROCESSING() Foreground_Processing.Clear()
#else
#define SET_FOREGROUND_PROCESSING()
#define CLEAR_FOREGROUND_PROCESSING()
#endif
#if defined(TRACE_UPDATE_MANAGER)
extern BitTrace Update_Manager;
#define SET_UPDATE_MANAGER() Update_Manager.Set()
#define CLEAR_UPDATE_MANAGER() Update_Manager.Clear()
#else
#define SET_UPDATE_MANAGER()
#define CLEAR_UPDATE_MANAGER()
#endif
#if defined(TRACE_RENDERER_MANAGER)
extern BitTrace Renderer_Manager;
#define SET_RENDERER_MANAGER() Renderer_Manager.Set()
#define CLEAR_RENDERER_MANAGER() Renderer_Manager.Clear()
#else
#define SET_RENDERER_MANAGER()
#define CLEAR_RENDERER_MANAGER()
#endif
class Mission;
class Registry;
class InterestManager;
class HostManager;
class UpdateManager;
class RendererManager;
class ControlsManager;
class Entity;
class EntityManager;
class Renderer;
class BackgroundTasks;
class ApplicationManager;
class CameraShip;
class SpoolFile;
class AudioRenderer;
class VideoRenderer;
class GaugeRenderer;
class IcomManager;
class ModeManager;
class Player;
class GeneralEventQueue;
class Entity__MakeMessage;
class ResourceFile;
//##########################################################################
//######################### Application ##############################
//##########################################################################
class Application__StateQueryMessage;
class Application__CheckLoadMessage;
class Application__RunMissionMessage;
class Application__StopMissionMessage;
class Application__SuspendMissionMessage;
class Application__ResumeMissionMessage;
class Application__AbortMissionMessage;
enum EventPriorities
{
MinEventPriority = 0,
LowEventPriority,
DefaultEventPriority,
HighEventPriority,
MaxEventPriority
};
const EventPriorities ControlsEventPriority = HighEventPriority;
const EventPriorities CreationEventPriority = HighEventPriority;
const EventPriorities DestructionEventPriority = HighEventPriority;
const EventPriorities UpdateEventPriority = MaxEventPriority;
const EventPriorities HighInterestEventPriority = DefaultEventPriority;
const EventPriorities LowInterestEventPriority = LowEventPriority;
const EventPriorities EntityManagerEventPriority = DefaultEventPriority;
const EventPriorities EntityInvalidEventPriority = LowEventPriority;
enum ApplicationID
{
RPL4,
BTL4,
NDL4
};
#define EVENT_PRIORITIES_COUNT (5)
class Application:
public NetworkClient
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction, Destruction, and Testing
//
public:
Application(
ResourceFile *resource_file,
ApplicationID application_id,
ClassID class_ID=ApplicationClassID,
SharedData &shared_data=DefaultData
);
~Application();
Logical
TestInstance() const;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Execution control
//
public:
virtual void Initialize();
virtual void
LoadBackgroundTasks();
virtual Logical
ExecuteForeground(
Time start_of_frame,
Scalar frame_duration
);
virtual void
ExecuteBackgroundTask();
void
Stop();
virtual Logical
Shutdown(int remainingApps);
virtual void
Terminate();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Creation Callbacks
//
public:
void
CreateMission(NotationFile *egg_notation_file);
virtual Entity*
MakeAndLinkViewpointEntity(Entity__MakeMessage *message);
protected:
virtual Mission*
MakeMission(
NotationFile *notation_file,
ResourceFile *resources
);
virtual Entity*
MakeViewpointEntity(Entity__MakeMessage *message);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Current mission
//
public:
Mission*
GetCurrentMission();
Player*
GetMissionPlayer()
{return missionPlayer;}
SpoolFile*
GetSpoolFile()
{return spoolFile;}
protected:
Player
*missionPlayer;
SpoolFile*
spoolFile;
Time
lastCreationMessage;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Application State
//
public:
enum {
InitializingState = 0,
WaitingForEgg,
LoadingMission,
WaitingForLaunch,
LaunchingMission,
RunningMission,
EndingMission,
StoppingMission,
SuspendingMission,
ResumingMission,
AbortingMission,
CreatingMission,
ApplicationStateCount
};
Enumeration
GetApplicationState();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// System level event processing
//
public:
void
Post(
int priority,
Receiver *target,
Receiver::Message *message,
const Time &when=Time::Null
);
void
SendEvent(
int priority,
HostID host_ID,
NetworkManager::ClientID client_ID,
Receiver::Message *message,
Time when=Time::Null
);
void
BroadcastEvent(
int priority,
NetworkManager::ClientID client_ID,
Receiver::Message *message,
Time when=Time::Null
);
void
ExclusiveBroadcastEvent(
int priority,
NetworkManager::ClientID client_ID,
Receiver::Message *message,
Time when=Time::Null
);
#if defined(TRACE_EVENT_COUNT)
size_t
GetEventCount();
#endif
void
DumpEventQueue();
#if 0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Creation and Interest Event Posting
//
public:
void
PostCreationEvent(
Receiver::Message *message,
const Time &when=Time::Null
);
void
PostInterestEvent(
Entity *entity,
Renderer *renderer
);
void
PostUpdateEvent(
Entity *entity,
Receiver::Message *message
);
void
PostDestructionEvent(
Entity *entity,
Receiver::Message *message
);
#endif
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// System level message processing
//
public:
void
SendMessage(
HostID host_ID,
NetworkManager::ClientID client_ID,
Receiver::Message *message
);
void
BroadcastMessage(
NetworkManager::ClientID client_ID,
Receiver::Message *message
);
void
ExclusiveBroadcastMessage(
NetworkManager::ClientID client_ID,
Receiver::Message *message
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Event level event processing
//
public:
Logical
ProcessOneEvent(int min_priority=0);
void
ProcessAllEvents(int min_priority=0);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Accessors
//
public:
Scalar
GetApplicationLoopFrameRate();
Scalar
GetSecondsRemainingInGame()
{return secondsRemainingInGame;}
ApplicationID
GetApplicationID()
{return applicationID;}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Module accessors
//
public:
//
// Managers
//
NetworkManager*
GetNetworkManager();
EntityManager*
GetEntityManager();
Registry*
GetRegistry();
HostManager*
GetHostManager();
InterestManager*
GetInterestManager();
UpdateManager*
GetUpdateManager();
RendererManager*
GetRendererManager();
ControlsManager*
GetControlsManager();
IcomManager*
GetIntercomManager();
AudioRenderer*
GetAudioRenderer();
VideoRenderer*
GetVideoRenderer();
GaugeRenderer*
GetGaugeRenderer();
ModeManager*
GetModeManager();
//
// StreamableResourceFile
//
ResourceFile*
GetResourceFile();
void
SetResourceFile(ResourceFile *resources);
ApplicationManager*
GetApplicationManager();
//
// Viewpoint entity
//
Entity*
GetViewpointEntity();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Message Support
//
public:
enum {
StateQueryMessageID = NetworkClient::NextMessageID,
CheckLoadMessageID,
RunMissionMessageID,
StopMissionMessageID,
KeyCommandMessageID,
SuspendMissionMessageID,
ResumeMissionMessageID,
LoadMissionMessageID,
AbortMissionMessageID,
NextMessageID
};
typedef Application__StateQueryMessage StateQueryMessage;
typedef Application__CheckLoadMessage CheckLoadMessage;
typedef Application__RunMissionMessage RunMissionMessage;
typedef Application__StopMissionMessage StopMissionMessage;
typedef Application__SuspendMissionMessage SuspendMissionMessage;
typedef Application__ResumeMissionMessage ResumeMissionMessage;
typedef Application__AbortMissionMessage AbortMissionMessage;
static const HandlerEntry
MessageHandlerEntries[];
//static MessageHandlerSet MessageHandlers;
static MessageHandlerSet& GetMessageHandlers();
void
StateQueryMessageHandler(StateQueryMessage *message);
void
CheckLoadMessageHandler(CheckLoadMessage *message);
void
RunMissionMessageHandler(RunMissionMessage *message);
void
StopMissionMessageHandler(StopMissionMessage *message);
void
SuspendMissionMessageHandler(SuspendMissionMessage *message);
void
ResumeMissionMessageHandler(ResumeMissionMessage *message);
void
KeyCommandMessageHandler(ReceiverDataMessageOf<int> *message);
void
LoadMissionMessageHandler(Message *message);
void
AbortMissionMessageHandler(AbortMissionMessage *message);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data Support
//
public:
static Derivation *GetClassDerivations();
static SharedData DefaultData;
static Logical DoSuppressGauges() { return suppressGauges; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Modules
//
protected:
//
// Managers
//
NetworkManager
*networkManager;
EntityManager
*entityManager;
Registry
*registry;
HostManager
*hostManager;
InterestManager
*interestManager;
UpdateManager
*updateManager;
RendererManager
*rendererManager;
ControlsManager
*controlsManager;
IcomManager
*intercomManager;
AudioRenderer
*audioRenderer;
VideoRenderer
*videoRenderer;
GaugeRenderer
*gaugeRenderer;
ModeManager
*modeManager;
static Logical suppressGauges;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Module Creation
//
protected:
//
// Managers
//
virtual NetworkManager*
MakeNetworkManager();
virtual Registry*
MakeRegistry();
virtual ControlsManager*
MakeControlsManager();
virtual IcomManager*
MakeIntercomManager();
virtual InterestManager*
MakeInterestManager();
virtual AudioRenderer*
MakeAudioRenderer();
virtual VideoRenderer*
MakeVideoRenderer();
virtual GaugeRenderer*
MakeGaugeRenderer(int *secondaryIndex, int *aux1Index, int *aux2Index);
virtual ModeManager*
MakeModeManager();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Private data
//
protected:
ApplicationID
applicationID;
Scalar
secondsRemainingInGame;
Time
gameStarted;
GeneralEventQueue
*eventQueue;
BackgroundTasks
*backgroundTasks;
ResourceFile
*resourceFile;
Entity
*viewpointEntity;
Logical
executeFrames;
StateIndicator
applicationState;
Mission
*currentMission;
Logical
routePacketFinished;
};
extern Application *application;
extern int Exit_Code;
//~~~~~~~~~~~~~~~~~~~~ Application__CheckLoadMessage ~~~~~~~~~~~~~~~~~~~~~~~
class Application__CheckLoadMessage:
public NetworkClient::Message
{
public:
Application__CheckLoadMessage();
};
//~~~~~~~~~~~~~~~~~~~~~~~~~ Application inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
inline Mission*
Application::GetCurrentMission()
{
Check(this);
return currentMission;
}
inline Enumeration
Application::GetApplicationState()
{
Check(this);
return applicationState.GetState();
}
inline void
Application::Post(
int priority,
Receiver *target,
Receiver::Message *message,
const Time &when
)
{
Check(this);
eventQueue->Post(priority,target,message,when);
}
inline void
Application::SendEvent(
int priority,
HostID host_ID,
NetworkClient::ClientID client_ID,
Receiver::Message *message,
Time when
)
{
Check(this);
eventQueue->SendEvent(priority,host_ID,client_ID,message,when);
}
inline void
Application::BroadcastEvent(
int priority,
NetworkClient::ClientID client_ID,
Receiver::Message *message,
Time when
)
{
Check(this);
eventQueue->BroadcastEvent(priority,client_ID,message,when);
}
inline void
Application::ExclusiveBroadcastEvent(
int priority,
NetworkClient::ClientID client_ID,
Receiver::Message *message,
Time when
)
{
Check(this);
eventQueue->ExclusiveBroadcastEvent(priority,client_ID,message,when);
}
#if defined(GET_EVENT_COUNT)
inline size_t
Application::GetEventCount()
{
return eventQueue->GetEventCount();
}
#endif
inline void
Application::DumpEventQueue()
{
eventQueue->DumpEventQueue();
}
inline void
Application::SendMessage(
HostID host_ID,
NetworkClient::ClientID client_ID,
Receiver::Message *message
)
{
Check(this);
networkManager->Send(message,client_ID,host_ID);
}
inline void
Application::BroadcastMessage(
NetworkManager::ClientID client_ID,
Receiver::Message *message
)
{
Check(this);
networkManager->Broadcast(message,client_ID);
}
inline void
Application::ExclusiveBroadcastMessage(
NetworkManager::ClientID client_ID,
Receiver::Message *message
)
{
Check(this);
networkManager->ExclusiveBroadcast(message,client_ID);
}
inline Logical
Application::ProcessOneEvent(int min_priority)
{
Check(this);
return eventQueue->ProcessOneEvent(min_priority);
}
inline void
Application::ProcessAllEvents(int min_priority)
{
Check(this);
eventQueue->ProcessAllEvents(min_priority);
}
inline NetworkManager*
Application::GetNetworkManager()
{
Check(networkManager);
return networkManager;
}
inline EntityManager*
Application::GetEntityManager()
{
return entityManager;
}
inline Registry*
Application::GetRegistry()
{
return registry;
}
inline HostManager*
Application::GetHostManager()
{
return hostManager;
}
inline InterestManager*
Application::GetInterestManager()
{
return interestManager;
}
inline UpdateManager*
Application::GetUpdateManager()
{
return updateManager;
}
inline RendererManager*
Application::GetRendererManager()
{
return rendererManager;
}
inline ControlsManager*
Application::GetControlsManager()
{
return controlsManager;
}
inline IcomManager*
Application::GetIntercomManager()
{
return intercomManager;
}
inline ResourceFile*
Application::GetResourceFile()
{
return resourceFile;
}
inline void
Application::SetResourceFile(ResourceFile *resources)
{
resourceFile = resources;
}
inline Entity*
Application::GetViewpointEntity()
{
return viewpointEntity;
}
inline AudioRenderer*
Application::GetAudioRenderer()
{
return audioRenderer;
}
inline VideoRenderer*
Application::GetVideoRenderer()
{
return videoRenderer;
}
inline GaugeRenderer*
Application::GetGaugeRenderer()
{
return gaugeRenderer;
}
inline ModeManager*
Application::GetModeManager()
{
return modeManager;
}
#endif
+267
View File
@@ -0,0 +1,267 @@
#if !defined(AUDREND_HPP)
# define AUDREND_HPP
# if !defined(RENDERER_HPP)
# include <renderer.hpp>
# endif
# if !defined(AUDIO_HPP)
# include <audio.hpp>
# endif
# if !defined(AUDSRC_HPP)
# include <audsrc.hpp>
# endif
# if !defined(AUDWGT_HPP)
# include <audwgt.hpp>
# endif
# if !defined(EVENT_HPP)
# include <event.hpp>
# endif
# if !defined(VCHAIN_HPP)
# include <vchain.hpp>
# endif
# if !defined(L4AUDHDW_HPP)
# include <l4audhdw.hpp>
# endif
//##########################################################################
//######################## AudioRenderer #############################
//##########################################################################
class AudioEvent;
class AudioRenderer:
public Renderer
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction, Destruction, Testing
//
public:
AudioRenderer(RendererRate render_rate);
~AudioRenderer();
Logical
TestInstance() const;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Renderer Interface
//
public:
virtual void
Initialize();
void
LinkToEntity(Entity *entity);
AudioHead*
GetAudioHead();
AudioFrameCount
GetAudioFrameCount();
void
PostAudioRequestMessage(
AudioSource *audio_source,
AudioSource::RequestMessage *message
);
Logical
ProcessAudioRequestMessage();
void
FlushAudioMessages(AudioSource *audio_source);
Logical
ExecuteBackground();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Implementations
//
protected:
void
ExecuteImplementation(
RendererComplexity complexity_update,
RendererOrigin::InterestingEntityIterator *iterator
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Private Methods
//
private:
virtual AudioHead*
MakeAudioHead();
void
StartEntityEffectImplementation(
Entity *entity,
DamageZone *damage_zone,
ResourceDescription::ResourceID resource_ID
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Private data
//
private:
typedef VChainOf<AudioEvent*, AudioWeighting>
AudioEventSocket;
typedef VChainIteratorOf<AudioEvent*, AudioWeighting>
AudioEventIterator;
AudioHead
*audioHead;
AudioEventSocket
audioEventSocket;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Audio Renderer Statistics
//
#ifdef LAB_ONLY
public:
int
sourceClippedCount;
int
sourceStartCount;
int
sourceSuspendCount;
int
sourceResumeCount;
int
doubleTriggerCount;
int
resourceStealCount;
int
resourceStealPriorityCount;
int
resourceStealVolumeCount;
int
stealShortDurationCount;
#endif
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioRenderer inlines ~~~~~~~~~~~~~~~~~~~~~~~~
inline AudioHead*
AudioRenderer::GetAudioHead()
{
Check(audioHead);
return audioHead;
}
inline AudioFrameCount
AudioRenderer::GetAudioFrameCount()
{
Check(audioHead);
return audioHead->GetAudioFrameCount();
}
inline Logical
AudioRenderer::ExecuteBackground()
{
Check(this);
return ProcessAudioRequestMessage();
}
//~~~~~~~~~~~~~~~~~~~~~~~~ AudioRenderer profile macros ~~~~~~~~~~~~~~~~~~~~
#if defined(TRACE_AUDIO_RENDERER)
extern BitTrace Audio_Renderer;
#define SET_AUDIO_RENDERER() Audio_Renderer.Set()
#define CLEAR_AUDIO_RENDERER() Audio_Renderer.Clear()
#else
#define SET_AUDIO_RENDERER()
#define CLEAR_AUDIO_RENDERER()
#endif
#if defined(TRACE_AUDIO_RENDERER_CREATE_OBJECTS)
extern BitTrace Audio_Renderer_Create_Objects;
#define SET_AUDIO_RENDERER_CREATE_OBJECTS() Audio_Renderer_Create_Objects.Set()
#define CLEAR_AUDIO_RENDERER_CREATE_OBJECTS() Audio_Renderer_Create_Objects.Clear()
#else
#define SET_AUDIO_RENDERER_CREATE_OBJECTS()
#define CLEAR_AUDIO_RENDERER_CREATE_OBJECTS()
#endif
#if defined(TRACE_AUDIO_RENDERER_DESTROY_OBJECTS)
extern BitTrace Audio_Renderer_Destroy_Objects;
#define SET_AUDIO_RENDERER_DESTROY_OBJECTS() Audio_Renderer_Destroy_Objects.Set()
#define CLEAR_AUDIO_RENDERER_DESTROY_OBJECTS() Audio_Renderer_Destroy_Objects.Clear()
#else
#define SET_AUDIO_RENDERER_DESTROY_OBJECTS()
#define CLEAR_AUDIO_RENDERER_DESTROY_OBJECTS()
#endif
#if defined(TRACE_AUDIO_RENDERER_START_HANDLER)
extern BitTrace Audio_Renderer_Start_Handler;
#define SET_AUDIO_RENDERER_START_HANDLER() Audio_Renderer_Start_Handler.Set()
#define CLEAR_AUDIO_RENDERER_START_HANDLER() Audio_Renderer_Start_Handler.Clear()
#else
#define SET_AUDIO_RENDERER_START_HANDLER()
#define CLEAR_AUDIO_RENDERER_START_HANDLER()
#endif
#if defined(TRACE_AUDIO_RENDERER_STOP_HANDLER)
extern BitTrace Audio_Renderer_Stop_Handler;
#define SET_AUDIO_RENDERER_STOP_HANDLER() Audio_Renderer_Stop_Handler.Set()
#define CLEAR_AUDIO_RENDERER_STOP_HANDLER() Audio_Renderer_Stop_Handler.Clear()
#else
#define SET_AUDIO_RENDERER_STOP_HANDLER()
#define CLEAR_AUDIO_RENDERER_STOP_HANDLER()
#endif
#if defined(TRACE_AUDIO_RENDERER_EXECUTE)
extern BitTrace Audio_Renderer_Execute;
#define SET_AUDIO_RENDERER_EXECUTE() Audio_Renderer_Execute.Set()
#define CLEAR_AUDIO_RENDERER_EXECUTE() Audio_Renderer_Execute.Clear()
#else
#define SET_AUDIO_RENDERER_EXECUTE()
#define CLEAR_AUDIO_RENDERER_EXECUTE()
#endif
//##########################################################################
//######################### AudioEvent ###############################
//##########################################################################
#define AUDIOEVENT_MEMORYBLOCK_ALLOCATION (20)
class AudioEvent:
public Node
{
friend class AudioRenderer;
private:
AudioEvent(
AudioSource *target,
AudioSource::RequestMessage *message
);
~AudioEvent();
static MemoryBlock* GetAllocatedMemory();
void* operator new(size_t) { return GetAllocatedMemory()->New(); }
void operator delete(void *where) { GetAllocatedMemory()->Delete(where); }
void
Process();
void
ReleaseLinkHandler(
Socket *socket,
Plug *plug
);
AudioSource::RequestMessage
*messageToSend;
SlotOf<AudioSource*>
targetReceiver;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioEvent inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
inline void
AudioEvent::Process()
{
Check(targetReceiver.GetCurrent());
targetReceiver.GetCurrent()->Receive(messageToSend);
Unregister_Object(this);
delete this;
}
#endif
@@ -0,0 +1,23 @@
# Engine header backfills — shared notes (2026-07-19)
Per-file evidence for the `MUNGA/` back-dates. All were produced by `../backdate.py` from the
BT412 WinTesla donors (`C:\VWE\BT412\engine\MUNGA\*.h`), then compile-reviewed under BC4.52 —
**the period compiler is the reviewer**: it rejects post-1994 constructs the donors carry.
Common mechanical transforms: `#pragma once`→guard, `#include "x.h"`→guarded `<x.hpp>`,
`std::`→(none), `true/false/bool``True/False/Logical`, drop `<ostream>`-era includes.
VDATA.HPP has its own sidecar (VDATA.NOTES.md).
| file | donor | validation | hand fixes / open items |
|---|---|---|---|
| ROTATION.HPP | ROTATION.h (307 l) | compile-proven via BTTEAM/BTL4ARND closure; `ROTATION.TCP` survives as the period test source (cross-check pending [T3]) | ostream idiom restored per surviving VECTOR3D.HPP |
| VECTOR2D.HPP | VECTOR2D.h (285 l) | compile-proven via CONTROLS.HPP closure | ostream + `true``True` |
| AUDREND.HPP | AUDREND.h (250 l) | **compile-proven: BTL4ARND.CPP (original) builds clean against it** | REMOVED `virtual ReleaseSourceSet(SourceSet&)=0` — OpenAL-era addition, zero period references [T1]; ADDED guarded `<vchain.hpp>` (donor relied on lax includes); relative `..\munga_l4\l4audhdw.h``<l4audhdw.hpp>` |
| APP.HPP | APP.h (764 l) | **compile-proven via BTTEAM/BTCNSL closure** (round 2) | none yet — re-review when a TU exercises more of it |
| LAMP.HPP | LAMP.h (189 l) | compile-proven via the BTTOOL closure (chain resolved by GAUGREND+GAUGE) | — |
| GAUGREND.HPP | GAUGREND.h (735 l) | parses through the BTTOOL closure [T3] | `<fstream>``<fstream.h>` |
| GAUGE.HPP | GAUGE.h (450 l) | parses through the BTTOOL closure [T3] | — |
Class-layout caution: a back-dated header that DROPS or ADDS virtuals/members changes vtable
and object layout versus the shipped binary. `AUDREND.HPP`'s removed virtual matches 1995
truth (no period reference anywhere); any future ambiguity must be settled against the decomp
(vtable slot counts at the class's PTR_FUN table) before trusting layout-sensitive code.
+450
View File
@@ -0,0 +1,450 @@
#if !defined(GAUGE_HPP)
# define GAUGE_HPP
# if !defined(STYLE_HPP)
# include <style.hpp>
# endif
typedef unsigned int GaugeRate;
class GaugeRenderer;
class GaugeBase;
class GraphicGaugeBackground;
class Gauge;
class GraphicGauge;
class GaugeConnection;
class Entity;
class GaugeAlarmManager;
# if !defined(MODE_HPP)
# include <mode.hpp>
# endif
# if !defined(SLOT_HPP)
# include <slot.hpp>
# endif
# if !defined(CHAIN_HPP)
# include <chain.hpp>
# endif
# if !defined(RECEIVER_HPP)
# include <receiver.hpp>
# endif
# if !defined(GRAPH2D_HPP)
# include <graph2d.hpp>
# endif
//#########################################################################
//############################# GaugeBase #################################
//#########################################################################
class GaugeBase :
public Node
{
friend class GaugeRenderer;
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
protected:
GaugeBase(
ModeMask mode_mask,
GaugeRenderer *renderer,
unsigned int owner_ID,
const char *identification_string
);
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
public:
virtual ~GaugeBase();
//----------------------------------------------------------------------
// Test methods
//----------------------------------------------------------------------
Logical
TestInstance() const;
//----------------------------------------------------------------------
// Update methods
//----------------------------------------------------------------------
virtual void
BecameActive(),
BecameInactive(),
Inactivate(),
UpdateProfile(Scalar frame_percentage),
ReportProfile();
virtual Logical
Update(GaugeRate rate_mask);
virtual void
LinkToEntity(Entity *entity),
NotifyOfNewInterestingEntity(Entity *entity),
NotifyOfBecomingUninterestingEntity(Entity *entity);
virtual int
DiscernTier();
//----------------------------------------------------------------------
// Public data
//----------------------------------------------------------------------
public:
Logical
alreadyActivatedFlag; // This is really a visibility flag.
// Active/inactive lists are more like
// "should get redrawn" lists
//----------------------------------------------------------------------
// Protected data
//----------------------------------------------------------------------
protected:
Logical
stayInactive; // used by GaugeRenderer during activation
unsigned int
ownerID;
ModeMask
modeMask;
GaugeRenderer
*renderer;
const char
*identificationString;
};
//#########################################################################
//########################### GaugeBackground #############################
//#########################################################################
class GaugeBackground :
public GaugeBase
{
protected:
GaugeBackground(
ModeMask mode_mask,
GaugeRenderer *renderer,
unsigned int owner_ID,
const char *identification_string = "GraphicGaugeBackground"
);
};
//#########################################################################
//######################## GraphicGaugeBackground #########################
//#########################################################################
class GraphicGaugeBackground :
public GaugeBackground
{
protected:
GraphicGaugeBackground(
ModeMask mode_mask,
GaugeRenderer *renderer,
unsigned int owner_ID,
int graphics_port_number,
const char *identification_string = "GraphicGaugeBackground"
);
//----------------------------------------------------------------------
// Protected data
//----------------------------------------------------------------------
GraphicsView
localView;
};
//#########################################################################
//########################## GaugeConnection ##############################
//#########################################################################
// The GaugeConnection object maintains one instance of a mapping from
// a value in some location to a parameter for a gauge.
class GaugeConnection :
public Plug
{
friend class Gauge;
public:
GaugeConnection(int parameter_ID);
~GaugeConnection();
Logical
TestInstance() const;
protected:
virtual void ShowInstance(char *indent);
virtual void Update();
int parameterID;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GaugeConnectionDirectOf ~~~~~~~~~~~~~~~~~~
template <class T> class GaugeConnectionDirectOf:
public GaugeConnection
{
friend class Gauge;
public:
GaugeConnectionDirectOf(
int parameter_ID,
T* data_destination,
T* data_source
);
~GaugeConnectionDirectOf();
Logical
TestInstance() const;
protected:
void
Update();
void
ShowInstance(char *indent);
T *dataSource;
T *dataDestination;
};
template <class T> GaugeConnectionDirectOf<T>::GaugeConnectionDirectOf(
int parameter_ID,
T* data_destination,
T* data_source
):
GaugeConnection(parameter_ID),
dataSource(data_source),
dataDestination(data_destination)
{
Check_Pointer(this);
Check_Pointer(data_destination);
//
// BT DEV-GAUGES bring-up: some gauge widgets bind to mech data sources that
// are not reconstructed yet, so the attribute resolves to a NULL data_source
// (see the "(Scalar *) is VERY dangerous!" note in L4GAUGE.cpp). Rather than
// AV here (and later in Update()), bind to a static zero so the gauge simply
// reads 0. Gated on BT_DEV_GAUGES so the POD path is byte-unchanged.
//
if (data_source == NULL)
{
// Desktop gauge modes (BT_DEV_GAUGES dev composite OR L4MFDSPLIT
// single-window cockpit) wake the gauge renderer off the pod, where
// some attribute sources bind NULL; bind a static zero so the gauge
// reads 0 instead of AV'ing here (and in Update()). The pod path
// binds every source, so this never triggers there -- byte-unchanged.
static int s_devGauges = -1;
if (s_devGauges < 0)
s_devGauges = (getenv("BT_DEV_GAUGES") != NULL ||
getenv("L4MFDSPLIT") != NULL) ? 1 : 0;
if (s_devGauges)
{
static T s_gaugeNullSource = T();
dataSource = &s_gaugeNullSource;
data_source = &s_gaugeNullSource;
}
}
Check_Pointer(data_source);
*dataDestination = *dataSource;
Verify(*dataDestination == *dataSource);
Check(this);
}
template <class T> GaugeConnectionDirectOf<T>::~GaugeConnectionDirectOf()
{}
template <class T> void
GaugeConnectionDirectOf<T>::Update()
{
Check(this);
Check_Pointer(dataSource);
Check_Pointer(dataDestination);
*dataDestination = *dataSource;
Verify(*dataDestination == *dataSource);
Check(this);
}
template <class T> void
GaugeConnectionDirectOf<T>::ShowInstance(char *indent)
{
Check(this);
Check_Pointer(dataSource);
Check_Pointer(dataDestination);
cout << indent << "GaugeConnectionDirectOf:\n";
cout << indent << "...dataSource at" <<
dataSource << "=" << *dataSource << "\n";
cout << indent << "...dataDestination at" <<
dataSource << "\n" << flush;
GaugeConnection::ShowInstance(indent);
}
template <class T> Logical
GaugeConnectionDirectOf<T>::TestInstance() const
{
Check_Pointer(this);
Check_Pointer(dataSource);
Check_Pointer(dataDestination);
return Plug::TestInstance();
}
//#########################################################################
//################################# Gauge #################################
//#########################################################################
class Gauge :
public GaugeBase
{
public:
enum
{
gaugeRate_A=0xFFFF, // every frame
gaugeRate_B=0xAAAA, // every other frame
gaugeRate_C=0x5555,
gaugeRate_D=0x8888, // every 4th frame
gaugeRate_E=0x4444,
gaugeRate_F=0x2222,
gaugeRate_G=0x1111,
gaugeRate_H=0x8080, // every 8th frame
gaugeRate_I=0x4040,
gaugeRate_J=0x2020,
gaugeRate_K=0x1010,
gaugeRate_L=0x0808,
gaugeRate_M=0x0404,
gaugeRate_N=0x0202,
gaugeRate_O=0x0101,
gaugeRate_P=0x8000, // every 16th frame
gaugeRate_Q=0x4000,
gaugeRate_R=0x2000,
gaugeRate_S=0x1000,
gaugeRate_T=0x0800,
gaugeRate_U=0x0400,
gaugeRate_V=0x0200,
gaugeRate_W=0x0100,
gaugeRate_X=0x0080,
gaugeRate_Y=0x0040,
gaugeRate_Z=0x0020,
gaugeRate_Z0=0x0010,
gaugeRate_Z1=0x0008,
gaugeRate_Z2=0x0004,
gaugeRate_Z3=0x0002,
gaugeRate_Z4=0x0001
};
//----------------------------------------------------------------------
// Public static methods and data
//----------------------------------------------------------------------
static GaugeRate
rateTable[31];
static GaugeRate
NextFirstTierGaugeRate(), // returns either B,C
NextSecondTierGaugeRate(), // returns DEFG
NextThirdTierGaugeRate(), // returns HIJKLMNO
NextFourthTierGaugeRate(); // returns PQRSTUVWXYZ
static GaugeRate
ConvertIndexToRate(int index);
//----------------------------------------------------------------------
// Constructor method
//----------------------------------------------------------------------
Gauge(
GaugeRate new_rate,
ModeMask mode_mask,
GaugeRenderer *renderer,
unsigned int owner_ID,
const char *identification_string = "Gauge"
);
//----------------------------------------------------------------------
// Destructor method
//----------------------------------------------------------------------
~Gauge();
//----------------------------------------------------------------------
// Test methods
//----------------------------------------------------------------------
Logical
TestInstance() const;
void
ShowInstance(char *indent);
int
DiscernTier();
static Logical
TestClass();
//----------------------------------------------------------------------
// Connection methods
//----------------------------------------------------------------------
virtual void
AddConnection(GaugeConnection *connection),
RemoveConnection(int parameter_ID),
RemoveAllConnections();
//----------------------------------------------------------------------
// Update methods
//----------------------------------------------------------------------
void
Disable(Logical disable_state);
Logical
Update(GaugeRate rate_mask);
protected:
virtual void
Execute(); // Execute internal processes to display the gauge
// BT DEV-GAUGES bring-up: SEH wrapper around Execute() so a gauge whose
// game-state data binding isn't reconstructed yet is skipped (not crashed).
// Returns False if Execute() raised a structured exception (e.g. an AV).
Logical
GuardedExecute();
//----------------------------------------------------------------------
// Protected data
//----------------------------------------------------------------------
protected:
GaugeRate
rate,
oldRate;
ChainOf<GaugeConnection*>
instanceList;
//---------------------------------------
// Profiling data
//---------------------------------------
void
UpdateProfile(Scalar frame_percentage),
ReportProfile();
Scalar
profileFramePercentage,
profileMaxFramePercentage;
int
profileCycles;
};
//#########################################################################
//############################# GraphicGauge ##############################
//#########################################################################
class GraphicGauge :
public Gauge
{
public:
//
//----------------------------------------------------------------------
// Public methods
//----------------------------------------------------------------------
//
GraphicGauge(
GaugeRate new_rate,
ModeMask mode_mask,
GaugeRenderer *renderer,
unsigned int owner_ID,
int graphics_port_number,
const char *identification_string = "GraphicGauge"
);
~GraphicGauge();
Logical
TestInstance() const;
void
ShowInstance(char *indent);
//----------------------------------------------------------------------
// Public data
//----------------------------------------------------------------------
GraphicsView
localView;
};
#endif
+741
View File
@@ -0,0 +1,741 @@
#if !defined(GAUGREND_HPP)
# define GAUGREND_HPP
#if defined(TRACE_GUAUGE_RENDERER)
extern BitTrace Gauge_Renderer;
#define SET_GUAGE_RENDERER() Gauge_Renderer.Set()
#define CLEAR_GUAGE_RENDERER() Gauge_Renderer.Clear()
#else
#define SET_GAUGE_RENDERER()
#define CLEAR_GAUGE_RENDERER()
#endif
class GaugeSymbol;
class GaugeSymbolTable;
class GaugeInterpreter;
struct ParameterDescription;
struct MethodDescription;
class GaugeRenderer;
class LampManager;
#include <fstream.h>
# if !defined(RENDERER_HPP)
# include <renderer.hpp>
# endif
# if !defined(GAUGALRM_HPP)
# include <gaugalrm.hpp>
# endif
# if !defined(RESOURCE_HPP)
# include <resource.hpp>
# endif
# if !defined(GAUGMAP_HPP)
# include <gaugmap.hpp>
# endif
# if !defined(GAUGE_HPP)
# include <gauge.hpp>
# endif
# if !defined(LAMP_HPP)
# include <lamp.hpp>
# endif
# if !defined(WRHOUS_HPP)
# include <wrhous.hpp>
# endif
struct LookupTable
{
const
char *typeString;
int
value;
int
Search(const char *string);
};
//#######################################################################
// Interpreter
//#######################################################################
typedef unsigned char GaugeInterpreterCommand;
typedef int GaugeInterpreterOffset;
class GaugeSymbol SIGNATURED
{
friend class GaugeSymbolTable;
friend class GaugeInterpreter;
public:
~GaugeSymbol(); // WARNING - do NOT destroy individual entries!
// This implementation assumes that once a symbol
// is defined, it exists until ALL symbols are
// destroyed: this allows a very simple singly-
// linked-list structure.
// Deleting an entry WILL corrupt the list.
Logical
TestInstance() const;
protected:
GaugeSymbol(
GaugeSymbol **head_pointer,
const char *label,
GaugeInterpreterOffset offset,
Logical resolved
);
char
label[32];
GaugeInterpreterOffset
offset;
Logical
resolved;
GaugeSymbol
*nextSymbol;
};
class GaugeSymbolTable SIGNATURED
{
friend class GaugeInterpreter;
public:
enum
{
errUnresolvedForwardReference = -2,
errUndefinedSymbol = -3
};
~GaugeSymbolTable();
Logical
TestInstance() const;
protected:
GaugeSymbolTable(char *table_pointer);
void
Add(const char *label, GaugeInterpreterOffset offset);
GaugeInterpreterOffset
Refer(const char *label, GaugeInterpreterOffset offset);
GaugeInterpreterOffset
Get(const char *label);
const char *
LabelFromValue(GaugeInterpreterOffset offset);
Logical
UnresolvedForwardReferences();
GaugeSymbol
*head;
char
*tablePointer;
};
class GaugeInterpreter SIGNATURED
{
friend struct MethodDescription;
friend class GaugeRenderer;
public:
~GaugeInterpreter();
Logical
TestInstance() const;
const char *
GetToken();
void
UngetPreviousToken();
Logical
GetInteger(int *int_pointer);
Logical
GetScalar(Scalar *scalar_pointer);
Logical
GetVector(Vector2DOf<int> *vector);
Logical
GetRate(GaugeRate *rate);
Logical
GetModeMask(ModeMask *mode_mask_pointer);
const char *
ReplaceVariable(const char *possible_variable_name);
void
DumpTable();
protected:
GaugeInterpreter();
void
Initialize(
const char *file_name,
MethodDescription **method_list,
Warehouse *warehouse_pointer
);
void
GetProcedureBody(
MethodDescription **method_list,
Warehouse *warehouse_pointer
);
void
ReportParsingError(
const char *string
);
Logical
ParsePrimitive(
const char *name,
MethodDescription **method_list,
Warehouse *warehouse_pointer
);
public:
void
Insert(const void *value, int size_in_chars);
void *
Retrieve(int size_in_chars);
void
InsertString(const char *string);
const char *
RetrieveString();
protected:
void
Interpret(
const char *label,
GaugeRenderer *renderer,
int display_port_index,
Vector2DOf<int> position,
Entity *entity
);
void
InterpretFromOffset(
GaugeInterpreterOffset offset,
GaugeRenderer *renderer,
int display_port_index,
Vector2DOf<int> position,
Entity *entity
);
enum
{
endMarker=0,
returnCommand,
setPortIndexCommand,
addOffsetCommand,
callCommand,
enableCommand,
disableCommand,
attributeVariableCommand,
nextAvailableCommand
};
enum
{
// The original (RP) value 46864 is too small for BattleTech's larger
// gauge config: as more BT gauge widgets are registered, more of
// L4GAUGE.CFG resolves into interpreter bytecode instead of being
// parse-skipped, overflowing the fixed table. The Insert() bounds guard
// is a Verify() that compiles out at DEBUG_LEVEL 0, so the overflow was
// a SILENT heap corruption (detected later in mission bitmap loading).
// Sized generously for BT's full config. (was 46864)
interpreterTableSize = 262144
};
enum
{
maxVariableNameArrayIndex = 10
};
filebuf file;
char currentToken[64];
Logical tokenNotTaken;
int lineNumber;
GaugeSymbolTable *symbolTable;
MethodDescription **primitiveTable;
int primitiveCount;
char *interpreterTable;
GaugeInterpreterOffset currentOffset;
const char *attributeNameArray[maxVariableNameArrayIndex];
};
//#######################################################################
// ParameterDescription
//#######################################################################
# define PARAMETER_DESCRIPTION_END \
{ ParameterDescription::typeEmpty, NULL }
struct ParameterDescription
{
enum ParameterType
{
typeEmpty = 0,
typeRate,
typeModeMask,
typeInteger,
typeColor,
typeScalar,
typeVector,
typeRectangle,
typeAttribute,
typeString
};
ParameterType
type;
enum
{
maxStringLength=64
};
union
{
// 'nextMethodList' is used to chain to the next method list...
MethodDescription **nextMethodList;
GaugeRate rate;
ModeMask modeMask;
int integer;
int color;
Scalar scalar;
BitMap *bitmap;
PixelMap8 *pixelmap;
Palette8 *palette;
void *attributePointer;
// can't use Vector2DOf<int> because constructor not allowed here!
struct
{
int x, y;
}
vector;
// can't use Rectangle2D because constructor not allowed here!
struct
{
struct
{
int x, y;
}
bottomLeft;
struct
{
int x, y;
}
topRight;
}
rectangle;
char string[maxStringLength];
}
data;
~ParameterDescription();
void
ShowInstance(char *indent);
void
CheckIt(int type);
void
Save(GaugeInterpreter *interpreter);
void
Restore(
GaugeInterpreter *interpreter,
Entity *entity
);
void
DumpInterpreterEntry(
GaugeInterpreter *interpreter,
const char *indent
);
void *
ParseAttribute(const char *string_pointer, Entity *entity);
Logical
Extract(
GaugeInterpreter *interpreter,
Warehouse *warehouse_pointer
);
};
//#######################################################################
// MethodDescription
//#######################################################################
# define METHOD_DESCRIPTION_CHAIN(pointer) \
{NULL, NULL, {{ ParameterDescription::typeEmpty, pointer }}}
struct MethodDescription
{
enum
{
MaximumParameters = 16
};
char
*name;
Logical
(*execute)(
int display_port_index,
Vector2DOf<int> position,
Entity *entity,
GaugeRenderer *renderer
);
ParameterDescription
parameterList[MaximumParameters];
void
ShowInstance(char *indent);
void
Execute(
int display_port_index,
Vector2DOf<int> position,
Entity *entity,
GaugeRenderer *renderer
);
};
//#######################################################################
// GaugeRenderer
//#######################################################################
struct GaugeRendererStatistics
{
int
sampleCount;
Scalar
sum,
maximum;
void
Clear(),
Update(Scalar delta);
Scalar
CalculateAverage();
};
class GaugeRenderer:
public Renderer
{
friend class Gauge;
friend class GaugeInterpreter;
friend Scalar draw_bar(
GaugeRenderer *renderer,
int bar_width,
int slot_index,
int bar_type
);
public:
enum
{
maximumGraphicsPorts = 16
};
//--------------------------------------------------------------------
// Construction, Destruction, Testing
//--------------------------------------------------------------------
GaugeRenderer();
~GaugeRenderer();
static void
EmergencyShutdown();
virtual void
LocalEmergencyShutdown();
Logical
TestInstance() const;
LampManager*
GetLampManager()
{
Check(this);
Check_Fpu();
return lampManager;
}
//--------------------------------------------------------------------
// Entity-related methods
//
// These are virtual functions defined by the Renderer class.
// Derived classes call these methods if the derived class
// doesn't do anything special about the entity.
//--------------------------------------------------------------------
void
LinkToEntity(Entity *entity);
void
NotifyOfNewInterestingEntity(Entity *entity);
void
NotifyOfBecomingUninterestingEntity(Entity *entity);
void
StartEntityAlarmImplementation(
Entity *entity,
Subsystem *subsystem,
Enumeration condition,
ResourceDescription::ResourceID resource_ID
);
void
StopEntityAlarmImplementation(
Entity *entity,
Subsystem *subsystem,
Enumeration condition
);
//--------------------------------------------------------------------
// LoadMissionImplementation
// ShutdownImplementation
// SuspendImplementation
// ResumeImplementation
//
// These are virtual functions defined by the Renderer class.
// Derived classes must call these methods.
//--------------------------------------------------------------------
void
LoadMissionImplementation(Mission *mission);
void
ShutdownImplementation();
void
SuspendImplementation();
void
ResumeImplementation();
//--------------------------------------------------------------------
// Video effects
// HACK!!!!!!!!
// Quick and dirty hack to allow calling L4GaugeRenderer::SpecialEffect
// from non L4 level. GDU 2/28/96
//--------------------------------------------------------------------
public:
enum VideoEffectType
{
scrambleVideo
};
virtual void
SpecialEffect(VideoEffectType type, Scalar duration) {};
//
//--------------------------------------------------------------------
// GetGraphicsPort
//--------------------------------------------------------------------
//
int
FindGraphicsPort(const char * port_name);
GraphicsPort
*GetGraphicsPort(const char *port_name);
GraphicsPort
*GetGraphicsPort(int port_number);
//
//--------------------------------------------------------------------
// GaugeEntityList operations
//--------------------------------------------------------------------
//
int
GetMovingEntities(
GaugeEntityList *destination_list
)
{
return movingEntities.CopyEntities(
destination_list
);
}
int
GetMovingEntitiesWithinBounds(
GaugeEntityList *destination_list,
Scalar minX,
Scalar minY,
Scalar minZ,
Scalar maxX,
Scalar maxY,
Scalar maxZ
)
{
return movingEntities.CopyEntitiesWithinBounds(
destination_list,
minX, minY, minZ,
maxX, maxY, maxZ
);
}
int
GetStaticEntities(
GaugeEntityList *destination_list
)
{
return staticEntities.CopyEntities(
destination_list
);
}
int
GetStaticEntitiesWithinBounds(
GaugeEntityList *destination_list,
Scalar minX,
Scalar minY,
Scalar minZ,
Scalar maxX,
Scalar maxY,
Scalar maxZ
)
{
return staticEntities.CopyEntitiesWithinBounds(
destination_list,
minX, minY, minZ,
maxX, maxY, maxZ
);
}
// Rebuild the moving/static entity grids that the radar/map gauge queries.
// The 1995 game fed these from ExecuteImplementation's InterestingEntity
// iterator, which the WinTesla port dropped, so the grids stayed empty and
// the radar found no contacts. Repopulate from the world entity list.
void
RebuildEntityGrid();
void
GetStaticBounds(
Scalar *min_x,
Scalar *min_y,
Scalar *min_z,
Scalar *max_x,
Scalar *max_y,
Scalar *max_z
)
{
staticEntities.GetBounds(
min_x, min_y, min_z,
max_x, max_y, max_z
);
}
//
//--------------------------------------------------------------------
// Configure
//--------------------------------------------------------------------
//
virtual void
Configure(
const char *configuration_name,
Entity *entity
);
int
parseConfigurationLine(
const char *entry,
char *buffer,
char **item_pointer,
int max_items
);
//--------------------------------------------------------------------
// Gauge methods
//--------------------------------------------------------------------
void
Add(GaugeBase *new_base),
Remove(unsigned int ownerID),
Inactivate(GaugeBase *the_base);
GaugeRate
FindBestFirstTierRate(),
FindBestSecondTierRate(),
FindBestThirdTierRate(),
FindBestFourthTierRate();
//--------------------------------------------------------------------
// ExecuteImplementation
//--------------------------------------------------------------------
protected:
void
ExecuteImplementation(
RendererComplexity complexity_update,
RendererOrigin::InterestingEntityIterator *iterator
);
public:
Logical
ExecuteBackground();
protected:
void
ActivateGaugeBases(ModeMask current_mode_mask, ModeMask change_mode_mask),
DeactivateGaugeBases(ModeMask current_mode_mask);
Logical
ProcessOneActiveGauge();
virtual void
ExecuteForeground();
virtual Logical
ExecuteBackgroundDisplayUpdate();
//--------------------------------------------------------------------
// Profiling support
//--------------------------------------------------------------------
protected:
virtual Scalar
GetCurrentFramePercentage();
public:
void
ProfileReport();
//--------------------------------------------------------------------
// Configuration parsing methods
//--------------------------------------------------------------------
protected:
void
BuildConfigurationFile(
const char *file_name,
MethodDescription **method_description
);
//--------------------------------------------------------------------
// Public data
//--------------------------------------------------------------------
public:
Warehouse
*warehousePointer;
GaugeInterpreter
*interpreter;
int GetTaskMode() { return taskMode; }
//--------------------------------------------------------------------
// Protected data
//--------------------------------------------------------------------
protected:
GraphicsPort *graphicsPort[maximumGraphicsPorts];
GaugeEntityList movingEntities;
GaugeEntityArray staticEntities;
LampManager *lampManager;
GaugeAlarmManager *gaugeAlarmManager;
enum
{
foreground,
background,
copy
}
taskMode;
private:
//
//--------------------------------------------------------------------
// Private data
//--------------------------------------------------------------------
//
ModeMask
previousModeMask;
SChainOf<GaugeBase*>
newList,
activeList,
inactiveList;
SChainIteratorOf<GaugeBase*>
*activeIterator;
Logical
suspended;
GaugeRate
rateBitMask;
int
rateProfileIndex;
static GaugeRenderer
*headGaugeRenderer;
GaugeRenderer
*nextGaugeRenderer;
//-----------------------------------
// Load-balancing data and profiling
//-----------------------------------
enum
{
slotCount = 16,
tierCount=5
};
Scalar
load[slotCount];
GaugeRendererStatistics
statistics[slotCount][tierCount];
};
#endif
+189
View File
@@ -0,0 +1,189 @@
#if !defined(LAMP_HPP)
# define LAMP_HPP
# if !defined(GAUGREND_HPP)
# include <gaugrend.hpp>
# endif
# if !defined(STYLE_HPP)
# include <style.hpp>
# endif
# if !defined(GRAPH2D_HPP)
# include <graph2d.hpp>
# endif
# if !defined(MODE_HPP)
# include <mode.hpp>
# endif
# if !defined(SLOT_HPP)
# include <slot.hpp>
# endif
# if !defined(CHAIN_HPP)
# include <chain.hpp>
# endif
class LampManager;
class GraphicLamp;
typedef int LampID;
typedef int LampState;
//#########################################################################
//################################# Lamp ##################################
//#########################################################################
class Lamp : public Node
{
friend class LampManager;
//----------------------------------------------------------------------
// Public methods
//----------------------------------------------------------------------
public:
enum
{
LampStateUndefined = -1,
LampStateOff = 0,
LampStateOn,
NextLampState
};
virtual ~Lamp();
Logical
TestInstance() const;
virtual void
SetState(LampState new_state);
void
SetAlertState(Logical alert_on = True);
LampState
GetState()
{
Check(this);
return previousState;
}
protected:
//----------------------------------------------------------------------
// Protected methods
//----------------------------------------------------------------------
Lamp(
LampID lamp_id,
ModeMask mode_mask,
LampManager *lamp_manager
);
virtual void
Update(Logical force_notify_of_state_change = False);
virtual void
NotifyOfStateChange();
//
//----------------------------------------------------------------------
// Protected data
//----------------------------------------------------------------------
//
LampID
lampID;
ModeMask
modeMask;
LampState
previousState;
LampManager
*manager;
int
alertActive;
};
//#########################################################################
//############################## GraphicLamp ##############################
//#########################################################################
class GraphicLamp :
public Lamp
{
//----------------------------------------------------------------------
// Public methods
//----------------------------------------------------------------------
public:
~GraphicLamp();
Logical
TestInstance() const;
//----------------------------------------------------------------------
// Protected methods
//----------------------------------------------------------------------
protected:
GraphicLamp(
LampID lamp_id,
ModeMask mode_mask,
LampManager *lamp_manager,
GaugeRenderer *renderer,
int graphics_port_number
);
//----------------------------------------------------------------------
// Public data
//----------------------------------------------------------------------
GaugeRenderer
*renderer;
GraphicsView
localView;
};
# if !defined(GAUGREND_HPP)
# include <gaugrend.hpp>
# endif
//############################## LampManager ##############################
// The Lamp Manager belongs to the Gauge Renderer: it is responsible for
// handling specialized 'lamp' objects similar to (but not identical to)
// gauge objects.
//#########################################################################
class LampManager SIGNATURED
{
friend class Lamp;
//----------------------------------------------------------------------
// Public methods
//----------------------------------------------------------------------
public:
virtual ~LampManager();
Logical
TestInstance() const;
virtual void
Update(ModeMask current_mode_mask);
Lamp *
FindLamp(LampID lamp_id, ModeMask mode_mask);
void
RemoveAllLamps();
ModeMask
GetPreviousModeMask()
{
Check(this);
Check_Fpu();
return previousModeMask;
}
//----------------------------------------------------------------------
// Protected methods
//----------------------------------------------------------------------
protected:
LampManager();
void
ActivateLamps(ModeMask bits_became_active);
void
DeactivateLamps(ModeMask bits_became_inactive);
void
AddLamp(Lamp *new_lamp);
void
RemoveLamp(LampID lamp_id, ModeMask mode_mask);
ModeMask
previousModeMask;
ChainOf<Lamp*>
lampList,
activeLampList,
inactiveLampList;
};
#endif
+312
View File
@@ -0,0 +1,312 @@
#if !defined(ROTATION_HPP)
# define ROTATION_HPP
# if !defined(ANGLE_HPP)
# include <angle.hpp>
# endif
class Quaternion;
class Origin;
class YawPitchRoll;
class UnitVector;
class LinearMatrix;
class Vector3D;
//##########################################################################
//############################ Hinge #################################
//##########################################################################
class Hinge
{
public:
int axisNumber;
Radian rotationAmount;
//
// Constructors
//
Hinge() {}
Hinge(int axis, const Radian &angle) : axisNumber(axis), rotationAmount(angle) {}
#if defined(USE_SIGNATURE)
friend int Is_Signature_Bad(const volatile Hinge *);
#endif
//
// Assignment operators
//
Hinge& operator=(const Hinge &hinge)
{
Check_Pointer(this);
Check(&hinge);
axisNumber = hinge.axisNumber;
rotationAmount = hinge.rotationAmount;
return *this;
}
//
// "Close-enough" comparators
//
friend Logical Small_Enough(const Hinge &a, Scalar e = SMALL)
{
Check(&a);
return Small_Enough(a, e);
}
Logical operator!() const { return Small_Enough(*this,SMALL); }
friend Logical Close_Enough(const Hinge &a1, const Hinge &a2, Scalar e = SMALL);
Logical operator==(const Hinge& a) const { return Close_Enough(*this, a, SMALL); }
Logical operator!=(const Hinge& a) const { return !Close_Enough(*this, a, SMALL); }
//
// Template support
//
Hinge& Lerp(const Hinge& v1, const Hinge& v2, Scalar t);
//
// Support functions
//
friend ostream& operator<<(ostream& stream, const Hinge& angles);
Logical TestInstance() const;
};
//##########################################################################
//######################### EulerAngles #############################
//##########################################################################
class EulerAngles
{
public:
Radian pitch, yaw, roll;
static const EulerAngles Identity;
#if defined(USE_SIGNATURE)
friend int Is_Signature_Bad(const volatile EulerAngles *);
#endif
//
// Constructors
//
EulerAngles() {}
EulerAngles(const Radian &pitch, const Radian &yaw, const Radian &roll)
{
this->pitch = pitch;
this->yaw = yaw;
this->roll = roll;
}
//
// Assignment operators
//
EulerAngles& operator=(const EulerAngles &angles);
EulerAngles& operator=(const YawPitchRoll &angles);
EulerAngles& operator=(const Hinge &hinge);
EulerAngles& operator=(const Quaternion &quaternion);
EulerAngles& operator=(const LinearMatrix &matrix);
EulerAngles& operator=(const Origin &p);
//
// "Close-enough" comparators
//
friend Logical Small_Enough(const EulerAngles &a, Scalar e = SMALL);
Logical operator!() const { return Small_Enough(*this); }
friend Logical Close_Enough(const EulerAngles &a1, const EulerAngles &a2, Scalar e = SMALL);
Logical operator==(const EulerAngles& a) const { return Close_Enough(*this, a, SMALL); }
Logical operator!=(const EulerAngles& a) const { return !Close_Enough(*this, a, SMALL); }
//
// Axis index operators
//
const Radian& operator[](size_t index) const
{
Check_Pointer(this);
Warn(index>Z_Axis);
return (&pitch)[index];
}
Radian& operator[](size_t index)
{
Check_Pointer(this);
Warn(index>Z_Axis);
return (&pitch)[index];
}
//
// Multiplication operators
//
EulerAngles& Multiply(const EulerAngles &q1, const EulerAngles &q2);
EulerAngles& Multiply(const EulerAngles &q, Scalar scale);
EulerAngles& MultiplyScaled(const EulerAngles &q1, const EulerAngles &q2, Scalar t);
//
// Template support
//
EulerAngles& Lerp(const EulerAngles& v1, const EulerAngles& v2, Scalar t);
//
// Support functions
//
EulerAngles& Normalize();
friend ostream& operator<<(ostream& stream, const EulerAngles& angles);
//
// Test functions
//
Logical TestInstance() const;
static Logical TestClass();
};
//##########################################################################
//######################### YawPitchRoll ############################
//##########################################################################
class YawPitchRoll
{
public:
Radian yaw, pitch, roll;
static const YawPitchRoll Identity;
#if defined(USE_SIGNATURE)
friend int Is_Signature_Bad(const volatile YawPitchRoll *);
#endif
//
// Constructors
//
YawPitchRoll() {}
YawPitchRoll(const Radian &yaw, const Radian &pitch, const Radian &roll)
{
this->pitch = pitch;
this->yaw = yaw;
this->roll = roll;
}
//
// Assignment operators
//
YawPitchRoll& operator=(const Hinge &hinge);
YawPitchRoll& operator=(const YawPitchRoll &angles);
YawPitchRoll& operator=(const EulerAngles &angles);
YawPitchRoll& operator=(const Quaternion &quaternion);
YawPitchRoll& operator=(const LinearMatrix &matrix);
YawPitchRoll& operator=(const Origin &p);
//
// "Close-enough" comparators
//
friend Logical Small_Enough(const YawPitchRoll &a, Scalar e = SMALL);
Logical operator!() const { return Small_Enough(*this); }
friend Logical Close_Enough(const YawPitchRoll &a1, const YawPitchRoll &a2, Scalar e = SMALL);
Logical operator==(const YawPitchRoll& a) const { return Close_Enough(*this, a); }
Logical operator!=(const YawPitchRoll& a) const { return !Close_Enough(*this, a); }
//
// Support functions
//
YawPitchRoll& Normalize();
friend ostream& operator<<(ostream& stream, const YawPitchRoll& angles);
//
// Test functions
//
Logical TestInstance() const;
};
//##########################################################################
//######################### Quaternion ###############################
//##########################################################################
class Quaternion
{
public:
static const Quaternion Identity;
#if defined(USE_SIGNATURE)
friend int Is_Signature_Bad(const volatile Quaternion *);
#endif
Scalar x, y, z, w;
//
// Constructors
//
Quaternion() {}
Quaternion(Scalar x, Scalar y, Scalar z, Scalar w);
//
// Assignment operators
//
Quaternion& operator=(const Quaternion &q);
Quaternion& operator=(const Hinge &hinge);
Quaternion& operator=(const EulerAngles &angles);
Quaternion& operator=(const YawPitchRoll &angles);
Quaternion& operator=(const LinearMatrix &matrix);
Quaternion& operator=(const Origin &p);
//
// "Close-enough" comparators
//
friend Logical Small_Enough(const Quaternion &q, Scalar e = SMALL)
{
Check(&q);
return Close_Enough(q.w, 1.0f, e);
}
Logical operator!() const { return Small_Enough(*this, SMALL); }
//
// Axis index operators
//
const Scalar& operator[](size_t index) const
{
Check_Pointer(this);
Warn(index>W_Axis);
return (&x)[index];
}
Scalar& operator[](size_t index)
{
Check_Pointer(this);
Warn(index>W_Axis);
return (&x)[index];
}
Scalar GetAngle();
void GetAxis(UnitVector *axis);
//
// Multiplication operators
//
Quaternion& Multiply(const Quaternion &q1, const Quaternion &q2);
Quaternion& Multiply(const Quaternion &q, Scalar scale);
Quaternion& MultiplyScaled(const Quaternion &q1, const Quaternion &q2, Scalar t);
Quaternion& Add(const Quaternion &source, const Vector3D &delta);
Quaternion& AddScaled(const Quaternion &source, const Vector3D &delta, Scalar t);
//
// Transform functions
//
Quaternion& Multiply(const Quaternion &q, const LinearMatrix &m);
Quaternion& operator*=(const LinearMatrix &m);
//
// Template support
//
Quaternion& Lerp(const Quaternion& v1, const Quaternion& v2, Scalar t);
//
// Miscellaneous functions
//
Quaternion& Normalize();
Quaternion& Subtract(const Quaternion &end, const Quaternion &start);
Quaternion& Subtract(const UnitVector &end, const UnitVector &start);
Quaternion& Subtract(const Vector3D &end, const Vector3D &start);
//
// Support functions
//
friend ostream& operator<<(ostream& stream, const Quaternion& quaternion);
Logical TestInstance() const;
static Logical TestClass();
};
#endif
+343
View File
@@ -0,0 +1,343 @@
//===========================================================================//
// File: vdata.hh //
// Project: MUNGA Brick: Connection Library //
// Contents: Interface specification for registered classes and virtual data //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- -----------------------------------------------------------//
// 11/03/94 ECH Initial coding. //
// 11/29/94 JMA Changed ClassIdentity to ClassID //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#if !defined(VDATA_HPP)
# define VDATA_HPP
# if !defined(MEMSTRM_HPP)
# include <memstrm.hpp>
# endif
class CString;
class ObjectStream;
class NameList;
typedef unsigned long ObjectID;
const ObjectID NullObjectID = 0;
typedef unsigned long RegisteredClassMemoryAddress;
//##########################################################################
//######################## RegisteredClass ###########################
//##########################################################################
class RegisteredClass SIGNATURED
{
public:
enum ClassID
{
//
//--------------
// Munga classes
//--------------
//
NullClassID = -1,
TrivialClassID = 0,
TrivialPlugClassID,
TrivialNodeClassID,
TrivialComponentClassID,
AttributeWatcherOfClassID,
ReceiverAttributeWatcherOfClassID,
MessageTapClassID,
DerivationClassID,
TrivialReceiverClassID,
EventClassID,
NetworkEventClassID,
GeneralEventQueueClassID,
EventQueueClassID,
DeferredEventQueueClassID,
TrivialModelClassID,
TrivialSubsystemClassID,
TrivialEntityClassID,
NetworkManagerClassID,
EntityManagerClassID,
EntityAttributeHandlerReferenceClassID,
PersistentReferenceClassID,
InterestManagerClassID,
HostManagerClassID,
ControlsInstanceClassID,
ControlsMappingGroupClassID,
ControlsOwnerClassID,
ControlsManagerClassID,
TrivialMoverClassID,
AudioStateTriggerClassID,
AudioMotionScaleClassID,
AudioRendererClassID,
AudioLocationClassID,
ApplicationClassID,
EntityGroupClassID,
GaugeConnectionClassID,
GaugeClassID,
GaugeRendererClassID,
CollisionAssistantClassID,
RendererManagerClassID,
AudioMotionTriggerClassID,
AudioMotionRandomTriggerClassID,
TerrainClassID,
UnscalableTerrainClassID,
AudioControlMixerClassID,
AudioHingeScaleClassID,
AudioControlSmootherClassID,
AudioControlMultiplierClassID,
AudioResourceSelectorClassID,
DropZoneClassID,
ExplosionClassID,
PlayerClassID,
JointSubsystemClassID,
AudioResourceIndexClassID,
AudioScalarScaleClassID,
AudioControlSendClassID,
GaugeEntityListClassID,
DirectControlsInstanceClassID,
EventControlsInstanceClassID,
AudioSampleAndHoldClassID,
AudioScalarTriggerClassID,
AudioEnumerationTriggerClassID,
AudioIntegerTriggerClassID,
AudioLogicalTriggerClassID,
EyeCandyClassID,
WarehouseObjectClassID,
WarehouseBinClassID,
AudioControlsButtonTriggerClassID,
IcomClassID,
IcomManagerClassID,
CameraShipClassID,
CameraDirectorClassID,
ExplosionResourceTableClassID,
ApplicationTaskClassID,
AudioIdleWatcherClassID,
AudioControlEventClassID,
AudioControlSequenceClassID,
AudioControlSplitterClassID,
ApplicationManagerClassID,
DamageZoneClassID,
AudioLFOClassID,
AudioEnumerationDeltaTriggerClassID,
AudioScalarDeltaTriggerClassID,
ControlsStringClassID,
ControlsStringManagerClassID,
AudioEntityClassID,
AudioLevelOfDetailClassID,
LandmarkClassID,
ScenarioRoleClassID,
TeamClassID,
AudioMessageWatcherClassID,
AudioControlsButtonMessageWatcherClassID,
GaugeAlarmManagerClassID,
GaugeAlarmClassID,
LightClassID,
CulturalIconClassID,
DoorFrameClassID,
DoorClassID,
//
//---------------------------------
// Class ID's for Munga LBE classes
//---------------------------------
//
L4AudioLocationClassID = 1000,
DirectPatchSourceClassID,
Dynamic3DPatchSourceClassID,
L4ApplicationClassID,
PatchResourceClassID,
Static3DPatchSourceClassID,
L4AudioCollisionTriggerClassID,
L4GaugeImageManagerClassID,
L4ControlsManagerClassID,
L4IcomClassID,
L4IcomManagerClassID,
PatchLevelOfDetailClassID,
//
//----------------------
// Class ID's for RP
//----------------------
//
RPL4ApplicationClassID = 2000,
VTVClassID,
RivetClassID,
DemolitionPackClassID,
BoosterClassID,
RivetGunClassID,
LaserDrillClassID,
DemolitionPackDropperClassID,
ChuteClassID,
ScoreZoneClassID,
VTVPowerClassID,
ThrusterClassID,
ControlsMapperClassID,
CrusherClassID,
BlockerClassID,
RunnerClassID,
RPDirectorClassID,
RPTeamClassID,
RPPlayerClassID,
//
//------------------
// Class ID's for BT
//------------------
//
BTL4ApplicationClassID = 3000,
MechClassID,
MissileClassID,
MechSubsystemClassID,
HeatableSubsystemClassID,
CondenserClassID,
HeatSinkClassID,
HeatWatcherClassID,
ReservoirClassID,
GeneratorClassID,
PoweredSubsystemClassID,
SensorClassID,
GyroscopeClassID,
TorsoClassID,
MyomersClassID,
CapacitorClassID,
EmitterClassID,
LaserClassID,
ParticleCannonClassID,
AmmoBinClassID,
AmmoFeederClassID,
ProjectileWeaponClassID,
GaussRifleClassID,
BallisticWeaponClassID,
MissileLauncherClassID,
ProjectileClassID,
SeekerClassID,
SubsystemMessageManagerClassID,
PPCClassID,
PowerWatcherClassID,
HUDClassID,
RadarClassID,
SearchlightClassID,
ThermalSightClassID,
BTTeamClassID,
BTPlayerClassID,
BTDirectorClassID,
MechTechClassID,
TurretClassID,
//
//------------------
// Class ID's for ND
//------------------
//
NDL4ApplicationClassID = 4000,
AirplaneClassID,
BulletClassID,
MachineGunClassID,
NDDirectorClassID,
NDTeamClassID,
NDPlayerClassID,
//
//----------------------
// Class ID's for Tools
//----------------------
//
ShapeClassID = 60000,
ShapeGroupListClassID,
ShapeGroupClassID,
ShapePlaneClassID,
ShapePolygonClassID,
ShapeLineClassID,
ShapePointClassID,
VertexReferenceClassID,
VertexClassID,
MaterialLibraryClassID,
MaterialReferenceClassID,
MaterialClassID,
TargaImageClassID,
ShapeListClassID,
SkeletonClassID,
SkeletonJointClassID,
SkeletonSiteClassID,
SkeletonSegmentClassID,
ModelClassID,
//
//---------------------------------
// Class ID's for Munga W4 classes
//---------------------------------
//
W4ApplicationClassID = 70000,
W4ControlsManagerClassID,
//
//-------------
// end of list
//-------------
//
MaxClassID
};
public:
RegisteredClass(ClassID class_id = TrivialClassID);
RegisteredClass(ObjectStream *stream);
virtual ~RegisteredClass();
Logical
TestInstance() const;
public:
ClassID
GetClassID();
static ClassID
GetClassID(const CString &class_name_string);
RegisteredClassMemoryAddress
GetMemoryAddress();
public:
static void
BuildFromPage(
ObjectStream *stream,
NameList *name_list,
ClassID class_ID,
ObjectID object_ID
);
private:
ClassID
classID;
};
//~~~~~~~~~~~~~~~~~~~~~ RegisteredClass inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
inline RegisteredClass::ClassID
RegisteredClass::GetClassID()
{
Check(this);
return classID;
}
inline RegisteredClassMemoryAddress
RegisteredClass::GetMemoryAddress()
{
Check(this);
return (RegisteredClassMemoryAddress)this;
}
inline MemoryStream&
MemoryStream_Read(MemoryStream* stream, RegisteredClass::ClassID *output)
{return stream->ReadBytes(output, sizeof(*output));}
inline MemoryStream&
MemoryStream_Write(MemoryStream* stream, const RegisteredClass::ClassID *input)
{return stream->WriteBytes(input, sizeof(*input));}
#endif
@@ -0,0 +1,24 @@
# VDATA.HPP — reconstruction notes (2026-07-19)
**The first ENGINE-side backfill** (the header `plug.hpp` includes; lost from both 1995 trees —
`VDATA.CPP` survives in `CODE/RP/MUNGA`, only the `.HPP` was missing).
Basis: back-dated from `C:\VWE\BT412\engine\MUNGA\VDATA.h` (the drifted WinTesla-era copy).
Transformations: `#pragma once` → the `VDATA_HPP` guard PLUG.HPP expects (PLUG.HPP:30 names it);
`#include "memstrm.h"` → guarded `<memstrm.hpp>` (survives in CODE/RP/MUNGA); banner cloned from
the surviving VDATA.CPP banner ("vdata.cc / Connection Library"); body/indentation restyled to
the 1995 house pattern. Content otherwise byte-for-byte the WinTesla enum + class.
Validation [T1]:
- Method set matches the surviving `VDATA.CPP` exactly (2 ctors, dtor, TestInstance,
BuildFromPage, static GetClassID(CString&)).
- ClassID numbering matches every decomp-known constant: `TrivialSubsystemClassID`=0xF,
`CameraShipClassID`=0x45, `MechClassID`=0xBB9, `MechSubsystemClassID`=0xBBC region,
`L4ApplicationClassID`=1003 — i.e. the WinTesla file preserved 1995 numbering.
- `MemoryStream_Read/Write` inline pair is a verified period idiom (used across 1995 headers).
- **Compile-proven**: with this one backfill, the ORIGINAL `BTL4MODE.CPP` and `BTMSSN.CPP`
compile CLEAN under BC++ 4.52 with the authentic OPT.MAK flags (btl4mode.obj 3,751 bytes).
Uncertainty [T4]: whether the ND (4000) / Tools (60000) / W4 (70000) enum sections and any
tail entries postdate 4.10 — appended IDs don't shift earlier values, so all decomp-verified
constants are unaffected either way.
+290
View File
@@ -0,0 +1,290 @@
#if !defined(VECTOR2D_HPP)
# define VECTOR2D_HPP
# if !defined(SCALAR_HPP)
# include <scalar.hpp>
# endif
template <class T> class Vector2DOf
{
public:
#if defined(USE_SIGNATURE)
friend int Is_Signature_Bad(const volatile Vector2DOf<T> *p);
#endif
// static const Vector2DOf<T>
// identity;
T x, y;
Vector2DOf() {}
Vector2DOf(T x, T y) : x(x), y(y) {}
friend Logical Small_Enough(const Vector2DOf<T> &v, Scalar e);
Logical operator!() const { return Small_Enough(*this,SMALL); }
friend Logical Close_Enough(const Vector2DOf<T> &v1, const Vector2DOf<T> &v2, Scalar e);
Logical operator==(const Vector2DOf<T>& v) const { return Close_Enough(*this,v,SMALL); }
Logical operator!=(const Vector2DOf<T>& v) const { return !Close_Enough(*this,v,SMALL); }
const T& operator[](size_t index) const
{
Check(this);
Warn(index>Y_Axis);
return (&x)[index];
}
T& operator[](size_t index)
{
Check(this);
Warn(index>Y_Axis);
return (&x)[index];
}
//
//-----------------------------------------------------------------------
// The following operators all assume that this points to the destination
// of the operation results
//-----------------------------------------------------------------------
//
Vector2DOf<T>& Negate(const Vector2DOf<T> &v);
Vector2DOf<T>& Add(const Vector2DOf<T>& v1, const Vector2DOf<T>& v2);
Vector2DOf<T>& operator+=(const Vector2DOf<T>& v) { return Add(*this,v); }
Vector2DOf<T>& Subtract(const Vector2DOf<T>& v1, const Vector2DOf<T>& v2);
Vector2DOf<T>& operator-=(const Vector2DOf<T>& v) { return Subtract(*this,v); }
T operator*(const Vector2DOf<T>& v) const
{
Check(this);
Check(&v);
return x*v.x + y*v.y;
}
Vector2DOf<T>& Multiply(const Vector2DOf<T>& v, T Scale);
Vector2DOf<T>& operator*=(T v) { return Multiply(*this,v); }
Vector2DOf<T>& Multiply(const Vector2DOf<T>& v1, const Vector2DOf<T>& v2);
Vector2DOf<T>& operator*=(const Vector2DOf<T> &v) { return Multiply(*this,v); }
Vector2DOf<T>& Divide(const Vector2DOf<T>& v, T scale);
Vector2DOf<T>& operator/=(T v) { return Divide(*this,v); }
Vector2DOf<T>& Divide(const Vector2DOf<T>& v1, const Vector2DOf<T>& v2);
Vector2DOf<T>& operator/=(const Vector2DOf<T> &v) { return Divide(*this,v); }
T LengthSquared() const
{
Check(this);
return operator*(*this);
}
T Length() const
{
Check(this);
return (T)Sqrt(LengthSquared());
}
Vector2DOf<T>& Normalize(const Vector2DOf<T> &v);
#if 0
Vector2DOf<T>& Combine(const Vector2DOf<T>& v1, Scalar t1, const Vector2DOf<T>& v2, Scalar t2);
Vector2DOf<T>& Lerp(const Vector2DOf<T>& v1, const Vector2DOf<T>& v2, Scalar t)
{
return Combine(v1,1.0f-t,v2,t);
}
#endif
friend ostream& operator<<(ostream& stream, const Vector2DOf<T>& v);
Logical TestInstance() const;
};
#if defined(USE_SIGNATURE)
template <class T> int Is_Signature_Bad(const volatile Vector2DOf<T> *)
{
return False;
}
#endif
// template <class T> const Vector2DOf<T>
// Vector2DOf<T>::identity(0.0f,0.0f);
template <class T> inline Logical
Small_Enough(const Vector2DOf<T> &v,Scalar e)
{
Check(&v);
return Small_Enough(v.x,e) && Small_Enough(v.y,e);
}
//REMOVED: RB 1/15/07
//template <class T> Logical
// Close_Enough(
// const Vector2DOf<T> &v1,
// const Vector2DOf<T> &v2,
// Scalar e
// )
//{
// Check(&v1);
// Check(&v2);
// return Close_Enough(v1.x,v2.x,e) && Close_Enough(v1.y,v2.y,e);
//}
inline Logical Close_Enough(const Vector2DOf<int> &v1, const Vector2DOf<int> &v2, Scalar e)
{
Check(&v1);
Check(&v2);
return Close_Enough(v1.x, v2.x,e) && Close_Enough(v1.y, v2.y,e);
}
inline Logical Close_Enough(const Vector2DOf<float> &v1, const Vector2DOf<float> &v2, Scalar e)
{
Check(&v1);
Check(&v2);
return Close_Enough(v1.x, v2.x,e) && Close_Enough(v1.y, v2.y,e);
}
template <class T> inline Vector2DOf<T>&
Vector2DOf<T>::Negate(const Vector2DOf<T> &v)
{
Check(this);
Check(&v);
x = -v.x;
y = -v.y;
return *this;
}
template <class T> inline Vector2DOf<T>&
Vector2DOf<T>::Add(
const Vector2DOf<T>& v1,
const Vector2DOf<T>& v2
)
{
Check(this);
Check(&v1);
Check(&v2);
x = v1.x + v2.x;
y = v1.y + v2.y;
return *this;
}
template <class T> inline Vector2DOf<T>&
Vector2DOf<T>::Subtract(
const Vector2DOf<T>& v1,
const Vector2DOf<T>& v2
)
{
Check(this);
Check(&v1);
Check(&v2);
x = v1.x - v2.x;
y = v1.y - v2.y;
return *this;
}
template <class T> inline Vector2DOf<T>&
Vector2DOf<T>::Multiply(
const Vector2DOf<T>& v,
T scale
)
{
Check(this);
Check(&v);
x = v.x * scale;
y = v.y * scale;
return *this;
}
template <class T> inline Vector2DOf<T>&
Vector2DOf<T>::Multiply(
const Vector2DOf<T>& v1,
const Vector2DOf<T>& v2
)
{
Check(this);
Check(&v1);
Check(&v2);
x = v1.x * v2.x;
y = v1.y * v2.y;
return *this;
}
template <class T> inline Vector2DOf<T>&
Vector2DOf<T>::Divide(
const Vector2DOf<T>& v,
T scale
)
{
Check(this);
Check(&v);
Verify(!Small_Enough(scale));
x = v.x / scale;
y = v.y / scale;
return *this;
}
template <class T> inline Vector2DOf<T>&
Vector2DOf<T>::Divide(
const Vector2DOf<T>& v1,
const Vector2DOf<T>& v2
)
{
Check(this);
Check(&v1);
Check(&v2);
Verify(!Small_Enough(v2.x));
Verify(!Small_Enough(v2.y));
x = v1.x / v2.x;
y = v1.y / v2.y;
return *this;
}
template <class T> inline Vector2DOf<T>& Vector2DOf<T>::Normalize(const Vector2DOf<T> &v)
{
Check_Pointer(this);
Check(&v);
T len = v.Length();
Verify(!Small_Enough(len));
x = v.x/len;
y = v.y/len;
return *this;
}
//template <class T> ostream& operator<<(ostream& stream, const Vector2DOf<T>& v)
//{
// Check(&v);
// return stream << '<' << v.x << ',' << v.y << '>';
//}
template <class T> inline Logical Vector2DOf<T>::TestInstance() const
{
return True;
}
inline ostream& operator<<(ostream& stream, const Vector2DOf<int>& v)
{
Check(&v);
return stream << '<' << v.x << ',' << v.y << '>';
}
#if 0
template <class T> Vector2DOf<T>&
Combine(
const Vector2DOf<T>& v1,
Scalar t1,
const Vector2DOf<T>& v2,
Scalar t2
)
{
Check(this);
Check(&v1);
Check(&v2);
x = v1.x*t1 + v2.x*t2;
y = v1.y*t1 + v2.y*t2;
return *this;
}
#endif
#endif
+73
View File
@@ -0,0 +1,73 @@
# source410 — literal reconstruction of the missing BT 4.10 game source
**Everything in this directory is RECONSTRUCTED, not recovered.** The authentic surviving
source lives in `CODE/` and is never mixed with this tree. The goal here is an
archival-grade recreation of the `d:\tesla_bt\` translation units that exist only inside
`BTL4OPT.EXE` (the shipped 4.10 binary), written in the 1995 VWE house style against the
1995 MUNGA/MUNGA_L4 engine headers that DID survive.
## Ground rules
1. **Never copy a reconstructed file into `CODE/`** — the assembled buildable tree
(originals + reconstructions) is produced by a script into a build directory, so
provenance stays unambiguous file-by-file.
2. **Every `.CPP` here has a `.NOTES.md` sidecar** carrying the evidence: the binary
address map, decomp references, which sibling sources supplied each idiom, and every
judgment call with its tier ([T1] decomp-proven … [T4] style guess). The `.CPP` itself
stays clean 1995 style — no modern annotations inside.
3. **Assert line numbers are constraints.** The binary's `Fail()` sites record the original
file+line (`BTL4APP.CPP:400` etc.); reconstructed files are shaped so those calls land on
their recorded lines. A file that can't meet its line constraints yet says so in the
sidecar.
4. **Layout mirrors the original tree**: `BT/` (bt.lib, 36 TUs) and `BT_L4/` (btl4.lib,
13 TUs + BTL4.CPP), matching the surviving `BT.MAK`/`BTL4.MAK`.
## What drives the work
- The per-TU manifest: `C:\VWE\BT411\reference\BT410_SOURCE_MANIFEST.md`
(tool `tools/manifest410.py`; method log `phases/phase-03-bt410-source-manifest.md`).
- The decomp: `C:\VWE\BT411\reference\decomp\all\part_*.c` (+ `section_dump.txt` strings).
- The port's semantic reconstructions: `C:\VWE\BT411\game\reconstructed\` (WinTesla-hosted;
each literal file here re-hosts one back onto the 1995 engine APIs).
- Style/idiom exemplars: surviving `CODE/BT/*.CPP`, `CODE/RP/RP_L4/*.CPP`,
`CODE/RP/MUNGA*/**` (the 1995 engine source itself).
## Status (2026-07-19)
**Compile verification is LIVE: `./compile410.sh --sweep`** (BC4.52 + the authentic OPT.MAK
flags; the period compiler is the reviewer). `backdate.py` mechanizes WinTesla→1995 header
back-dating (donors: `C:\VWE\BT412\engine\MUNGA\*.h`).
| item | state |
|---|---|
| ORIGINAL **BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND** | ✅ **COMPILE CLEAN — 6 of 10 surviving originals** (first builds since 1996) |
| BT/BTCNSL.HPP + BT/BTSCNRL.HPP | ✅ reconstructed round 2 — **console wire IDs recovered from the binary** (Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1]; TeamScore=12 [T4 GUESS — verify]); see BTCNSL.NOTES.md |
| BT_L4/BTL4APP.CPP (pilot reconstruction) | 12/12 functions, Fail() at recorded line 400; compile gated on the mech-family header package |
| MUNGA backfills (VDATA, ROTATION, VECTOR2D, AUDREND, APP, LAMP, GAUGREND, GAUGE) | ✅ 6 compile-proven, 2 parse-proven (BACKFILLS.NOTES.md) |
| ORIGINALS still blocked | BTREG (`btplayer.hpp`), GAUSS+PPC (`emitter.hpp`), BTTOOL (`mech.hpp`) — all gated on the mech-family package |
**Next work package — the mech-family, REVISED (round-3 finding, 2026-07-19):** the plan to
"reconstruct mech.hpp first" was the wrong order. A full read of the port's mech.hpp shows
it is a hybrid (1995 skeleton + Recon proxies + port-only members + relocated fields), and
substantial regions of the binary's 0x854-byte Mech object remain UNMAPPED — the port
declares "the remaining members up to sizeof==0x854" in its mech2-4 slices. A literal
MECH.HPP that precedes those TU reconstructions would be fiction. Corrected order:
1. **MECH.HPP is the CAPSTONE, grown incrementally** with each mech-family TU
reconstruction (mech.cpp → mech2-4 → subsystem TUs), starting as an interface +
known-ordered members with explicit `reserved[]` filler for unmapped regions
(sidecar-tracked), tightened as each TU pins its slice.
2. The dependent headers (`mechsub`, `mechmppr`, `btl4mppr`, `emitter`+`mechweap`,
`btplayer`, `projtile`, `missile`) ship WITH their TUs against the staged MECH.HPP.
3. The blocked originals (BTTOOL, GAUSS, PPC, BTREG) and the BTL4APP pilot compile
green as those land — BTREG last (it includes the whole game-header world).
Offset oracles for every stage: BT411 CLASSMAP.md, decomp-reference.md §3, and the port
headers' static_assert-locked members.
## Toolchain — IN HAND (2026-07-19)
**Borland C++ 4.52**, archived at `../../BORLAND/BC45/`, chosen by byte-match: the fleet's own
`CODE/RP/CW32.LIB` is identical to 4.52's (and not 4.5's). BCC32/TLINK32/TLIB/MAKE run natively
on Win11. The shipped `BTL4OPT.EXE` recipe is `CODE/BT/OPT.MAK` (plain `bcc32`,
`-DLBE4;DEBUG_LEVEL=0;DEBUG_STREAM=cout`, `-5 -a4 -ff -k- -V -Jg -x- -RT-` + the full `-O` set,
PCH `btopt.csm`; link `-Tpe -ax` with `c0x32.obj + dpmi32.lib + cw32.lib` = Borland PowerPack
DPMI32, not Phar Lap TNT). Compile verification of reconstructed TUs is therefore possible
file-by-file; the current blocker for full closure is the 1995 engine header gap (`vdata.hpp`
first — only the drifted WinTesla `VDATA.h` survives, in BT412/engine). Include order for
builds: `CODE/BT/*` over `CODE/RP/*`, `-DNO_PRECOMPILED_HEADERS` until the mech-family headers
are reconstructed. Remaining gap: TASM32 (JOYSTICK.ASM only).
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env python3
"""
backdate.py -- mechanically back-date a WinTesla-era engine header (BT411/BT412
engine/MUNGA*/X.h) to its 1995 form (source410/MUNGA/X.HPP).
Transforms (the mechanical part -- ALWAYS eyeball the result and write the
.NOTES.md sidecar; content drift is NOT detected here):
#pragma once -> #if !defined(X_HPP) / #define X_HPP ... #endif
#include "y.h" -> guarded #if !defined(Y_HPP) #include <y.hpp> #endif
(system includes like <string.h> are left alone)
Usage: py -3 backdate.py <donor.h> <OUTPUT.HPP>
"""
import os
import re
import sys
def main():
donor, out = sys.argv[1], sys.argv[2]
name = os.path.splitext(os.path.basename(out))[0].upper()
guard = "%s_HPP" % name
body = open(donor, "r", errors="replace").read().splitlines()
res = []
warned = set()
for line in body:
s = line.strip()
if s == "#pragma once":
continue
# local include, possibly with a relative path -- keep the basename
m = re.match(r'#include\s+"(?:[.\\/A-Za-z0-9_]*[\\/])?([A-Za-z0-9_]+)\.h(?:pp)?"', s)
if m:
inc = m.group(1).lower()
g = inc.upper() + "_HPP"
res.append("#\tif !defined(%s)" % g)
res.append("#\t\tinclude <%s.hpp>" % inc)
res.append("#\tendif")
continue
# post-1994 C++ the 4.52 compiler rejects: de-modernize
line = re.sub(r"\bstd::", "", line)
line = re.sub(r"\btrue\b", "True", line)
line = re.sub(r"\bfalse\b", "False", line)
line = re.sub(r"\bbool\b", "Logical", line)
for bad in ("<ostream>",):
if bad in line:
line = None
break
if line is None:
continue
for marker in ("namespace", "static_cast", "reinterpret_cast", "const_cast"):
if marker in s and marker not in warned:
warned.add(marker)
print("WARNING: post-1994 construct '%s' present -- fix by hand" % marker)
res.append(line)
# strip leading blank lines
while res and not res[0].strip():
res.pop(0)
with open(out, "w", newline="\r\n") as f:
f.write("#if !defined(%s)\n#\tdefine %s\n\n" % (guard, guard))
f.write("\n".join(res))
f.write("\n\n#endif\n")
print("wrote %s (%d lines from %s)" % (out, len(res) + 5, donor))
if __name__ == "__main__":
main()
+46
View File
@@ -0,0 +1,46 @@
#!/bin/bash
# compile410.sh -- per-TU compile verification for the 4.10 literal-source
# reconstruction, using the fleet's own Borland C++ 4.52 with the authentic
# OPT.MAK flags (CODE/BT/OPT.MAK = the BTL4OPT.EXE recipe).
#
# Usage:
# ./compile410.sh <file.cpp> [more.cpp ...] compile specific TUs
# ./compile410.sh --sweep sweep all surviving originals
#
# Output .obj files land in the current directory. -DNO_PRECOMPILED_HEADERS
# dodges the not-yet-reconstructed mech-family headers (BT.HPP gates on it);
# drop it once mech.hpp/btplayer.hpp/mechsub.hpp exist in 1995 form.
T=/c/VWE/TeslaRel410
export PATH="$T/BORLAND/BC45/BIN:$PATH"
C=c:/VWE/TeslaRel410/CODE/BT
R=c:/VWE/TeslaRel410/CODE/RP
S=c:/VWE/TeslaRel410/restoration/source410
# include order: BT tree over RP tree over source410 backfills over BC45
INC="$C/BT_L4;$C/BT;$C/MUNGA;$C/MUNGA_L4;$C/MUNGA_L4/SOS/BC4;$R/MUNGA;$R/MUNGA_L4;$R/MUNGA_L4/sos/bc4;$S/MUNGA;$S/BT;$S/BT_L4;c:/VWE/TeslaRel410/BORLAND/BC45/INCLUDE"
# CODE/BT/OPT.MAK flags (minus -H PCH, plus the NO_PRECOMPILED_HEADERS dodge)
FLAGS="-c -DLBE4 -DDEBUG_LEVEL=0 -DDEBUG_STREAM=cout -DNO_PRECOMPILED_HEADERS \
-b -r -ff -AT -k- -N- -v- -5 -a4 -V -Jg -x- -RT- -O2 -w-"
one() {
r=$(bcc32 $FLAGS -I"$INC" "$1" 2>&1 | grep "^Error" | head -1)
if [ -z "$r" ]; then
echo "OK $(basename "$1")"
else
echo "FAIL $(basename "$1"): $(echo "$r" | sed 's/.*Error //')"
fi
}
if [ "$1" = "--sweep" ]; then
for f in "$C"/BT/BTMSSN.CPP "$C"/BT/BTCNSL.CPP "$C"/BT/BTREG.CPP \
"$C"/BT/BTSCNRL.CPP "$C"/BT/BTTEAM.CPP "$C"/BT/BTTOOL.CPP \
"$C"/BT/GAUSS.CPP "$C"/BT/PPC.CPP \
"$C"/BT_L4/BTL4MODE.CPP "$C"/BT_L4/BTL4ARND.CPP \
"$S"/BT_L4/*.CPP; do
[ -f "$f" ] && one "$f"
done
else
for f in "$@"; do one "$f"; done
fi