Clean, self-contained extraction of the BattleTech-specific work from the
reverse-engineering workspace -- engine + game + content + build, with nothing
from Red Planet or the raw archive dumps. Builds green (Win32) and runs the
single-player drive->animate->target->fire->damage->destroy loop out of the box.
Layout:
engine/ MUNGA + MUNGA_L4 shared 2007 engine, carrying our BT render/loader
work (bgfload/L4D3D/L4VIDEO: BSL bit-slice decode, LOD/ground/shadow
models) + image codec; the minimal rp/ headers the audio HAL needs
game/ reconstructed BT logic + surviving-original BT source + fwd shims
+ WinMain launcher
content/ full runtime tree (BTL4.RES, VIDEO/, GAUGE/, AUDIO/, eggs, BTDPL.INI)
docs/ format specs + reconstruction ledgers
reference/ raw Ghidra pseudocode (recon source-of-truth) + decomp exporter
tools/ MP console emulator + map/resource scanners
One top-level CMake builds munga_engine lib + bt410_l4 game lib + btl4.exe.
All paths relativized (186 fwd shims + ~437 CMake abs paths -> repo-relative);
DXSDK is the one external, overridable via -DDXSDK. Verified: builds to a
byte-identical 2.27MB exe and runs combat (TARGET DESTROYED, 0 crashes) against
the bundled content.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
721 lines
17 KiB
C++
721 lines
17 KiB
C++
#pragma once
|
|
|
|
#include "style.h"
|
|
#include "audio.h"
|
|
#include "audloc.h"
|
|
#include "average.h"
|
|
#include "audtime.h"
|
|
|
|
//##########################################################################
|
|
//######################## AudioMessageWatcher #######################
|
|
//##########################################################################
|
|
|
|
class AudioMessageWatcher:
|
|
public AudioComponent
|
|
{
|
|
public:
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Constructor, Destructor
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
AudioMessageWatcher(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
);
|
|
~AudioMessageWatcher();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// BuildFromPage
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
static void
|
|
BuildFromPage(
|
|
PlugStream *stream,
|
|
NameList *name_list,
|
|
ClassID class_ID,
|
|
ObjectID object_ID
|
|
);
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// MessageTapScanCallback
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
void
|
|
MessageTapScanCallback(
|
|
Receiver::Message *message,
|
|
Receiver *receiver
|
|
);
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Controller methods
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
void
|
|
ReceiveControl(
|
|
AudioControlID control_ID,
|
|
AudioControlValue control_value
|
|
);
|
|
|
|
private:
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Controller methods
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
virtual Logical
|
|
DoesMessageMatch(Receiver::Message*)
|
|
{return True;}
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Private Data
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
SlotOf<AudioComponent*>
|
|
audioComponentSocket;
|
|
|
|
AudioControlID controlID;
|
|
AudioControlValue controlValue;
|
|
|
|
MessageTap *messageTap;
|
|
|
|
#if DEBUG_LEVEL>0
|
|
Receiver *verifyReceiver;
|
|
Receiver::MessageID verifyMessageID;
|
|
#endif
|
|
};
|
|
|
|
//##########################################################################
|
|
//############### AudioControlsButtonMessageWatcher ##################
|
|
//##########################################################################
|
|
|
|
class AudioControlsButtonMessageWatcher:
|
|
public AudioMessageWatcher
|
|
{
|
|
public:
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Constructor, Destructor
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
AudioControlsButtonMessageWatcher(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
);
|
|
~AudioControlsButtonMessageWatcher();
|
|
|
|
private:
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Controller methods
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
Logical
|
|
DoesMessageMatch(Receiver::Message*);
|
|
};
|
|
|
|
//##########################################################################
|
|
//######################### AudioControlSend #########################
|
|
//##########################################################################
|
|
|
|
class AudioControlSend:
|
|
public AudioComponent
|
|
{
|
|
public:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Construction, Destruction, Testing
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioControlSend(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
);
|
|
~AudioControlSend();
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// BuildFromPage
|
|
//--------------------------------------------------------------------
|
|
//
|
|
static void
|
|
BuildFromPage(
|
|
PlugStream *stream,
|
|
NameList *name_list,
|
|
ClassID class_ID,
|
|
ObjectID object_ID
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Controller methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
ReceiveControl(
|
|
AudioControlID control_ID,
|
|
AudioControlValue control_value
|
|
);
|
|
};
|
|
|
|
//##########################################################################
|
|
//####################### AudioControlSplitter #######################
|
|
//##########################################################################
|
|
|
|
class AudioControlSplitter:
|
|
public AudioComponent
|
|
{
|
|
public:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Construction, Destruction, Testing
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioControlSplitter(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
);
|
|
void
|
|
AudioControlSplitterX(Entity *entity);
|
|
~AudioControlSplitter();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// BuildFromPage
|
|
//--------------------------------------------------------------------
|
|
//
|
|
static void
|
|
BuildFromPage(
|
|
PlugStream *stream,
|
|
NameList *name_list,
|
|
ClassID class_ID,
|
|
ObjectID object_ID
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Controller methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
ReceiveControl(
|
|
AudioControlID control_ID,
|
|
AudioControlValue control_value
|
|
);
|
|
|
|
private:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Private data
|
|
//--------------------------------------------------------------------
|
|
//
|
|
SChainOf<AudioComponent*> audioComponentSocket;
|
|
};
|
|
|
|
//##########################################################################
|
|
//####################### AudioControlMixer ##########################
|
|
//##########################################################################
|
|
|
|
#define AUDIO_CONTROL_MIXER_MAX_CONTROLS (4)
|
|
|
|
class AudioControlMixer:
|
|
public AudioComponent
|
|
{
|
|
public:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Construction, Destruction, Testing
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioControlMixer(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
);
|
|
void
|
|
AudioControlMixerX(
|
|
AudioComponent *audio_component,
|
|
Entity *entity,
|
|
AudioControlID first_input_control_ID,
|
|
AudioControlID last_input_control_ID,
|
|
AudioControlID output_control_ID
|
|
);
|
|
~AudioControlMixer();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// BuildFromPage
|
|
//--------------------------------------------------------------------
|
|
//
|
|
static void
|
|
BuildFromPage(
|
|
PlugStream *stream,
|
|
NameList *name_list,
|
|
ClassID class_ID,
|
|
ObjectID object_ID
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Controller methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
ReceiveControl(
|
|
AudioControlID control_ID,
|
|
AudioControlValue control_value
|
|
);
|
|
|
|
private:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Private data
|
|
//--------------------------------------------------------------------
|
|
//
|
|
SlotOf<AudioComponent*>
|
|
audioComponentSocket;
|
|
|
|
AudioControlValue
|
|
controlValueArray[AUDIO_CONTROL_MIXER_MAX_CONTROLS];
|
|
AudioControlID
|
|
firstInputControlID;
|
|
int
|
|
numberOfInputs;
|
|
AudioControlID
|
|
outputControlID;
|
|
};
|
|
|
|
//##########################################################################
|
|
//###################### AudioControlMultiplier ######################
|
|
//##########################################################################
|
|
|
|
#define AUDIO_CONTROL_MULTIPLIER_MAX_CONTROLS (4)
|
|
|
|
class AudioControlMultiplier:
|
|
public AudioComponent
|
|
{
|
|
public:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Construction, Destruction, Testing
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioControlMultiplier(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
);
|
|
void
|
|
AudioControlMultiplierX(
|
|
AudioComponent *audio_component,
|
|
Entity *entity,
|
|
AudioControlID first_input_control_ID,
|
|
AudioControlID last_input_control_ID,
|
|
AudioControlID output_control_ID
|
|
);
|
|
~AudioControlMultiplier();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// BuildFromPage
|
|
//--------------------------------------------------------------------
|
|
//
|
|
static void
|
|
BuildFromPage(
|
|
PlugStream *stream,
|
|
NameList *name_list,
|
|
ClassID class_ID,
|
|
ObjectID object_ID
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Controller methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
ReceiveControl(
|
|
AudioControlID control_ID,
|
|
AudioControlValue control_value
|
|
);
|
|
|
|
private:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Private data
|
|
//--------------------------------------------------------------------
|
|
//
|
|
SlotOf<AudioComponent*>
|
|
audioComponentSocket;
|
|
|
|
AudioControlValue
|
|
controlValueArray[AUDIO_CONTROL_MULTIPLIER_MAX_CONTROLS];
|
|
AudioControlID
|
|
firstInputControlID;
|
|
int
|
|
numberOfInputs;
|
|
AudioControlID
|
|
outputControlID;
|
|
};
|
|
|
|
//##########################################################################
|
|
//######################## AudioControlSmoother ######################
|
|
//##########################################################################
|
|
|
|
class AudioControlSmoother:
|
|
public AudioComponent
|
|
{
|
|
public:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Construction, Destruction, Testing
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioControlSmoother(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
);
|
|
void
|
|
AudioControlSmootherX(
|
|
AudioComponent *audio_component,
|
|
Entity *entity,
|
|
AudioControlID control_ID
|
|
);
|
|
~AudioControlSmoother();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// BuildFromPage
|
|
//--------------------------------------------------------------------
|
|
//
|
|
static void
|
|
BuildFromPage(
|
|
PlugStream *stream,
|
|
NameList *name_list,
|
|
ClassID class_ID,
|
|
ObjectID object_ID
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Controller methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
ReceiveControl(
|
|
AudioControlID control_ID,
|
|
AudioControlValue control_value
|
|
);
|
|
|
|
private:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Private data
|
|
//--------------------------------------------------------------------
|
|
//
|
|
SlotOf<AudioComponent*>
|
|
audioComponentSocket;
|
|
AverageOf<AudioControlValue>
|
|
audioControlAverage;
|
|
AudioControlID
|
|
controlID;
|
|
};
|
|
|
|
//##########################################################################
|
|
//####################### AudioResourceSelector ######################
|
|
//##########################################################################
|
|
|
|
class AudioResourceIndex;
|
|
|
|
class AudioResourceSelector:
|
|
public AudioComponent
|
|
{
|
|
public:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Construction, Destruction, Testing
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioResourceSelector(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
);
|
|
void
|
|
AudioResourceSelectorX(
|
|
AudioSource *audio_source,
|
|
Entity *entity,
|
|
AudioResourceIndex *audio_resource_index,
|
|
AudioControlID control_ID,
|
|
AudioControlValue min_control_value,
|
|
AudioControlValue max_control_value,
|
|
Logical dump_value
|
|
);
|
|
~AudioResourceSelector();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// BuildFromPage
|
|
//--------------------------------------------------------------------
|
|
//
|
|
static void
|
|
BuildFromPage(
|
|
PlugStream *stream,
|
|
NameList *name_list,
|
|
ClassID class_ID,
|
|
ObjectID object_ID
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Controller methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
ReceiveControl(
|
|
AudioControlID control_ID,
|
|
AudioControlValue control_value
|
|
);
|
|
|
|
private:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Private data
|
|
//--------------------------------------------------------------------
|
|
//
|
|
SlotOf<AudioComponent*>
|
|
audioSourceSocket;
|
|
|
|
AudioResourceIndex
|
|
*audioResourceIndex;
|
|
|
|
AudioControlID
|
|
controlID;
|
|
AudioControlValue
|
|
minControlValue,
|
|
maxControlValue;
|
|
|
|
Logical
|
|
dumpValue;
|
|
};
|
|
|
|
//##########################################################################
|
|
//######################## AudioSampleAndHold ########################
|
|
//##########################################################################
|
|
|
|
class AudioSampleAndHold:
|
|
public AudioComponent
|
|
{
|
|
public:
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Construction, Destruction, Testing
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
AudioSampleAndHold(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
);
|
|
void
|
|
AudioSampleAndHoldX(
|
|
AudioComponent *audio_component,
|
|
Entity *entity,
|
|
AudioControlID audio_control_ID,
|
|
const AudioTime &sample_duration,
|
|
Scalar min_value,
|
|
Scalar max_value
|
|
);
|
|
~AudioSampleAndHold();
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// BuildFromPage
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
static void
|
|
BuildFromPage(
|
|
PlugStream *stream,
|
|
NameList *name_list,
|
|
ClassID class_ID,
|
|
ObjectID object_ID
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Execute
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
Execute();
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Controller methods
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
void
|
|
ReceiveControl(
|
|
AudioControlID control_ID,
|
|
AudioControlValue control_value
|
|
);
|
|
|
|
private:
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Private methods
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
void
|
|
SampleAndHold();
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Private data
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
SlotOf<AudioComponent*>
|
|
audioComponentSocket;
|
|
|
|
AudioControlID
|
|
audioControlID;
|
|
AudioControlValue
|
|
minValue,
|
|
maxValue,
|
|
currentValue;
|
|
AudioTime
|
|
nextSampleTime,
|
|
sampleDuration;
|
|
};
|
|
|
|
//##########################################################################
|
|
//############################# AudioLFO #############################
|
|
//##########################################################################
|
|
|
|
enum AudioLFOWaveForm
|
|
{
|
|
SinusoidalAudioLFOWaveForm = 0,
|
|
TriangularAudioLFOWaveForm = 1
|
|
};
|
|
|
|
inline MemoryStream&
|
|
MemoryStream_Read(
|
|
MemoryStream *stream,
|
|
AudioLFOWaveForm *ptr
|
|
)
|
|
{return stream->ReadBytes(ptr, sizeof(*ptr));}
|
|
inline MemoryStream&
|
|
MemoryStream_Write(
|
|
MemoryStream *stream,
|
|
const AudioLFOWaveForm *ptr
|
|
)
|
|
{return stream->WriteBytes(ptr, sizeof(*ptr));}
|
|
|
|
class AudioLFO:
|
|
public AudioComponent
|
|
{
|
|
public:
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Construction, Destruction, Testing
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
AudioLFO(
|
|
PlugStream *stream,
|
|
Entity *entity
|
|
);
|
|
void
|
|
AudioLFOX(
|
|
AudioComponent *audio_component,
|
|
Entity *entity,
|
|
AudioControlID audio_control_ID,
|
|
AudioLFOWaveForm wave_form,
|
|
Scalar the_period,
|
|
AudioControlValue min_value,
|
|
AudioControlValue max_value,
|
|
Logical dump_value
|
|
);
|
|
~AudioLFO();
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// BuildFromPage
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
static void
|
|
BuildFromPage(
|
|
PlugStream *stream,
|
|
NameList *name_list,
|
|
ClassID class_ID,
|
|
ObjectID object_ID
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Execute
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
Execute();
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Controller methods
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
void
|
|
ReceiveControl(
|
|
AudioControlID control_ID,
|
|
AudioControlValue control_value
|
|
);
|
|
|
|
private:
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Private methods
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
void
|
|
Generate();
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Private data
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
SlotOf<AudioComponent*>
|
|
audioComponentSocket;
|
|
|
|
AudioControlID
|
|
audioControlID;
|
|
AudioLFOWaveForm
|
|
waveForm;
|
|
AudioControlValue
|
|
minValue,
|
|
maxValue;
|
|
AudioTime
|
|
period;
|
|
AudioTime
|
|
startTime;
|
|
Logical
|
|
dumpValue;
|
|
};
|