Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.

This commit is contained in:
LFeenanEA 2025-02-27 17:34:39 +00:00
parent 2e338c00cb
commit 3d0ee53a05
No known key found for this signature in database
GPG key ID: C6EBE8C2EA08F7E0
6072 changed files with 2283311 additions and 0 deletions

View file

@ -0,0 +1,83 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/AABTreeSoundCullClass.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 4/12/99 11:07a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __AABTREESOUNDCULLCLASS_H
#define __AABTREESOUNDCULLCLASS_H
#include "AABTreeCull.H"
/////////////////////////////////////////////////////////////////////////////////
//
// AABTreeSoundCullClass
//
// Simple derived class that implements 2 required methods from AABTreeCullClass.
//
class AABTreeSoundCullClass : public AABTreeCullClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
AABTreeSoundCullClass (void)
: AABTreeCullClass (NULL) { }
virtual ~AABTreeSoundCullClass (void) { }
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
void Load (ChunkLoadClass & cload) { }
void Save (ChunkSaveClass & csave) { }
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
virtual void Load_Node_Contents (AABTreeNodeClass * node,ChunkLoadClass & cload) { };
virtual void Save_Node_Contents (AABTreeNodeClass * node,ChunkSaveClass & csave) { };
};
#endif //__AABTREESOUNDCULLCLASS_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,464 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/AudibleSound.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 12:08p $*
* *
* $Revision:: 22 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUNDOBJ_H
#define __SOUNDOBJ_H
#pragma warning (push, 3)
#include "mss.h"
#pragma warning (pop)
//#include <malloc.h>
#include "vector3.h"
#include "matrix3d.h"
#include "refcount.h"
#include "rawfile.h"
#include "soundsceneobj.h"
#include "vector.h"
#include "wwstring.h"
#include "definition.h"
/////////////////////////////////////////////////////////////////////////////////
// Forward declarations
/////////////////////////////////////////////////////////////////////////////////
class SoundBufferClass;
class RenderObjClass;
class LogicalSoundClass;
class AudibleSoundDefinitionClass;
class Sound3DClass;
class SoundPseudo3DClass;
class FilteredSoundClass;
class Listener3DClass;
class SoundHandleClass;
/////////////////////////////////////////////////////////////////////////////////
//
// Typedefs
//
typedef unsigned long MILES_HANDLE;
typedef enum
{
INFO_OBJECT_PTR = 0,
INFO_MAX
} HANDLE_USER_INDEX;
/////////////////////////////////////////////////////////////////////////////////
//
// Constants
//
/////////////////////////////////////////////////////////////////////////////////
const MILES_HANDLE INVALID_MILES_HANDLE = (MILES_HANDLE)-1;
const int INFINITE_LOOPS = 0;
/////////////////////////////////////////////////////////////////////////////////
//
// AudibleSoundClass
//
// Base class defining a common interface to all sound object types.
//
/////////////////////////////////////////////////////////////////////////////////
class AudibleSoundClass : public SoundSceneObjClass
{
public:
//////////////////////////////////////////////////////////////////////
// Friend classes
//////////////////////////////////////////////////////////////////////
friend class WWAudioClass;
//////////////////////////////////////////////////////////////////////
// Public data types
//////////////////////////////////////////////////////////////////////
typedef enum
{
TYPE_MUSIC = 0,
TYPE_SOUND_EFFECT,
TYPE_COUNT
} SOUND_TYPE;
typedef enum
{
STATE_STOPPED = 0,
STATE_PLAYING,
STATE_PAUSED,
STATE_COUNT
} SOUND_STATE;
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
AudibleSoundClass (const AudibleSoundClass &src);
AudibleSoundClass (void);
virtual ~AudibleSoundClass (void);
//////////////////////////////////////////////////////////////////////
// Public operators
//////////////////////////////////////////////////////////////////////
const AudibleSoundClass &operator= (const AudibleSoundClass &src);
//////////////////////////////////////////////////////////////////////
// Identification methods
//////////////////////////////////////////////////////////////////////
virtual SOUND_CLASSID Get_Class_ID (void) const { return CLASSID_2D; }
virtual SOUND_TYPE Get_Type (void) const { return m_Type; }
virtual void Set_Type (SOUND_TYPE type) { m_Type = type; }
//////////////////////////////////////////////////////////////////////
// Conversion methods
//////////////////////////////////////////////////////////////////////
virtual AudibleSoundClass * As_AudibleSoundClass(void) { return this; }
//////////////////////////////////////////////////////////////////////
// Update methods
//////////////////////////////////////////////////////////////////////
virtual bool On_Frame_Update (unsigned int milliseconds = 0);
//////////////////////////////////////////////////////////////////////
// State control methods
//////////////////////////////////////////////////////////////////////
virtual bool Play (bool alloc_handle = true);
virtual bool Pause (void);
virtual bool Resume (void);
virtual bool Stop (bool remove_from_playlist = true);
virtual void Seek (unsigned long milliseconds);
virtual SOUND_STATE Get_State (void) const { return m_State; }
// The timestamp represents when the sound started playing
virtual unsigned long Get_Timestamp (void) const { return m_Timestamp; }
//////////////////////////////////////////////////////////////////////
// Informational methods
//////////////////////////////////////////////////////////////////////
virtual LPCTSTR Get_Filename (void) const;
virtual bool Is_Playing (void) const {return(Get_State() == STATE_PLAYING);}
//////////////////////////////////////////////////////////////////////
// Pan control
//////////////////////////////////////////////////////////////////////
//
// Note: Pan values are normalized values from 0 (hard left) to
// 1.0F (hard right). Dead center is 0.5F.
//
virtual float Get_Pan (void);
virtual void Set_Pan (float pan = 0.5F);
//////////////////////////////////////////////////////////////////////
// Volume control
//////////////////////////////////////////////////////////////////////
virtual float Get_Volume (void);
virtual void Set_Volume (float volume = 1.0F);
virtual void Update_Volume (void) { Set_Volume (m_Volume); }
//////////////////////////////////////////////////////////////////////
// Loop control
//////////////////////////////////////////////////////////////////////
virtual int Get_Loop_Count (void) const { return m_LoopCount; }
virtual int Get_Loops_Left (void) const;
// Note: Use the INFINITE_LOOPS constant for an infinite number of loops. (i.e. for use w/ music)
virtual void Set_Loop_Count (int count = 1);
//////////////////////////////////////////////////////////////////////
// Priority control
//////////////////////////////////////////////////////////////////////
virtual float Get_Priority (void) const { return m_Priority; }
virtual float Peek_Priority (void) const { return m_Priority; }
virtual void Set_Priority (float priority = 0.5F);
virtual float Get_Runtime_Priority (void) const { return m_RuntimePriority; }
virtual void Set_Runtime_Priority (float priority) { m_RuntimePriority = priority; }
//////////////////////////////////////////////////////////////////////
// Playback rate control
//////////////////////////////////////////////////////////////////////
virtual int Get_Playback_Rate (void);
virtual void Set_Playback_Rate (int rate_in_hz);
virtual float Get_Pitch_Factor (void) { return m_PitchFactor; }
virtual void Set_Pitch_Factor (float factor);
//////////////////////////////////////////////////////////////////////
// Buffer position manipulation
//////////////////////////////////////////////////////////////////////
//
// Note: The duration is in milliseconds. The play position
// can either be set as a normalized value from 0 to 1 or a millisecond
// offset from the start of the sound.
//
virtual unsigned long Get_Duration (void) const { return m_Length; }
virtual unsigned long Get_Play_Position (void) const { return m_CurrentPosition; }
virtual void Set_Play_Position (float position) { Seek (position * m_Length); }
virtual void Set_Play_Position (unsigned long milliseconds) { Seek (milliseconds); }
virtual void Set_Start_Offset (float offset) { m_StartOffset = offset; }
virtual float Get_Start_Offset (void) const { return m_StartOffset; }
//////////////////////////////////////////////////////////////////////
// Position/direction methods
//////////////////////////////////////////////////////////////////////
virtual void Set_Position (const Vector3 &position);
virtual Vector3 Get_Position (void) const { return m_Transform.Get_Translation (); }
virtual void Set_Listener_Transform (const Matrix3D &tm) { m_ListenerTransform = tm; }
virtual void Set_Transform (const Matrix3D &transform);
virtual Matrix3D Get_Transform (void) const { return m_Transform; }
//////////////////////////////////////////////////////////////////////
// Culling methods
//////////////////////////////////////////////////////////////////////
virtual void Cull_Sound (bool culled = true);
virtual bool Is_Sound_Culled (void) const { return m_IsCulled; }
//////////////////////////////////////////////////////////////////////
// Scene integration
//////////////////////////////////////////////////////////////////////
virtual void Add_To_Scene (bool start_playing = true);
virtual void Remove_From_Scene (void);
//////////////////////////////////////////////////////////////////////
// Attenuation settings
//////////////////////////////////////////////////////////////////////
//
// This is the distance where the sound can not be heard any longer. (its vol is 0)
//
virtual void Set_DropOff_Radius (float radius = 1);
virtual float Get_DropOff_Radius (void) const { return m_DropOffRadius; }
//////////////////////////////////////////////////////////////////////
// Update methods
//////////////////////////////////////////////////////////////////////
virtual void Set_Dirty (bool dirty = true) { m_bDirty = dirty; }
virtual bool Is_Dirty (void) const { return m_bDirty; }
//////////////////////////////////////////////////////////////////////
// Definition managmenent
//////////////////////////////////////////////////////////////////////
virtual void Set_Definition (AudibleSoundDefinitionClass *def) { m_Definition = def; }
virtual AudibleSoundDefinitionClass * Get_Definition (void) { return m_Definition; }
//////////////////////////////////////////////////////////////////////
// Conversion methods
//////////////////////////////////////////////////////////////////////
virtual void Re_Sync (AudibleSoundClass &src);
virtual void Free_Conversion (void);
virtual void Convert_To_Filtered (void);
virtual AudibleSoundClass *As_Converted_Format (void);
//////////////////////////////////////////////////////////////////////
// From PersistClass
//////////////////////////////////////////////////////////////////////
const PersistFactoryClass & Get_Factory (void) const;
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
virtual float Determine_Real_Volume (void) const;
//////////////////////////////////////////////////////////////////////
// Handle information
//////////////////////////////////////////////////////////////////////
virtual SoundHandleClass * Get_Miles_Handle (void) const { return m_SoundHandle; }
virtual void Set_Miles_Handle (MILES_HANDLE handle = INVALID_MILES_HANDLE);
virtual void Free_Miles_Handle (void);
virtual void Initialize_Miles_Handle (void);
virtual void Allocate_Miles_Handle (void);
//////////////////////////////////////////////////////////////////////
// Buffer information
//////////////////////////////////////////////////////////////////////
virtual SoundBufferClass * Get_Buffer (void) const;
virtual SoundBufferClass * Peek_Buffer (void) const;
virtual void Set_Buffer (SoundBufferClass *buffer);
//////////////////////////////////////////////////////////////////////
// Loop methods
//////////////////////////////////////////////////////////////////////
virtual void Restart_Loop (void) {}
virtual void Update_Play_Position (void);
//////////////////////////////////////////////////////////////////////
// Event handling
//////////////////////////////////////////////////////////////////////
virtual void On_Loop_End (void);
//////////////////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////////////////
SoundHandleClass * m_SoundHandle;
unsigned long m_Timestamp;
SOUND_STATE m_State;
SOUND_TYPE m_Type;
// Buffer information
SoundBufferClass * m_Buffer;
// Cached settings
float m_RuntimePriority;
float m_Priority;
float m_Volume;
float m_Pan;
int m_LoopCount;
int m_LoopsLeft;
// Offset and length information (in milliseconds)
unsigned long m_Length;
unsigned long m_CurrentPosition;
float m_StartOffset;
float m_PitchFactor;
// 3D scene information
Matrix3D m_ListenerTransform;
Matrix3D m_Transform;
Matrix3D m_PrevTransform;
bool m_IsCulled;
bool m_bDirty;
float m_DropOffRadius;
// Conversion data
AudibleSoundClass * m_pConvertedFormat;
// Definition pointer
AudibleSoundDefinitionClass * m_Definition;
// Logical sound information
LogicalSoundClass * m_LogicalSound;
};
//////////////////////////////////////////////////////////////////////////////////
//
// AudibleSoundDefinitionClass
//
//////////////////////////////////////////////////////////////////////////////////
class AudibleSoundDefinitionClass : public DefinitionClass
{
public:
/////////////////////////////////////////////////////////////////////
// Editable interface requirements
/////////////////////////////////////////////////////////////////////
DECLARE_EDITABLE(AudibleSoundDefinitionClass, DefinitionClass);
//////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////
AudibleSoundDefinitionClass (void);
virtual ~AudibleSoundDefinitionClass (void) { }
// From DefinitionClass
virtual uint32 Get_Class_ID (void) const;
// From PersistClass
virtual const PersistFactoryClass & Get_Factory (void) const;
virtual bool Save (ChunkSaveClass &csave);
virtual bool Load (ChunkLoadClass &cload);
virtual PersistClass * Create (void) const;
virtual AudibleSoundClass * Create_Sound (int classid_hint) const;
// Initialization
virtual void Initialize_From_Sound (AudibleSoundClass *sound);
// Accessors
virtual const StringClass & Get_Filename (void) const { return m_Filename; }
virtual const StringClass & Get_Display_Text (void) const { return m_DisplayText; }
virtual float Get_Max_Vol_Radius (void) const { return m_MaxVolRadius; }
virtual float Get_DropOff_Radius (void) const { return m_DropOffRadius; }
virtual const Vector3 & Get_Sphere_Color (void) const { return m_AttenuationSphereColor; }
virtual float Get_Volume (void) const { return m_Volume; }
virtual float Get_Start_Offset (void) const { return m_StartOffset; }
virtual float Get_Pitch_Factor (void) const { return m_PitchFactor; }
virtual void Set_Volume (float volume) { m_Volume = volume; }
virtual void Set_Max_Vol_Radius (float radius){ m_MaxVolRadius = radius; }
virtual void Set_DropOff_Radius (float radius){ m_DropOffRadius = radius; }
virtual void Set_Start_Offset (float offset) { m_StartOffset = offset; }
virtual void Set_Pitch_Factor (float factor) { m_PitchFactor = factor; }
// Logical sound creation
virtual LogicalSoundClass * Create_Logical (void);
protected:
/////////////////////////////////////////////////////////////////////
// Private methods
/////////////////////////////////////////////////////////////////////
bool Save_Variables (ChunkSaveClass &csave);
bool Load_Variables (ChunkLoadClass &cload);
//////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////
float m_Priority;
float m_Volume;
float m_Pan;
int m_LoopCount;
float m_DropOffRadius;
float m_MaxVolRadius;
bool m_Is3D;
StringClass m_Filename;
int m_Type;
StringClass m_DisplayText;
float m_StartOffset;
float m_PitchFactor;
int m_LogicalTypeMask;
float m_LogicalNotifyDelay;
float m_LogicalDropOffRadius;
bool m_CreateLogical;
// Misc UI info
Vector3 m_AttenuationSphereColor;
};
#endif //__SOUNDOBJ_H

View file

@ -0,0 +1,210 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/AudioEvents.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 5/24/00 5:40p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __AUDIO_EVENTS_H
#define __AUDIO_EVENTS_H
#include "simplevec.h"
#include "bittype.h"
/////////////////////////////////////////////////////////////////////////////////
// Forward declarations
/////////////////////////////////////////////////////////////////////////////////
class SoundSceneObjClass;
class LogicalListenerClass;
class LogicalSoundClass;
class AudibleSoundClass;
class StringClass;
/////////////////////////////////////////////////////////////////////////////////
//
// Global callbacks (C Style)
//
/////////////////////////////////////////////////////////////////////////////////
//
// Callback declarations. These functions are called when a registered event occurs
// in the sound library/
//
typedef void (_stdcall *LPFNSOSCALLBACK) (SoundSceneObjClass *sound_obj, uint32 user_param);
typedef void (_stdcall *LPFNEOSCALLBACK) (SoundSceneObjClass *sound_obj, uint32 user_param);
typedef void (_stdcall *LPFNHEARDCALLBACK) (LogicalListenerClass *listener, LogicalSoundClass *sound_obj, uint32 user_param);
typedef void (_stdcall *LPFNTEXTCALLBACK) (AudibleSoundClass *sound_obj, const StringClass &text, uint32 user_param);
/////////////////////////////////////////////////////////////////////////////////
//
// Object callbacks (C++ Style)
//
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//
// AudioCallbackClass
//
// To use this callback mechanism, simply derive from this class and override
// the methods you want notifications of. These methods will be called when
// the event occurs.
//
/////////////////////////////////////////////////////////////////////////////////
class AudioCallbackClass
{
public:
/////////////////////////////////////////////////////////////////////////////////
// Event identifiers
/////////////////////////////////////////////////////////////////////////////////
typedef enum
{
EVENT_NONE = 0x0000,
EVENT_SOUND_STARTED = 0x0001,
EVENT_SOUND_ENDED = 0x0002,
EVENT_LOGICAL_HEARD = 0x0004
} EVENTS;
/////////////////////////////////////////////////////////////////////////////////
// Overrideables (callback-methods)
/////////////////////////////////////////////////////////////////////////////////
virtual void On_Sound_Started (SoundSceneObjClass *sound_obj) { }
virtual void On_Sound_Ended (SoundSceneObjClass *sound_obj) { }
virtual void On_Logical_Heard (LogicalListenerClass *listener, LogicalSoundClass *sound_obj) { }
};
/////////////////////////////////////////////////////////////////////////////////
//
// Internal implementation
//
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//
// AudioCallbackListClass
//
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
// Protected structures
/////////////////////////////////////////////////////////////////////////////////
template <class T>
struct AUDIO_CALLBACK_STRUCT
{
T callback_ptr;
uint32 user_data;
AUDIO_CALLBACK_STRUCT (void)
: callback_ptr (NULL), user_data (0) {}
AUDIO_CALLBACK_STRUCT (T _ptr, uint32 _data)
: callback_ptr (_ptr), user_data (_data) {}
};
/////////////////////////////////////////////////////////////////////////////////
// Protected structures
/////////////////////////////////////////////////////////////////////////////////
template <class T>
class AudioCallbackListClass : public SimpleDynVecClass< AUDIO_CALLBACK_STRUCT<T> >
{
public:
/////////////////////////////////////////////////////////////////////////////////
// Public constructors/destructors
/////////////////////////////////////////////////////////////////////////////////
AudioCallbackListClass (void) { }
virtual ~AudioCallbackListClass (void) { }
/////////////////////////////////////////////////////////////////////////////////
// Public methods
/////////////////////////////////////////////////////////////////////////////////
void Add_Callback (T pointer, uint32 user_data);
T Get_Callback (int index, uint32 *user_data);
void Remove_Callback (T pointer);
};
/////////////////////////////////////////////////////////////////////////////////
// Add_Callback
/////////////////////////////////////////////////////////////////////////////////
template <class T> void
AudioCallbackListClass<T>::Add_Callback (T pointer, uint32 user_data)
{
Add ( AUDIO_CALLBACK_STRUCT<T> (pointer, user_data));
return ;
}
/////////////////////////////////////////////////////////////////////////////////
// Get_Callback
/////////////////////////////////////////////////////////////////////////////////
template <class T> T
AudioCallbackListClass<T>::Get_Callback (int index, uint32 *user_data)
{
if (user_data != NULL) {
(*user_data) = Vector[index].user_data;
}
return Vector[index].callback_ptr;
}
/////////////////////////////////////////////////////////////////////////////////
// Remove_Callback
/////////////////////////////////////////////////////////////////////////////////
template <class T> void
AudioCallbackListClass<T>::Remove_Callback (T pointer)
{
for (int index = 0; index < ActiveCount; index ++) {
if (Vector[index].callback_ptr == pointer) {
Delete (index);
break;
}
}
return ;
}
#endif //__AUDIO_EVENTS_H

View file

@ -0,0 +1,275 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : LevelEdit *
* *
* $Archive:: /Commando/Code/WWAudio/AudioSaveLoad.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/14/01 11:46a $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "always.h"
#include "audiosaveload.h"
#include "persist.h"
#include "persistfactory.h"
#include "definition.h"
#include "soundchunkids.h"
#include "chunkio.h"
#include "SoundScene.h"
#include "wwmemlog.h"
///////////////////////////////////////////////////////////////////////
// Global singleton instance
///////////////////////////////////////////////////////////////////////
StaticAudioSaveLoadClass _StaticAudioSaveLoadSubsystem;
DynamicAudioSaveLoadClass _DynamicAudioSaveLoadSubsystem;
///////////////////////////////////////////////////////////////////////
// Constants
///////////////////////////////////////////////////////////////////////
enum
{
CHUNKID_STATIC_SCENE = 0x10291220,
CHUNKID_DYNAMIC_SCENE,
CHUNKID_DYNAMIC_VARIABLES
};
enum
{
VARID_INCLUDE_FILE = 0x01,
VARID_CAMERA_TM,
VARID_BACK_COLOR,
VARID_LOGICAL_LISTENER_GLOBAL_SCALE
};
///////////////////////////////////////////////////////////////////////
//
// Chunk_ID
//
///////////////////////////////////////////////////////////////////////
uint32
StaticAudioSaveLoadClass::Chunk_ID (void) const
{
return CHUNKID_STATIC_SAVELOAD;
}
///////////////////////////////////////////////////////////////////////
//
// Contains_Data
//
///////////////////////////////////////////////////////////////////////
bool
StaticAudioSaveLoadClass::Contains_Data (void) const
{
return true;
}
///////////////////////////////////////////////////////////////////////
//
// Save
//
///////////////////////////////////////////////////////////////////////
bool
StaticAudioSaveLoadClass::Save (ChunkSaveClass &csave)
{
WWMEMLOG(MEM_SOUND);
bool retval = true;
//
// Save the static sounds
//
SoundSceneClass *scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
if (scene != NULL) {
csave.Begin_Chunk (CHUNKID_STATIC_SCENE);
scene->Save_Static (csave);
csave.End_Chunk ();
}
return retval;
}
///////////////////////////////////////////////////////////////////////
//
// Load
//
///////////////////////////////////////////////////////////////////////
bool
StaticAudioSaveLoadClass::Load (ChunkLoadClass &cload)
{
WWMEMLOG(MEM_SOUND);
bool retval = true;
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
//
// Load the static scene information
//
case CHUNKID_STATIC_SCENE:
{
SoundSceneClass *scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
if (scene != NULL) {
scene->Load_Static (cload);
}
}
break;
}
cload.Close_Chunk ();
}
return retval;
}
//*******************************************************************//
//*
//* Start of DynamicAudioSaveLoadClass
//*
//*******************************************************************//
///////////////////////////////////////////////////////////////////////
//
// Chunk_ID
//
///////////////////////////////////////////////////////////////////////
uint32
DynamicAudioSaveLoadClass::Chunk_ID (void) const
{
return CHUNKID_DYNAMIC_SAVELOAD;
}
///////////////////////////////////////////////////////////////////////
//
// Contains_Data
//
///////////////////////////////////////////////////////////////////////
bool
DynamicAudioSaveLoadClass::Contains_Data (void) const
{
return true;
}
///////////////////////////////////////////////////////////////////////
//
// Save
//
///////////////////////////////////////////////////////////////////////
bool
DynamicAudioSaveLoadClass::Save (ChunkSaveClass &csave)
{
bool retval = true;
//
// Save the static sounds
//
SoundSceneClass *scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
if (scene != NULL) {
csave.Begin_Chunk (CHUNKID_DYNAMIC_VARIABLES);
float global_scale = LogicalListenerClass::Get_Global_Scale ();
WRITE_MICRO_CHUNK (csave, VARID_LOGICAL_LISTENER_GLOBAL_SCALE, global_scale);
csave.End_Chunk ();
csave.Begin_Chunk (CHUNKID_DYNAMIC_SCENE);
scene->Save_Dynamic (csave);
csave.End_Chunk ();
}
return retval;
}
///////////////////////////////////////////////////////////////////////
//
// Load
//
///////////////////////////////////////////////////////////////////////
bool
DynamicAudioSaveLoadClass::Load (ChunkLoadClass &cload)
{
bool retval = true;
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
case CHUNKID_DYNAMIC_VARIABLES:
{
//
// Read all the variables from their micro-chunks
//
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {
//
// Load the global scale for logical listeners
//
case VARID_LOGICAL_LISTENER_GLOBAL_SCALE:
{
float global_scale = 1.0F;
LOAD_MICRO_CHUNK (cload, global_scale);
LogicalListenerClass::Set_Global_Scale (global_scale);
break;
}
}
cload.Close_Micro_Chunk ();
}
}
break;
//
// Load the static scene information
//
case CHUNKID_DYNAMIC_SCENE:
{
SoundSceneClass *scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
if (scene != NULL) {
scene->Load_Dynamic (cload);
}
}
break;
}
cload.Close_Chunk ();
}
return retval;
}

