| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894 |
- /*
- ** 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/agg_def.cpp $*
- * *
- * Author:: Patrick Smith
- * *
- * $Modtime:: 4/05/01 10:21a $*
- * *
- * $Revision:: 5 $*
- * *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "agg_def.h"
- #include "htree.h"
- #include "w3derr.h"
- #include "chunkio.h"
- #include "wwdebug.h"
- #include "assetmgr.h"
- #include "matinfo.h"
- #include "texture.h"
- #include "wwstring.h"
- #include <windows.h>
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Local constants
- //
- const char * const EMPTY_STRING = "";
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Global variable initialization
- //
- AggregateLoaderClass _AggregateLoader;
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // AggregateDefClass
- //
- AggregateDefClass::AggregateDefClass (void)
- : m_pName (NULL)
- {
- // Set our member data to default settings
- ::memset (&m_Info, 0, sizeof (m_Info));
- ::memset (&m_MiscInfo, 0, sizeof (m_MiscInfo));
- m_MiscInfo.OriginalClassID = RenderObjClass::CLASSID_HLOD;
- return ;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // AggregateDefClass
- //
- AggregateDefClass::AggregateDefClass (const AggregateDefClass &src)
- : m_pName (NULL)
- {
- // Set our member data to default settings
- ::memset (&m_Info, 0, sizeof (m_Info));
- ::memset (&m_MiscInfo, 0, sizeof (m_MiscInfo));
- m_MiscInfo.OriginalClassID = RenderObjClass::CLASSID_HLOD;
- // Invoke the assignment operator
- (*this) = src;
- return ;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // AggregateDefClass
- //
- AggregateDefClass::AggregateDefClass (RenderObjClass &base_model)
- : m_pName (NULL)
- {
- // Set our member data to default settings
- ::memset (&m_Info, 0, sizeof (m_Info));
- ::memset (&m_MiscInfo, 0, sizeof (m_MiscInfo));
- m_MiscInfo.OriginalClassID = RenderObjClass::CLASSID_HLOD;
- Initialize (base_model);
- return ;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // ~AggregateDefClass
- //
- AggregateDefClass::~AggregateDefClass (void)
- {
- // Free the name buffer if necessary
- if (m_pName != NULL) {
-
- // free() is used because the buffer was allocated with ::_strdup().
- ::free (m_pName);
- m_pName = NULL;
- }
- Free_Subobject_List ();
- return ;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // operator=
- //
- const AggregateDefClass &
- AggregateDefClass::operator= (const AggregateDefClass &src)
- {
- int index;
- // Free the name buffer if necessary
- if (m_pName != NULL) {
- ::free (m_pName);
- m_pName = NULL;
- }
- // Start with a fresh set of data
- Free_Subobject_List ();
- // Copy the src object's name and info struct
- Set_Name (src.Get_Name ());
- ::memcpy (&m_Info, &src.m_Info, sizeof (m_Info));
- ::memcpy (&m_MiscInfo, &src.m_MiscInfo, sizeof (m_MiscInfo));
- m_Version = src.m_Version;
- // Loop through all the entries in the src object's subobj list
- for (index = 0; index < src.m_SubobjectList.Count (); index ++) {
- W3dAggregateSubobjectStruct *pinfo = src.m_SubobjectList[index];
- if (pinfo != NULL) {
- // Copy the src object's info for this subobj
- W3dAggregateSubobjectStruct *new_info = new W3dAggregateSubobjectStruct;
- ::memcpy (new_info, pinfo, sizeof (W3dAggregateSubobjectStruct));
- // Add this subobj to our list
- m_SubobjectList.Add (new_info);
- }
- }
- // Return a reference to ourselves
- return *this;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Free_Subobject_List
- //
- void
- AggregateDefClass::Free_Subobject_List (void)
- {
- // Delete all the stucture pointers contained in the subobject list
- for (int index = 0; index < m_SubobjectList.Count (); index ++) {
- W3dAggregateSubobjectStruct *pinfo = m_SubobjectList[index];
- if (pinfo) {
- delete pinfo;
- }
- }
- // Reset the lists contents
- m_SubobjectList.Delete_All ();
- return ;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Create
- //
- RenderObjClass *
- AggregateDefClass::Create (void)
- {
- // Attempt to create an instance of the hierarchy
- RenderObjClass *pmodel = Create_Render_Object (m_Info.BaseModelName);
- if (pmodel != NULL) {
-
- // Perform the aggregation
- Attach_Subobjects (*pmodel);
- // Let the new object know what its new name and base name are.
- pmodel->Set_Name (m_pName);
- pmodel->Set_Base_Model_Name (m_Info.BaseModelName);
- pmodel->Set_Sub_Objects_Match_LOD ((m_MiscInfo.Flags & W3D_AGGREGATE_FORCE_SUB_OBJ_LOD) == W3D_AGGREGATE_FORCE_SUB_OBJ_LOD);
- } else {
- WWDEBUG_SAY (("Unable to load aggregate %s.\r\n", m_Info.BaseModelName));
- }
- // Return a pointer to the new aggregate
- return pmodel;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Find_Subobject
- //
- RenderObjClass *
- AggregateDefClass::Find_Subobject
- (
- RenderObjClass &model,
- const char mesh_path[MESH_PATH_ENTRIES][MESH_PATH_ENTRY_LEN],
- const char bone_path[MESH_PATH_ENTRIES][MESH_PATH_ENTRY_LEN]
- )
- {
- RenderObjClass *parent_model = &model;
- parent_model->Add_Ref ();
-
- // Loop through all the models in our "path" until we've either failed
- // or found the exact mesh we were looking for...
- for (int index = 1;
- (mesh_path[index][0] != 0) && (parent_model != NULL);
- index ++) {
- // Look one level deeper into the subobject chain...
- RenderObjClass *sub_obj = NULL;
- if (bone_path[index][0] == 0) {
- sub_obj = parent_model->Get_Sub_Object_By_Name (mesh_path[index]);
- } else {
-
- int bone_index = parent_model->Get_Bone_Index (bone_path[index]);
- int subobj_count = parent_model->Get_Num_Sub_Objects_On_Bone (bone_index);
-
- // Loop through all the subobjects on this bone
- for (int subobj_index = 0; (subobj_index < subobj_count) && (sub_obj == NULL); subobj_index ++) {
-
- // Is this the subobject we were looking for?
- RenderObjClass *ptemp_obj = parent_model->Get_Sub_Object_On_Bone (subobj_index, bone_index);
- if (::lstrcmpi (ptemp_obj->Get_Name (), mesh_path[index]) == 0) {
- sub_obj = ptemp_obj;
- } else {
- REF_PTR_RELEASE (ptemp_obj);
- }
- }
- }
- REF_PTR_RELEASE (parent_model);
- // The parent for the next iteration is the subobject on this one.
- parent_model = sub_obj;
- }
- // Return a pointer to the subobject
- return parent_model;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Attach_Subobjects
- //
- void
- AggregateDefClass::Attach_Subobjects (RenderObjClass &base_model)
- {
- // Now loop through all the subobjects and attach them to the appropriate bone
- for (int index = 0; index < m_SubobjectList.Count (); index ++) {
- W3dAggregateSubobjectStruct *psubobj_info = m_SubobjectList[index];
- if (psubobj_info != NULL) {
-
- // Now create this subobject and attach it to its bone.
- RenderObjClass *prender_obj = Create_Render_Object (psubobj_info->SubobjectName);
- if (prender_obj != NULL) {
- // Attach this object to the requested bone
- if (base_model.Add_Sub_Object_To_Bone (prender_obj, psubobj_info->BoneName) == false) {
- WWDEBUG_SAY (("Unable to attach %s to %s.\r\n", psubobj_info->SubobjectName, psubobj_info->BoneName));
- }
- // Release our hold on this pointer
- prender_obj->Release_Ref ();
- } else {
- WWDEBUG_SAY (("Unable to load aggregate subobject %s.\r\n", psubobj_info->SubobjectName));
- }
- }
- }
-
- return ;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Create_Render_Object
- //
- RenderObjClass *
- AggregateDefClass::Create_Render_Object (const char *passet_name)
- {
- // Assume failure
- RenderObjClass *prender_obj = NULL;
- // Attempt to get an instance of the render object from the asset manager
- prender_obj = WW3DAssetManager::Get_Instance()->Create_Render_Obj (passet_name);
-
- // If we couldn't find the render object in the asset manager, then attempt to
- // load it from file
- if ((prender_obj == NULL) &&
- Load_Assets (passet_name)) {
- // It should be in the asset manager now, so attempt to get it again.
- prender_obj = WW3DAssetManager::Get_Instance()->Create_Render_Obj (passet_name);
- }
-
- // Return a pointer to the render object
- return prender_obj;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Load_Assets
- //
- bool
- AggregateDefClass::Load_Assets (const char *passet_name)
- {
- // Assume failure
- bool retval = false;
- // Param OK?
- if (passet_name != NULL) {
-
- // Determine what the current working directory is
- char path[MAX_PATH];
- ::GetCurrentDirectory (sizeof (path), path);
- // Ensure the path is directory delimited
- if (path[::lstrlen(path)-1] != '\\') {
- ::lstrcat (path, "\\");
- }
- // Assume the filename is simply the "asset name" + the w3d extension
- ::lstrcat (path, passet_name);
- ::lstrcat (path, ".w3d");
- // If the file exists, then load it into the asset manager.
- if (::GetFileAttributes (path) != 0xFFFFFFFF) {
- retval = WW3DAssetManager::Get_Instance()->Load_3D_Assets (path);
- }
- }
- // Return the true/false result code
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Initialize
- //
- void
- AggregateDefClass::Initialize (RenderObjClass &base_model)
- {
- // Start with fresh lists
- Free_Subobject_List ();
- // Determine what the render objects original name was.
- const char *orig_model_name = base_model.Get_Base_Model_Name ();
- orig_model_name = (orig_model_name == NULL) ? base_model.Get_Name () : orig_model_name;
- // Record information about this base model
- ::lstrcpy (m_Info.BaseModelName, orig_model_name);
- m_Info.SubobjectCount = 0;
- m_MiscInfo.OriginalClassID = base_model.Class_ID ();
- m_MiscInfo.Flags = 0;
- m_MiscInfo.Flags |= base_model.Is_Sub_Objects_Match_LOD_Enabled () ? W3D_AGGREGATE_FORCE_SUB_OBJ_LOD : 0;
-
- // Pass the aggregate name along
- Set_Name (base_model.Get_Name ());
- // Create a new instance of the model which we can use
- // to compare with the supplied model and determine
- // which 'bones-models' and textures are new.
- RenderObjClass *pvanilla_model = (RenderObjClass *)Create_Render_Object (orig_model_name);
- // Build lists of changes from the delta between the original model and the provided one
- Build_Subobject_List (*pvanilla_model, base_model);
- // Release the model if necessary
- REF_PTR_RELEASE (pvanilla_model);
- return ;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Build_Subobject_List
- //
- void
- AggregateDefClass::Build_Subobject_List
- (
- RenderObjClass &original_model,
- RenderObjClass &model
- )
- {
- int index;
- // Loop through all the bones in this render obj
- int bone_count = model.Get_Num_Bones ();
- for (int bone_index = 0; bone_index < bone_count; bone_index ++) {
- const char *pbone_name = model.Get_Bone_Name (bone_index);
-
- // Build a list of nodes that are contained in the vanilla model
- DynamicVectorClass <RenderObjClass *> orig_node_list;
- for (index = 0;
- index < original_model.Get_Num_Sub_Objects_On_Bone (bone_index);
- index ++) {
- RenderObjClass *psubobj = original_model.Get_Sub_Object_On_Bone (index, bone_index);
- if (psubobj != NULL) {
- orig_node_list.Add (psubobj);
- }
- }
- // Build a list of nodes that are contained in this bone
- DynamicVectorClass <RenderObjClass *> node_list;
- for (index = 0;
- index < model.Get_Num_Sub_Objects_On_Bone (bone_index);
- index ++) {
- RenderObjClass *psubobj = model.Get_Sub_Object_On_Bone (index, bone_index);
- if (psubobj != NULL) {
- node_list.Add (psubobj);
- }
- }
- int node_count = node_list.Count ();
- if (node_count > 0) {
-
- // Loop through the subobjects and add each one to our internal list
- W3dAggregateSubobjectStruct subobj_info = { 0 };
- for (int node_index = 0; node_index < node_count; node_index ++) {
- RenderObjClass *psubobject = node_list[node_index];
- WWASSERT (psubobject != NULL);
-
- // Is this subobject new? (i.e. not in a 'vanilla' instance?)
- const char *prototype_name = psubobject->Get_Name ();
- if (psubobject != NULL &&
- (Is_Object_In_List (prototype_name, orig_node_list) == false)) {
-
- // Add this subobject to our list
- ::lstrcpy (subobj_info.SubobjectName, prototype_name);
- ::lstrcpy (subobj_info.BoneName, pbone_name);
- Add_Subobject (subobj_info);
- m_Info.SubobjectCount ++;
- // Attach this render object to the 'original' model (this is done
- // so we can do texture compares later)
- RenderObjClass *prender_obj = WW3DAssetManager::Get_Instance ()->Create_Render_Obj (prototype_name);
- ((RenderObjClass &)original_model).Add_Sub_Object_To_Bone (prender_obj, pbone_name);
- REF_PTR_RELEASE (prender_obj);
- }
- }
- }
- // Free our hold on the render objs in the original node list
- for (index = 0; index < orig_node_list.Count (); index ++) {
- REF_PTR_RELEASE (orig_node_list[index]);
- }
- orig_node_list.Delete_All ();
- // Free our hold on the render objs in the node list
- for (index = 0; index < node_list.Count (); index ++) {
- REF_PTR_RELEASE (node_list[index]);
- }
- node_list.Delete_All ();
- }
- return ;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Is_Object_In_List
- //
- bool
- AggregateDefClass::Is_Object_In_List
- (
- const char *passet_name,
- DynamicVectorClass <RenderObjClass *> &node_list
- )
- {
- // Assume failure
- bool retval = false;
- // Loop through the nodes in the list until we've found the one
- // were are looking for.
- for (int node_index = 0; (node_index < node_list.Count ()) && (retval == false); node_index ++) {
- RenderObjClass *prender_obj = node_list[node_index];
-
- // Is this the render object we were looking for?
- if (prender_obj != NULL &&
- ::lstrcmpi (prender_obj->Get_Name (), passet_name) == 0) {
- retval = true;
- }
- }
- // Return the true/false result code
- return retval;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Load
- //
- WW3DErrorType
- AggregateDefClass::Load_W3D (ChunkLoadClass &chunk_load)
- {
- W3dTextureReplacerHeaderStruct header = { 0 };
-
- while (chunk_load.Open_Chunk()) {
- WW3DErrorType error = WW3D_ERROR_OK;
- switch (chunk_load.Cur_Chunk_ID()) {
- case W3D_CHUNK_AGGREGATE_HEADER:
- error = Read_Header(chunk_load);
- break;
- case W3D_CHUNK_AGGREGATE_INFO:
- error = Read_Info(chunk_load);
- break;
- case W3D_CHUNK_TEXTURE_REPLACER_INFO:
- if (chunk_load.Read (&header, sizeof (header)) == sizeof (header)) {
- if (header.ReplacedTexturesCount > 0) {
- WWDEBUG_SAY(("Obsolete texture replacement chunk encountered in aggregate: %s\r\n",m_pName));
- }
- }
- break;
- case W3D_CHUNK_AGGREGATE_CLASS_INFO:
- error = Read_Class_Info(chunk_load);
- break;
- default:
-
- // Unknown chunk.
- break;
- }
- chunk_load.Close_Chunk();
- if (error != WW3D_ERROR_OK) return (error);
- }
-
- return WW3D_ERROR_OK;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Read_Header
- //
- WW3DErrorType
- AggregateDefClass::Read_Header (ChunkLoadClass &chunk_load)
- {
- // Assume error
- WW3DErrorType ret_val = WW3D_ERROR_LOAD_FAILED;
- // Is this the header chunk?
- W3dAggregateHeaderStruct header = { 0 };
- if (chunk_load.Read (&header, sizeof (header)) == sizeof (header)) {
- // Copy the name from the header structure
- m_pName = ::_strdup (header.Name);
- m_Version = header.Version;
- // Success!
- ret_val = WW3D_ERROR_OK;
- }
- // Return the WW3D_ERROR_TYPE return code
- return ret_val;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Read_Info
- //
- WW3DErrorType
- AggregateDefClass::Read_Info (ChunkLoadClass &chunk_load)
- {
- // Assume error
- WW3DErrorType ret_val = WW3D_ERROR_LOAD_FAILED;
- // Read the chunk straight into our member structure
- ::memset (&m_Info, 0, sizeof (m_Info));
- if (chunk_load.Read (&m_Info, sizeof (m_Info)) == sizeof (m_Info)) {
- // Success!
- ret_val = WW3D_ERROR_OK;
- // Read all the subobjects from the file
- for (UINT isubobject = 0;
- (isubobject < m_Info.SubobjectCount) && (ret_val == WW3D_ERROR_OK);
- isubobject ++) {
- // Read this subobject's definition from the file
- ret_val = Read_Subobject (chunk_load);
- }
- }
- // Return the WW3D_ERROR_TYPE return code
- return ret_val;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Read_Subobject
- //
- WW3DErrorType
- AggregateDefClass::Read_Subobject (ChunkLoadClass &chunk_load)
- {
- // Assume error
- WW3DErrorType ret_val = WW3D_ERROR_LOAD_FAILED;
- // Read the subobject information from the file
- W3dAggregateSubobjectStruct subobj_info = { 0 };
- if (chunk_load.Read (&subobj_info, sizeof (subobj_info)) == sizeof (subobj_info)) {
- // Add this subobject to our list
- Add_Subobject (subobj_info);
- // Success!
- ret_val = WW3D_ERROR_OK;
- }
- // Return the WW3D_ERROR_TYPE return code
- return ret_val;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Add_Subobject
- //
- void
- AggregateDefClass::Add_Subobject (const W3dAggregateSubobjectStruct &subobj_info)
- {
- // Create a new structure and copy the contents of the src
- W3dAggregateSubobjectStruct *pnew_entry = new W3dAggregateSubobjectStruct;
- ::lstrcpy (pnew_entry->SubobjectName, subobj_info.SubobjectName);
- ::lstrcpy (pnew_entry->BoneName, subobj_info.BoneName);
- // Add this new entry to the list
- m_SubobjectList.Add (pnew_entry);
- return ;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Read_Class_Info
- //
- WW3DErrorType
- AggregateDefClass::Read_Class_Info (ChunkLoadClass &chunk_load)
- {
- // Assume error
- WW3DErrorType ret_val = WW3D_ERROR_LOAD_FAILED;
- // Read the chunk straight into our header structure
- ::memset (&m_MiscInfo, 0, sizeof (m_MiscInfo));
- if (chunk_load.Read (&m_MiscInfo, sizeof (m_MiscInfo)) == sizeof (m_MiscInfo)) {
- // Success!
- ret_val = WW3D_ERROR_OK;
- }
- // Return the WW3D_ERROR_TYPE return code
- return ret_val;
- }
- //////////////////////////////////////////////////////////////////////////////////
- //
- // Save
- //
- WW3DErrorType
- AggregateDefClass::Save_W3D (ChunkSaveClass &chunk_save)
- {
- // Assume error
- WW3DErrorType ret_val = WW3D_ERROR_SAVE_FAILED;
- // Begin a chunk that identifies an aggregate
- if (chunk_save.Begin_Chunk (W3D_CHUNK_AGGREGATE) == TRUE) {
-
- // Attempt to save the different sections of the aggregate definition
- if ((Save_Header (chunk_save) == WW3D_ERROR_OK) &&
- (Save_Info (chunk_save) == WW3D_ERROR_OK) &&
- (Save_Class_Info (chunk_save) == WW3D_ERROR_OK)) {
-
- // Success!
- ret_val = WW3D_ERROR_OK;
- }
- // Close the aggregate chunk
- chunk_save.End_Chunk ();
- }
- // Return the WW3D_ERROR_TYPE return code
- return ret_val;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Save_Header
- //
- WW3DErrorType
- AggregateDefClass::Save_Header (ChunkSaveClass &chunk_save)
- {
- // Assume error
- WW3DErrorType ret_val = WW3D_ERROR_SAVE_FAILED;
- // Begin a chunk that identifies the aggregate
- if (chunk_save.Begin_Chunk (W3D_CHUNK_AGGREGATE_HEADER) == TRUE) {
-
- // Fill the header structure
- W3dAggregateHeaderStruct header = { 0 };
- header.Version = W3D_CURRENT_AGGREGATE_VERSION;
- ::lstrcpyn (header.Name, m_pName, sizeof (header.Name));
- header.Name[sizeof (header.Name) - 1] = 0;
- // Write the header out to the chunk
- if (chunk_save.Write (&header, sizeof (header)) == sizeof (header)) {
- // Success!
- ret_val = WW3D_ERROR_OK;
- }
- // End the header chunk
- chunk_save.End_Chunk ();
- }
- // Return the WW3D_ERROR_TYPE return code
- return ret_val;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Save_Info
- //
- WW3DErrorType
- AggregateDefClass::Save_Info (ChunkSaveClass &chunk_save)
- {
- // Assume error
- WW3DErrorType ret_val = WW3D_ERROR_SAVE_FAILED;
- // Begin a chunk that identifies the aggregate settings
- if (chunk_save.Begin_Chunk (W3D_CHUNK_AGGREGATE_INFO) == TRUE) {
-
- // Write the settings structure out to the chunk
- if (chunk_save.Write (&m_Info, sizeof (m_Info)) == sizeof (m_Info)) {
- // Success!
- ret_val = WW3D_ERROR_OK;
- // Write all the subobjects to the file
- for (int isubobject = 0;
- (isubobject < m_SubobjectList.Count ()) && (ret_val == WW3D_ERROR_OK);
- isubobject ++) {
- // Write this object to the file
- ret_val = Save_Subobject (chunk_save, m_SubobjectList[isubobject]);
- }
- }
- // End the settings chunk
- chunk_save.End_Chunk ();
- }
- // Return the WW3D_ERROR_TYPE return code
- return ret_val;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Save_Subobject
- //
- WW3DErrorType
- AggregateDefClass::Save_Subobject
- (
- ChunkSaveClass &chunk_save,
- W3dAggregateSubobjectStruct *psubobject
- )
- {
- // Assume error
- WW3DErrorType ret_val = WW3D_ERROR_SAVE_FAILED;
- // Write the subobj structure out to the chunk
- if (chunk_save.Write (psubobject, sizeof (W3dAggregateSubobjectStruct)) == sizeof (W3dAggregateSubobjectStruct)) {
- // Success!
- ret_val = WW3D_ERROR_OK;
- }
- // Return the WW3D_ERROR_TYPE return code
- return ret_val;
- }
- /////////////////////////////////////////////////////////////////////////////////
- //
- // Save_Class_Info
- //
- WW3DErrorType
- AggregateDefClass::Save_Class_Info (ChunkSaveClass &chunk_save)
- {
- // Assume error
- WW3DErrorType ret_val = WW3D_ERROR_SAVE_FAILED;
- // Begin a chunk that identifies the texture replacer header
- if (chunk_save.Begin_Chunk (W3D_CHUNK_AGGREGATE_CLASS_INFO) == TRUE) {
-
- // Write the class information structure out to the chunk
- if (chunk_save.Write (&m_MiscInfo, sizeof (m_MiscInfo)) == sizeof (m_MiscInfo)) {
-
- // Success!
- ret_val = WW3D_ERROR_OK;
- }
- // End the class info chunk
- chunk_save.End_Chunk ();
- }
- // Return the WW3D_ERROR_TYPE return code
- return ret_val;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- //
- // Load
- //
- PrototypeClass *
- AggregateLoaderClass::Load_W3D (ChunkLoadClass &chunk_load)
- {
- // Assume failure
- AggregatePrototypeClass *pprototype = NULL;
- // Create a definition object
- AggregateDefClass *pdefinition = new AggregateDefClass;
- if (pdefinition != NULL) {
-
- // Ask the definition object to load the aggregate data
- if (pdefinition->Load_W3D (chunk_load) != WW3D_ERROR_OK) {
-
- // Error! Free the definition
- delete pdefinition;
- pdefinition = NULL;
- } else {
- // Success! Create a prototype from the definition
- pprototype = new AggregatePrototypeClass (pdefinition);
- }
- }
- // Return a pointer to the prototype
- return pprototype;
- }
|