768 lines
19 KiB
C++
768 lines
19 KiB
C++
/*
|
|
** Command & Conquer Renegade(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 : WW3D *
|
|
* *
|
|
* $Archive:: /Commando/Code/ww3d2/soundrobj.cpp $*
|
|
* *
|
|
* Author:: Patrick Smith *
|
|
* *
|
|
* $Modtime:: 1/16/02 10:21a $*
|
|
* *
|
|
* $Revision:: 4 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
#include "soundrobj.h"
|
|
#include "audiblesound.h"
|
|
#include "sound3d.h"
|
|
#include "wwaudio.h"
|
|
#include "ffactory.h"
|
|
#include "wwfile.h"
|
|
#include "chunkio.h"
|
|
#include "scene.h"
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
// Global variables
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
SoundRenderObjLoaderClass _SoundRenderObjLoader;
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SoundRenderObjClass
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
SoundRenderObjClass::SoundRenderObjClass (void)
|
|
: Flags (FLAG_STOP_WHEN_HIDDEN),
|
|
Sound (NULL),
|
|
IsInitialized (false)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SoundRenderObjClass
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
SoundRenderObjClass::SoundRenderObjClass (const SoundRenderObjClass &src)
|
|
: Flags (FLAG_STOP_WHEN_HIDDEN),
|
|
Sound (NULL),
|
|
IsInitialized (false)
|
|
{
|
|
(*this) = src;
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ~SoundRenderObjClass
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
SoundRenderObjClass::~SoundRenderObjClass (void)
|
|
{
|
|
//
|
|
// Remove the old sound from the world (if necessary)
|
|
//
|
|
if (Sound != NULL) {
|
|
Sound->Attach_To_Object (NULL);
|
|
Sound->Remove_From_Scene ();
|
|
REF_PTR_RELEASE (Sound);
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// operator=
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
const SoundRenderObjClass &
|
|
SoundRenderObjClass::operator= (const SoundRenderObjClass &src)
|
|
{
|
|
//
|
|
// Create a definition from the src sound object
|
|
//
|
|
AudibleSoundDefinitionClass definition;
|
|
definition.Initialize_From_Sound (src.Sound);
|
|
|
|
//
|
|
// Create the internal sound object from the definition
|
|
//
|
|
Set_Sound (&definition);
|
|
|
|
//
|
|
// Copy the other misc settings
|
|
//
|
|
Name = src.Name;
|
|
return *this;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set_Sound
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Set_Sound (AudibleSoundDefinitionClass *definition)
|
|
{
|
|
//
|
|
// Remove the old sound from the world (if necessary)
|
|
//
|
|
if (Sound != NULL) {
|
|
Sound->Remove_From_Scene ();
|
|
REF_PTR_RELEASE (Sound);
|
|
}
|
|
|
|
//
|
|
// Create the sound object from its definition
|
|
//
|
|
if (definition != NULL) {
|
|
Sound = (AudibleSoundClass *)definition->Create ();
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// On_Frame_Update
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::On_Frame_Update (void)
|
|
{
|
|
//
|
|
// Stop the sound from playing (if necessary)
|
|
//
|
|
if ( Sound != NULL &&
|
|
Sound->Is_In_Scene () &&
|
|
Sound->Is_Playing () == false)
|
|
{
|
|
Sound->Attach_To_Object (NULL);
|
|
Sound->Remove_From_Scene ();
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set_Hidden
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Set_Hidden (int onoff)
|
|
{
|
|
int before = Is_Not_Hidden_At_All ();
|
|
RenderObjClass::Set_Hidden (onoff);
|
|
|
|
//
|
|
// If we've changed state, then update the visibility
|
|
//
|
|
if (IsInitialized == false || Is_Not_Hidden_At_All () != before) {
|
|
IsInitialized = true;
|
|
Update_On_Visibilty ();
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set_Visible
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Set_Visible (int onoff)
|
|
{
|
|
int before = Is_Not_Hidden_At_All ();
|
|
RenderObjClass::Set_Visible (onoff);
|
|
|
|
//
|
|
// If we've changed state, then update the visibility
|
|
//
|
|
if (IsInitialized == false || Is_Not_Hidden_At_All () != before) {
|
|
IsInitialized = true;
|
|
Update_On_Visibilty ();
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set_Animation_Hidden
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Set_Animation_Hidden (int onoff)
|
|
{
|
|
int before = Is_Not_Hidden_At_All ();
|
|
RenderObjClass::Set_Animation_Hidden (onoff);
|
|
|
|
//
|
|
// If we've changed state, then update the visibility
|
|
//
|
|
if (IsInitialized == false || Is_Not_Hidden_At_All () != before) {
|
|
IsInitialized = true;
|
|
Update_On_Visibilty ();
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set_Force_Visible
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Set_Force_Visible (int onoff)
|
|
{
|
|
int before = Is_Not_Hidden_At_All ();
|
|
RenderObjClass::Set_Force_Visible (onoff);
|
|
|
|
//
|
|
// If we've changed state, then update the visibility
|
|
//
|
|
if (IsInitialized == false || Is_Not_Hidden_At_All () != before) {
|
|
IsInitialized = true;
|
|
Update_On_Visibilty ();
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Update_On_Visibilty
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Update_On_Visibilty (void)
|
|
{
|
|
if (Sound == NULL) {
|
|
return ;
|
|
}
|
|
|
|
//
|
|
// Ensure our transform is correct
|
|
//
|
|
Validate_Transform ();
|
|
|
|
//
|
|
// Either add the sound object to the sound scene
|
|
// or remove it from the sound scene depending
|
|
// on the visibility state of the render object.
|
|
//
|
|
if ( Is_Not_Hidden_At_All () &&
|
|
Sound->Is_In_Scene () == false &&
|
|
Peek_Scene () != NULL)
|
|
{
|
|
//
|
|
// Make sure the sound is properly attached to this render
|
|
// object and then add it to the scene
|
|
//
|
|
Sound->Attach_To_Object (this);
|
|
Sound->Add_To_Scene (true);
|
|
|
|
} else if ((Is_Not_Hidden_At_All () == false) || (Peek_Scene () == NULL)) {
|
|
|
|
//
|
|
// Remove the sound from the scene (it will stop playing)
|
|
//
|
|
if ((Flags & FLAG_STOP_WHEN_HIDDEN) != 0 || (Peek_Scene () == NULL)) {
|
|
Sound->Attach_To_Object (NULL);
|
|
Sound->Remove_From_Scene ();
|
|
}
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Get_Sound
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
AudibleSoundClass *
|
|
SoundRenderObjClass::Get_Sound (void) const
|
|
{
|
|
if (Sound != NULL) {
|
|
Sound->Add_Ref ();
|
|
}
|
|
|
|
return Sound;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set_Flag
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Set_Flag (uint32 flag, bool onoff)
|
|
{
|
|
Flags &= ~flag;
|
|
if (onoff) {
|
|
Flags |= flag;
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Notify_Added
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Notify_Added (SceneClass *scene)
|
|
{
|
|
RenderObjClass::Notify_Added (scene);
|
|
scene->Register (this, SceneClass::ON_FRAME_UPDATE);
|
|
|
|
Update_On_Visibilty ();
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Notify_Removed
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Notify_Removed (SceneClass *scene)
|
|
{
|
|
scene->Unregister (this, SceneClass::ON_FRAME_UPDATE);
|
|
RenderObjClass::Notify_Removed (scene);
|
|
|
|
Update_On_Visibilty ();
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set_Transform
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Set_Transform (const Matrix3D &tm)
|
|
{
|
|
RenderObjClass::Set_Transform (tm);
|
|
|
|
if (IsInitialized == false) {
|
|
IsInitialized = true;
|
|
Update_On_Visibilty ();
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Set_Position
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjClass::Set_Position (const Vector3 &pos)
|
|
{
|
|
RenderObjClass::Set_Position (pos);
|
|
|
|
if (IsInitialized == false) {
|
|
IsInitialized = true;
|
|
Update_On_Visibilty ();
|
|
}
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
//*********************************************************************************
|
|
//
|
|
// Start of SoundRenderObjDefClass
|
|
//
|
|
//*********************************************************************************
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SoundRenderObjDefClass
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
SoundRenderObjDefClass::SoundRenderObjDefClass (void)
|
|
: Version (W3D_CURRENT_SOUNDROBJ_VERSION),
|
|
Flags (SoundRenderObjClass::FLAG_STOP_WHEN_HIDDEN)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SoundRenderObjDefClass
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
SoundRenderObjDefClass::SoundRenderObjDefClass (SoundRenderObjClass &render_obj)
|
|
: Version (W3D_CURRENT_SOUNDROBJ_VERSION),
|
|
Flags (SoundRenderObjClass::FLAG_STOP_WHEN_HIDDEN)
|
|
{
|
|
Initialize (render_obj);
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SoundRenderObjDefClass
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
SoundRenderObjDefClass::SoundRenderObjDefClass (const SoundRenderObjDefClass &src)
|
|
: Version (W3D_CURRENT_SOUNDROBJ_VERSION),
|
|
Flags (SoundRenderObjClass::FLAG_STOP_WHEN_HIDDEN)
|
|
{
|
|
(*this) = src;
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ~SoundRenderObjDefClass
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
SoundRenderObjDefClass::~SoundRenderObjDefClass (void)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// operator=
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
const SoundRenderObjDefClass &
|
|
SoundRenderObjDefClass::operator= (const SoundRenderObjDefClass &src)
|
|
{
|
|
Definition = src.Definition;
|
|
Version = src.Version;
|
|
Name = src.Name;
|
|
return (*this);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Create
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
RenderObjClass *
|
|
SoundRenderObjDefClass::Create (void)
|
|
{
|
|
//
|
|
// Allocate and initialize a new instance
|
|
//
|
|
SoundRenderObjClass *render_obj = new SoundRenderObjClass;
|
|
render_obj->Set_Name (Name);
|
|
render_obj->Set_Sound (&Definition);
|
|
render_obj->Set_Flags (Flags);
|
|
|
|
return render_obj;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Initialize
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
SoundRenderObjDefClass::Initialize (SoundRenderObjClass &render_obj)
|
|
{
|
|
//
|
|
// Copy the settings from the sound object into our definition
|
|
//
|
|
Definition.Initialize_From_Sound (render_obj.Peek_Sound ());
|
|
|
|
//
|
|
// Copy the flags from the render object
|
|
//
|
|
Flags = (SoundRenderObjClass::FLAGS)render_obj.Get_Flags ();
|
|
|
|
//
|
|
// Copy the name
|
|
//
|
|
Name = render_obj.Get_Name ();
|
|
return ;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Load
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
WW3DErrorType
|
|
SoundRenderObjDefClass::Load_W3D (ChunkLoadClass &cload)
|
|
{
|
|
WW3DErrorType retval = WW3D_ERROR_LOAD_FAILED;
|
|
|
|
//
|
|
// Attempt to read the different sections of the definition
|
|
//
|
|
if ((Read_Header (cload) == WW3D_ERROR_OK) &&
|
|
(Read_Definition (cload) == WW3D_ERROR_OK))
|
|
{
|
|
retval = WW3D_ERROR_OK;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Save_W3D
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
WW3DErrorType
|
|
SoundRenderObjDefClass::Save_W3D (ChunkSaveClass &csave)
|
|
{
|
|
WW3DErrorType retval = WW3D_ERROR_SAVE_FAILED;
|
|
|
|
//
|
|
// Begin a chunk that identifies a sound render object
|
|
//
|
|
if (csave.Begin_Chunk (W3D_CHUNK_SOUNDROBJ) == TRUE) {
|
|
|
|
//
|
|
// Attempt to save the different sections of the aggregate definition
|
|
//
|
|
if ((Write_Header (csave) == WW3D_ERROR_OK) &&
|
|
(Write_Definition (csave) == WW3D_ERROR_OK))
|
|
{
|
|
retval = WW3D_ERROR_OK;
|
|
}
|
|
|
|
csave.End_Chunk ();
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Read_Header
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
WW3DErrorType
|
|
SoundRenderObjDefClass::Read_Header (ChunkLoadClass &cload)
|
|
{
|
|
WW3DErrorType retval = WW3D_ERROR_LOAD_FAILED;
|
|
|
|
//
|
|
// Is this the header chunk?
|
|
//
|
|
if (cload.Open_Chunk () &&
|
|
(cload.Cur_Chunk_ID () == W3D_CHUNK_SOUNDROBJ_HEADER))
|
|
{
|
|
//
|
|
// Read the header from the chunk
|
|
//
|
|
W3dSoundRObjHeaderStruct header = { 0 };
|
|
if (cload.Read (&header, sizeof (header)) == sizeof (header)) {
|
|
|
|
//
|
|
// Copy the names from the header structure
|
|
//
|
|
Name = header.Name;
|
|
Version = header.Version;
|
|
Flags = (SoundRenderObjClass::FLAGS)header.Flags;
|
|
retval = WW3D_ERROR_OK;
|
|
}
|
|
|
|
cload.Close_Chunk ();
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Read_Definition
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
WW3DErrorType
|
|
SoundRenderObjDefClass::Read_Definition (ChunkLoadClass &cload)
|
|
{
|
|
WW3DErrorType retval = WW3D_ERROR_LOAD_FAILED;
|
|
|
|
//
|
|
// Is this the right chunk?
|
|
//
|
|
if (cload.Open_Chunk () &&
|
|
(cload.Cur_Chunk_ID () == W3D_CHUNK_SOUNDROBJ_DEFINITION))
|
|
{
|
|
//
|
|
// Ask the definition to load its settings from the chunk
|
|
//
|
|
if (Definition.Load (cload)) {
|
|
retval = WW3D_ERROR_OK;
|
|
}
|
|
|
|
cload.Close_Chunk ();
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Write_Header
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
WW3DErrorType
|
|
SoundRenderObjDefClass::Write_Header (ChunkSaveClass &csave)
|
|
{
|
|
WW3DErrorType retval = WW3D_ERROR_SAVE_FAILED;
|
|
|
|
//
|
|
// Begin a chunk that identifies the aggregate
|
|
//
|
|
if (csave.Begin_Chunk (W3D_CHUNK_SOUNDROBJ_HEADER) == TRUE) {
|
|
|
|
//
|
|
// Fill the header structure
|
|
//
|
|
W3dSoundRObjHeaderStruct header = { 0 };
|
|
header.Version = W3D_CURRENT_AGGREGATE_VERSION;
|
|
header.Flags = Flags;
|
|
::lstrcpyn (header.Name, (const char *)Name, sizeof (header.Name));
|
|
header.Name[sizeof (header.Name) - 1] = 0;
|
|
|
|
//
|
|
// Write the header out to the chunk
|
|
//
|
|
if (csave.Write (&header, sizeof (header)) == sizeof (header)) {
|
|
retval = WW3D_ERROR_OK;
|
|
}
|
|
|
|
// End the header chunk
|
|
csave.End_Chunk ();
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Write_Definition
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
WW3DErrorType
|
|
SoundRenderObjDefClass::Write_Definition (ChunkSaveClass &csave)
|
|
{
|
|
WW3DErrorType retval = WW3D_ERROR_SAVE_FAILED;
|
|
|
|
//
|
|
// Save the definition to its own chunk
|
|
//
|
|
if (csave.Begin_Chunk (W3D_CHUNK_SOUNDROBJ_DEFINITION) == TRUE) {
|
|
if (Definition.Save (csave)) {
|
|
retval = WW3D_ERROR_OK;
|
|
}
|
|
csave.End_Chunk ();
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
//*********************************************************************************
|
|
//
|
|
// Start of SoundRenderObjDefClass
|
|
//
|
|
//*********************************************************************************
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Load_W3D
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
PrototypeClass *
|
|
SoundRenderObjLoaderClass::Load_W3D (ChunkLoadClass &cload)
|
|
{
|
|
SoundRenderObjPrototypeClass *prototype = NULL;
|
|
|
|
//
|
|
// Create a definition object
|
|
//
|
|
SoundRenderObjDefClass *definition = new SoundRenderObjDefClass;
|
|
if (definition != NULL) {
|
|
|
|
//
|
|
// Ask the definition object to load the sound data
|
|
//
|
|
if (definition->Load_W3D (cload) == WW3D_ERROR_OK) {
|
|
|
|
//
|
|
// Success! Create a prototype from the definition
|
|
//
|
|
prototype = new SoundRenderObjPrototypeClass (definition);
|
|
}
|
|
|
|
REF_PTR_RELEASE (definition);
|
|
}
|
|
|
|
return prototype;
|
|
}
|
|
|
|
|