View file

@ -0,0 +1,128 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : LevelEdit *
* *
* $Archive:: /Commando/Code/WWAudio/AudioSaveLoad.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 6/12/00 4:29p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __AUDIO_SAVE_LOAD_H
#define __AUDIO_SAVE_LOAD_H
#include "saveloadsubsystem.h"
#include "vector.h"
#include "bittype.h"
// Singleton instances
extern class StaticAudioSaveLoadClass _StaticAudioSaveLoadSubsystem;
extern class DynamicAudioSaveLoadClass _DynamicAudioSaveLoadSubsystem;
//////////////////////////////////////////////////////////////////////////
//
// StaticAudioSaveLoadClass
//
//////////////////////////////////////////////////////////////////////////
class StaticAudioSaveLoadClass : public SaveLoadSubSystemClass
{
public:
//////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////
StaticAudioSaveLoadClass (void) { }
virtual ~StaticAudioSaveLoadClass (void) { }
//////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////
// From SaveLoadSubSystemClass
virtual uint32 Chunk_ID (void) const;
protected:
//////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////
virtual bool Contains_Data(void) const;
virtual bool Save (ChunkSaveClass &csave);
virtual bool Load (ChunkLoadClass &cload);
virtual const char* Name() const { return "StaticAudioSaveLoadClass"; }
};
//////////////////////////////////////////////////////////////////////////
//
// DynamicAudioSaveLoadClass
//
//////////////////////////////////////////////////////////////////////////
class DynamicAudioSaveLoadClass : public SaveLoadSubSystemClass
{
public:
//////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////
DynamicAudioSaveLoadClass (void) { }
virtual ~DynamicAudioSaveLoadClass (void) { }
//////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////
// From SaveLoadSubSystemClass
virtual uint32 Chunk_ID (void) const;
protected:
//////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////
virtual bool Contains_Data(void) const;
virtual bool Save (ChunkSaveClass &csave);
virtual bool Load (ChunkLoadClass &cload);
virtual const char* Name() const { return "DynamicAudioSaveLoadClass"; }
//bool Save_Micro_Chunks (ChunkSaveClass &csave);
//bool Load_Micro_Chunks (ChunkLoadClass &cload);
};
#endif //__AUDIO_SAVE_LOAD_H

View file

