Files
CydandClaude Fable 5 fdd9ac9d97 Initial import: Tesla Release 4.10 (Tesla:BattleTech & Tesla:Red Planet)
Archival snapshot of the Virtual World Entertainment Tesla cockpit
software, 1994-1996: MUNGA engine and L4 pod layer source (Borland
C++ 5.0), BT/RP game code, and game content (models, audio, maps,
gauges, Division renderer data). Includes third-party libraries:
Division dVS/DPL graphics, HMI SOS audio, WATTCP networking.

Files are preserved byte-for-byte (.gitattributes disables all
line-ending conversion). README.md documents the layout, target
hardware, and toolchain.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 13:21:58 -05:00

489 lines
12 KiB
C++

//===========================================================================//
// File: audio.hh //
// Project: MUNGA Brick: Audio manager //
// Contents: //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 01/30/95 ECH Initial coding. //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include <munga.hpp>
#pragma hdrstop
#if !defined(AUDIO_HPP)
# include <audio.hpp>
#endif
#if !defined(AUDREND_HPP)
# include <audrend.hpp>
#endif
#if !defined(APP_HPP)
#include <app.hpp>
#endif
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Audio Constants ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const Scalar AudioDoubleTriggerCutoff = 0.2f;
const AudioControlValue MaxAudioVolume = 1.0f;
const AudioControlValue MinAudioVolume = 0.0f;
const AudioControlValue LowAudioVolumeThreshold = 0.3f;
const AudioControlValue MaxAudioBrightness = 1.0f;
const AudioControlValue MinAudioBrightness = 0.0f;
const AudioControlValue MaxAudioAttack = 1.0f;
const AudioControlValue MinAudioAttack = 0.0f;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioHead ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//#############################################################################
//#############################################################################
//
AudioHead::AudioHead():
headEntitySocket(NULL)
{
//
// Start frame counter at 0, other counts should be at
// NullAudioFrameCount
//
audioFrameCount = 0;
//
// Other audio parameters
//
clippingRadius = 100.0f;
distanceBetweenEars = 1.0f;
amplitudeRollOffExponent = 1.0f;
amplitudeRollOffKnee = 10.0f,
amplitudeRollOffDistanceScale = 0.05f;
highFrequencyRollOffExponent = 0.5f;
highFrequencyRollOffKnee = 10.0f;
highFrequencyRollOffDistanceScale = 0.05f;
reverbToDryRatio = 0.1f;
audioSoundSpeed = 345.0f;
audioDopplerConstant = 20.0f;
sourceCompressionExponent = 0.5f;
sourceCompressionScale = 0.5f;
Check_Fpu();
}
//
//#############################################################################
//#############################################################################
//
AudioHead::~AudioHead()
{
Check(this);
Check_Fpu();
}
//
//#############################################################################
//#############################################################################
//
Logical
AudioHead::TestInstance() const
{
Check(&headEntitySocket);
return True;
}
//
//#############################################################################
//#############################################################################
//
void
AudioHead::LinkToEntity(Entity *entity)
{
Check(this);
Check(entity);
//
// Remove existing entity, add new one
//
if (headEntitySocket.GetCurrent() != NULL)
{
headEntitySocket.Remove();
}
headEntitySocket.Add(entity);
#if 0
//
// Make the new clipping sphere
//
clippingSphere.SetCurrentOrigin(entity->localOrigin.linearPosition);
#endif
}
//
//#############################################################################
//#############################################################################
//
LinearMatrix
AudioHead::GetEarToWorld()
{
Check(this);
Entity *entity = headEntitySocket.GetCurrent();
Check(entity);
return entity->localToWorld;
}
//
//#############################################################################
//#############################################################################
//
void
AudioHead::Execute()
{
Check(this);
//
// Increment frame counter
//
audioFrameCount++;
Verify(audioFrameCount < LONG_MAX);
#if 0
//
// Get the entity
//
Entity *entity = headEntitySocket.GetCurrent();
Check(entity);
//
// Make the new clipping sphere
//
clippingSphere.SetCurrentOrigin(entity->localOrigin.linearPosition);
#endif
}
//
//#############################################################################
//#############################################################################
//
void
AudioHead::DefineClippingSphere(Scalar radius)
{
Check(this);
clippingRadius = radius;
#if 0
//
// Get entity position
//
Entity *entity;
Point3D position(0.0f, 0.0f, 0.0f);
if ((entity = headEntitySocket.GetCurrent()) != NULL)
{
Check(entity);
position = entity->localOrigin.linearPosition;
}
//
// Make the new clipping sphere
//
clippingSphere.SetCurrentOrigin(position);
clippingSphere.SetReferenceRadius(radius);
#endif
}
//
//#############################################################################
//#############################################################################
//
Logical
AudioHead::IsPointClipped(const Point3D &point)
{
Check(this);
Entity
*entity;
Vector3D
difference;
entity = headEntitySocket.GetCurrent();
Check(entity);
difference.Subtract(entity->localOrigin.linearPosition, point);
return difference.LengthSquared() > clippingRadius*clippingRadius;
}
//
//#############################################################################
//#############################################################################
//
void
AudioHead::ControlDopplerEffect(
Scalar doppler_constant,
Scalar sound_speed
)
{
Check(this);
audioDopplerConstant = doppler_constant;
audioSoundSpeed = sound_speed;
Check_Fpu();
}
//
//#############################################################################
//#############################################################################
//
void
AudioHead::ControlAmplitudeRollOff(
Scalar exponent,
Scalar amplitude_rolloff_knee,
Scalar distance_scale
)
{
Check(this);
amplitudeRollOffExponent = exponent;
amplitudeRollOffKnee = amplitude_rolloff_knee;
amplitudeRollOffDistanceScale = distance_scale;
Check_Fpu();
}
//
//#############################################################################
//#############################################################################
//
void
AudioHead::ControlHighFrequencyRollOff(
Scalar exponent,
Scalar high_frequency_rolloff_knee,
Scalar distance_scale
)
{
Check(this);
highFrequencyRollOffExponent = exponent;
highFrequencyRollOffKnee = high_frequency_rolloff_knee;
highFrequencyRollOffDistanceScale = distance_scale;
Check_Fpu();
}
//
//#############################################################################
//#############################################################################
//
void
AudioHead::ControlSourceCompression(
Scalar exponent,
Scalar scale
)
{
Check(this);
sourceCompressionExponent = exponent;
sourceCompressionScale = scale;
Check_Fpu();
}
//
//#############################################################################
//#############################################################################
//
void
AudioHead::SetPositionalCulling(Logical)
{
Check(this);
Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioComponent ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//#############################################################################
//#############################################################################
//
const Receiver::HandlerEntry
AudioComponent::MessageHandlerEntries[]=
{
{
AudioComponent::ReceiveControlMessageID,
"ReceiveControl",
(AudioComponent::Handler)&AudioComponent::ReceiveControlMessageHandler
}
};
AudioComponent::MessageHandlerSet
AudioComponent::MessageHandlers(
ELEMENTS(AudioComponent::MessageHandlerEntries),
AudioComponent::MessageHandlerEntries,
Component::MessageHandlers
);
//
//#############################################################################
//#############################################################################
//
Derivation
AudioComponent::ClassDerivations(
Component::ClassDerivations,
"AudioComponent"
);
AudioComponent::SharedData
AudioComponent::DefaultData(
AudioComponent::ClassDerivations,
AudioComponent::MessageHandlers
);
//
//#############################################################################
//#############################################################################
//
AudioComponent::AudioComponent(
PlugStream *stream,
SharedData &shared_data
):
Component(stream, shared_data),
audioWatcherSocket(NULL)
{
nextExecuteWatcherFrame = NullAudioFrameCount;
}
//
//#############################################################################
//#############################################################################
//
AudioComponent::~AudioComponent()
{
}
//
//#############################################################################
//#############################################################################
//
Logical
AudioComponent::TestInstance() const
{
if (!IsDerivedFrom(ClassDerivations))
{
return False;
}
Check(&audioWatcherSocket);
return True;
}
//
//#############################################################################
//#############################################################################
//
void
AudioComponent::ExecuteWatchers()
{
Check(this);
//
// Execute watchers if this is the next watcher frame
//
AudioFrameCount
audio_frame_count;
Check(application);
Check(application->GetAudioRenderer());
audio_frame_count = application->GetAudioRenderer()->GetAudioFrameCount();
if (nextExecuteWatcherFrame <= audio_frame_count)
{
nextExecuteWatcherFrame = audio_frame_count + DefaultAudioFrameDelay;
//
// Execute watchers
//
ChainIteratorOf<Component*>
iterator(&audioWatcherSocket);
Component
*component;
while ((component = iterator.ReadAndNext()) != NULL)
{
Check(component);
component->Execute();
}
}
}
//
//#############################################################################
//#############################################################################
//
void
AudioComponent::Execute()
{
Check(this);
ExecuteWatchers();
Check_Fpu();
}
//
//#############################################################################
//#############################################################################
//
void
AudioComponent::ReceiveControl(
AudioControlID,
AudioControlValue
)
{
Fail("AudioComponent::ReceiveControl - Should never reach here");
}
//
//#############################################################################
//#############################################################################
//
void
AudioComponent::PostReceiveControl(
AudioControlID control_ID,
AudioControlValue control_value
)
{
Check(this);
ReceiveControlMessage
message(control_ID, control_value);
Check(application);
// ECH 1/26/96 - application->Post(HighEventPriority, this, &message);
application->Post(DefaultEventPriority, this, &message);
Check_Fpu();
}
//
//#############################################################################
//#############################################################################
//
void
AudioComponent::ReceiveControlMessageHandler(ReceiveControlMessage *message)
{
Check(this);
Check(message);
ReceiveControl(message->controlID, message->controlValue);
Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~ AudioComponent__ReceiveControlMessage ~~~~~~~~~~~~~~~~~~~~
AudioComponent__ReceiveControlMessage::AudioComponent__ReceiveControlMessage(
AudioControlID control_ID,
AudioControlValue control_value
):
Receiver::Message(
AudioComponent::ReceiveControlMessageID,
sizeof(AudioComponent__ReceiveControlMessage)
)
{
controlID = control_ID;
controlValue = control_value;
}