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:
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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]
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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).
|
||||
@@ -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()
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user