@ -0,0 +1,184 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/FilteredSound.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 3:03p $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "filteredsound.h"
#include "wwaudio.h"
#include "soundscene.h"
#include "soundchunkids.h"
#include "persistfactory.h"
#include "soundhandle.h"
//////////////////////////////////////////////////////////////////////////////////
//
// Static factories
//
//////////////////////////////////////////////////////////////////////////////////
SimplePersistFactoryClass<FilteredSoundClass, CHUNKID_FILTERED_SOUND> _FilteredSoundPersistFactory;
/////////////////////////////////////////////////////////////////////////////////
//
// FilteredSoundClass
//
/////////////////////////////////////////////////////////////////////////////////
FilteredSoundClass::FilteredSoundClass (void)
: m_hFilter (INVALID_MILES_HANDLE)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// FilteredSoundClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
FilteredSoundClass::FilteredSoundClass (const FilteredSoundClass &src)
: m_hFilter (INVALID_MILES_HANDLE),
SoundPseudo3DClass (src)
{
(*this) = src;
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// ~FilteredSoundClass
//
/////////////////////////////////////////////////////////////////////////////////
FilteredSoundClass::~FilteredSoundClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// operator=
//
////////////////////////////////////////////////////////////////////////////////////////////////
const FilteredSoundClass &
FilteredSoundClass::operator= (const FilteredSoundClass &src)
{
// Call the base class
SoundPseudo3DClass::operator= (src);
return (*this);
}
/////////////////////////////////////////////////////////////////////////////////
//
// Initialize_Miles_Handle
//
/////////////////////////////////////////////////////////////////////////////////
void
FilteredSoundClass::Initialize_Miles_Handle (void)
{
SoundPseudo3DClass::Initialize_Miles_Handle ();
m_hFilter = WWAudioClass::Get_Instance ()->Get_Reverb_Filter ();
if ((m_SoundHandle != NULL) &&
(m_hFilter != INVALID_MILES_HANDLE)) {
//
// Pass the filter onto the sample
//
::AIL_set_sample_processor (m_SoundHandle->Get_HSAMPLE (), DP_FILTER, m_hFilter);
//
// Change the reverb's settings to simulate a 'tinny' effect.
//
F32 reverb_level = 0.3F;
F32 reverb_reflect = 0.01F;
F32 reverb_decay = 0.535F;
::AIL_set_filter_sample_preference (m_SoundHandle->Get_HSAMPLE (),
"Reverb level",
&reverb_level);
::AIL_set_filter_sample_preference (m_SoundHandle->Get_HSAMPLE (),
"Reverb reflect time",
&reverb_reflect);
::AIL_set_filter_sample_preference (m_SoundHandle->Get_HSAMPLE (),
"Reverb decay time",
&reverb_decay);
}
Update_Volume ();
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Update_Volume
//
/////////////////////////////////////////////////////////////////////////////////
void
FilteredSoundClass::Update_Volume (void)
{
if (m_SoundHandle != NULL) {
// Determine the listener's position and the sound's position
SoundSceneClass *scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
Listener3DClass *listener = scene->Peek_2nd_Listener ();
if (listener != NULL) {
Vector3 listener_pos = listener->Get_Position ();
Vector3 sound_pos = m_Transform.Get_Translation ();
// Determine a normalized volume from the position
float distance = (sound_pos - listener_pos).Quick_Length ();
Update_Pseudo_Volume (distance);
}
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Get_Factory
//
/////////////////////////////////////////////////////////////////////////////////
const PersistFactoryClass &
FilteredSoundClass::Get_Factory (void) const
{
return _FilteredSoundPersistFactory;
}

View file

@ -0,0 +1,106 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/FilteredSound.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/11/00 12:01p $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __FILTERED_SOUND_H
#define __FILTERED_SOUND_H
#include "SoundPseudo3D.H"
/////////////////////////////////////////////////////////////////////////////////
//
// FilteredSoundClass
//
// Sound object that applies the specified 'reverb' filter so as to sound 'tinny'.
//
/////////////////////////////////////////////////////////////////////////////////
class FilteredSoundClass : public SoundPseudo3DClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
FilteredSoundClass (const FilteredSoundClass &src);
FilteredSoundClass (void);
virtual ~FilteredSoundClass (void);
//////////////////////////////////////////////////////////////////////
// Public operators
//////////////////////////////////////////////////////////////////////
const FilteredSoundClass &operator= (const FilteredSoundClass &src);
//////////////////////////////////////////////////////////////////////
// Identification methods
//////////////////////////////////////////////////////////////////////
virtual SOUND_CLASSID Get_Class_ID (void) { return CLASSID_FILTERED; }
//////////////////////////////////////////////////////////////////////
// Conversion methods
//////////////////////////////////////////////////////////////////////
virtual FilteredSoundClass * As_FilteredSoundClass (void) { return this; }
//////////////////////////////////////////////////////////////////////
// Volume control
//////////////////////////////////////////////////////////////////////
virtual void Update_Volume (void);
// From PersistClass
const PersistFactoryClass & Get_Factory (void) const;
protected:
//////////////////////////////////////////////////////////////////////
// Handle information
//////////////////////////////////////////////////////////////////////
virtual void Initialize_Miles_Handle (void);
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
HPROVIDER m_hFilter;
};
#endif //__FILTERED_SOUND_H

View file

@ -0,0 +1,142 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/Listener.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 3:05p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "listener.h"
#include "wwaudio.h"
#include "utils.h"
#include "soundhandle.h"
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Listener3DClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
Listener3DClass::Listener3DClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// ~Listener3DClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
Listener3DClass::~Listener3DClass (void)
{
Free_Miles_Handle ();
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Initialize_Miles_Handle
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Listener3DClass::Initialize_Miles_Handle (void)
{
MMSLockClass lock;
// Do we have a valid sample handle from miles?
if (m_SoundHandle != NULL) {
::AIL_set_3D_position (m_SoundHandle->Get_H3DSAMPLE (), 0.0F, 0.0F, 0.0F);
::AIL_set_3D_orientation (m_SoundHandle->Get_H3DSAMPLE (),
0.0F, 0.0F, 1.0F,
0.0F, 1.0F, 0.0F);
// Associate this object instance with the handle
m_SoundHandle->Set_Sample_User_Data (INFO_OBJECT_PTR, (S32)this);
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Allocate_Miles_Handle
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Listener3DClass::Allocate_Miles_Handle (void)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Free_Miles_Handle
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Listener3DClass::Free_Miles_Handle (void)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// On_Added_To_Scene
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Listener3DClass::On_Added_To_Scene (void)
{
Allocate_Miles_Handle ();
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// On_Removed_From_Scene
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Listener3DClass::On_Removed_From_Scene (void)
{
Free_Miles_Handle ();
return ;
}

View file

@ -0,0 +1,147 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/Listener.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 2/07/01 6:10p $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __LISTENER_H
#define __LISTENER_H
#include "Sound3D.H"
/////////////////////////////////////////////////////////////////////////////////
//
// Listener3DClass
//
// Class defining the 'listeners' 3D position/velocity in the world. This should
// only be used by the SoundSceneClass.
//
class Listener3DClass : public Sound3DClass
{
public:
//////////////////////////////////////////////////////////////////////
// Friend classes
//////////////////////////////////////////////////////////////////////
friend class SoundSceneClass;
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
Listener3DClass (void);
virtual ~Listener3DClass (void);
//////////////////////////////////////////////////////////////////////
// Identification methods
//////////////////////////////////////////////////////////////////////
virtual SOUND_CLASSID Get_Class_ID (void) const { return CLASSID_LISTENER; }
//////////////////////////////////////////////////////////////////////
// Conversion methods
//////////////////////////////////////////////////////////////////////
virtual Listener3DClass * As_Listener3DClass (void) { return this; }
//////////////////////////////////////////////////////////////////////
// Initialization methods
//////////////////////////////////////////////////////////////////////
virtual void On_Added_To_Scene (void);
virtual void On_Removed_From_Scene (void);
//////////////////////////////////////////////////////////////////////
// State control methods
//////////////////////////////////////////////////////////////////////
//virtual bool Play (void) { return false; }
virtual bool Pause (void) { return false; }
virtual bool Resume (void) { return false; }
virtual bool Stop (bool /*remove*/) { return false; }
virtual void Seek (unsigned long milliseconds) { }
virtual SOUND_STATE Get_State (void) const { return STATE_STOPPED; }
//////////////////////////////////////////////////////////////////////
// Attenuation settings
//////////////////////////////////////////////////////////////////////
virtual void Set_Max_Vol_Radius (float radius = 0) { }
virtual float Get_Max_Vol_Radius (void) const { return 0; }
virtual void Set_DropOff_Radius (float radius = 1) { }
virtual float Get_DropOff_Radius (void) const { return 0; }
//////////////////////////////////////////////////////////////////////
// Velocity methods
//////////////////////////////////////////////////////////////////////
virtual void Set_Velocity (const Vector3 &velocity) { }
protected:
//////////////////////////////////////////////////////////////////////
// Internal representations
//////////////////////////////////////////////////////////////////////
virtual void Start_Sample (void) { }
virtual void Stop_Sample (void) { }
virtual void Resume_Sample (void) { }
virtual void End_Sample (void) { }
virtual void Set_Sample_Volume (S32 volume) { }
virtual S32 Get_Sample_Volume (void) { return 0; }
virtual void Set_Sample_Pan (S32 pan) { }
virtual S32 Get_Sample_Pan (void) { return 64; }
virtual void Set_Sample_Loop_Count (U32 count) { }
virtual U32 Get_Sample_Loop_Count (void) { return 0; }
virtual void Set_Sample_MS_Position (U32 ms) { }
virtual void Get_Sample_MS_Position (S32 *len, S32 *pos) { }
virtual S32 Get_Sample_Playback_Rate (void) { return 0; }
virtual void Set_Sample_Playback_Rate (S32 rate) { }
//////////////////////////////////////////////////////////////////////
// Handle information
//////////////////////////////////////////////////////////////////////
virtual void Initialize_Miles_Handle (void);
virtual void Allocate_Miles_Handle (void);
virtual void Free_Miles_Handle (void);
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
};
#endif //__LISTENER_H

View file

@ -0,0 +1,219 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/LogicalListener.cpp $*
* *
* $Modtime:: 8/14/01 11:45a $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "LogicalListener.H"
#include "WWAudio.H"
#include "SoundScene.H"
#include "SoundChunkIDs.h"
#include "persistfactory.h"
//////////////////////////////////////////////////////////////////////////////////
// Static member initialization
//////////////////////////////////////////////////////////////////////////////////
uint32 LogicalListenerClass::m_OldestTimestamp = 0;
uint32 LogicalListenerClass::m_NewestTimestamp = 1;
float LogicalListenerClass::m_GlobalScale = 1.0F;
//////////////////////////////////////////////////////////////////////////////////
// Static factories
//////////////////////////////////////////////////////////////////////////////////
SimplePersistFactoryClass<LogicalListenerClass, CHUNKID_LOGICALLISTENER> _LogicalListenerPersistFactory;
//////////////////////////////////////////////////////////////////////////////////
// Save/Load constants
//////////////////////////////////////////////////////////////////////////////////
enum
{
CHUNKID_VARIABLES = 0x03270542,
CHUNKID_BASE_CLASS
};
enum
{
XXXVARID_DROP_OFF_RADIUS = 0x01,
VARID_TYPE_MASK,
VARID_XXX1,
VARID_POSITION,
VARID_SCALE
};
////////////////////////////////////////////////////////////////////////////////////////////////
//
// LogicalListenerClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
LogicalListenerClass::LogicalListenerClass (void)
: m_Scale (1),
m_TypeMask (0),
m_Position (0, 0, 0),
m_Timestamp (0)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// ~LogicalListenerClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
LogicalListenerClass::~LogicalListenerClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Add_To_Scene
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
LogicalListenerClass::Add_To_Scene (bool /*start_playing*/)
{
SoundSceneClass *scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
if ((scene != NULL) && (m_Scene == NULL)) {
//
// Add this listener to the culling system
//
m_Scene = scene;
scene->Add_Logical_Listener (this);
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Remove_From_Scene
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
LogicalListenerClass::Remove_From_Scene (void)
{
if (m_Scene != NULL) {
//
// Remove this listener from the culling system
//
m_Scene->Remove_Logical_Listener (this);
m_Scene = NULL;
m_PhysWrapper = NULL;
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Get_Factory
//
/////////////////////////////////////////////////////////////////////////////////
const PersistFactoryClass &
LogicalListenerClass::Get_Factory (void) const
{
return _LogicalListenerPersistFactory;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Save
//
//////////////////////////////////////////////////////////////////////////////////
bool
LogicalListenerClass::Save (ChunkSaveClass &csave)
{
csave.Begin_Chunk (CHUNKID_BASE_CLASS);
SoundSceneObjClass::Save (csave);
csave.End_Chunk ();
csave.Begin_Chunk (CHUNKID_VARIABLES);
WRITE_MICRO_CHUNK (csave, VARID_SCALE, m_Scale);
WRITE_MICRO_CHUNK (csave, VARID_TYPE_MASK, m_TypeMask);
WRITE_MICRO_CHUNK (csave, VARID_POSITION, m_Position);
csave.End_Chunk ();
return true;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Load
//
//////////////////////////////////////////////////////////////////////////////////
bool
LogicalListenerClass::Load (ChunkLoadClass &cload)
{
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
case CHUNKID_BASE_CLASS:
PersistClass::Load (cload);
break;
case CHUNKID_VARIABLES:
{
//
// Read all the variables from their micro-chunks
//
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {
READ_MICRO_CHUNK (cload, VARID_SCALE, m_Scale);
READ_MICRO_CHUNK (cload, VARID_TYPE_MASK, m_TypeMask);
READ_MICRO_CHUNK (cload, VARID_POSITION, m_Position);
}
cload.Close_Micro_Chunk ();
}
}
break;
}
cload.Close_Chunk ();
}
return true;
}

View file

@ -0,0 +1,153 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/LogicalListener.h $Modtime:: 7/01/99 10:18a $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __LOGICAL_LISTENER_H
#define __LOGICAL_LISTENER_H
#include "SoundSceneObj.H"
#include "BitType.H"
#include "Vector3.H"
#include "Matrix3D.H"
/////////////////////////////////////////////////////////////////////////////////
//
// LogicalListenerClass
//
// This class represents listeners in the 'world' that can hear and react to
// logical sounds.
//
/////////////////////////////////////////////////////////////////////////////////
class LogicalListenerClass : public SoundSceneObjClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
LogicalListenerClass (void);
virtual ~LogicalListenerClass (void);
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// LogicalSoundClass specific
//////////////////////////////////////////////////////////////////////
virtual void Set_Type_Mask (uint32 mask = 0) { m_TypeMask = mask; }
virtual uint32 Get_Type_Mask (void) const { return m_TypeMask; }
//////////////////////////////////////////////////////////////////////
// Position/direction methods
//////////////////////////////////////////////////////////////////////
virtual void Set_Position (const Vector3 &position) { m_Position = position; }
virtual Vector3 Get_Position (void) const { return m_Position; }
virtual void Set_Transform (const Matrix3D &transform) { m_Position = transform.Get_Translation (); }
virtual Matrix3D Get_Transform (void) const { Matrix3D tm(1); tm.Set_Translation (m_Position); return tm; }
//////////////////////////////////////////////////////////////////////
// Culling methods (not used for listeners)
//////////////////////////////////////////////////////////////////////
virtual void Cull_Sound (bool culled = true) { };
virtual bool Is_Sound_Culled (void) const { return false; };
//////////////////////////////////////////////////////////////////////
// Scene integration
//////////////////////////////////////////////////////////////////////
virtual void Add_To_Scene (bool /*start_playing*/ = true);
virtual void Remove_From_Scene (void);
//////////////////////////////////////////////////////////////////////
// Attenuation settings
//////////////////////////////////////////////////////////////////////
//
// This is the distance where the listener can no longer hear sounds.
//
virtual void Set_Scale (float scale = 1.0F) { m_Scale = scale; }
virtual float Get_Scale (void) const { return m_Scale; }
virtual float Get_Effective_Scale (void) const { return m_Scale * m_GlobalScale; }
static float Get_Global_Scale (void) { return m_GlobalScale; }
static void Set_Global_Scale (float scale) { m_GlobalScale = scale; }
virtual void Set_DropOff_Radius (float radius = 1) {}
virtual float Get_DropOff_Radius (void) const { return 1.0F; }
//////////////////////////////////////////////////////////////////////
// From PersistClass
//////////////////////////////////////////////////////////////////////
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
const PersistFactoryClass & Get_Factory (void) const;
//////////////////////////////////////////////////////////////////////
// Timestamp
//////////////////////////////////////////////////////////////////////
uint32 Get_Timestamp (void) const { return m_Timestamp; }
void Set_Timestamp (int timestamp) { m_Timestamp = timestamp; }
static uint32 Get_New_Timestamp (void) { return m_NewestTimestamp ++; }
static uint32 Get_Newest_Timestamp (void) { return m_NewestTimestamp - 1; }
static uint32 Get_Oldest_Timestamp (void) { return m_OldestTimestamp; }
static void Set_Oldest_Timestamp (uint32 timestamp) { WWASSERT (m_OldestTimestamp < timestamp); m_OldestTimestamp = timestamp; }
protected:
//////////////////////////////////////////////////////////////////////
// Update methods
//////////////////////////////////////////////////////////////////////
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
static float m_GlobalScale;
float m_Scale;
uint32 m_TypeMask;
Vector3 m_Position;
uint32 m_Timestamp;
static uint32 m_OldestTimestamp;
static uint32 m_NewestTimestamp;
};
#endif //__LOGICAL_LISTENER_H

View file

@ -0,0 +1,260 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/LogicalSound.cpp $Modtime:: 7/02/99 10:18a $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "LogicalSound.H"
#include "WWAudio.H"
#include "SoundScene.H"
#include "SoundChunkIDs.h"
#include "persistfactory.h"
//////////////////////////////////////////////////////////////////////////////////
// Static factories
//////////////////////////////////////////////////////////////////////////////////
SimplePersistFactoryClass<LogicalSoundClass, CHUNKID_LOGICALSOUND> _LogicalSoundPersistFactory;
//////////////////////////////////////////////////////////////////////////////////
// Save/Load constants
//////////////////////////////////////////////////////////////////////////////////
enum
{
CHUNKID_VARIABLES = 0x03270459,
CHUNKID_BASE_CLASS
};
enum
{
VARID_DROP_OFF_RADIUS = 0x01,
VARID_IS_SINGLE_SHOT,
VARID_TYPE_MASK,
VARID_XXX1,
VARID_POSITION,
VARID_MAX_LISTENERS,
VARID_NOTIFY_DELAY,
VARID_LAST_NOTIFY,
};
////////////////////////////////////////////////////////////////////////////////////////////////
//
// LogicalSoundClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
LogicalSoundClass::LogicalSoundClass (void)
: m_DropOffRadius (1),
m_TypeMask (0),
m_Position (0, 0, 0),
m_IsSingleShot (false),
m_OldestListenerTimestamp (0),
m_MaxListeners (0),
m_NotifyDelayInMS (2000),
m_LastNotification (0)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// ~LogicalSoundClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
LogicalSoundClass::~LogicalSoundClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Add_To_Scene
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
LogicalSoundClass::Add_To_Scene (bool /*start_playing*/)
{
SoundSceneClass *scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
if ((scene != NULL) && (m_Scene == NULL)) {
//
// Add this sound to the culling system
//
m_Scene = scene;
scene->Add_Logical_Sound (this, m_IsSingleShot);
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Remove_From_Scene
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
LogicalSoundClass::Remove_From_Scene (void)
{
if (m_Scene != NULL) {
//
// Remove this sound from the culling system
//
m_Scene->Remove_Logical_Sound (this, m_IsSingleShot);
m_Scene = NULL;
m_PhysWrapper = NULL;
m_LastNotification = 0;
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Allow_Notify
//
////////////////////////////////////////////////////////////////////////////////////////////////
bool
LogicalSoundClass::Allow_Notify (uint32 timestamp)
{
bool retval = false;
if (m_IsSingleShot || timestamp > (m_LastNotification + m_NotifyDelayInMS)) {
retval = true;
m_LastNotification = timestamp;
}
return retval;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// On_Frame_Update
//
////////////////////////////////////////////////////////////////////////////////////////////////
bool
LogicalSoundClass::On_Frame_Update (unsigned int milliseconds)
{
//
// Update the sound's position if its linked to a render object
//
Apply_Auto_Position ();
return SoundSceneObjClass::On_Frame_Update (milliseconds);;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Get_Factory
//
/////////////////////////////////////////////////////////////////////////////////
const PersistFactoryClass &
LogicalSoundClass::Get_Factory (void) const
{
return _LogicalSoundPersistFactory;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Save
//
//////////////////////////////////////////////////////////////////////////////////
bool
LogicalSoundClass::Save (ChunkSaveClass &csave)
{
csave.Begin_Chunk (CHUNKID_BASE_CLASS);
SoundSceneObjClass::Save (csave);
csave.End_Chunk ();
csave.Begin_Chunk (CHUNKID_VARIABLES);
WRITE_MICRO_CHUNK (csave, VARID_DROP_OFF_RADIUS, m_DropOffRadius);
WRITE_MICRO_CHUNK (csave, VARID_IS_SINGLE_SHOT, m_IsSingleShot);
WRITE_MICRO_CHUNK (csave, VARID_TYPE_MASK, m_TypeMask);
WRITE_MICRO_CHUNK (csave, VARID_POSITION, m_Position);
WRITE_MICRO_CHUNK (csave, VARID_MAX_LISTENERS, m_MaxListeners);
WRITE_MICRO_CHUNK (csave, VARID_NOTIFY_DELAY, m_NotifyDelayInMS);
WRITE_MICRO_CHUNK (csave, VARID_LAST_NOTIFY, m_LastNotification);
csave.End_Chunk ();
return true;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Load
//
//////////////////////////////////////////////////////////////////////////////////
bool
LogicalSoundClass::Load (ChunkLoadClass &cload)
{
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
case CHUNKID_BASE_CLASS:
PersistClass::Load (cload);
break;
case CHUNKID_VARIABLES:
{
//
// Read all the variables from their micro-chunks
//
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {
READ_MICRO_CHUNK (cload, VARID_DROP_OFF_RADIUS, m_DropOffRadius);
READ_MICRO_CHUNK (cload, VARID_IS_SINGLE_SHOT, m_IsSingleShot);
READ_MICRO_CHUNK (cload, VARID_TYPE_MASK, m_TypeMask);
READ_MICRO_CHUNK (cload, VARID_POSITION, m_Position);
READ_MICRO_CHUNK (cload, VARID_MAX_LISTENERS, m_MaxListeners);
READ_MICRO_CHUNK (cload, VARID_NOTIFY_DELAY, m_NotifyDelayInMS);
READ_MICRO_CHUNK (cload, VARID_LAST_NOTIFY, m_LastNotification);
}
cload.Close_Micro_Chunk ();
}
}
break;
}
cload.Close_Chunk ();
}
return true;
}

View file

@ -0,0 +1,153 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/LogicalSound.h $Modtime:: 7/01/99 10:18a $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __LOGICAL_SOUND_H
#define __LOGICAL_SOUND_H
#include "SoundSceneObj.H"
#include "BitType.H"
#include "Vector3.H"
#include "Matrix3D.H"
/////////////////////////////////////////////////////////////////////////////////
//
// LogicalSoundClass
//
// This class represents 'logical' sounds that affect gameplay but do not
// actually make an audible sound
//
class LogicalSoundClass : public SoundSceneObjClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public friends
//////////////////////////////////////////////////////////////////////
friend class SoundSceneClass;
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
LogicalSoundClass (void);
virtual ~LogicalSoundClass (void);
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// LogicalSoundClass specific
//////////////////////////////////////////////////////////////////////
virtual bool Is_Single_Shot (void) const { return m_IsSingleShot; }
virtual void Set_Single_Shot (bool single_shot) { m_IsSingleShot = single_shot; }
virtual void Set_Type_Mask (uint32 mask = 0) { m_TypeMask = mask; }
virtual uint32 Get_Type_Mask (void) const { return m_TypeMask; }
virtual float Get_Notify_Delay (void) const { return (float)m_NotifyDelayInMS / 1000.0F; }
virtual void Set_Notify_Delay (float secs) { m_NotifyDelayInMS = uint32(secs * 1000.0F); }
virtual bool Allow_Notify (uint32 timestamp);
virtual uint32 Get_Listener_Timestamp (void) const { return m_OldestListenerTimestamp; }
virtual void Set_Listener_Timestamp (int timestamp) { m_OldestListenerTimestamp = timestamp; }
//////////////////////////////////////////////////////////////////////
// Update methods
//////////////////////////////////////////////////////////////////////
virtual bool On_Frame_Update (unsigned int milliseconds = 0);
//////////////////////////////////////////////////////////////////////
// Position/direction methods
//////////////////////////////////////////////////////////////////////
virtual void Set_Position (const Vector3 &position) { m_Position = position; }
virtual Vector3 Get_Position (void) const { return m_Position; }
virtual void Set_Transform (const Matrix3D &transform) { m_Position = transform.Get_Translation (); }
virtual Matrix3D Get_Transform (void) const { Matrix3D tm(1); tm.Set_Translation (m_Position); return tm; }
//////////////////////////////////////////////////////////////////////
// Culling methods
//////////////////////////////////////////////////////////////////////
virtual void Cull_Sound (bool culled = true) { };
virtual bool Is_Sound_Culled (void) const { return false; };
//////////////////////////////////////////////////////////////////////
// Scene integration
//////////////////////////////////////////////////////////////////////
virtual void Add_To_Scene (bool start_playing = true);
virtual void Remove_From_Scene (void);
//////////////////////////////////////////////////////////////////////
// Attenuation settings
//////////////////////////////////////////////////////////////////////
//
// This is the distance where the sound can not be heard any longer. (its vol is 0)
//
virtual void Set_DropOff_Radius (float radius = 1) { m_DropOffRadius = radius; }
virtual float Get_DropOff_Radius (void) const { return m_DropOffRadius; }
//////////////////////////////////////////////////////////////////////
// From PersistClass
//////////////////////////////////////////////////////////////////////
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
const PersistFactoryClass & Get_Factory (void) const;
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
float m_DropOffRadius;
bool m_IsSingleShot;
uint32 m_TypeMask;
Vector3 m_Position;
uint32 m_OldestListenerTimestamp;
int m_MaxListeners;
uint32 m_NotifyDelayInMS;
uint32 m_LastNotification;
};
#endif //__LOGICAL_SOUND_H

View file

@ -0,0 +1,117 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio.h *
* *
* $Archive:: /Commando/Code/WWAudio/PriorityVector.h $Modtime:: 7/02/99 11:43a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __PRIORITY_VECTOR_H
#define __PRIORITY_VECTOR_H
#include "Vector.H"
////////////////////////////////////////////////////////////////////
//
// PriorityVectorClass
//
////////////////////////////////////////////////////////////////////
template<class T>
class PriorityVectorClass : public DynamicVectorClass<T>
{
public:
virtual bool Process_Head (T &object);
virtual bool Add_Low (T const &object);
virtual bool Add_High (T const &object);
/*PriorityVectorClass<T> & operator= (PriorityVectorClass<T> const & rvalue) {
DynamicVectorClass<T>::operator= (rvalue);
return(*t8his);
}*/
};
////////////////////////////////////////////////////////////////////
//
// Process_Head
//
////////////////////////////////////////////////////////////////////
template <class T>
__inline bool PriorityVectorClass<T>::Process_Head (T &object)
{
bool retval = false;
if (Vector != NULL) {
// Pass the object back to the caller
object = Vector[0];
//
// Move the head object to the end of the list
//
for (int index = 1; index < ActiveCount; index ++) {
Vector[index - 1] = Vector[index];
}
Vector[ActiveCount - 1] = object;
// Success!
retval = true;
}
return retval;
}
////////////////////////////////////////////////////////////////////
//
// Add_Low
//
////////////////////////////////////////////////////////////////////
template <class T>
__inline bool PriorityVectorClass<T>::Add_Low (T const &object)
{
return DynamicVectorClass<T>::Add (object);
}
////////////////////////////////////////////////////////////////////
//
// Add_High
//
////////////////////////////////////////////////////////////////////
template <class T>
__inline bool PriorityVectorClass<T>::Add_High (T const &object)
{
return DynamicVectorClass<T>::Add_Head (object);
}
#endif //__PRIORITY_VECTOR_H

View file

@ -0,0 +1,736 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/Sound3D.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 3:50p $*
* *
* $Revision:: 18 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "sound3d.h"
#include "soundbuffer.h"
#include "wwaudio.h"
#include "soundscene.h"
#include "utils.h"
#include "soundchunkids.h"
#include "persistfactory.h"
#include "chunkio.h"
#include "sound3dhandle.h"
//////////////////////////////////////////////////////////////////////////////////
//
// Static factories
//
//////////////////////////////////////////////////////////////////////////////////
SimplePersistFactoryClass<Sound3DClass, CHUNKID_SOUND3D> _Sound3DPersistFactory;
enum
{
CHUNKID_VARIABLES = 0x11090955,
CHUNKID_BASE_CLASS
};
enum
{
VARID_AUTO_CALC_VEL = 0x01,
VARID_CURR_VEL,
VARID_XXX1,
VARID_XXX2,
VARID_MAX_VOL_RADIUS,
VARID_IS_STATIC,
};
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Sound3DClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
Sound3DClass::Sound3DClass (void)
: m_bAutoCalcVel (true),
m_CurrentVelocity (0, 0, 0),
m_MaxVolRadius (0),
m_LastUpdate (0),
m_IsStatic (false),
m_IsTransformInitted (false)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Sound3DClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
Sound3DClass::Sound3DClass (const Sound3DClass &src)
: m_bAutoCalcVel (true),
m_CurrentVelocity (0, 0, 0),
m_MaxVolRadius (0),
m_LastUpdate (0),
m_IsStatic (false),
m_IsTransformInitted (false),
AudibleSoundClass (src)
{
(*this) = src;
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// ~Sound3DClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
Sound3DClass::~Sound3DClass (void)
{
Free_Miles_Handle ();
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// operator=
//
////////////////////////////////////////////////////////////////////////////////////////////////
const Sound3DClass &
Sound3DClass::operator= (const Sound3DClass &src)
{
m_bAutoCalcVel = src.m_bAutoCalcVel;
m_CurrentVelocity = src.m_CurrentVelocity;
m_MaxVolRadius = src.m_MaxVolRadius;
m_IsStatic = src.m_IsStatic;
m_LastUpdate = src.m_LastUpdate;
// Call the base class
AudibleSoundClass::operator= (src);
return (*this);
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Play
//
////////////////////////////////////////////////////////////////////////////////////////////////
bool
Sound3DClass::Play (bool alloc_handle)
{
// Record our first 'tick' if we just started playing
if (m_State != STATE_PLAYING) {
m_LastUpdate = ::GetTickCount ();
}
// Allow the base class to process this call
return AudibleSoundClass::Play (m_IsCulled == false);
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// On_Frame_Update
//
////////////////////////////////////////////////////////////////////////////////////////////////
bool
Sound3DClass::On_Frame_Update (unsigned int milliseconds)
{
Matrix3D prev_tm = m_PrevTransform;
if (m_bDirty && (m_PhysWrapper != NULL)) {
m_Scene->Update_Sound (m_PhysWrapper);
m_bDirty = false;
}
//
// Update the sound's position if its linked to a render object
//
Apply_Auto_Position ();
//
// Make sure the transform is initialized
//
if (m_IsTransformInitted == false) {
prev_tm = m_Transform;
}
//
// Update the current velocity if we are 'auto-calcing'.
//
if (m_bAutoCalcVel && Get_Class_ID () != CLASSID_LISTENER) {
Vector3 last_pos = prev_tm.Get_Translation ();
Vector3 curr_pos = m_Transform.Get_Translation ();
//
// Don't update the velocity if we haven't moved (optimization -- Miles calls
// can be really slow)
//
if (last_pos != curr_pos) {
Vector3 curr_vel;
//
// Extrapolate our current velocity given the last time slice and the distance
// we moved.
//
float secs_since_last_update = (::GetTickCount () - m_LastUpdate);
if (secs_since_last_update > 0) {
curr_vel = ((curr_pos - last_pos) / secs_since_last_update);
} else {
curr_vel.Set (0, 0, 0);
}
Set_Velocity (curr_vel);
}
}
// Remember when the last time we updated our 'auto-calc'
// variables.
m_LastUpdate = ::GetTickCount ();
m_PrevTransform = m_Transform;
// Allow the base class to process this call
return AudibleSoundClass::On_Frame_Update ();
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Transform
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Set_Transform (const Matrix3D &transform)
{
if (transform == m_Transform) {
return ;
}
// Update our internal transform
m_PrevTransform = m_Transform;
m_Transform = transform;
Set_Dirty ();
if (m_IsTransformInitted == false) {
m_PrevTransform = transform;
m_IsTransformInitted = true;
}
Update_Miles_Transform ();
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Listener_Transform
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Set_Listener_Transform (const Matrix3D &tm)
{
//
// If the transform has changed, then cache the new transform
// and update the sound's position in the "Mile's" world
//
if (m_ListenerTransform != tm) {
m_ListenerTransform = tm;
Update_Miles_Transform ();
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Update_Miles_Transform
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Update_Miles_Transform (void)
{
//
// Do we have a valid miles handle?
//
if (m_SoundHandle != NULL) {
//
// Build a matrix to transform coordinates from world-space to listener-space
//
Matrix3D world_to_listener_tm;
m_ListenerTransform.Get_Orthogonal_Inverse (world_to_listener_tm);
//
// Transform the object's TM into "listener-space"
//
#ifdef ALLOW_TEMPORARIES
Matrix3D listener_space_tm = world_to_listener_tm * m_Transform;
#else
Matrix3D listener_space_tm;
listener_space_tm.mul(world_to_listener_tm, m_Transform);
#endif
//
// Pass the sound's position onto miles
//
Vector3 position = listener_space_tm.Get_Translation ();
::AIL_set_3D_position (m_SoundHandle->Get_H3DSAMPLE (), -position.Y, position.Z, position.X);
//
// Pass the sound's orientation (facing) onto miles
//
Vector3 facing = listener_space_tm.Get_X_Vector ();
Vector3 up = listener_space_tm.Get_Z_Vector ();
::AIL_set_3D_orientation (m_SoundHandle->Get_H3DSAMPLE (),
-facing.Y,
facing.Z,
facing.X,
-up.Y,
up.Z,
up.X);
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Position
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Set_Position (const Vector3 &position)
{
//
// Pass the sound's position onto miles
//
if (m_Transform.Get_Translation () != position) {
// Update our internal transform
//
// SKB: 4/13/01 - Confirmed to be OK by Pat Smith.
// Took Set_Transform() outside of condition because even if sound is
// not playing I need to be able to change it's position.
// I had a problem that sounds would never be added to the scene because
// their positions stayed at 0,0,0 even after this Set_Postion() call.
m_PrevTransform = m_Transform;
m_Transform.Set_Translation (position);
Set_Dirty ();
if (m_IsTransformInitted == false) {
m_PrevTransform = m_Transform;
m_IsTransformInitted = true;
}
if (m_SoundHandle != NULL) {
//
// Transform the sound's position into 'listener-space'
//
Vector3 sound_pos = position;
Vector3 listener_space_pos;
Matrix3D::Inverse_Transform_Vector (m_ListenerTransform, sound_pos, &listener_space_pos);
//
// Update the object's position inside of Miles
//
::AIL_set_3D_position (m_SoundHandle->Get_H3DSAMPLE (), -listener_space_pos.Y,
listener_space_pos.Z, listener_space_pos.X);
}
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Velocity
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Set_Velocity (const Vector3 &velocity)
{
MMSLockClass lock;
m_CurrentVelocity = velocity;
Set_Dirty ();
//
// Pass the sound's velocity onto miles
//
if (m_SoundHandle != NULL) {
//WWDEBUG_SAY (("Current Velocity: %.2f %.2f %.2f\n", m_CurrentVelocity.X, m_CurrentVelocity.Y, m_CurrentVelocity.Z));
::AIL_set_3D_velocity_vector (m_SoundHandle->Get_H3DSAMPLE (),
-m_CurrentVelocity.Y,
m_CurrentVelocity.Z,
m_CurrentVelocity.X);
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set_DropOff_Radius
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Set_DropOff_Radius (float radius)
{
//MMSLockClass lock;
m_DropOffRadius = radius;
Set_Dirty ();
// Pass attenuation settings onto miles
if (m_SoundHandle != NULL) {
::AIL_set_3D_sample_distances ( m_SoundHandle->Get_H3DSAMPLE (),
m_DropOffRadius,
(m_MaxVolRadius > 1.0F) ? m_MaxVolRadius : 1.0F);
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Max_Vol_Radius
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Set_Max_Vol_Radius (float radius)
{
m_MaxVolRadius = radius;
Set_Dirty ();
// Pass attenuation settings onto miles
if (m_SoundHandle != NULL) {
::AIL_set_3D_sample_distances ( m_SoundHandle->Get_H3DSAMPLE (),
m_DropOffRadius,
(m_MaxVolRadius > 1.0F) ? m_MaxVolRadius : 1.0F);
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Initialize_Miles_Handle
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Initialize_Miles_Handle (void)
{
MMSLockClass lock;
// If this sound is already playing, then update its
// playing position to make sure we really should
// be playing it... (it will free the miles handle if not)
if (m_State == STATE_PLAYING) {
Update_Play_Position ();
}
// Do we have a valid sample handle from miles?
if (m_SoundHandle != NULL) {
//
// Pass the actual sound data onto the sample
//
m_SoundHandle->Initialize (m_Buffer);
//
// Record the total length of the sample in milliseconds...
//
m_SoundHandle->Get_Sample_MS_Position ((S32 *)&m_Length, NULL);
//
// Pass our cached settings onto miles
//
float real_volume = Determine_Real_Volume ();
m_SoundHandle->Set_Sample_Volume (int(real_volume * 127.0F));
m_SoundHandle->Set_Sample_Pan (int(m_Pan * 127.0F));
m_SoundHandle->Set_Sample_Loop_Count (m_LoopCount);
//
// Pass attenuation settings onto miles
//
::AIL_set_3D_sample_distances ( m_SoundHandle->Get_H3DSAMPLE (),
m_DropOffRadius,
(m_MaxVolRadius > 1.0F) ? m_MaxVolRadius : 1.0F);
//
// Assign the 3D effects level accordingly (for reverb, etc)
//
::AIL_set_3D_sample_effects_level (m_SoundHandle->Get_H3DSAMPLE (),
WWAudioClass::Get_Instance ()->Get_Effects_Level ());
//
// Pass the sound's position and orientation onto Miles
//
Update_Miles_Transform ();
//
// Apply the pitch factor (if necessary)
//
if (m_PitchFactor != 1.0F) {
Set_Pitch_Factor (m_PitchFactor);
}
// If this sound is already playing (and just now got a handle)
// then make sure we start it.
if (m_State == STATE_PLAYING) {
m_SoundHandle->Start_Sample ();
// Update the loop count based on the number of loops left
m_SoundHandle->Set_Sample_Loop_Count (m_LoopsLeft);
}
// Seek to the position of the sound where we last left off.
// For example, this sound could have gotten bumped due to a low priority,
// but is now back and ready to resume at the position it would have been
// at if it was never bumped.
Seek (m_CurrentPosition);
// Associate this object instance with the handle
m_SoundHandle->Set_Sample_User_Data (INFO_OBJECT_PTR, (S32)this);
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Allocate_Miles_Handle
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Allocate_Miles_Handle (void)
{
//MMSLockClass lock;
//
// If we need to, get a play-handle from the audio system
//
if (m_SoundHandle == NULL) {
Set_Miles_Handle ((MILES_HANDLE)WWAudioClass::Get_Instance ()->Get_3D_Sample (*this));
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Add_To_Scene
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Add_To_Scene (bool start_playing)
{
SoundSceneClass *scene = WWAudioClass::Get_Instance ()->Get_Sound_Scene ();
if ((scene != NULL) && (m_Scene == NULL)) {
// Determine what culling system this sound belongs to
if (m_IsStatic) {
scene->Add_Static_Sound (this, start_playing);
} else {
scene->Add_Sound (this, start_playing);
}
m_Scene = scene;
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Remove_From_Scene
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Remove_From_Scene (void)
{
if (m_Scene != NULL) {
// Determine what culling system this sound belongs to
if (m_IsStatic) {
m_Scene->Remove_Static_Sound (this);
} else {
m_Scene->Remove_Sound (this);
}
m_Scene = NULL;
m_PhysWrapper = NULL;
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// On_Loop_End
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::On_Loop_End (void)
{
// Allow the base class to process this message
AudibleSoundClass::On_Loop_End ();
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Get_Factory
//
/////////////////////////////////////////////////////////////////////////////////
const PersistFactoryClass &
Sound3DClass::Get_Factory (void) const
{
return _Sound3DPersistFactory;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Save
//
//////////////////////////////////////////////////////////////////////////////////
bool
Sound3DClass::Save (ChunkSaveClass &csave)
{
csave.Begin_Chunk (CHUNKID_BASE_CLASS);
AudibleSoundClass::Save (csave);
csave.End_Chunk ();
csave.Begin_Chunk (CHUNKID_VARIABLES);
WRITE_MICRO_CHUNK (csave, VARID_AUTO_CALC_VEL, m_bAutoCalcVel);
WRITE_MICRO_CHUNK (csave, VARID_CURR_VEL, m_CurrentVelocity);
WRITE_MICRO_CHUNK (csave, VARID_MAX_VOL_RADIUS, m_MaxVolRadius);
WRITE_MICRO_CHUNK (csave, VARID_IS_STATIC, m_IsStatic);
csave.End_Chunk ();
return true;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Load
//
//////////////////////////////////////////////////////////////////////////////////
bool
Sound3DClass::Load (ChunkLoadClass &cload)
{
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
case CHUNKID_BASE_CLASS:
AudibleSoundClass::Load (cload);
break;
case CHUNKID_VARIABLES:
{
//
// Read all the variables from their micro-chunks
//
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {
READ_MICRO_CHUNK (cload, VARID_AUTO_CALC_VEL, m_bAutoCalcVel);
READ_MICRO_CHUNK (cload, VARID_CURR_VEL, m_CurrentVelocity);
READ_MICRO_CHUNK (cload, VARID_MAX_VOL_RADIUS, m_MaxVolRadius);
READ_MICRO_CHUNK (cload, VARID_IS_STATIC, m_IsStatic);
}
cload.Close_Micro_Chunk ();
}
}
break;
}
cload.Close_Chunk ();
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Miles_Handle
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
Sound3DClass::Set_Miles_Handle (MILES_HANDLE handle)
{
//
// Start fresh
//
Free_Miles_Handle ();
//
// Is our data valid?
//
if (handle != INVALID_MILES_HANDLE && m_Buffer != NULL) {
//
// Configure the sound handle
//
m_SoundHandle = W3DNEW Sound3DHandleClass;
m_SoundHandle->Set_Miles_Handle (handle);
//
// Use this new handle
//
Initialize_Miles_Handle ();
}
return ;
}

View file

@ -0,0 +1,201 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/Sound3D.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 12:06p $*
* *
* $Revision:: 13 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUND3DOBJ_H
#define __SOUND3DOBJ_H
#include "AudibleSound.H"
#include "mempool.h"
/////////////////////////////////////////////////////////////////////////////////
//
// Sound3DClass
//
// Class defining a 3D sound. A 3D sound uses position and velocity information
// to determine volume/panning/doppler etc.
//
// A 3D sound should be added to the SoundScene rather than explicitly played. The
// SoundScene will determine when a 3D sound is 'in range' and play it...
//
class Sound3DClass : public AudibleSoundClass
{
public:
//////////////////////////////////////////////////////////////////////
// Friend classes
//////////////////////////////////////////////////////////////////////
friend class SoundSceneClass;
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
Sound3DClass (const Sound3DClass &src);
Sound3DClass (void);
virtual ~Sound3DClass (void);
//////////////////////////////////////////////////////////////////////
// Public operators
//////////////////////////////////////////////////////////////////////
const Sound3DClass &operator= (const Sound3DClass &src);
//////////////////////////////////////////////////////////////////////
// Identification methods
//////////////////////////////////////////////////////////////////////
virtual SOUND_CLASSID Get_Class_ID (void) const { return CLASSID_3D; }
virtual void Make_Static (bool is_static = true) { m_IsStatic = is_static; }
virtual bool Is_Static (void) const { return m_IsStatic; }
//////////////////////////////////////////////////////////////////////
// Conversion methods
//////////////////////////////////////////////////////////////////////
virtual Sound3DClass * As_Sound3DClass (void) { return this; }
//////////////////////////////////////////////////////////////////////
// State control methods
//////////////////////////////////////////////////////////////////////
virtual bool Play (bool alloc_handle = true);
//////////////////////////////////////////////////////////////////////
// Priority control
//////////////////////////////////////////////////////////////////////
virtual float Get_Priority (void) const { if (m_IsCulled) return 0; return m_Priority; }
//////////////////////////////////////////////////////////////////////
// Scene integration
//////////////////////////////////////////////////////////////////////
virtual void Add_To_Scene (bool start_playing = true);
virtual void Remove_From_Scene (void);
//////////////////////////////////////////////////////////////////////
// Position/direction methods
//////////////////////////////////////////////////////////////////////
virtual void Set_Position (const Vector3 &position);
virtual Vector3 Get_Position (void) const { return m_Transform.Get_Translation (); }
virtual void Set_Listener_Transform (const Matrix3D &tm);
virtual void Set_Transform (const Matrix3D &transform);
virtual Matrix3D Get_Transform (void) const { return m_Transform; }
void Update_Miles_Transform (void);
//////////////////////////////////////////////////////////////////////
// Velocity methods
//////////////////////////////////////////////////////////////////////
//
// The velocity settings are in meters per millisecond.
//
virtual void Set_Velocity (const Vector3 &velocity);
virtual Vector3 Get_Velocity (void) const { return m_CurrentVelocity; }
virtual void Get_Velocity (Vector3 &velocity) const { velocity = m_CurrentVelocity; }
virtual void Auto_Calc_Velocity (bool autocalc = true) { m_bAutoCalcVel = autocalc; }
virtual bool Is_Auto_Calc_Velocity_On (void) const { return m_bAutoCalcVel; }
//////////////////////////////////////////////////////////////////////
// Attenuation settings
//////////////////////////////////////////////////////////////////////
//
// The maximum-volume radius is the distance from the sound-emitter where
// it seems as loud as it is going to get. Volume does not increase after this
// point. Volume is linerally interpolated from the DropOff distance to the MaxVol
// distance. For some objects (like an airplane) the max-vol distance is
// not 0, but would be 100 or so meters away.
//
virtual void Set_Max_Vol_Radius (float radius = 0);
virtual float Get_Max_Vol_Radius (void) const { return m_MaxVolRadius; }
//
// This is the distance where the sound can not be heard any longer. (its vol is 0)
//
virtual void Set_DropOff_Radius (float radius = 1);
virtual float Get_DropOff_Radius () {return(m_DropOffRadius);}
// From PersistClass
const PersistFactoryClass & Get_Factory (void) const;
//
// From PersistClass
//
virtual bool Save (ChunkSaveClass &csave);
virtual bool Load (ChunkLoadClass &cload);
protected:
//////////////////////////////////////////////////////////////////////
// Handle information
//////////////////////////////////////////////////////////////////////
virtual SoundCullObjClass * Peek_Cullable_Wrapper (void) const { return m_PhysWrapper; }
virtual void Set_Cullable_Wrapper (SoundCullObjClass *obj) { m_PhysWrapper = obj; }
//////////////////////////////////////////////////////////////////////
// Update methods
//////////////////////////////////////////////////////////////////////
virtual bool On_Frame_Update (unsigned int milliseconds = 0);
//////////////////////////////////////////////////////////////////////
// Handle information
//////////////////////////////////////////////////////////////////////
virtual void Set_Miles_Handle (MILES_HANDLE handle);
virtual void Initialize_Miles_Handle (void);
virtual void Allocate_Miles_Handle (void);
//////////////////////////////////////////////////////////////////////
// Event handling
//////////////////////////////////////////////////////////////////////
virtual void On_Loop_End (void);
//////////////////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////////////////
bool m_IsTransformInitted;
bool m_bAutoCalcVel;
Vector3 m_CurrentVelocity;
float m_MaxVolRadius;
bool m_IsStatic;
unsigned int m_LastUpdate;
};
#endif //__SOUND3DOBJ_H

View file

@ -0,0 +1,381 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/SoundBuffer.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/17/01 11:22a $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "soundbuffer.h"
#include "rawfile.h"
#include "wwdebug.h"
#include "utils.h"
#include "ffactory.h"
#include "win.h"
/////////////////////////////////////////////////////////////////////////////////
// FileMappingClass
/////////////////////////////////////////////////////////////////////////////////
class FileMappingClass
{
public:
StringClass Filename;
HANDLE FileMapping;
int RefCount;
bool operator== (const FileMappingClass &src) { return false; }
bool operator!= (const FileMappingClass &src) { return false; }
};
static DynamicVectorClass<FileMappingClass> MappingList;
/////////////////////////////////////////////////////////////////////////////////
//
// SoundBufferClass
//
SoundBufferClass::SoundBufferClass (void)
: m_Buffer (NULL),
m_Length (0),
m_Filename (NULL),
m_Duration (0),
m_Rate (0),
m_Bits (0),
m_Channels (0),
m_Type (WAVE_FORMAT_IMA_ADPCM)
{
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// ~SoundBufferClass
//
SoundBufferClass::~SoundBufferClass (void)
{
SAFE_FREE (m_Filename);
Free_Buffer ();
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Free_Buffer
//
void
SoundBufferClass::Free_Buffer (void)
{
// Free the buffer's memory
if (m_Buffer != NULL) {
delete [] m_Buffer;
m_Buffer = NULL;
}
// Make sure we reset the length
m_Length = 0L;
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Determine_Stats
//
void
SoundBufferClass::Determine_Stats (unsigned char *buffer)
{
MMSLockClass lock;
m_Duration = 0;
m_Rate = 0;
m_Channels = 0;
m_Bits = 0;
m_Type = WAVE_FORMAT_IMA_ADPCM;
// Attempt to get statistical information about this sound
AILSOUNDINFO info = { 0 };
if ((buffer != NULL) && (::AIL_WAV_info (buffer, &info) != 0)) {
// Cache this information
m_Rate = info.rate;
m_Channels = info.channels;
m_Bits = info.bits;
m_Type = info.format;
// Determine how long this sound will play for
float bytes_sec = float((m_Channels * m_Rate * m_Bits) >> 3);
m_Duration = (unsigned long)((((float)m_Length) / bytes_sec) * 1000.0F);
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Set_Filename
//
void
SoundBufferClass::Set_Filename (const char *name)
{
SAFE_FREE (m_Filename);
if (name != NULL) {
m_Filename = ::strdup (name);
}
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Load_From_File
//
bool
SoundBufferClass::Load_From_File (const char *filename)
{
// Assume failure
bool retval = false;
// Param OK?
WWASSERT (filename != NULL);
if (filename != NULL) {
// Create a file object and pass it onto the appropriate function
FileClass *file=_TheFileFactory->Get_File(filename);
if ( file ) {
retval = Load_From_File(*file);
_TheFileFactory->Return_File(file);
}
file=NULL;
}
// Return the true/false result code
return retval;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Load_From_File
//
bool
SoundBufferClass::Load_From_File (FileClass &file)
{
MMSLockClass lock;
// Assume failure
bool retval = false;
// Start from scratch
Free_Buffer ();
Set_Filename (file.File_Name ());
// Open the file if necessary
bool we_opened = false;
if (file.Is_Open () == false) {
we_opened = (file.Open () == TRUE);
}
// Determine the size of the buffer
m_Length = file.Size ();
WWASSERT (m_Length > 0L);
if (m_Length > 0L) {
// Allocate a new buffer of the correct length and read the contents
// of the file into the buffer
m_Buffer = W3DNEWARRAY unsigned char[m_Length];
retval = bool(file.Read (m_Buffer, m_Length) == (int)m_Length);
// If we failed, free the buffer
if (retval == false) {
Free_Buffer ();
}
Determine_Stats (m_Buffer);
}
// Close the file if necessary
if (we_opened) {
file.Close ();
}
// Return the true/false result code
return retval;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Load_From_Memory
//
bool
SoundBufferClass::Load_From_Memory
(
unsigned char *mem_buffer,
unsigned long size
)
{
MMSLockClass lock;
// Assume failure
bool retval = false;
// Start from scratch
Free_Buffer ();
Set_Filename ("unknown.wav");
// Params OK?
WWASSERT (mem_buffer != NULL);
WWASSERT (size > 0L);
if ((mem_buffer != NULL) && (size > 0L)) {
// Allocate a new buffer of the correct length and copy the contents
// into the buffer
m_Length = size;
m_Buffer = W3DNEWARRAY unsigned char[m_Length];
::memcpy (m_Buffer, mem_buffer, size);
retval = true;
// If we failed, free the buffer
if (retval == false) {
Free_Buffer ();
}
Determine_Stats (m_Buffer);
}
// Return the true/false result code
return retval;
}
/////////////////////////////////////////////////////////////////////////////////
//
// StreamSoundBufferClass
//
StreamSoundBufferClass::StreamSoundBufferClass (void) :
SoundBufferClass ()
{
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// ~StreamSoundBufferClass
//
StreamSoundBufferClass::~StreamSoundBufferClass (void)
{
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Free_Buffer
//
void
StreamSoundBufferClass::Free_Buffer (void)
{
return ;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Load_From_File
//
/////////////////////////////////////////////////////////////////////////////////
bool
StreamSoundBufferClass::Load_From_File
(
HANDLE /*hfile*/,
unsigned long /*size*/,
unsigned long /*offset*/
)
{
return true;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Load_From_File
//
/////////////////////////////////////////////////////////////////////////////////
bool
StreamSoundBufferClass::Load_From_File (const char *filename)
{
return true;
}
/////////////////////////////////////////////////////////////////////////////////
//
// Load_From_File
//
/////////////////////////////////////////////////////////////////////////////////
bool
StreamSoundBufferClass::Load_From_File (FileClass &file)
{
MMSLockClass lock;
// Start from scratch
Free_Buffer ();
Set_Filename (file.File_Name ());
// Open the file if necessary
bool we_opened = false;
if (file.Is_Open () == false) {
we_opened = (file.Open () == TRUE);
}
m_Length = file.Size ();
// Allocate a new buffer of the correct length and read the contents
// of the file into the buffer
unsigned char buffer[4096] = { 0 };
file.Read (buffer, sizeof (buffer));
Determine_Stats (buffer);
// Close the file if necessary
if (we_opened) {
file.Close ();
}
return true;
}

View file

@ -0,0 +1,180 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/SoundBuffer.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/17/01 11:12a $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUNDBUFFER_H
#define __SOUNDBUFFER_H
#pragma warning (push, 3)
#include "Mss.H"
#pragma warning (pop)
#include "RefCount.H"
// Forward declarations
class FileClass;
/////////////////////////////////////////////////////////////////////////////////
//
// SoundBufferClass
//
// A sound buffer manages the raw sound data for any of the SoundObj types
// except for the StreamSoundClass object.
//
class SoundBufferClass : public RefCountClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
SoundBufferClass (void);
virtual ~SoundBufferClass (void);
//////////////////////////////////////////////////////////////////////
// Public operators
//////////////////////////////////////////////////////////////////////
operator unsigned char * (void) { return Get_Raw_Buffer (); }
//////////////////////////////////////////////////////////////////////
// File methods
//////////////////////////////////////////////////////////////////////
virtual bool Load_From_File (const char *filename);
virtual bool Load_From_File (FileClass &file);
//////////////////////////////////////////////////////////////////////
// Memory methods
//////////////////////////////////////////////////////////////////////
virtual bool Load_From_Memory (unsigned char *mem_buffer, unsigned long size);
//////////////////////////////////////////////////////////////////////
// Buffer access
//////////////////////////////////////////////////////////////////////
virtual unsigned char * Get_Raw_Buffer (void) const { return m_Buffer; }
virtual unsigned long Get_Raw_Length (void) const { return m_Length; }
//////////////////////////////////////////////////////////////////////
// Information methods
//////////////////////////////////////////////////////////////////////
virtual const char * Get_Filename (void) const { return m_Filename; }
virtual void Set_Filename (const char *name);
virtual unsigned long Get_Duration (void) const { return m_Duration; }
virtual unsigned long Get_Rate (void) const { return m_Rate; }
virtual unsigned long Get_Bits (void) const { return m_Bits; }
virtual unsigned long Get_Channels (void) const { return m_Channels; }
virtual unsigned long Get_Type (void) const { return m_Type; }
//////////////////////////////////////////////////////////////////////
// Type methods
//////////////////////////////////////////////////////////////////////
virtual bool Is_Streaming (void) const { return false; }
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
virtual void Free_Buffer (void);
virtual void Determine_Stats (unsigned char *buffer);
//////////////////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////////////////
unsigned char * m_Buffer;
unsigned long m_Length;
char * m_Filename;
unsigned long m_Duration;
unsigned long m_Rate;
unsigned long m_Bits;
unsigned long m_Channels;
unsigned long m_Type;
};
/////////////////////////////////////////////////////////////////////////////////
//
// StreamSoundBufferClass
//
// A sound buffer manages the raw sound data for any of the SoundObj types
// except for the StreamSoundClass object.
//
class StreamSoundBufferClass : public SoundBufferClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
StreamSoundBufferClass (void);
virtual ~StreamSoundBufferClass (void);
//////////////////////////////////////////////////////////////////////
// File methods
//////////////////////////////////////////////////////////////////////
virtual bool Load_From_File (const char *filename);
virtual bool Load_From_File (FileClass &file);
//////////////////////////////////////////////////////////////////////
// Memory methods
//////////////////////////////////////////////////////////////////////
virtual bool Load_From_Memory (unsigned char *mem_buffer, unsigned long size) { return false; }
//////////////////////////////////////////////////////////////////////
// Type methods
//////////////////////////////////////////////////////////////////////
virtual bool Is_Streaming (void) const { return true; }
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
virtual void Free_Buffer (void);
virtual bool Load_From_File (HANDLE hfile, unsigned long size, unsigned long offset);
//////////////////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////////////////
};
#endif //__SOUNDBUFFER_H

View file

@ -0,0 +1,82 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : LevelEdit *
* *
* $Archive:: /Commando/Code/WWAudio/SoundChunkIDs.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 3/27/00 5:43p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUND_CHUNK_IDS_H
#define __SOUND_CHUNK_IDS_H
#include "saveloadids.h"
#include "definitionclassids.h"
//////////////////////////////////////////////////////////////////////////////////
//
// These are the chunk IDs that serve as 'globally-unique' persist identifiers for
// all persist objects inside the editor. These are used when building the
// PersistFactoryClass's for definitions.
//
//////////////////////////////////////////////////////////////////////////////////
enum
{
CHUNKID_SOUND_DEF = CHUNKID_WWAUDIO_BEGIN,
CHUNKID_AUDIBLE_SOUND,
CHUNKID_FILTERED_SOUND,
CHUNKID_SOUND3D,
CHUNKID_PSEUDO_SOUND3D,
CHUNKID_STATIC_SAVELOAD,
CHUNKID_DYNAMIC_SAVELOAD,
CHUNKID_LOGICALSOUND,
CHUNKID_LOGICALLISTENER
};
//////////////////////////////////////////////////////////////////////////////////
//
// These are the globally-unique class identifiers that the definition system
// uses inside the editor.
//
//////////////////////////////////////////////////////////////////////////////////
enum
{
CLASSID_SOUND_DEF = CLASSID_SOUND,
};
#endif //__SOUND_CHUNK_IDS_H

View file

@ -0,0 +1,173 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/SoundCullObj.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 6/26/01 5:36p $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUNDCULLOBJ_H
#define __SOUNDCULLOBJ_H
#include "soundsceneobj.h"
#include "cullsys.h"
#include "refcount.h"
#include "mempool.h"
#include "multilist.h"
/////////////////////////////////////////////////////////////////////////////
//
// SoundCullObjClass
//
// Simple 'sound physics' object that wraps a SoundClass object and is derived
// from PhysClass so it can be used with the different culling systems.
//
class SoundCullObjClass : public MultiListObjectClass, public CullableClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
SoundCullObjClass (void)
: m_SoundObj (NULL),
m_Transform (1) {}
virtual ~SoundCullObjClass (void) { REF_PTR_RELEASE (m_SoundObj); }
//////////////////////////////////////////////////////////////////////
// Get the 'bounds' of this sound
//////////////////////////////////////////////////////////////////////
virtual const AABoxClass & Get_Bounding_Box (void) const;
//////////////////////////////////////////////////////////////////////
// Access to the Position/Orientation state of the object
//////////////////////////////////////////////////////////////////////
virtual const Matrix3D & Get_Transform (void) const;
virtual void Set_Transform (const Matrix3D &transform);
//////////////////////////////////////////////////////////////////////
// Timestep methods
//////////////////////////////////////////////////////////////////////
virtual void Timestep (float dt) {}
//////////////////////////////////////////////////////////////////////
// Sound object wrapping
//////////////////////////////////////////////////////////////////////
virtual void Set_Sound_Obj (SoundSceneObjClass *sound_obj);
virtual SoundSceneObjClass * Peek_Sound_Obj (void) const { return m_SoundObj; }
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
SoundSceneObjClass * m_SoundObj;
mutable Matrix3D m_Transform;
mutable AABoxClass m_AABox;
};
__inline const Matrix3D &
SoundCullObjClass::Get_Transform (void) const
{
// Determine the transform to use
if (m_SoundObj != NULL) {
m_Transform = m_SoundObj->Get_Transform ();
}
// Return a reference to the matrix
return m_Transform;
}
__inline void
SoundCullObjClass::Set_Transform (const Matrix3D &transform)
{
m_Transform = transform;
// Pass the tranform on
if (m_SoundObj != NULL) {
m_SoundObj->Set_Transform (m_Transform);
Set_Cull_Box (Get_Bounding_Box ());
}
return ;
}
__inline void
SoundCullObjClass::Set_Sound_Obj (SoundSceneObjClass *sound_obj)
{
// Start using this sound object
REF_PTR_SET (m_SoundObj, sound_obj);
//m_SoundObj = sound_obj;
if (m_SoundObj != NULL) {
m_Transform = m_SoundObj->Get_Transform ();
Set_Cull_Box (Get_Bounding_Box ());
}
return ;
}
__inline const AABoxClass &
SoundCullObjClass::Get_Bounding_Box (void) const
{
// Get the 'real' values from the
if (m_SoundObj != NULL) {
m_Transform = m_SoundObj->Get_Transform ();
m_AABox.Extent.X = m_SoundObj->Get_DropOff_Radius ();
m_AABox.Extent.Y = m_SoundObj->Get_DropOff_Radius ();
m_AABox.Extent.Z = m_SoundObj->Get_DropOff_Radius ();
} else {
m_AABox.Extent.X = 0;
m_AABox.Extent.Y = 0;
m_AABox.Extent.Z = 0;
}
m_AABox.Center = m_Transform.Get_Translation ();
return m_AABox;
}
#endif //__SOUNDCULLOBJ_H

View file

@ -0,0 +1,294 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/SoundPseudo3D.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 12:09p $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "soundpseudo3d.h"
#include "wwaudio.h"
#include "soundscene.h"
#include "utils.h"
#include "soundchunkids.h"
#include "persistfactory.h"
#include "soundhandle.h"
//////////////////////////////////////////////////////////////////////////////////
// Static factories
//////////////////////////////////////////////////////////////////////////////////
SimplePersistFactoryClass<SoundPseudo3DClass, CHUNKID_PSEUDO_SOUND3D> _PseudoSound3DPersistFactory;
////////////////////////////////////////////////////////////////////////////////////////////////
//
// SoundPseudo3DClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
SoundPseudo3DClass::SoundPseudo3DClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// SoundPseudo3DClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
SoundPseudo3DClass::SoundPseudo3DClass (const SoundPseudo3DClass &src)
: Sound3DClass (src)
{
(*this) = src;
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// ~SoundPseudo3DClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
SoundPseudo3DClass::~SoundPseudo3DClass (void)
{
Free_Miles_Handle ();
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// operator=
//
////////////////////////////////////////////////////////////////////////////////////////////////
const SoundPseudo3DClass &
SoundPseudo3DClass::operator= (const SoundPseudo3DClass &src)
{
// Call the base class
Sound3DClass::operator= (src);
return (*this);
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Set_Miles_Handle
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
SoundPseudo3DClass::Set_Miles_Handle (MILES_HANDLE handle)
{
AudibleSoundClass::Set_Miles_Handle (handle);
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Initialize_Miles_Handle
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
SoundPseudo3DClass::Initialize_Miles_Handle (void)
{
AudibleSoundClass::Initialize_Miles_Handle ();
Update_Pseudo_Volume ();
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Update_Pseudo_Volume
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
SoundPseudo3DClass::Update_Pseudo_Volume (float distance)
{
MMSLockClass lock;
//
// Only do this if the sound is really playing
//
if (m_SoundHandle != NULL) {
float volume_mod = Determine_Real_Volume ();
float max_distance = Get_DropOff_Radius ();
float min_distance = Get_Max_Vol_Radius ();
float delta = max_distance - min_distance;
// Determine a normalized volume from the position
float volume = 1.0F;
if (distance > min_distance) {
volume = 1.0F - ((distance - min_distance) / delta);
volume = min (volume, 1.0F);
volume = max (volume, 0.0F);
}
// Multiply the 'max' volume with the calculated volume
volume = volume * volume_mod;
//
// Pass the volume on
//
m_SoundHandle->Set_Sample_Volume (int(volume * 127.0F));
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Update_Pseudo_Volume
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
SoundPseudo3DClass::Update_Pseudo_Volume (void)
{
MMSLockClass lock;
// Only do this if the sound is really playing
if (m_SoundHandle != NULL) {
//
// Find the difference in the sound position and its listener's position
//
Vector3 sound_pos = m_ListenerTransform.Get_Translation () - m_Transform.Get_Translation ();
float distance = sound_pos.Quick_Length ();
//
// Determine a normalized volume from the position
//
Update_Pseudo_Volume (distance);
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Update_Pseudo_Pan
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
SoundPseudo3DClass::Update_Pseudo_Pan (void)
{
MMSLockClass lock;
//
// Only do this if the sound is really playing
//
if (m_SoundHandle != NULL) {
//
// Transform the sound's position into 'listener-space'
//
Vector3 sound_pos = m_Transform.Get_Translation ();
Vector3 rel_sound_pos;
Matrix3D::Inverse_Transform_Vector (m_ListenerTransform, sound_pos, &rel_sound_pos);
//
// Calculate a normalized pan from 0 (hard left) to 1.0F (hard right)
//
float angle = WWMath::Atan2 (rel_sound_pos.Y, rel_sound_pos.X);
float pan = -WWMath::Fast_Sin (angle);
pan = (pan / 2.0F) + 0.5F;
//
// Pass the pan on
//
m_SoundHandle->Set_Sample_Pan (S32(pan * 127.0F));
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Allocate_Miles_Handle
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
SoundPseudo3DClass::Allocate_Miles_Handle (void)
{
AudibleSoundClass::Allocate_Miles_Handle ();
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Free_Miles_Handle
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
SoundPseudo3DClass::Free_Miles_Handle (void)
{
AudibleSoundClass::Free_Miles_Handle ();
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// On_Frame_Update
//
////////////////////////////////////////////////////////////////////////////////////////////////
bool
SoundPseudo3DClass::On_Frame_Update (unsigned int milliseconds)
{
// If necessary, update the volume based on the distance
// from the listener
if (m_SoundHandle != NULL) {
Update_Pseudo_Volume ();
Update_Pseudo_Pan ();
}
// Allow the base Sound3DClass to process this call
return Sound3DClass::On_Frame_Update ();
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Get_Factory
//
////////////////////////////////////////////////////////////////////////////////////////////////
const PersistFactoryClass &
SoundPseudo3DClass::Get_Factory (void) const
{
return _PseudoSound3DPersistFactory;
}

View file

@ -0,0 +1,163 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/SoundPseudo3D.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 12:06p $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUND_PSEUDO_3DOBJ_H
#define __SOUND_PSEUDO_3DOBJ_H
#include "Sound3D.H"
/////////////////////////////////////////////////////////////////////////////////
//
// SoundPseudo3DClass
//
// Pseudo-3D objects are not true 3D sounds. They have the
// same properties as 3D 'sound effects' but do not use 3D
// hardware, are not restricted to mono, uncompressed, WAV data,
// and do not calculate doppler and reverb effects.
//
class SoundPseudo3DClass : public Sound3DClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
SoundPseudo3DClass (const SoundPseudo3DClass &src);
SoundPseudo3DClass (void);
virtual ~SoundPseudo3DClass (void);
//////////////////////////////////////////////////////////////////////
// Public operators
//////////////////////////////////////////////////////////////////////
const SoundPseudo3DClass &operator= (const SoundPseudo3DClass &src);
//////////////////////////////////////////////////////////////////////
// Identification methods
//////////////////////////////////////////////////////////////////////
virtual SOUND_CLASSID Get_Class_ID (void) const { return CLASSID_PSEUDO3D; }
//////////////////////////////////////////////////////////////////////
// Conversion methods
//////////////////////////////////////////////////////////////////////
virtual SoundPseudo3DClass * As_SoundPseudo3DClass (void) { return this; }
//////////////////////////////////////////////////////////////////////
// Volume control
//////////////////////////////////////////////////////////////////////
virtual void Update_Volume (void) { Update_Pseudo_Volume (); }
//////////////////////////////////////////////////////////////////////
// Position/direction methods
//////////////////////////////////////////////////////////////////////
virtual void Set_Listener_Transform (const Matrix3D &tm) { m_ListenerTransform = tm; }
virtual void Set_Position (const Vector3 &position) { Set_Dirty (); m_Transform.Set_Translation (position); }
virtual void Set_Transform (const Matrix3D &transform) { Set_Dirty (); m_Transform = transform; }
//////////////////////////////////////////////////////////////////////
// Velocity methods
//////////////////////////////////////////////////////////////////////
//
// The velocity settings are in meters per millisecond.
//
virtual void Set_Velocity (const Vector3 &velocity) { }
//////////////////////////////////////////////////////////////////////
// Attenuation settings
//////////////////////////////////////////////////////////////////////
//
// The maximum-volume radius is the distance from the sound-emitter where
// it seems as loud as it is going to get. Volume does not increase after this
// point. Volume is linerally interpolated from the DropOff distance to the MaxVol
// distance. For some objects (like an airplane) the max-vol distance is
// not 0, but would be 100 or so meters away.
//
virtual void Set_Max_Vol_Radius (float radius = 0) { m_MaxVolRadius = radius; }
virtual float Get_Max_Vol_Radius (void) const { return m_MaxVolRadius; }
//
// This is the distance where the sound can not be heard any longer. (its vol is 0)
//
virtual void Set_DropOff_Radius (float radius = 1) { m_DropOffRadius = radius; }
virtual float Get_DropOff_Radius (void) const { return m_DropOffRadius; }
//////////////////////////////////////////////////////////////////////
// Volume control
//////////////////////////////////////////////////////////////////////
virtual void Update_Pseudo_Volume (void);
virtual void Update_Pseudo_Volume (float distance);
//////////////////////////////////////////////////////////////////////
// Pan control
//////////////////////////////////////////////////////////////////////
virtual void Update_Pseudo_Pan (void);
// From PersistClass
const PersistFactoryClass & Get_Factory (void) const;
protected:
//////////////////////////////////////////////////////////////////////
// Update methods
//////////////////////////////////////////////////////////////////////
virtual bool On_Frame_Update (unsigned int milliseconds = 0);
//////////////////////////////////////////////////////////////////////
// Handle information
//////////////////////////////////////////////////////////////////////
virtual void Set_Miles_Handle (MILES_HANDLE handle);
virtual void Initialize_Miles_Handle (void);
virtual void Allocate_Miles_Handle (void);
virtual void Free_Miles_Handle (void);
virtual void On_Loop_End (void) { Sound3DClass::On_Loop_End (); }
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
};
#endif //__SOUND_PSEUDO_3DOBJ_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,227 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/SoundScene.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 2/07/01 6:10p $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUNDSCENE_H
#define __SOUNDSCENE_H
#include "aabtreecull.h"
#include "gridcull.h"
#include "listener.h"
#include "vector.h"
#include "priorityvector.h"
#include "soundcullobj.h"
#include "logicallistener.h"
#include "multilist.h"
// Forward declarations
class RenderObjClass;
class ChunkSaveClass;
class ChunkLoadClass;
//////////////////////////////////////////////////////////////////////////////////
//
// Typedefs
//
//////////////////////////////////////////////////////////////////////////////////
typedef TypedGridCullSystemClass<SoundCullObjClass> DynamicSoundCullClass;
typedef TypedAABTreeCullSystemClass<SoundCullObjClass> StaticSoundCullClass;
typedef MultiListClass<AudibleSoundClass> AUDIBLE_SOUND_LIST;
typedef MultiListClass<SoundCullObjClass> SOUND_LIST;
typedef MultiListClass<LogicalSoundClass> LOGICAL_SOUND_LIST;
typedef MultiListClass<LogicalListenerClass> LOGICAL_LISTENER_LIST;
/////////////////////////////////////////////////////////////////////////////////
//
// SoundSceneClass
//
// Mimics the 'SceneClass' for render objects. Used to insert 3D sounds into
// a virtual world. Used to efficiently cull sounds that are too far away
// from the listner to be heard.
//
class SoundSceneClass
{
public:
//////////////////////////////////////////////////////////////////////
// Friend classes
//////////////////////////////////////////////////////////////////////
friend class WWAudioClass;
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
SoundSceneClass (void);
virtual ~SoundSceneClass (void);
//////////////////////////////////////////////////////////////////////
// Partition methods
//////////////////////////////////////////////////////////////////////
virtual void Re_Partition (const Vector3 &min_dimension, const Vector3 &max_dimension);
//////////////////////////////////////////////////////////////////////
// Logical sound methods
//////////////////////////////////////////////////////////////////////
virtual void Collect_Logical_Sounds (int listener_count = -1);
//////////////////////////////////////////////////////////////////////
// Listener methods
//////////////////////////////////////////////////////////////////////
virtual void Attach_Listener_To_Obj (RenderObjClass *render_obj, int bone_index = -1) { m_Listener->Attach_To_Object (render_obj, bone_index); }
virtual void Set_Listener_Position (const Vector3 &pos) { m_Listener->Set_Position (pos); }
virtual Vector3 Get_Listener_Position (void) const { return m_Listener->Get_Position (); }
virtual void Set_Listener_Transform (const Matrix3D &transform) { m_Listener->Set_Transform (transform); }
virtual Matrix3D Get_Listener_Transform (void) const { return m_Listener->Get_Transform (); }
virtual Listener3DClass *Peek_2nd_Listener (void) const { return m_2ndListener; }
virtual void Set_2nd_Listener (Listener3DClass *listener);
//////////////////////////////////////////////////////////////////////
// Sound insertion
//////////////////////////////////////////////////////////////////////
virtual void Flush_Scene (void);
virtual void Update_Sound (SoundCullObjClass *sound_obj);
//
// These methods are for inserting audible-dynamic sounds into the scene.
//
virtual void Add_Sound (AudibleSoundClass *sound_obj, bool start_playing = true);
virtual void Remove_Sound (AudibleSoundClass *sound_obj, bool stop_playing = true);
//
// Static sounds are those that will never change position in the world.
// These sounds can be more efficiently culled.
//
virtual void Add_Static_Sound (AudibleSoundClass *sound_obj, bool start_playing = true);
virtual void Remove_Static_Sound (AudibleSoundClass *sound_obj, bool stop_playing = true);
//
// These methods are for inserting logical sounds and listeners into the scene.
//
virtual void Add_Logical_Sound (LogicalSoundClass *sound_obj, bool single_shot = false);
virtual void Remove_Logical_Sound (LogicalSoundClass *sound_obj, bool single_shot = false, bool remove_from_list = true);
virtual void Add_Logical_Listener (LogicalListenerClass *listener_obj);
virtual void Remove_Logical_Listener (LogicalListenerClass *listener_obj);
//////////////////////////////////////////////////////////////////////
// Save/Load
//////////////////////////////////////////////////////////////////////
bool Save_Static (ChunkSaveClass &csave);
bool Load_Static (ChunkLoadClass &cload);
bool Save_Dynamic (ChunkSaveClass &csave);
bool Load_Dynamic (ChunkLoadClass &cload);
bool Is_Batch_Mode (void) const { return m_IsBatchMode; }
void Set_Batch_Mode (bool batch_mode) { m_IsBatchMode = batch_mode; }
//////////////////////////////////////////////////////////////////////
// Debugging
//////////////////////////////////////////////////////////////////////
bool Is_Sound_In_Scene (AudibleSoundClass *sound_obj, bool all = true);
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
virtual void On_Frame_Update (unsigned int milliseconds = 0);
virtual void Initialize (void);
virtual bool Is_Logical_Sound_In_Scene (LogicalSoundClass *sound_obj, bool single_shot = false);
// Save/load methods
virtual void Save_Static_Sounds (ChunkSaveClass &csave);
virtual void Load_Static_Sounds (ChunkLoadClass &cload);
//////////////////////////////////////////////////////////////////////
// Collection methods
//////////////////////////////////////////////////////////////////////
class AudibleInfoClass : public MultiListObjectClass, public AutoPoolClass<AudibleInfoClass, 64>
{
public:
AudibleInfoClass (void)
: sound_obj (NULL),
distance2 (0) { }
AudibleInfoClass (AudibleSoundClass *obj, float dist2)
: sound_obj (obj),
distance2 (dist2) { }
AudibleSoundClass * sound_obj;
float distance2;
};
typedef MultiListClass<AudibleInfoClass> COLLECTED_SOUNDS;
virtual void Collect_Audible_Sounds (Listener3DClass *listener, COLLECTED_SOUNDS &list);
private:
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
Listener3DClass * m_Listener;
Listener3DClass * m_2ndListener;
AUDIBLE_SOUND_LIST m_LastSoundsAudible;
SOUND_LIST m_DynamicSounds;
SOUND_LIST m_StaticSounds;
LOGICAL_SOUND_LIST m_LogicalSounds;
LOGICAL_SOUND_LIST m_SingleShotLogicalSounds;
LOGICAL_LISTENER_LIST m_LogicalListeners;
DynamicSoundCullClass m_ListenerCullingSystem;
DynamicSoundCullClass m_LogicalCullingSystem;
DynamicSoundCullClass m_DynamicCullingSystem;
StaticSoundCullClass m_StaticCullingSystem;
Vector3 m_MinExtents;
Vector3 m_MaxExtents;
bool m_IsBatchMode;
};
#endif //__SOUNDSCENE_H

View file

@ -0,0 +1,503 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/SoundSceneObj.cpp $*
* *
* $Modtime:: 8/24/01 5:10p $*
* *
* $Revision:: 15 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "SoundSceneObj.h"
#include "camera.h"
#include "rendobj.h"
#include "persistfactory.h"
#include "SoundChunkIDs.h"
#include "utils.h"
//////////////////////////////////////////////////////////////////////////////////
// Save/Load constants
//////////////////////////////////////////////////////////////////////////////////
enum
{
CHUNKID_VARIABLES = 0x03270459,
CHUNKID_BASE_CLASS
};
enum
{
VARID_ATTACHED_OBJ = 0x01,
VARID_ATTACHED_BONE,
VARID_USER_DATA,
VARID_USER_OBJ,
VARID_ID
};
//////////////////////////////////////////////////////////////////////////////////
// Static member initialization
//////////////////////////////////////////////////////////////////////////////////
DynamicVectorClass<SoundSceneObjClass *> SoundSceneObjClass::m_GlobalSoundList;
uint32 SoundSceneObjClass::m_NextAvailableID = SOUND_OBJ_START_ID;
CriticalSectionClass SoundSceneObjClass::m_IDListMutex;
//////////////////////////////////////////////////////////////////////////////////
// Mutex managment
//////////////////////////////////////////////////////////////////////////////////
/*
class HandleMgrClass
{
public:
HandleMgrClass (void) { SoundSceneObjClass::m_IDListMutex = ::CreateMutex (NULL, FALSE, NULL); }
~HandleMgrClass (void) { ::CloseHandle (SoundSceneObjClass::m_IDListMutex); }
};
HandleMgrClass _GlobalMutexHandleMgr;
*/
////////////////////////////////////////////////////////////////////////////////////////////////
//
// SoundSceneObjClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
SoundSceneObjClass::SoundSceneObjClass (void)
: m_Scene (NULL),
m_PhysWrapper (NULL),
m_pCallback (NULL),
m_AttachedObject (NULL),
m_UserData (0),
m_UserObj (NULL),
m_ID (SOUND_OBJ_DEFAULT_ID),
m_RegisteredEvents (AudioCallbackClass::EVENT_NONE)
{
m_ID = m_NextAvailableID ++;
Register_Sound_Object (this);
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// SoundSceneObjClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
SoundSceneObjClass::SoundSceneObjClass (const SoundSceneObjClass &src)
: m_Scene (NULL),
m_PhysWrapper (NULL),
m_pCallback (NULL),
m_AttachedObject (NULL),
m_UserData (0),
m_UserObj (NULL),
m_ID (SOUND_OBJ_DEFAULT_ID),
m_RegisteredEvents (AudioCallbackClass::EVENT_NONE)
{
m_ID = m_NextAvailableID ++;
(*this) = src;
Register_Sound_Object (this);
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// ~SoundSceneObjClass
//
////////////////////////////////////////////////////////////////////////////////////////////////
SoundSceneObjClass::~SoundSceneObjClass (void)
{
REF_PTR_RELEASE (m_UserObj);
REF_PTR_RELEASE (m_AttachedObject);
Unregister_Sound_Object (this);
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// operator=
//
////////////////////////////////////////////////////////////////////////////////////////////////
const SoundSceneObjClass &
SoundSceneObjClass::operator= (const SoundSceneObjClass &src)
{
m_Scene = src.m_Scene;
m_pCallback = src.m_pCallback;
m_RegisteredEvents = src.m_RegisteredEvents;
Attach_To_Object (src.m_AttachedObject, src.m_AttachedBone);
PersistClass::operator= ((const PersistClass &)src);
return (*this);
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Attach_To_Object
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
SoundSceneObjClass::Attach_To_Object
(
RenderObjClass * render_obj,
const char * bone_name
)
{
REF_PTR_SET (m_AttachedObject, render_obj);
if (m_AttachedObject != NULL && bone_name != NULL) {
m_AttachedBone = m_AttachedObject->Get_Bone_Index (bone_name);
} else {
m_AttachedBone = -1;
}
return ;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Attach_To_Object
//
////////////////////////////////////////////////////////////////////////////////////////////////
void
SoundSceneObjClass::Attach_To_Object
(
RenderObjClass * render_obj,
int bone_index
)
{
if (m_AttachedObject != render_obj || m_AttachedBone != bone_index) {
//
// Record the attachment
//
REF_PTR_SET (m_AttachedObject, render_obj);
m_AttachedBone = bone_index;
//
// Update the transform
//
Apply_Auto_Position ();
}
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// Apply_Auto_Position
//
//////////////////////////////////////////////////////////////////////////////
void
SoundSceneObjClass::Apply_Auto_Position (void)
{
// If the sound is attached to an object, then update its transform
// based on this link.
if (m_AttachedObject != NULL) {
// Determine which transform to use
Matrix3D transform (1);
if (m_AttachedBone >= 0) {
transform = m_AttachedObject->Get_Bone_Transform (m_AttachedBone);
} else {
transform = m_AttachedObject->Get_Transform ();
//
// Convert the camera's transform to an object transform
//
if (m_AttachedObject->Class_ID () == RenderObjClass::CLASSID_CAMERA) {
Matrix3D cam_to_world (Vector3 (0, 0, -1), Vector3 (-1, 0, 0), Vector3 (0, 1, 0), Vector3 (0, 0, 0));
#ifdef ALLOW_TEMPORARIES
transform = transform * cam_to_world;
#else
transform.postMul(cam_to_world);
#endif
}
}
// Update the sound's transform
Set_Transform (transform);
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Save
//
//////////////////////////////////////////////////////////////////////////////////
bool
SoundSceneObjClass::Save (ChunkSaveClass &csave)
{
csave.Begin_Chunk (CHUNKID_BASE_CLASS);
PersistClass::Save (csave);
csave.End_Chunk ();
csave.Begin_Chunk (CHUNKID_VARIABLES);
WRITE_MICRO_CHUNK (csave, VARID_ATTACHED_OBJ, m_AttachedObject);
WRITE_MICRO_CHUNK (csave, VARID_ATTACHED_BONE, m_AttachedBone);
WRITE_MICRO_CHUNK (csave, VARID_USER_DATA, m_UserData);
WRITE_MICRO_CHUNK (csave, VARID_USER_OBJ, m_UserObj);
WRITE_MICRO_CHUNK (csave, VARID_ID, m_ID);
csave.End_Chunk ();
return true;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Load
//
//////////////////////////////////////////////////////////////////////////////////
bool
SoundSceneObjClass::Load (ChunkLoadClass &cload)
{
uint32 id = SOUND_OBJ_DEFAULT_ID;
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
case CHUNKID_BASE_CLASS:
PersistClass::Load (cload);
break;
case CHUNKID_VARIABLES:
{
//
// Read all the variables from their micro-chunks
//
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {
READ_MICRO_CHUNK (cload, VARID_ATTACHED_OBJ, m_AttachedObject);
READ_MICRO_CHUNK (cload, VARID_ATTACHED_BONE, m_AttachedBone);
READ_MICRO_CHUNK (cload, VARID_USER_DATA, m_UserData);
READ_MICRO_CHUNK (cload, VARID_USER_OBJ, m_UserObj);
READ_MICRO_CHUNK (cload, VARID_ID, id);
}
cload.Close_Micro_Chunk ();
}
}
break;
}
cload.Close_Chunk ();
}
//
// Set the ID (this will cause the sound object to
// be re-inserted in the master sorted list)
//
if (id != SOUND_OBJ_DEFAULT_ID) {
Set_ID (id);
}
//
// Max sure the next available ID is the largest ID in existence
//
m_NextAvailableID = max (m_NextAvailableID, m_ID + 1);
//
// We need to 'swizzle' the attached object pointer. We saved the pointer's
// value, and need to map it (hopefully) to the new value.
//
if (m_AttachedObject != NULL) {
SaveLoadSystemClass::Request_Ref_Counted_Pointer_Remap ((RefCountClass **)&m_AttachedObject);
}
return true;
}
//////////////////////////////////////////////////////////////////////////////////
//
// On_Frame_Update
//
//////////////////////////////////////////////////////////////////////////////////
bool
SoundSceneObjClass::On_Frame_Update (unsigned int /*milliseconds*/)
{
Apply_Auto_Position ();
return true;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Set_ID
//
//////////////////////////////////////////////////////////////////////////////////
void
SoundSceneObjClass::Set_ID (uint32 id)
{
//
// Remove the sound object from our sorted list
//
Unregister_Sound_Object (this);
//
// Change the sound object's ID
//
m_ID = id;
//
// Reinsert the sound object in our sorted list
//
Register_Sound_Object (this);
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Register_Sound_Object
//
//////////////////////////////////////////////////////////////////////////////////
void
SoundSceneObjClass::Register_Sound_Object (SoundSceneObjClass *sound_obj)
{
int sound_id = sound_obj->Get_ID ();
CriticalSectionClass::LockClass lock(m_IDListMutex);
//
// Special case a non-ID
//
if (sound_id == SOUND_OBJ_DEFAULT_ID) {
m_GlobalSoundList.Insert (0, sound_obj);
} else {
//
// Check to ensure the object isn't already in the list
//
int index = 0;
if (Find_Sound_Object (sound_id, &index) == false) {
//
// Insert the object into the list
//
m_GlobalSoundList.Insert (index, sound_obj);
}
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Unregister_Sound_Object
//
//////////////////////////////////////////////////////////////////////////////////
void
SoundSceneObjClass::Unregister_Sound_Object (SoundSceneObjClass *sound_obj)
{
CriticalSectionClass::LockClass lock(m_IDListMutex);
//
// Try to find the object in the list
//
int index = 0;
if (Find_Sound_Object (sound_obj->Get_ID (), &index)) {
//
// Remove the object from the list
//
m_GlobalSoundList.Delete (index);
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Find_Sound_Object
//
//////////////////////////////////////////////////////////////////////////////////
bool
SoundSceneObjClass::Find_Sound_Object (uint32 id_to_find, int *index)
{
CriticalSectionClass::LockClass lock(m_IDListMutex);
bool found = false;
(*index) = 0;
int min_index = 0;
int max_index = m_GlobalSoundList.Count () - 1;
//
// Keep looping until we've closed the window of possiblity
//
bool keep_going = (max_index >= min_index);
while (keep_going) {
//
// Calculate what slot we are currently looking at
//
int curr_index = min_index + ((max_index - min_index) / 2);
uint32 curr_id = m_GlobalSoundList[curr_index]->Get_ID ();
//
// Did we find the right slot?
//
if (id_to_find == curr_id) {
(*index) = curr_index;
keep_going = false;
found = true;
} else {
//
// Stop if we've narrowed the window to one entry
//
keep_going = (max_index > min_index);
//
// Move the window to the appropriate side
// of the test index.
//
if (id_to_find < curr_id) {
max_index = curr_index - 1;
(*index) = curr_index;
} else {
min_index = curr_index + 1;
(*index) = curr_index + 1;
}
}
}
return found;
}

View file

@ -0,0 +1,279 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/SoundSceneObj.h $*
* *
* $Modtime:: 8/24/01 3:51p $*
* *
* $Revision:: 12 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUND_SCENE_OBJ_H
#define __SOUND_SCENE_OBJ_H
#include "Refcount.H"
#include "WWAudio.H"
#include "BitType.H"
#include "persist.h"
#include "multilist.h"
#include "mutex.h"
/////////////////////////////////////////////////////////////////////////////////
// Forward declarations
/////////////////////////////////////////////////////////////////////////////////
class SoundCullObjClass;
class SoundSceneClass;
class RenderObjClass;
class Vector3;
class Matrix3D;
class LogicalListenerClass;
class LogicalSoundClass;
class Sound3DClass;
class SoundPseudo3DClass;
class FilteredSoundClass;
class Listener3DClass;
class AudibleSoundClass;
/////////////////////////////////////////////////////////////////////////////////
// Constants
/////////////////////////////////////////////////////////////////////////////////
const uint32 SOUND_OBJ_DEFAULT_ID = 0;
const uint32 SOUND_OBJ_START_ID = 1000000000;
/////////////////////////////////////////////////////////////////////////////////
//
// SoundSceneObjClass
//
// Abstract base class to defines an interface for any sound
// object that will be inserted in the culling system.
//
/////////////////////////////////////////////////////////////////////////////////
class SoundSceneObjClass : public MultiListObjectClass, public PersistClass, public RefCountClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public friends
//////////////////////////////////////////////////////////////////////
friend class SoundSceneClass;
friend class WWAudioClass;
friend class HandleMgrClass;
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
SoundSceneObjClass (void);
SoundSceneObjClass (const SoundSceneObjClass &src);
virtual ~SoundSceneObjClass (void);
//////////////////////////////////////////////////////////////////////
// Public operators
//////////////////////////////////////////////////////////////////////
const SoundSceneObjClass &operator= (const SoundSceneObjClass &src);
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Conversion methods
//////////////////////////////////////////////////////////////////////
virtual Sound3DClass * As_Sound3DClass (void) { return NULL; }
virtual SoundPseudo3DClass * As_SoundPseudo3DClass (void) { return NULL; }
virtual FilteredSoundClass * As_FilteredSoundClass (void) { return NULL; }
virtual Listener3DClass * As_Listener3DClass (void) { return NULL; }
virtual AudibleSoundClass * As_AudibleSoundClass(void) { return NULL; }
//////////////////////////////////////////////////////////////////////
// Identification methods
//////////////////////////////////////////////////////////////////////
virtual uint32 Get_ID (void) const { return m_ID; }
virtual void Set_ID (uint32 id);
//////////////////////////////////////////////////////////////////////
// Update methods
//////////////////////////////////////////////////////////////////////
virtual bool On_Frame_Update (unsigned int milliseconds = 0);
//////////////////////////////////////////////////////////////////////
// Event handling
//////////////////////////////////////////////////////////////////////
virtual void On_Event (AudioCallbackClass::EVENTS event, uint32 param1 = 0, uint32 param2 = 0);
virtual void Register_Callback (AudioCallbackClass::EVENTS events, AudioCallbackClass *callback);
//////////////////////////////////////////////////////////////////////
// Position/direction methods
//////////////////////////////////////////////////////////////////////
virtual void Set_Position (const Vector3 &position) = 0;
virtual Vector3 Get_Position (void) const = 0;
virtual void Set_Listener_Transform (const Matrix3D &tm) {};
virtual void Set_Transform (const Matrix3D &transform) = 0;
virtual Matrix3D Get_Transform (void) const = 0;
//////////////////////////////////////////////////////////////////////
// Culling methods
//////////////////////////////////////////////////////////////////////
virtual void Cull_Sound (bool culled = true) = 0;
virtual bool Is_Sound_Culled (void) const = 0;
//////////////////////////////////////////////////////////////////////
// User data methods
//////////////////////////////////////////////////////////////////////
virtual void Set_User_Data (RefCountClass *user_obj = NULL, uint32 user = 0) { REF_PTR_SET (m_UserObj, user_obj); m_UserData = user; }
virtual uint32 Get_User_Data (void) const { return m_UserData; }
virtual RefCountClass *Peek_User_Obj (void) const { return m_UserObj; }
//////////////////////////////////////////////////////////////////////
// Attached object methods
//////////////////////////////////////////////////////////////////////
virtual void Attach_To_Object (RenderObjClass *render_obj, int bone_index = -1);
virtual void Attach_To_Object (RenderObjClass *render_obj, const char *bone_name);
virtual RenderObjClass *Peek_Parent_Object (void) { return m_AttachedObject; }
virtual int Get_Parent_Bone (void) { return m_AttachedBone; }
virtual void Apply_Auto_Position (void);
//////////////////////////////////////////////////////////////////////
// Scene integration
//////////////////////////////////////////////////////////////////////
virtual void Add_To_Scene (bool start_playing = true) = 0;
virtual void Remove_From_Scene (void) = 0;
virtual bool Is_In_Scene (void) const { return m_Scene != NULL; }
//////////////////////////////////////////////////////////////////////
// Attenuation settings
//////////////////////////////////////////////////////////////////////
//
// This is the distance where the sound can not be heard any longer. (its vol is 0)
//
virtual void Set_DropOff_Radius (float radius = 1) = 0;
virtual float Get_DropOff_Radius (void) const = 0;
//////////////////////////////////////////////////////////////////////
// From PersistClass
//////////////////////////////////////////////////////////////////////
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
protected:
//////////////////////////////////////////////////////////////////////
// Handle information
//////////////////////////////////////////////////////////////////////
virtual SoundCullObjClass * Peek_Cullable_Wrapper (void) const { return m_PhysWrapper; }
virtual void Set_Cullable_Wrapper (SoundCullObjClass *obj) { m_PhysWrapper = obj; }
//////////////////////////////////////////////////////////////////////
// Sound object managment
//////////////////////////////////////////////////////////////////////
static void Register_Sound_Object (SoundSceneObjClass *sound_obj);
static void Unregister_Sound_Object (SoundSceneObjClass *sound_obj);
static bool Find_Sound_Object (uint32 id_to_find, int *index);
//////////////////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////////////////
SoundSceneClass * m_Scene;
SoundCullObjClass * m_PhysWrapper;
AudioCallbackClass * m_pCallback;
AudioCallbackClass::EVENTS m_RegisteredEvents;
uint32 m_ID;
RenderObjClass * m_AttachedObject;
int m_AttachedBone;
uint32 m_UserData;
RefCountClass * m_UserObj;
static DynamicVectorClass<SoundSceneObjClass *> m_GlobalSoundList;
static uint32 m_NextAvailableID;
static CriticalSectionClass m_IDListMutex;
};
//////////////////////////////////////////////////////////////////////////////
//
// On_Event
//
//////////////////////////////////////////////////////////////////////////////
__inline void
SoundSceneObjClass::On_Event
(
AudioCallbackClass::EVENTS event,
uint32 param1,
uint32 param2
)
{
if ((m_pCallback != NULL) && (m_RegisteredEvents & event)) {
switch (event)
{
case AudioCallbackClass::EVENT_SOUND_STARTED:
m_pCallback->On_Sound_Started (this);
break;
case AudioCallbackClass::EVENT_SOUND_ENDED:
m_pCallback->On_Sound_Ended (this);
break;
case AudioCallbackClass::EVENT_LOGICAL_HEARD:
m_pCallback->On_Logical_Heard ((LogicalListenerClass *)param1, (LogicalSoundClass *)param2);
break;
}
}
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// Register_Callback
//
//////////////////////////////////////////////////////////////////////////////
__inline void
SoundSceneObjClass::Register_Callback
(
AudioCallbackClass::EVENTS events,
AudioCallbackClass * callback
)
{
m_RegisteredEvents = events;
m_pCallback = callback;
return ;
}
#endif //__SOUND_SCENE_OBJ_H

View file

@ -0,0 +1,303 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/Threads.cpp $Modtime:: 7/17/99 3:32p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "Threads.h"
#include "refcount.h"
#include "Utils.h"
#include <Process.h>
#include "wwdebug.h"
///////////////////////////////////////////////////////////////////////////////////////////
// Static member initialization
///////////////////////////////////////////////////////////////////////////////////////////
WWAudioThreadsClass::DELAYED_RELEASE_INFO * WWAudioThreadsClass::m_ReleaseListHead = NULL;
CriticalSectionClass WWAudioThreadsClass::m_ListMutex;
HANDLE WWAudioThreadsClass::m_hDelayedReleaseThread = (HANDLE)-1;
HANDLE WWAudioThreadsClass::m_hDelayedReleaseEvent = (HANDLE)-1;
CriticalSectionClass WWAudioThreadsClass::m_CriticalSection;
bool WWAudioThreadsClass::m_IsShuttingDown = false;
///////////////////////////////////////////////////////////////////////////////////////////
//
// WWAudioThreadsClass
//
///////////////////////////////////////////////////////////////////////////////////////////
WWAudioThreadsClass::WWAudioThreadsClass (void)
{
return ;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// ~WWAudioThreadsClass
//
///////////////////////////////////////////////////////////////////////////////////////////
WWAudioThreadsClass::~WWAudioThreadsClass (void)
{
return ;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Create_Delayed_Release_Thread
//
///////////////////////////////////////////////////////////////////////////////////////////
HANDLE
WWAudioThreadsClass::Create_Delayed_Release_Thread (LPVOID param)
{
//
// If the thread isn't already running, then
//
if (m_hDelayedReleaseThread == (HANDLE)-1) {
m_hDelayedReleaseEvent = ::CreateEvent (NULL, FALSE, FALSE, NULL);
m_hDelayedReleaseThread = (HANDLE)::_beginthread (Delayed_Release_Thread_Proc, 0, param);
}
return m_hDelayedReleaseThread;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// End_Delayed_Release_Thread
//
///////////////////////////////////////////////////////////////////////////////////////////
void
WWAudioThreadsClass::End_Delayed_Release_Thread (DWORD timeout)
{
m_IsShuttingDown = true;
//
// If the thread is running, then wait for it to finish
//
if (m_hDelayedReleaseThread != (HANDLE)-1) {
::SetEvent (m_hDelayedReleaseEvent);
::WaitForSingleObject (m_hDelayedReleaseThread, timeout);
m_hDelayedReleaseEvent = (HANDLE)-1;
m_hDelayedReleaseThread = (HANDLE)-1;
}
return ;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Add_Delayed_Release_Object
//
///////////////////////////////////////////////////////////////////////////////////////////
void
WWAudioThreadsClass::Add_Delayed_Release_Object
(
RefCountClass * object,
DWORD delay
)
{
if (m_IsShuttingDown) {
REF_PTR_RELEASE (object);
} else {
//
// Make sure we have a thread running that will handle
// the operation for us.
//
if (m_hDelayedReleaseThread == (HANDLE)-1) {
Create_Delayed_Release_Thread ();
}
//
// Wait for the release thread to finish using the
// list pointer
//
{
CriticalSectionClass::LockClass lock(m_ListMutex);
//
// Create a new delay-information structure and
// add it to our list
//
DELAYED_RELEASE_INFO *info = W3DNEW DELAYED_RELEASE_INFO;
info->object = object;
info->time = ::GetTickCount () + delay;
info->next = m_ReleaseListHead;
m_ReleaseListHead = info;
}
}
return ;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Flush_Delayed_Release_Objects
//
///////////////////////////////////////////////////////////////////////////////////////////
void
WWAudioThreadsClass::Flush_Delayed_Release_Objects (void)
{
CriticalSectionClass::LockClass lock(m_CriticalSection);
//
// Loop through all the objects in our delay list, and
// free them now.
//
DELAYED_RELEASE_INFO *info = NULL;
DELAYED_RELEASE_INFO *next = NULL;
for (info = m_ReleaseListHead; info != NULL; info = next) {
next = info->next;
//
// Free the object
//
REF_PTR_RELEASE (info->object);
SAFE_DELETE (info);
}
m_ReleaseListHead = NULL;
return ;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Delayed_Release_Thread_Proc
//
///////////////////////////////////////////////////////////////////////////////////////////
void __cdecl
WWAudioThreadsClass::Delayed_Release_Thread_Proc (LPVOID /*param*/)
{
const DWORD base_timeout = 2000;
DWORD timeout = base_timeout + rand () % 1000;
//
// Keep looping forever until we are singalled to quit (or an error occurs)
//
while (::WaitForSingleObject (m_hDelayedReleaseEvent, timeout) == WAIT_TIMEOUT) {
{
CriticalSectionClass::LockClass lock(m_ListMutex);
//
// Loop through all the objects in our delay list, and
// free any that have expired.
//
DWORD current_time = ::GetTickCount ();
DELAYED_RELEASE_INFO *curr = NULL;
DELAYED_RELEASE_INFO *prev = NULL;
DELAYED_RELEASE_INFO *next = NULL;
for (curr = m_ReleaseListHead; curr != NULL; curr = next) {
next = curr->next;
//
// If the time has expired, free the object
//
if (current_time >= curr->time) {
//
// Unlink the object
//
if (prev == NULL) {
m_ReleaseListHead = next;
} else {
prev->next = next;
}
//
// Free the object
//
REF_PTR_RELEASE (curr->object);
SAFE_DELETE (curr);
} else {
prev = curr;
}
}
}
//
// To avoid 'periodic' releases, randomize our timeout
//
timeout = base_timeout + rand () % 1000;
}
Flush_Delayed_Release_Objects ();
return ;
}
/*
///////////////////////////////////////////////////////////////////////////////////////////
//
// Begin_Modify_List
//
///////////////////////////////////////////////////////////////////////////////////////////
bool
WWAudioThreadsClass::Begin_Modify_List (void)
{
bool retval = false;
//
// Wait for up to one second to modify the list object
//
if (m_ListMutex != NULL) {
retval = (::WaitForSingleObject (m_ListMutex, 1000) == WAIT_OBJECT_0);
WWASSERT (retval);
}
return retval;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// End_Modify_List
//
///////////////////////////////////////////////////////////////////////////////////////////
void
WWAudioThreadsClass::End_Modify_List (void)
{
//
// Release this thread's hold on the mutex object.
//
if (m_ListMutex != NULL) {
::ReleaseMutex (m_ListMutex);
}
return ;
}
*/

View file

@ -0,0 +1,112 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/Threads.h $Modtime:: 7/17/99 3:32p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __WWAUDIO_THREADS_H
#define __WWAUDIO_THREADS_H
#include "Windows.H"
#include "Vector.H"
#include "mutex.h"
// Forward declarations
class RefCountClass;
//////////////////////////////////////////////////////////////////////////
//
// WWAudioThreadsClass
//
// Simple class that provides a common namespace for tying thread
// information together.
//
//////////////////////////////////////////////////////////////////////////
class WWAudioThreadsClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
WWAudioThreadsClass (void);
~WWAudioThreadsClass (void);
//////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////
//
// Delayed release mechanism
//
static HANDLE Create_Delayed_Release_Thread (LPVOID param = NULL);
static void End_Delayed_Release_Thread (DWORD timeout = 20000);
static void Add_Delayed_Release_Object (RefCountClass *object, DWORD delay = 2000);
static void Flush_Delayed_Release_Objects (void);
private:
//////////////////////////////////////////////////////////////////////
// Private methods
//////////////////////////////////////////////////////////////////////
static void __cdecl Delayed_Release_Thread_Proc (LPVOID param);
//////////////////////////////////////////////////////////////////////
// Private data types
//////////////////////////////////////////////////////////////////////
typedef struct _DELAYED_RELEASE_INFO
{
RefCountClass * object;
DWORD time;
_DELAYED_RELEASE_INFO *next;
} DELAYED_RELEASE_INFO;
//typedef DynamicVectorClass<DELAYED_RELEASE_INFO *> RELEASE_LIST;
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
static HANDLE m_hDelayedReleaseThread;
static HANDLE m_hDelayedReleaseEvent;
//static RELEASE_LIST m_ReleaseList;
static CriticalSectionClass m_CriticalSection;
static DELAYED_RELEASE_INFO * m_ReleaseListHead;
static CriticalSectionClass m_ListMutex;
static bool m_IsShuttingDown;
};
#endif //__WWAUDIO_THREADS_H

View file

@ -0,0 +1,42 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/Utils.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 6/15/00 11:40a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#pragma warning (disable : 4514)
#include "Utils.H"
CRITICAL_SECTION MMSLockClass::_MSSLockCriticalSection;

View file

@ -0,0 +1,105 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio *
* *
* $Archive:: /Commando/Code/WWAudio/Utils.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/24/01 4:37p $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __UTILS_H
#define __UTILS_H
#pragma warning (push, 3)
#include "Mss.H"
#pragma warning (pop)
/////////////////////////////////////////////////////////////////////////////
//
// Macros
//
#define SAFE_DELETE(pobject) \
if (pobject) { \
delete pobject; \
pobject = NULL; \
} \
#define SAFE_DELETE_ARRAY(pobject) \
if (pobject) { \
delete [] pobject; \
pobject = NULL; \
} \
#define SAFE_FREE(pobject) \
if (pobject) { \
::free (pobject); \
pobject = NULL; \
} \
/////////////////////////////////////////////////////////////////////////////
//
// MMSLockClass
//
/////////////////////////////////////////////////////////////////////////////
class MMSLockClass
{
public:
MMSLockClass (void) { ::AIL_lock (); }
~MMSLockClass (void) { ::AIL_unlock (); }
static CRITICAL_SECTION _MSSLockCriticalSection;
};
////////////////////////////////////////////////////////////////////////////
//
// Get_Filename_From_Path
//
__inline LPCTSTR
Get_Filename_From_Path (LPCTSTR path)
{
// Find the last occurance of the directory deliminator
LPCTSTR filename = ::strrchr (path, '\\');
if (filename != NULL) {
// Increment past the directory deliminator
filename ++;
} else {
filename = path;
}
// Return the filename part of the path
return filename;
}
#endif //__UTILS_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,335 @@
# Microsoft Developer Studio Project File - Name="WWAudio" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=WWAudio - Win32 DebugE
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "WWAudio.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "WWAudio.mak" CFG="WWAudio - Win32 DebugE"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "WWAudio - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "WWAudio - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "WWAudio - Win32 Profile" (based on "Win32 (x86) Static Library")
!MESSAGE "WWAudio - Win32 DebugE" (based on "Win32 (x86) Static Library")
!MESSAGE "WWAudio - Win32 ProfileE" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/WWAudio", VIPBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "WWAudio - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /WX /Gi /GR- /GX /O2 /Ob2 /I "..\miles6\include" /I "..\wwlib" /I "..\wwmath" /I "..\wwdebug" /I "..\ww3d2" /I "..\wwsaveload" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "G_CODE_BASE" /D "_WINDOWS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWAudio.lib"
!ELSEIF "$(CFG)" == "WWAudio - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /WX /Gm /Gi /GR- /GX /ZI /Od /I "..\miles6\include" /I "..\wwlib" /I "..\wwmath" /I "..\wwdebug" /I "..\ww3d2" /I "..\wwsaveload" /D "_DEBUG" /D "WWDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "G_CODE_BASE" /D "_WINDOWS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWAudioDebug.lib"
!ELSEIF "$(CFG)" == "WWAudio - Win32 Profile"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Profile"
# PROP BASE Intermediate_Dir "Profile"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Profile"
# PROP Intermediate_Dir "Profile"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\miles" /I "..\wwlib" /I "..\wwmath" /I "..\wwdebug" /I "..\ww3d" /I "..\wwphys" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /WX /Gm /Gi /GR- /GX /Zi /O2 /Op /Ob2 /I "..\miles6\include" /I "..\wwlib" /I "..\wwmath" /I "..\wwdebug" /I "..\ww3d2" /I "..\wwsaveload" /D "NDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "WWDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "G_CODE_BASE" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo /out:"..\Libs\Release\WWAudio.lib"
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWAudioProfile.lib"
!ELSEIF "$(CFG)" == "WWAudio - Win32 DebugE"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "DebugE"
# PROP BASE Intermediate_Dir "DebugE"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "DebugE"
# PROP Intermediate_Dir "DebugE"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W4 /Gm /Gi /GX /ZI /Od /I "..\miles6\include" /I "..\wwlib" /I "..\wwmath" /I "..\wwdebug" /I "..\ww3d" /I "..\wwsaveload" /D "_DEBUG" /D "WWDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "G_CODE_BASE" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /WX /Gm /Gi /GR- /GX /ZI /Od /I "..\miles6\include" /I "..\wwlib" /I "..\wwmath" /I "..\wwdebug" /I "..\ww3d2" /I "..\wwsaveload" /D "_DEBUG" /D "WWDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "G_CODE_BASE" /D "PARAM_EDITING_ON" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo /out:"..\Libs\Debug\WWAudio.lib"
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWAudioDebugE.lib"
!ELSEIF "$(CFG)" == "WWAudio - Win32 ProfileE"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "ProfileE"
# PROP BASE Intermediate_Dir "ProfileE"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "ProfileE"
# PROP Intermediate_Dir "ProfileE"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /Gm /Gi /GX /Zi /O2 /I "..\miles6\include" /I "..\wwlib" /I "..\wwmath" /I "..\wwdebug" /I "..\ww3d" /I "..\wwsaveload" /D "NDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "WWDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "G_CODE_BASE" /YX /FD /c
# ADD CPP /nologo /MD /W3 /WX /Gm /Gi /GR- /GX /Zi /O2 /I "..\miles6\include" /I "..\wwlib" /I "..\wwmath" /I "..\wwdebug" /I "..\ww3d2" /I "..\wwsaveload" /D "NDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "WWDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "G_CODE_BASE" /D "PARAM_EDITING_ON" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo /out:"..\Libs\profile\WWAudio.lib"
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWAudioProfileE.lib"
!ENDIF
# Begin Target
# Name "WWAudio - Win32 Release"
# Name "WWAudio - Win32 Debug"
# Name "WWAudio - Win32 Profile"
# Name "WWAudio - Win32 DebugE"
# Name "WWAudio - Win32 ProfileE"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\AudibleSound.cpp
# End Source File
# Begin Source File
SOURCE=.\AudioSaveLoad.cpp
# End Source File
# Begin Source File
SOURCE=.\FilteredSound.cpp
# End Source File
# Begin Source File
SOURCE=.\Listener.cpp
# End Source File
# Begin Source File
SOURCE=.\listenerhandle.cpp
# End Source File
# Begin Source File
SOURCE=.\LogicalListener.cpp
# End Source File
# Begin Source File
SOURCE=.\LogicalSound.cpp
# End Source File
# Begin Source File
SOURCE=.\sound2dhandle.cpp
# End Source File
# Begin Source File
SOURCE=.\Sound3D.cpp
# End Source File
# Begin Source File
SOURCE=.\sound3dhandle.cpp
# End Source File
# Begin Source File
SOURCE=.\SoundBuffer.cpp
# End Source File
# Begin Source File
SOURCE=.\soundhandle.cpp
# End Source File
# Begin Source File
SOURCE=.\SoundPseudo3D.cpp
# End Source File
# Begin Source File
SOURCE=.\SoundScene.cpp
# End Source File
# Begin Source File
SOURCE=.\SoundSceneObj.cpp
# End Source File
# Begin Source File
SOURCE=.\soundstreamhandle.cpp
# End Source File
# Begin Source File
SOURCE=.\Threads.cpp
# End Source File
# Begin Source File
SOURCE=.\Utils.cpp
# End Source File
# Begin Source File
SOURCE=.\WWAudio.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\AABTreeSoundCullClass.h
# End Source File
# Begin Source File
SOURCE=.\AudibleSound.h
# End Source File
# Begin Source File
SOURCE=.\AudioEvents.h
# End Source File
# Begin Source File
SOURCE=.\AudioSaveLoad.h
# End Source File
# Begin Source File
SOURCE=.\FilteredSound.h
# End Source File
# Begin Source File
SOURCE=.\Listener.h
# End Source File
# Begin Source File
SOURCE=.\listenerhandle.h
# End Source File
# Begin Source File
SOURCE=.\LogicalListener.h
# End Source File
# Begin Source File
SOURCE=.\LogicalSound.h
# End Source File
# Begin Source File
SOURCE=.\PriorityVector.h
# End Source File
# Begin Source File
SOURCE=.\sound2dhandle.h
# End Source File
# Begin Source File
SOURCE=.\Sound3D.h
# End Source File
# Begin Source File
SOURCE=.\sound3dhandle.h
# End Source File
# Begin Source File
SOURCE=.\SoundBuffer.h
# End Source File
# Begin Source File
SOURCE=.\SoundCullObj.h
# End Source File
# Begin Source File
SOURCE=.\soundhandle.h
# End Source File
# Begin Source File
SOURCE=.\SoundPseudo3D.h
# End Source File
# Begin Source File
SOURCE=.\SoundScene.h
# End Source File
# Begin Source File
SOURCE=.\SoundSceneObj.h
# End Source File
# Begin Source File
SOURCE=.\soundstreamhandle.h
# End Source File
# Begin Source File
SOURCE=.\Threads.h
# End Source File
# Begin Source File
SOURCE=.\Utils.h
# End Source File
# Begin Source File
SOURCE=.\WWAudio.h
# End Source File
# End Group
# End Target
# End Project

View file

@ -0,0 +1,586 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWAudio.h *
* *
* $Archive:: /Commando/Code/WWAudio/WWAudio.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/14/01 2:27p $*
* *
* $Revision:: 19 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __WWAUDIO_H
#define __WWAUDIO_H
#include "always.h"
#pragma warning (push, 3)
#include "Mss.H"
#pragma warning (pop)
#include "Vector.H"
#include "SoundBuffer.H"
#include "AudioEvents.H"
#include "wwstring.h"
/////////////////////////////////////////////////////////////////////////////////
// Forward declaration
/////////////////////////////////////////////////////////////////////////////////
class AudibleSoundClass;
class Sound3DClass;
class Sound2DTriggerClass;
class StreamSoundClass;
class FileClass;
class SoundSceneClass;
class FileFactoryClass;
class SoundSceneObjClass;
class LogicalListenerClass;
class LogicalSoundClass;
class Matrix3D;
/////////////////////////////////////////////////////////////////////////////////
// Class IDs
/////////////////////////////////////////////////////////////////////////////////
typedef enum
{
CLASSID_UNKNOWN = 0,
CLASSID_2D,
CLASSID_3D,
CLASSID_LISTENER,
CLASSID_PSEUDO3D,
CLASSID_2DTRIGGER,
CLASSID_LOGICAL,
CLASSID_FILTERED,
CLASSID_COUNT
} SOUND_CLASSID;
/////////////////////////////////////////////////////////////////////////////////
// Default values
/////////////////////////////////////////////////////////////////////////////////
const int DEF_2D_SAMPLE_COUNT = 16;
const int DEF_3D_SAMPLE_COUNT = 16;
const float DEF_MUSIC_VOL = 1.0F;
const float DEF_SFX_VOL = 1.0F;
const int DEF_CACHE_SIZE = 1024;
const int DEF_MAX_2D_BUFFER_SIZE = 20000;
const int DEF_MAX_3D_BUFFER_SIZE = 100000;
/////////////////////////////////////////////////////////////////////////////////
// Constants
/////////////////////////////////////////////////////////////////////////////////
enum
{
MAX_CACHE_HASH = 256,
CACHE_HASH_MASK = 0x000000FF
};
/////////////////////////////////////////////////////////////////////////////////
//
// WWAudioClass
//
// Main controlling entity for all music and sound effects in a game. Used
// to:
//
// -- Select hardware devices
// -- Modify quality preferences
// -- Modify global volume settings
// -- Allocate new sounds
// -- Cache reuseable sounds
// -- Play music and sound effects
//
//
/////////////////////////////////////////////////////////////////////////////////
class WWAudioClass
{
public:
//////////////////////////////////////////////////////////////////////
// Public data types
//////////////////////////////////////////////////////////////////////
typedef enum
{
DRIVER2D_ERROR = 0,
DRIVER2D_DSOUND,
DRIVER2D_WAVEOUT,
DRIVER2D_COUNT
} DRIVER_TYPE_2D;
typedef enum
{
DRIVER3D_ERROR = 0,
DRIVER3D_D3DSOUND,
DRIVER3D_EAX,
DRIVER3D_A3D,
DRIVER3D_RSX,
DRIVER3D_PSEUDO,
DRIVER3D_DOLBY,
DRIVER3D_COUNT
} DRIVER_TYPE_3D;
typedef struct _DRIVER_INFO_STRUCT
{
HPROVIDER driver;
char * name;
} DRIVER_INFO_STRUCT;
//////////////////////////////////////////////////////////////////////
// Friend classes
//////////////////////////////////////////////////////////////////////
friend class AudibleSoundClass;
friend class Sound3DClass;
friend class Listener3DClass;
//////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////
WWAudioClass (void);
virtual ~WWAudioClass (void);
//////////////////////////////////////////////////////////////////////
// Static methods
//////////////////////////////////////////////////////////////////////
static WWAudioClass * Get_Instance (void) { return _theInstance; }
//////////////////////////////////////////////////////////////////////
// Initialization methods
//////////////////////////////////////////////////////////////////////
//
// Note: After call Initialize () you can begin using the library, you don't
// need to explicity call Open_2D_Device () or Select_3D_Device (). Those
// methods were provided as a means of opening devices other than the default.
//
// The Initialize () method defaults to a stereo, 16bit, 44100hz 2D DirectSound
// driver and a RSX 3D provider. If RSX isn't available, it trys A3D, then
// EAX, then D3DSound, then whatever driver is first available.
//
void Initialize (bool stereo = true, int bits = 16, int hertz = 44100);
void Initialize (const char *registry_subkey_name);
void Shutdown (void);
//////////////////////////////////////////////////////////////////////
// Driver methods
//////////////////////////////////////////////////////////////////////
HDIGDRIVER Get_2D_Driver (void) const { return m_Driver2D; }
HPROVIDER Get_3D_Driver (void) const { return m_Driver3D; }
HPROVIDER Get_Reverb_Filter (void) const { return m_ReverbFilter; }
//////////////////////////////////////////////////////////////////////
// 2D Hardware/driver selection methods
//////////////////////////////////////////////////////////////////////
DRIVER_TYPE_2D Open_2D_Device (LPWAVEFORMAT format = NULL);
DRIVER_TYPE_2D Open_2D_Device (bool stereo, int bits, int hertz);
bool Close_2D_Device (void);
int Get_Playback_Rate (void) const { return m_PlaybackRate; }
int Get_Playback_Bits (void) const { return m_PlaybackBits; }
bool Get_Playback_Stereo (void) const { return m_PlaybackStereo; }
//////////////////////////////////////////////////////////////////////
// 3D Hardware/driver selection methods
//////////////////////////////////////////////////////////////////////
// Device information
int Get_3D_Device_Count (void) const { return m_Driver3DList.Count (); }
bool Get_3D_Device (int index, DRIVER_INFO_STRUCT **info) { (*info) = m_Driver3DList[index]; return true; }
bool Is_3D_Device_Available (DRIVER_TYPE_3D type) { return Find_3D_Device (type) >= 0; }
int Find_3D_Device (DRIVER_TYPE_3D type);
// Device selection
bool Select_3D_Device (int index);
bool Select_3D_Device (const char *device_name, HPROVIDER provider);
bool Select_3D_Device (DRIVER_TYPE_3D type);
bool Select_3D_Device (const char *device_name);
//////////////////////////////////////////////////////////////////////
// Registry settings
//////////////////////////////////////////////////////////////////////
bool Load_From_Registry (const char *subkey_name);
bool Load_From_Registry (const char *subkey_name, StringClass &device_name, bool &is_stereo, int &bits, int &hertz, bool &sound_enabled, bool &music_enabled, float &sound_volume, float &music_volume);
bool Save_To_Registry (const char *subkey_name);
bool Save_To_Registry (const char *subkey_name, const StringClass &device_name, bool is_stereo, int bits, int hertz, bool sound_enabled, bool music_enabled, float sound_volume, float music_volume);
//////////////////////////////////////////////////////////////////////
// File interface methods
//////////////////////////////////////////////////////////////////////
//
// Note: The user is responsible for freeing this file factory, the
// sound library does not.
//
void Set_File_Factory (FileFactoryClass *ffactory) { m_FileFactory = ffactory; }
//////////////////////////////////////////////////////////////////////
// Preference settings methods
//////////////////////////////////////////////////////////////////////
bool Set_Max_2D_Sample_Count (int count = DEF_2D_SAMPLE_COUNT);
int Get_Max_2D_Sample_Count (void) const;
int Get_Avail_2D_Sample_Count (void) const;
bool Set_Max_3D_Sample_Count (int count = DEF_3D_SAMPLE_COUNT);
int Get_Max_3D_Sample_Count (void) const;
int Get_Avail_3D_Sample_Count (void) const;
//
// Reverb Support: Only works with Create Labs EAX chipset.
//
float Get_Effects_Level (void) { return m_EffectsLevel; }
// See ENVIRONMENT_ defines in MSS.H for a list of possible values.
int Get_Reverb_Room_Type (void) { return m_ReverbRoomType; }
void Set_Reverb_Room_Type (int type);
//////////////////////////////////////////////////////////////////////
// Volume methods
//////////////////////////////////////////////////////////////////////
void Set_Sound_Effects_Volume (float volume = DEF_SFX_VOL);
float Get_Sound_Effects_Volume (void) const { return m_SoundVolume; }
void Set_Music_Volume (float volume = DEF_MUSIC_VOL);
float Get_Music_Volume (void) const { return m_MusicVolume; }
void Allow_Sound_Effects (bool onoff = true);
bool Are_Sound_Effects_On (void) const { return m_AreSoundEffectsEnabled; }
void Allow_Music (bool onoff = true);
bool Is_Music_On (void) const { return m_IsMusicEnabled; }
//////////////////////////////////////////////////////////////////////
// Update methods
//////////////////////////////////////////////////////////////////////
void On_Frame_Update (unsigned int milliseconds = 0);
//////////////////////////////////////////////////////////////////////
// Callback methods
//////////////////////////////////////////////////////////////////////
void Register_EOS_Callback (LPFNEOSCALLBACK callback, DWORD user_param);
void UnRegister_EOS_Callback (LPFNEOSCALLBACK callback);
void Register_Text_Callback (LPFNTEXTCALLBACK callback, DWORD user_param);
void UnRegister_Text_Callback (LPFNTEXTCALLBACK callback);
void Fire_Text_Callback (AudibleSoundClass *sound_obj, const StringClass &text);
//////////////////////////////////////////////////////////////////////
// Sound allocation methods
//////////////////////////////////////////////////////////////////////
//
// Note: The string_id is either the filename (for file-based sounds)
// or the string_id passed into the create-from-memory methods.
// It is important to note that the AudibleSoundClass object is not cached, but
// the raw sound data the AudibleSoundClass object plays.
//
bool Is_Sound_Cached (const char *string_id);
//
// Note: We differentiate between a 'music' object and
// a 'sound effect' for volume control. A music object
// is simply a sound effect with a 'SOUND_TYPE' of TYPE_MUSIC.
// When the user adjusts the 'music' volume, we loop through
// the sound effects marked 'music' and update their volume.
// Same for 'sound effect' volume.
//
//
// Note: The sound data these objects support can be PCM WAV,
// ADPCM WAV, VOC, or MP3.
//
AudibleSoundClass * Create_Sound_Effect (FileClass &file, const char *string_id);
AudibleSoundClass * Create_Sound_Effect (const char *filename);
AudibleSoundClass * Create_Sound_Effect (const char *string_id, unsigned char *raw_wave_data, unsigned long bytes);
//
// Note: 3D sound effects should be inserted into the SoundScene.
// They should not be manually played/stopped/etc.
//
// True 3D sound effects require mono, uncompressed, WAV data.
// If the supplied data is not in this format the sound will
// become a pseudo-3D sound.
//
// Pseudo-3D sounds are not true 3D sounds. They have the
// same properties as 3D 'sound effects' but do not use 3D
// hardware, are not restricted to mono, uncompressed, WAV data,
// and do not calculate doppler and reverb effects.
//
Sound3DClass * Create_3D_Sound (FileClass &file, const char *string_id, int classid_hint = CLASSID_3D);
Sound3DClass * Create_3D_Sound (const char *filename, int classid_hint = CLASSID_3D);
Sound3DClass * Create_3D_Sound (const char *string_id, unsigned char *raw_wave_data, unsigned long bytes, int classid_hint = CLASSID_3D);
//////////////////////////////////////////////////////////////////////
// Logical-sound related methods
//////////////////////////////////////////////////////////////////////
LogicalSoundClass * Create_Logical_Sound (void);
LogicalListenerClass * Create_Logical_Listener (void);
//
// Logical type identification for use with the definition system
//
void Add_Logical_Type (int id, LPCTSTR display_name);
void Reset_Logical_Types (void);
int Get_Logical_Type_Count (void) const { return m_LogicalTypes.Count (); }
int Get_Logical_Type (int index, StringClass &name);
//////////////////////////////////////////////////////////////////////
// Definition related methods
//////////////////////////////////////////////////////////////////////
//
// Sound creation methods
//
int Create_Instant_Sound (int definition_id, const Matrix3D &tm, RefCountClass *user_obj = NULL, uint32 user_data = 0, int classid_hint = CLASSID_3D);
int Create_Instant_Sound (const char *def_name, const Matrix3D &tm, RefCountClass *user_obj = NULL, uint32 user_data = 0, int classid_hint = CLASSID_3D);
AudibleSoundClass * Create_Continuous_Sound (int definition_id, RefCountClass *user_obj = NULL, uint32 user_data = 0, int classid_hint = CLASSID_3D);
AudibleSoundClass * Create_Continuous_Sound (const char *def_name, RefCountClass *user_obj = NULL, uint32 user_data = 0, int classid_hint = CLASSID_3D);
AudibleSoundClass * Create_Sound (int definition_id, RefCountClass *user_obj = NULL, uint32 user_data = 0, int classid_hint = CLASSID_3D);
AudibleSoundClass * Create_Sound (const char *def_name, RefCountClass *user_obj = NULL, uint32 user_data = 0, int classid_hint = CLASSID_3D);
//////////////////////////////////////////////////////////////////////
// Sound object lookup
//////////////////////////////////////////////////////////////////////
SoundSceneObjClass * Find_Sound_Object (uint32 sound_obj_id);
//////////////////////////////////////////////////////////////////////
// Sound scene methods (for 3D sounds)
//////////////////////////////////////////////////////////////////////
SoundSceneClass * Get_Sound_Scene (void) const { return m_SoundScene; }
//////////////////////////////////////////////////////////////////////
// Cache methods
//////////////////////////////////////////////////////////////////////
//
// Note: The cache sizes are in kilo-bytes. The default
// is currently set to 1MB.
//
bool Set_Cache_Size (int kbytes = DEF_CACHE_SIZE) { m_MaxCacheSize = (kbytes * 1024); }
int Get_Cache_Size (void) const { return m_MaxCacheSize / 1024; }
int Get_Current_Cache_Size (void) const { return m_CurrentCacheSize; }
//
// This settings determines whether a sound buffer is loaded
// into memory or streamed from file.
//
// Note: True 3D sounds can't be streamed, so if the buffer size
// is larger then the following setting, the sound is created as
// a pseudo-3d sound effect and streamed.
//
void Set_Max_2D_Sound_Buffer (int bytes = DEF_MAX_2D_BUFFER_SIZE) { m_Max2DBufferSize = bytes; }
void Set_Max_3D_Sound_Buffer (int bytes = DEF_MAX_3D_BUFFER_SIZE) { m_Max3DBufferSize = bytes; }
//////////////////////////////////////////////////////////////////////
// Play control methods
//////////////////////////////////////////////////////////////////////
bool Simple_Play_2D_Sound_Effect (const char *filename, float priority = 1.0F, float volume = DEF_SFX_VOL);
bool Simple_Play_2D_Sound_Effect (FileClass &file, float priority = 1.0F, float volume = DEF_SFX_VOL);
//////////////////////////////////////////////////////////////////////
// Playlist methods
//////////////////////////////////////////////////////////////////////
bool Add_To_Playlist (AudibleSoundClass *sound);
bool Remove_From_Playlist (AudibleSoundClass *sound);
int Get_Playlist_Count (void) const { return m_Playlist.Count (); }
AudibleSoundClass * Get_Playlist_Entry (int index) const;
AudibleSoundClass * Peek_Playlist_Entry (int index) const { return m_Playlist[index]; }
void Flush_Playlist (void);
bool Is_Sound_In_Playlist (AudibleSoundClass *sound_obj);
//////////////////////////////////////////////////////////////////////
// Statistics methods
//////////////////////////////////////////////////////////////////////
//
// This CPU percent includes total CPU being used for:
// Mixing
// Format conversions
// ADPCM or MP3 decompression
// System buffer fills
//
float Get_Digital_CPU_Percent (void) const;
//////////////////////////////////////////////////////////////////////
// Debug methods
//////////////////////////////////////////////////////////////////////
bool Is_Disabled (void) const;
// Um somtimes you need to get rid of all the completed sounds without
// being in the update render function and without totally shutting down
// the sound system. This is primarily because completed (non static) sounds
// still may have a reference to the object they're attached to.
void Free_Completed_Sounds (void);
protected:
//////////////////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////////////////
void Build_3D_Driver_List (void);
void Free_3D_Driver_List (void);
void Reprioritize_Playlist (void);
bool Validate_3D_Sound_Buffer (SoundBufferClass *buffer);
FileClass * Get_File (LPCTSTR filename);
void Return_File (FileClass *file);
//////////////////////////////////////////////////////////////////////
// Handle management
//////////////////////////////////////////////////////////////////////
void Allocate_2D_Handles (void);
void Release_2D_Handles (void);
void Allocate_3D_Handles (void);
void Release_3D_Handles (void);
HSAMPLE Get_2D_Sample (const AudibleSoundClass &sound_obj);
H3DSAMPLE Get_3D_Sample (const Sound3DClass &sound_obj);
H3DPOBJECT Get_Listener_Handle (void);
void ReAssign_2D_Handles (void);
void ReAssign_3D_Handles (void);
void Remove_2D_Sound_Handles (void);
void Remove_3D_Sound_Handles (void);
bool Is_OK_To_Give_Handle (const AudibleSoundClass &sound_obj);
//////////////////////////////////////////////////////////////////////
// Cache methods
//////////////////////////////////////////////////////////////////////
SoundBufferClass * Get_Sound_Buffer (FileClass &file, const char *string_id, bool is_3d);
SoundBufferClass * Get_Sound_Buffer (const char *filename, bool is_3d);
SoundBufferClass * Find_Cached_Buffer (const char *string_id);
SoundBufferClass * Create_Sound_Buffer (FileClass &file, const char *string_id, bool is_3d);
SoundBufferClass * Create_Sound_Buffer (unsigned char *file_image, unsigned long bytes, const char *string_id, bool is_3d);
bool Cache_Buffer (SoundBufferClass *buffer, const char *string_id);
bool Free_Cache_Space (int bytes);
void Flush_Cache (void);
//////////////////////////////////////////////////////////////////////
// Miles File Callbacks
//////////////////////////////////////////////////////////////////////
static U32 AILCALLBACK File_Open_Callback (char const *filename, U32 *file_handle);
static void AILCALLBACK File_Close_Callback (U32 file_handle);
static S32 AILCALLBACK File_Seek_Callback (U32 file_handle, S32 offset, U32 type);
static U32 AILCALLBACK File_Read_Callback (U32 file_handle, void *buffer, U32 bytes);
private:
//////////////////////////////////////////////////////////////////////
// Static member data
//////////////////////////////////////////////////////////////////////
static WWAudioClass * _theInstance;
static HANDLE _TimerSyncEvent;
//////////////////////////////////////////////////////////////////////
// Private data types
//////////////////////////////////////////////////////////////////////
typedef struct _CACHE_ENTRY_STRUCT
{
char * string_id;
SoundBufferClass * buffer;
_CACHE_ENTRY_STRUCT (void)
: string_id (0), buffer (NULL) {}
_CACHE_ENTRY_STRUCT &operator= (const _CACHE_ENTRY_STRUCT &src) { string_id = ::strdup (src.string_id); REF_PTR_SET (buffer, src.buffer); return *this; }
operator== (const _CACHE_ENTRY_STRUCT &src) { return false; }
operator!= (const _CACHE_ENTRY_STRUCT &src) { return true; }
} CACHE_ENTRY_STRUCT;
typedef struct _LOGICAL_TYPE_STRUCT
{
StringClass display_name;
int id;
_LOGICAL_TYPE_STRUCT (void)
: id (0) {}
_LOGICAL_TYPE_STRUCT (int _id, LPCTSTR name)
: display_name (name), id (_id) {}
operator== (const _LOGICAL_TYPE_STRUCT &src) { return false; }
operator!= (const _LOGICAL_TYPE_STRUCT &src) { return true; }
} LOGICAL_TYPE_STRUCT;
//////////////////////////////////////////////////////////////////////
// Private member data
//////////////////////////////////////////////////////////////////////
int m_PlaybackRate;
int m_PlaybackBits;
bool m_PlaybackStereo;
float m_MusicVolume;
float m_SoundVolume;
int m_Max2DSamples;
int m_Max3DSamples;
int m_Max2DBufferSize;
int m_Max3DBufferSize;
HTIMER m_UpdateTimer;
bool m_IsMusicEnabled;
bool m_AreSoundEffectsEnabled;
FileFactoryClass * m_FileFactory;
// Callback lists
AudioCallbackListClass<LPFNEOSCALLBACK> m_EOSCallbackList;
AudioCallbackListClass<LPFNTEXTCALLBACK> m_TextCallbackList;
// Sound scene management
SoundSceneClass * m_SoundScene;
// Driver information
HDIGDRIVER m_Driver2D;
HPROVIDER m_Driver3D;
HPROVIDER m_Driver3DPseudo;
HPROVIDER m_ReverbFilter;
DynamicVectorClass<DRIVER_INFO_STRUCT *> m_Driver3DList;
// Available sample handles
DynamicVectorClass<HSAMPLE> m_2DSampleHandles;
DynamicVectorClass<H3DSAMPLE> m_3DSampleHandles;
// Playlist managment
DynamicVectorClass<AudibleSoundClass *> m_Playlist;
DynamicVectorClass<AudibleSoundClass *> m_CompletedSounds;
// Buffer caching
DynamicVectorClass<CACHE_ENTRY_STRUCT> m_CachedBuffers[MAX_CACHE_HASH];
int m_MaxCacheSize;
int m_CurrentCacheSize;
// Logical type management
DynamicVectorClass<LOGICAL_TYPE_STRUCT> m_LogicalTypes;
// Reverb support
float m_EffectsLevel;
int m_ReverbRoomType;
};
#endif //__WWAUDIO_H

View file

@ -0,0 +1,60 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwaudio *
* *
* $Archive:: /Commando/Code/WWAudio/listenerhandle.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 11:54a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "listenerhandle.h"
#include "audiblesound.h"
//////////////////////////////////////////////////////////////////////
//
// Sound3DHandleClass
//
//////////////////////////////////////////////////////////////////////
ListenerHandleClass::ListenerHandleClass (void)
{
return ;
}
//////////////////////////////////////////////////////////////////////
//
// ~ListenerHandleClass
//
//////////////////////////////////////////////////////////////////////
ListenerHandleClass::~ListenerHandleClass (void)
{
return ;
}

View file

@ -0,0 +1,102 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwaudio *
* *
* $Archive:: /Commando/Code/WWAudio/listenerhandle.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 11:54a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __LISTENERHANDLE_H
#define __LISTENERHANDLE_H
#include "sound3dhandle.h"
//////////////////////////////////////////////////////////////////////
//
// ListenerHandleClass
//
//////////////////////////////////////////////////////////////////////
class ListenerHandleClass : public Sound3DHandleClass
{
public:
///////////////////////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////////////////////
ListenerHandleClass (void);
~ListenerHandleClass (void);
///////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////
//
// RTTI
//
ListenerHandleClass * As_ListenerHandleClass (void) { return this; }
//
// Inherited
//
void Initialize (SoundBufferClass *buffer);
void Start_Sample (void) { }
void Stop_Sample (void) { }
void Resume_Sample (void) { }
void End_Sample (void) { }
void Set_Sample_Volume (S32 volume) { }
S32 Get_Sample_Volume (void) { return 0; }
void Set_Sample_Pan (S32 pan) { }
S32 Get_Sample_Pan (void) { return 64; }
void Set_Sample_Loop_Count (U32 count) { }
U32 Get_Sample_Loop_Count (void) { return 0; }
void Set_Sample_MS_Position (U32 ms) { }
void Get_Sample_MS_Position (S32 *len, S32 *pos) { }
S32 Get_Sample_Playback_Rate (void) { return 0; }
void Set_Sample_Playback_Rate (S32 rate) { }
protected:
///////////////////////////////////////////////////////////////////
// Protected methods
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Protected member data
///////////////////////////////////////////////////////////////////
};
#endif //__LISTENERHANDLE_H

View file

@ -0,0 +1,369 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwaudio *
* *
* $Archive:: /Commando/Code/WWAudio/sound2dhandle.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/23/01 5:07p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "sound2dhandle.h"
#include "audiblesound.h"
//////////////////////////////////////////////////////////////////////
//
// Sound2DHandleClass
//
//////////////////////////////////////////////////////////////////////
Sound2DHandleClass::Sound2DHandleClass (void) :
SampleHandle ((HSAMPLE)INVALID_MILES_HANDLE)
{
return ;
}
//////////////////////////////////////////////////////////////////////
//
// ~Sound2DHandleClass
//
//////////////////////////////////////////////////////////////////////
Sound2DHandleClass::~Sound2DHandleClass (void)
{
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Initialize
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Initialize (SoundBufferClass *buffer)
{
SoundHandleClass::Initialize (buffer);
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
//
// Make sure this handle is fresh
//
::AIL_init_sample (SampleHandle);
//
// Pass the actual sound data onto the sample
//
if (Buffer != NULL) {
::AIL_set_named_sample_file (SampleHandle, (char *)Buffer->Get_Filename (),
Buffer->Get_Raw_Buffer (), Buffer->Get_Raw_Length (), 0);
}
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Start_Sample
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Start_Sample (void)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_start_sample (SampleHandle);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Stop_Sample
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Stop_Sample (void)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_stop_sample (SampleHandle);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Resume_Sample
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Resume_Sample (void)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_resume_sample (SampleHandle);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// End_Sample
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::End_Sample (void)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_end_sample (SampleHandle);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Pan
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Set_Sample_Pan (S32 pan)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_sample_pan (SampleHandle, pan);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Pan
//
//////////////////////////////////////////////////////////////////////
S32
Sound2DHandleClass::Get_Sample_Pan (void)
{
S32 retval = 0;
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
retval = ::AIL_sample_pan (SampleHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Volume
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Set_Sample_Volume (S32 volume)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_sample_volume (SampleHandle, volume);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Volume
//
//////////////////////////////////////////////////////////////////////
S32
Sound2DHandleClass::Get_Sample_Volume (void)
{
S32 retval = 0;
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
retval = ::AIL_sample_volume (SampleHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Loop_Count
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Set_Sample_Loop_Count (U32 count)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_sample_loop_count (SampleHandle, count);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Loop_Count
//
//////////////////////////////////////////////////////////////////////
U32
Sound2DHandleClass::Get_Sample_Loop_Count (void)
{
U32 retval = 0;
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
retval = ::AIL_sample_loop_count (SampleHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_MS_Position
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Set_Sample_MS_Position (U32 ms)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_sample_ms_position (SampleHandle, ms);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_MS_Position
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Get_Sample_MS_Position (S32 *len, S32 *pos)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_sample_ms_position (SampleHandle, len, pos);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_User_Data
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Set_Sample_User_Data (S32 i, U32 val)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_sample_user_data (SampleHandle, i, val);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_User_Data
//
//////////////////////////////////////////////////////////////////////
U32
Sound2DHandleClass::Get_Sample_User_Data (S32 i)
{
U32 retval = 0;
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
retval = ::AIL_sample_user_data (SampleHandle, i);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Playback_Rate
//
//////////////////////////////////////////////////////////////////////
S32
Sound2DHandleClass::Get_Sample_Playback_Rate (void)
{
S32 retval = 0;
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
retval = ::AIL_sample_playback_rate (SampleHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Playback_Rate
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Set_Sample_Playback_Rate (S32 rate)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_sample_playback_rate (SampleHandle, rate);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Miles_Handle
//
//////////////////////////////////////////////////////////////////////
void
Sound2DHandleClass::Set_Miles_Handle (uint32 handle)
{
SampleHandle = (HSAMPLE)handle;
return ;
}

View file

@ -0,0 +1,107 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwaudio *
* *
* $Archive:: /Commando/Code/WWAudio/sound2dhandle.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 3:10p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUND2DHANDLE_H
#define __SOUND2DHANDLE_H
#include "soundhandle.h"
//////////////////////////////////////////////////////////////////////
//
// Sound2DHandleClass
//
//////////////////////////////////////////////////////////////////////
class Sound2DHandleClass : public SoundHandleClass
{
public:
///////////////////////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////////////////////
Sound2DHandleClass (void);
~Sound2DHandleClass (void);
///////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////
//
// RTTI
//
Sound2DHandleClass * As_Sound2DHandleClass (void) { return this; }
//
// Handle access
//
HSAMPLE Get_HSAMPLE (void) { return SampleHandle; }
//
// Inherited
//
void Set_Miles_Handle (uint32 handle);
void Initialize (SoundBufferClass *buffer);
void Start_Sample (void);
void Stop_Sample (void);
void Resume_Sample (void);
void End_Sample (void);
void Set_Sample_Pan (S32 pan);
S32 Get_Sample_Pan (void);
void Set_Sample_Volume (S32 volume);
S32 Get_Sample_Volume (void);
void Set_Sample_Loop_Count (U32 count);
U32 Get_Sample_Loop_Count (void);
void Set_Sample_MS_Position (U32 ms);
void Get_Sample_MS_Position (S32 *len, S32 *pos);
void Set_Sample_User_Data (S32 i, U32 val);
U32 Get_Sample_User_Data (S32 i);
S32 Get_Sample_Playback_Rate (void);
void Set_Sample_Playback_Rate (S32 rate);
protected:
///////////////////////////////////////////////////////////////////
// Protected member data
///////////////////////////////////////////////////////////////////
HSAMPLE SampleHandle;
};
#endif //__SOUND2DHANDLE_H

View file

@ -0,0 +1,383 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwaudio *
* *
* $Archive:: /Commando/Code/WWAudio/sound3dhandle.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/23/01 4:54p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "sound3dhandle.h"
#include "audiblesound.h"
//////////////////////////////////////////////////////////////////////
//
// Sound3DHandleClass
//
//////////////////////////////////////////////////////////////////////
Sound3DHandleClass::Sound3DHandleClass (void) :
SampleHandle ((H3DSAMPLE)INVALID_MILES_HANDLE)
{
return ;
}
//////////////////////////////////////////////////////////////////////
//
// ~Sound3DHandleClass
//
//////////////////////////////////////////////////////////////////////
Sound3DHandleClass::~Sound3DHandleClass (void)
{
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Initialize
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Initialize (SoundBufferClass *buffer)
{
SoundHandleClass::Initialize (buffer);
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE && Buffer != NULL) {
//
// Configure the 3D sample
//
U32 success = ::AIL_set_3D_sample_file (SampleHandle, Buffer->Get_Raw_Buffer ());
S32 test1 = 0;
S32 test2 = 0;
Get_Sample_MS_Position (&test1, &test2);
//
// Check for success
//
WWASSERT (success != 0);
if (success == 0) {
WWDEBUG_SAY (("WWAudio: Couldn't set 3d sample file. Reason %s\r\n", ::AIL_last_error ()));
}
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Start_Sample
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Start_Sample (void)
{
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
::AIL_start_3D_sample (SampleHandle);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Stop_Sample
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Stop_Sample (void)
{
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
::AIL_stop_3D_sample (SampleHandle);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Resume_Sample
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Resume_Sample (void)
{
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
::AIL_resume_3D_sample (SampleHandle);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// End_Sample
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::End_Sample (void)
{
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
::AIL_end_3D_sample (SampleHandle);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Pan
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Set_Sample_Pan (S32 /*pan*/)
{
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Pan
//
//////////////////////////////////////////////////////////////////////
S32
Sound3DHandleClass::Get_Sample_Pan (void)
{
return 64;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Volume
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Set_Sample_Volume (S32 volume)
{
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_3D_sample_volume (SampleHandle, volume);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Volume
//
//////////////////////////////////////////////////////////////////////
S32
Sound3DHandleClass::Get_Sample_Volume (void)
{
S32 retval = 0;
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
retval = ::AIL_3D_sample_volume (SampleHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Loop_Count
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Set_Sample_Loop_Count (U32 count)
{
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_3D_sample_loop_count (SampleHandle, count);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Loop_Count
//
//////////////////////////////////////////////////////////////////////
U32
Sound3DHandleClass::Get_Sample_Loop_Count (void)
{
U32 retval = 0;
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
retval = ::AIL_3D_sample_loop_count (SampleHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_MS_Position
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Set_Sample_MS_Position (U32 ms)
{
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
WWASSERT (Buffer != NULL);
U32 bytes_per_sec = (Buffer->Get_Rate () * Buffer->Get_Bits ()) >> 3;
U32 bytes = (ms * bytes_per_sec) / 1000;
bytes += (bytes & 1);
::AIL_set_3D_sample_offset (SampleHandle, bytes);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_MS_Position
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Get_Sample_MS_Position (S32 *len, S32 *pos)
{
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
WWASSERT (Buffer != NULL);
if (pos != NULL) {
U32 bytes = ::AIL_3D_sample_offset (SampleHandle);
U32 bytes_per_sec = (Buffer->Get_Rate () * Buffer->Get_Bits ()) >> 3;
U32 ms = (bytes * 1000) / bytes_per_sec;
(*pos) = ms;
}
if (len != NULL) {
U32 bytes = ::AIL_3D_sample_length (SampleHandle);
U32 bytes_per_sec = (Buffer->Get_Rate () * Buffer->Get_Bits ()) >> 3;
U32 ms = (bytes * 1000) / bytes_per_sec;
(*len) = ms;
}
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_User_Data
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Set_Sample_User_Data (S32 i, U32 val)
{
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_3D_object_user_data (SampleHandle, i, val);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_User_Data
//
//////////////////////////////////////////////////////////////////////
U32
Sound3DHandleClass::Get_Sample_User_Data (S32 i)
{
U32 retval = 0;
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
retval = AIL_3D_object_user_data (SampleHandle, i);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Playback_Rate
//
//////////////////////////////////////////////////////////////////////
S32
Sound3DHandleClass::Get_Sample_Playback_Rate (void)
{
S32 retval = 0;
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
retval = ::AIL_3D_sample_playback_rate (SampleHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Playback_Rate
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Set_Sample_Playback_Rate (S32 rate)
{
if (SampleHandle != (H3DSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_3D_sample_playback_rate (SampleHandle, rate);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Miles_Handle
//
//////////////////////////////////////////////////////////////////////
void
Sound3DHandleClass::Set_Miles_Handle (uint32 handle)
{
WWASSERT (SampleHandle == (H3DSAMPLE)INVALID_MILES_HANDLE);
SampleHandle = (H3DSAMPLE)handle;
return ;
}

View file

@ -0,0 +1,112 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwaudio *
* *
* $Archive:: /Commando/Code/WWAudio/sound3dhandle.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 3:11p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUND3DHANDLE_H
#define __SOUND3DHANDLE_H
#include "soundhandle.h"
//////////////////////////////////////////////////////////////////////
//
// Sound3DHandleClass
//
//////////////////////////////////////////////////////////////////////
class Sound3DHandleClass : public SoundHandleClass
{
public:
///////////////////////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////////////////////
Sound3DHandleClass (void);
~Sound3DHandleClass (void);
///////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////
//
// RTTI
//
Sound3DHandleClass * As_Sound3DHandleClass (void) { return this; }
//
// Handle access
//
H3DSAMPLE Get_H3DSAMPLE (void) { return SampleHandle; }
//
// Inherited
//
void Set_Miles_Handle (uint32 handle);
void Initialize (SoundBufferClass *buffer);
void Start_Sample (void);
void Stop_Sample (void);
void Resume_Sample (void);
void End_Sample (void);
void Set_Sample_Pan (S32 pan);
S32 Get_Sample_Pan (void);
void Set_Sample_Volume (S32 volume);
S32 Get_Sample_Volume (void);
void Set_Sample_Loop_Count (U32 count);
U32 Get_Sample_Loop_Count (void);
void Set_Sample_MS_Position (U32 ms);
void Get_Sample_MS_Position (S32 *len, S32 *pos);
void Set_Sample_User_Data (S32 i, U32 val);
U32 Get_Sample_User_Data (S32 i);
S32 Get_Sample_Playback_Rate (void);
void Set_Sample_Playback_Rate (S32 rate);
protected:
///////////////////////////////////////////////////////////////////
// Protected methods
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Protected member data
///////////////////////////////////////////////////////////////////
H3DSAMPLE SampleHandle;
};
#endif //__SOUND3DHANDLE_H

View file

@ -0,0 +1,84 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwaudio *
* *
* $Archive:: /Commando/Code/WWAudio/soundhandle.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 12:18p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "soundhandle.h"
#include "threads.h"
//////////////////////////////////////////////////////////////////////
//
// SoundHandleClass
//
//////////////////////////////////////////////////////////////////////
SoundHandleClass::SoundHandleClass (void) :
Buffer (NULL)
{
return ;
}
//////////////////////////////////////////////////////////////////////
//
// ~SoundHandleClass
//
//////////////////////////////////////////////////////////////////////
SoundHandleClass::~SoundHandleClass (void)
{
//
// Delay the release of the buffer (fixes a sync bug
// with Miles internals).
//
if (Buffer != NULL) {
WWAudioThreadsClass::Add_Delayed_Release_Object (Buffer);
Buffer = NULL;
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Initialize
//
//////////////////////////////////////////////////////////////////////
void
SoundHandleClass::Initialize (SoundBufferClass *buffer)
{
REF_PTR_SET (Buffer, buffer);
return ;
}

View file

@ -0,0 +1,129 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwaudio *
* *
* $Archive:: /Commando/Code/WWAudio/soundhandle.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 3:11p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUNDHANDLE_H
#define __SOUNDHANDLE_H
#include "wwaudio.h"
//////////////////////////////////////////////////////////////////////
// Forward declarations
//////////////////////////////////////////////////////////////////////
class Sound3DHandleClass;
class Sound2DHandleClass;
class SoundStreamHandleClass;
class SoundBufferClass;
class ListenerHandleClass;
//////////////////////////////////////////////////////////////////////
//
// SoundHandleClass
//
//////////////////////////////////////////////////////////////////////
class SoundHandleClass
{
public:
///////////////////////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////////////////////
SoundHandleClass (void);
virtual ~SoundHandleClass (void);
///////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////
//
// RTTI
//
virtual Sound3DHandleClass * As_Sound3DHandleClass (void) { return NULL; }
virtual Sound2DHandleClass * As_Sound2DHandleClass (void) { return NULL; }
virtual SoundStreamHandleClass * As_SoundStreamHandleClass (void) { return NULL; }
virtual ListenerHandleClass * As_ListenerHandleClass (void) { return NULL; }
//
// Handle access
//
virtual H3DSAMPLE Get_H3DSAMPLE (void) { return NULL; }
virtual HSAMPLE Get_HSAMPLE (void) { return NULL; }
virtual HSTREAM Get_HSTREAM (void) { return NULL; }
//
// Initialization
//
virtual void Set_Miles_Handle (uint32 handle) = 0;
virtual void Initialize (SoundBufferClass *buffer);
//
// Sample control
//
virtual void Start_Sample (void) = 0;
virtual void Stop_Sample (void) = 0;
virtual void Resume_Sample (void) = 0;
virtual void End_Sample (void) = 0;
virtual void Set_Sample_Pan (S32 pan) = 0;
virtual S32 Get_Sample_Pan (void) = 0;
virtual void Set_Sample_Volume (S32 volume) = 0;
virtual S32 Get_Sample_Volume (void) = 0;
virtual void Set_Sample_Loop_Count (U32 count) = 0;
virtual U32 Get_Sample_Loop_Count (void) = 0;
virtual void Set_Sample_MS_Position (U32 ms) = 0;
virtual void Get_Sample_MS_Position (S32 *len, S32 *pos) = 0;
virtual void Set_Sample_User_Data (S32 i, U32 val) = 0;
virtual U32 Get_Sample_User_Data (S32 i) = 0;
virtual S32 Get_Sample_Playback_Rate (void) = 0;
virtual void Set_Sample_Playback_Rate (S32 rate) = 0;
protected:
///////////////////////////////////////////////////////////////////
// Protected methods
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Protected member data
///////////////////////////////////////////////////////////////////
SoundBufferClass * Buffer;
};
#endif //__SOUNDHANDLE_H

View file

@ -0,0 +1,366 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwaudio *
* *
* $Archive:: /Commando/Code/WWAudio/soundstreamhandle.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/23/01 4:47p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "soundstreamhandle.h"
#include "audiblesound.h"
//////////////////////////////////////////////////////////////////////
//
// SoundStreamHandleClass
//
//////////////////////////////////////////////////////////////////////
SoundStreamHandleClass::SoundStreamHandleClass (void) :
SampleHandle ((HSAMPLE)INVALID_MILES_HANDLE),
StreamHandle ((HSTREAM)INVALID_MILES_HANDLE)
{
return ;
}
//////////////////////////////////////////////////////////////////////
//
// ~SoundStreamHandleClass
//
//////////////////////////////////////////////////////////////////////
SoundStreamHandleClass::~SoundStreamHandleClass (void)
{
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Initialize
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Initialize (SoundBufferClass *buffer)
{
SoundHandleClass::Initialize (buffer);
if (Buffer != NULL) {
//
// Create a stream from the sample handle
//
StreamHandle = ::AIL_open_stream_by_sample (WWAudioClass::Get_Instance ()->Get_2D_Driver (),
SampleHandle, buffer->Get_Filename (), 0);
/*StreamHandle = ::AIL_open_stream (WWAudioClass::Get_Instance ()->Get_2D_Driver (),
buffer->Get_Filename (), 0);*/
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Start_Sample
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Start_Sample (void)
{
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_start_stream (StreamHandle);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Stop_Sample
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Stop_Sample (void)
{
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_pause_stream (StreamHandle, 1);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Resume_Sample
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Resume_Sample (void)
{
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_pause_stream (StreamHandle, 0);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// End_Sample
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::End_Sample (void)
{
//
// Stop the sample and then release our hold on the stream handle
//
Stop_Sample ();
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_close_stream (StreamHandle);
StreamHandle = (HSTREAM)INVALID_MILES_HANDLE;
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Pan
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Set_Sample_Pan (S32 pan)
{
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_set_stream_pan (StreamHandle, pan);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Pan
//
//////////////////////////////////////////////////////////////////////
S32
SoundStreamHandleClass::Get_Sample_Pan (void)
{
S32 retval = 0;
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
retval = ::AIL_stream_pan (StreamHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Volume
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Set_Sample_Volume (S32 volume)
{
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_set_stream_volume (StreamHandle, volume);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Volume
//
//////////////////////////////////////////////////////////////////////
S32
SoundStreamHandleClass::Get_Sample_Volume (void)
{
S32 retval = 0;
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
retval = ::AIL_stream_volume (StreamHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Loop_Count
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Set_Sample_Loop_Count (U32 count)
{
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_set_stream_loop_block (StreamHandle, 0, -1);
::AIL_set_stream_loop_count (StreamHandle, count);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Loop_Count
//
//////////////////////////////////////////////////////////////////////
U32
SoundStreamHandleClass::Get_Sample_Loop_Count (void)
{
U32 retval = 0;
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_stream_loop_count (StreamHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_MS_Position
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Set_Sample_MS_Position (U32 ms)
{
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_set_stream_ms_position (StreamHandle, ms);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_MS_Position
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Get_Sample_MS_Position (S32 *len, S32 *pos)
{
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_stream_ms_position (StreamHandle, len, pos);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_User_Data
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Set_Sample_User_Data (S32 i, U32 val)
{
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
::AIL_set_sample_user_data (SampleHandle, i, val);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_User_Data
//
//////////////////////////////////////////////////////////////////////
U32
SoundStreamHandleClass::Get_Sample_User_Data (S32 i)
{
U32 retval = 0;
if (SampleHandle != (HSAMPLE)INVALID_MILES_HANDLE) {
retval = ::AIL_sample_user_data (SampleHandle, i);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Get_Sample_Playback_Rate
//
//////////////////////////////////////////////////////////////////////
S32
SoundStreamHandleClass::Get_Sample_Playback_Rate (void)
{
S32 retval = 0;
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
retval = ::AIL_stream_playback_rate (StreamHandle);
}
return retval;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Sample_Playback_Rate
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Set_Sample_Playback_Rate (S32 rate)
{
if (StreamHandle != (HSTREAM)INVALID_MILES_HANDLE) {
::AIL_set_stream_playback_rate (StreamHandle, rate);
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Set_Miles_Handle
//
//////////////////////////////////////////////////////////////////////
void
SoundStreamHandleClass::Set_Miles_Handle (uint32 handle)
{
SampleHandle = (HSAMPLE)handle;
return ;
}

View file

@ -0,0 +1,114 @@
/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwaudio *
* *
* $Archive:: /Commando/Code/WWAudio/soundstreamhandle.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/13/01 3:10p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SOUNDSTREAMHANDLE_H
#define __SOUNDSTREAMHANDLE_H
#include "soundhandle.h"
//////////////////////////////////////////////////////////////////////
//
// SoundStreamHandleClass
//
//////////////////////////////////////////////////////////////////////
class SoundStreamHandleClass : public SoundHandleClass
{
public:
///////////////////////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////////////////////
SoundStreamHandleClass (void);
~SoundStreamHandleClass (void);
///////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////
//
// RTTI
//
SoundStreamHandleClass * As_SoundStreamHandleClass (void) { return this; }
//
// Handle access
//
HSAMPLE Get_HSAMPLE (void) { return SampleHandle; }
HSTREAM Get_HSTREAM (void) { return StreamHandle; }
//
// Inherited
//
void Set_Miles_Handle (uint32 handle);
void Initialize (SoundBufferClass *buffer);
void Start_Sample (void);
void Stop_Sample (void);
void Resume_Sample (void);
void End_Sample (void);
void Set_Sample_Pan (S32 pan);
S32 Get_Sample_Pan (void);
void Set_Sample_Volume (S32 volume);
S32 Get_Sample_Volume (void);
void Set_Sample_Loop_Count (U32 count);
U32 Get_Sample_Loop_Count (void);
void Set_Sample_MS_Position (U32 ms);
void Get_Sample_MS_Position (S32 *len, S32 *pos);
void Set_Sample_User_Data (S32 i, U32 val);
U32 Get_Sample_User_Data (S32 i);
S32 Get_Sample_Playback_Rate (void);
void Set_Sample_Playback_Rate (S32 rate);
protected:
///////////////////////////////////////////////////////////////////
// Protected methods
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Protected member data
///////////////////////////////////////////////////////////////////
HSAMPLE SampleHandle;
HSTREAM StreamHandle;
};
#endif //__SOUNDSTREAMHANDLE_H