| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666 |
- /*
- ** 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 : LevelEdit *
- * *
- * $Archive:: /Commando/Code/Tools/LevelEdit/EditorAssetMgr.cpp $*
- * *
- * Author:: Patrick Smith *
- * *
- * $Modtime:: 1/29/02 3:16p $*
- * *
- * $Revision:: 29 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "stdafx.h"
- #include "editorassetmgr.h"
- #include "texture.h"
- #include "proto.h"
- #include "editorini.h"
- #include "ffactory.h"
- #include "ww3d.h"
- #include "utils.h"
- #include "filemgr.h"
- #include "rawfile.h"
- #include "rcfile.h"
- #include "filelocations.h"
- #include "editorbuild.h"
- #include "assetdatabase.h"
- ////////////////////////////////////////////////////////////////////////
- // Forward declarations
- ////////////////////////////////////////////////////////////////////////
- DynamicVectorClass<StringClass> EditorFileFactoryClass::SearchPathList;
- ////////////////////////////////////////////////////////////////////////
- //
- // EditorAssetMgrClass
- //
- ////////////////////////////////////////////////////////////////////////
- EditorAssetMgrClass::EditorAssetMgrClass (void)
- {
- Set_Activate_Fog_On_Load (true);
- m_CurrentDir = ::Get_Startup_Directory ();
- return ;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Reload_File
- //
- void
- EditorAssetMgrClass::Reload_File (const char *filename)
- {
- // Param OK?
- ASSERT (filename != NULL);
- if (filename != NULL) {
- CString extension = ::strrchr (filename, '.');
- // Is this a W3D file?
- if (extension.CompareNoCase (".W3D") == 0) {
- CString asset_name = ::Asset_Name_From_Filename (filename);
- Remove_Prototype (asset_name);
- Load_3D_Assets (filename);
- }
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Is_File_Here
- //
- ////////////////////////////////////////////////////////////////////////
- bool
- EditorAssetMgrClass::Is_File_Here (LPCTSTR full_path, bool get_from_vss)
- {
- //
- // Output this file lookup to the message window
- //
- CString message;
- message.Format ("Attempting to load: %s\r\n", full_path);
- ::Output_Message (message);
- //
- // Check to see if the file exists in this location
- //
- return ::Get_File_Mgr ()->Does_File_Exist (full_path, get_from_vss);
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Determine_Real_Location
- //
- ////////////////////////////////////////////////////////////////////////
- bool
- EditorAssetMgrClass::Determine_Real_Location
- (
- LPCTSTR path,
- CString & real_location
- )
- {
- bool retval = false;
- TCHAR full_path[MAX_PATH];
- //
- // Did the caller supply a path?
- //
- if (Is_Full_Path (path)) {
- ::lstrcpy (full_path, path);
- } else {
- //
- // Make a full path out of the filename
- //
- CString test_path = Make_Path (m_CurrentDir, path);
- //
- // If the file doesn't exist here, then try the search paths
- //
- if (::GetFileAttributes (test_path) == 0xFFFFFFFF) {
-
- //
- // Try to find the file in our search path list
- //
- DynamicVectorClass<StringClass> &path_list = EditorFileFactoryClass::Get_Search_Path ();
- for (int index = 0; index < path_list.Count (); index ++) {
-
- //
- // Does the file exist in this directoy?
- //
- StringClass full_path = Make_Path (path_list[index], path);
- if (::GetFileAttributes (full_path) != 0xFFFFFFFF) {
- test_path = full_path;
- break;
- }
- }
- }
- ::lstrcpy (full_path, test_path);
- }
- //
- // Find out if the file lives in the directory
- //
- if (Is_File_Here (full_path, true) == false) {
-
- //
- // Hmmm... not here, try up a directory level
- //
- CString parent_dir = ::Up_One_Directory (::Strip_Filename_From_Path (full_path));
- CString filename = ::Get_Filename_From_Path (full_path);
- parent_dir = ::Make_Path (parent_dir, filename);
- //
- // Does the file live in the parent directory?
- //
- if (Is_File_Here (parent_dir, true) == false) {
-
- //
- // Is this a texture file?
- //
- if (Is_Texture_Filename (full_path)) {
- #ifndef PUBLIC_EDITOR_VER
- //
- // Does the file live in the global texture directory?
- //
- CString texture_path = ::Make_Path (GLOBAL_TEXTURE_PATH, filename);
- if (Is_File_Here (texture_path, false)) {
- real_location = texture_path;
- retval = true;
- }
- #endif //!PUBLIC_EDITOR_VER
- } else if (::strnicmp ("h_a_", filename, 4) == 0) {
-
- //
- // We are 'assuming' this is a human animation file, so
- // try to find it in the human animation directory.
- //
- CString anim_path = ::Make_Path (CHAR_ANIMS_PATH, filename);
- if (Is_File_Here (anim_path, true)) {
- real_location = anim_path;
- retval = true;
- }
- }
- } else {
- real_location = parent_dir;
- retval = true;
- }
- } else {
- real_location = full_path;
- retval = true;
- }
- #ifdef PUBLIC_EDITOR_VER
-
- //
- // If the file does not exist locally, then use the one from the mix file
- //
- if (retval == false && ::Get_File_Mgr ()->Is_File_In_VSS (full_path)) {
- real_location = full_path;
- retval = true;
- }
- #endif //PUBLIC_EDITOR_VER
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Create_Render_Obj
- //
- RenderObjClass *
- EditorAssetMgrClass::Create_Render_Obj (const char * name)
- {
- // Let windows do some processing
- ::Pump_Messages ();
- // Assume failure
- RenderObjClass *prenderobj = NULL;
- // Try to find a prototype
- PrototypeClass * proto = Find_Prototype(name);
- if (WW3D_Load_On_Demand && proto == NULL) { // If we didn't find one, try to load on demand
- char filename[ MAX_PATH ];
- sprintf( filename, "%s.W3D", name);
- char *mesh_name = ::strchr (name, '.');
- if (mesh_name != NULL) {
- ::lstrcpyn (filename, name, ((int)mesh_name) - ((int)name) + 1);
- ::lstrcat (filename, ".W3D");
- } else {
- sprintf( filename, "%s.W3D", name);
- }
- // See if we can determine where this file exists
- CString real_location;
- if (Determine_Real_Location (filename, real_location)) {
- ::lstrcpy (filename, real_location);
- } else {
- TRACE ("Asset file not found!\n");
- }
- // Load the assets from this file into the manager
- Load_3D_Assets (filename);
- // Attempt to find the prototype loader now.
- proto = Find_Prototype (name);
- }
- // If we found a prototype for this object, then
- // use it to create a new instance of the requested asset.
- if (proto != NULL) {
- prenderobj = proto->Create ();
- }
- // Return a pointer to the render object
- return prenderobj;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Get_HAnim
- //
- HAnimClass *
- EditorAssetMgrClass::Get_HAnim (const char * name)
- {
- // Let windows do some processing
- ::Pump_Messages ();
- // Try to find the animation
- HAnimClass *panim = HAnimManager.Get_Anim(name);
- if (WW3D_Load_On_Demand && panim == NULL) { // If we didn't find it, try to load on demand
-
- char filename[ MAX_PATH ];
- char *animname = strchr( name, '.');
- if (animname != NULL) {
- sprintf( filename, "%s.W3D", animname+1);
- } else {
- TRACE ("Animation has no . in the name\n");
- return NULL;
- }
- // See if we can determine where this file exists
- CString real_location;
- if (Determine_Real_Location (filename, real_location)) {
- ::lstrcpy (filename, real_location);
- } else {
- TRACE ("Asset file not found!\n");
- }
- // Load the assets from this file into the manager
- Load_3D_Assets (filename);
- // Attempt to find the prototype loader now.
- panim = HAnimManager.Get_Anim(name);
- }
- // Return a pointer to the animation
- return panim;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Get_HTree
- //
- HTreeClass *
- EditorAssetMgrClass::Get_HTree (const char * name)
- {
- // Let windows do some processing
- ::Pump_Messages ();
- // Try to find the htree
- HTreeClass *phtree = HTreeManager.Get_Tree(name);
- if (WW3D_Load_On_Demand && phtree == NULL) { // If we didn't find it, try to load on demand
-
- char filename[ MAX_PATH ];
- sprintf( filename, "%s.W3D", name);
- // See if we can determine where this file exists
- CString real_location;
- if (Determine_Real_Location (filename, real_location)) {
- ::lstrcpy (filename, real_location);
- } else {
- TRACE ("Asset file not found!\n");
- }
- // Load the assets from this file into the manager
- Load_3D_Assets (filename);
- // Attempt to find the object loader now.
- phtree = HTreeManager.Get_Tree(name);
- }
- // Return a pointer to the animation
- return phtree;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Get_INI
- //
- EditorINIClass *
- EditorAssetMgrClass::Get_INI (const char *filename)
- {
- EditorINIClass *pini = NULL;
- FileClass * pini_file = _TheFileFactory->Get_File (filename);
- if (pini_file) {
- pini = new EditorINIClass (*pini_file);
- _TheFileFactory->Return_File (pini_file);
- }
- // Return a pointer to the INI file class
- return pini;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Get_Texture
- //
- ////////////////////////////////////////////////////////////////////////
- TextureClass *
- EditorAssetMgrClass::Get_Texture
- (
- const char * tga_filename,
- TextureClass::MipCountType mip_level_count,
- WW3DFormat texture_format,
- bool allow_compression
- )
- {
- //
- // Let windows do some processing
- //
- ::Pump_Messages ();
- /*
- ** Bail if the user isn't really asking for anything
- */
- if ((tga_filename == NULL) || (strlen(tga_filename) == 0)) {
- return NULL;
- }
- //
- // Determine what the texture's "name" should be
- //
- CString texture_name;
- if (::strstr (tga_filename, "+\\") != NULL) {
- texture_name = ::Get_Subdir_And_Filename_From_Path (tga_filename);
- } else {
- texture_name = ::Get_Filename_From_Path (tga_filename);
- }
- texture_name.MakeLower ();
- /*
- ** See if the texture has already been loaded.
- */
- TextureClass* tex = TextureHash.Get ((const char *)texture_name);
- if (tex && texture_format!=WW3D_FORMAT_UNKNOWN) {
- WWASSERT_PRINT(tex->Get_Texture_Format()==texture_format,("Texture %s has already been loaded witt different format",(const char *)texture_name));
- }
- /*
- ** Didn't have it so we have to create a new texture
- */
- if (!tex) {
- //
- // See if we can determine where this file exists
- //
- CString real_location;
- if (Determine_Real_Location (tga_filename, real_location) == false) {
- CString message;
- message.Format ("Texture file not found: %s\r\n", (LPCTSTR)texture_name);
- ::Output_Message (message);
- real_location = tga_filename;
- }
- /*
- ** Didn't have it so we have to create a new texture
- */
- tex = NEW_REF(TextureClass,(texture_name, real_location, mip_level_count, texture_format, allow_compression));
- TextureHash.Insert(tex->Get_Texture_Name(),tex);
- }
- tex->Add_Ref();
- return tex;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Load_Resource_Texture
- //
- ////////////////////////////////////////////////////////////////////////
- void
- EditorAssetMgrClass::Load_Resource_Texture (const char *filename)
- {
- CString texture_path = ::Get_File_Mgr ()->Get_Texture_Cache_Path ();
- CString texture_filename = ::Make_Path (texture_path, filename);
- //
- // Open the resource texture and create the
- // real file.
- //
- ResourceFileClass res_texture (NULL, filename);
- RawFileClass texture_file (texture_filename);
- if (texture_file.Create () == 1) {
- texture_file.Open (FileClass::WRITE);
- //
- // Copy the contents of the resource (memory) texture
- // to a file.
- //
- BYTE buffer[2048];
- int size = res_texture.Size ();
- int total_written = 0;
- while (total_written < size) {
- int bytes_read = res_texture.Read (buffer, sizeof (buffer));
- int bytes_written = texture_file.Write (buffer, bytes_read);
- total_written += bytes_written;
- if (bytes_written == 0) {
- break;
- }
- }
- texture_file.Close ();
- //
- // Force the texture to be loaded into memory
- //
- TextureClass *texture = Get_Texture (texture_filename);
- REF_PTR_RELEASE (texture);
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Load_3D_Assets
- //
- ////////////////////////////////////////////////////////////////////////
- bool
- EditorAssetMgrClass::Load_3D_Assets (const char *path)
- {
- bool retval = true;
-
- //
- // Check to see if the asset is already in the asset manager
- //
- CString filename = ::Get_Filename_From_Path (path);
- CString asset_name = ::Asset_Name_From_Filename (filename);
- PrototypeClass *prototype = Find_Prototype (asset_name);
- //
- // Load the asset fresh if necessary
- //
- if (prototype == NULL) {
- CString full_path = ::Get_File_Mgr ()->Make_Full_Path (path);
- retval = false;
- #ifdef PUBLIC_EDITOR_VER
-
- //
- // If the file exists locally, or its coming from the mix file
- // then load it.
- //
- if ( ::Get_File_Mgr ()->Does_File_Exist (full_path) ||
- ::Get_File_Mgr ()->Is_File_In_VSS (full_path))
- {
- retval = WW3DAssetManager::Load_3D_Assets (full_path);
- }
- #else
- //
- // If the file exists, then load it.
- //
- if (::Get_File_Mgr ()->Does_File_Exist (full_path, true)) {
- retval = WW3DAssetManager::Load_3D_Assets (full_path);
- }
- #endif //PUBLIC_EDITOR_VER
- }
- return retval;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Get_File
- //
- ////////////////////////////////////////////////////////////////////////
- FileClass *
- EditorFileFactoryClass::Get_File (char const *filename)
- {
- CString path;
- //
- // If the filename contains a relative path, then
- // turn it into an absolute path.
- //
- if (::Is_Path (filename)) {
- path = ::Get_File_Mgr ()->Make_Full_Path (filename);
- } else {
- //
- // Make a full path out of the filename
- //
- const char *curr_dir = _pThe3DAssetManager->Get_Current_Directory ();
- path = Make_Path (curr_dir, filename);
- //
- // If the file doesn't exist here, then try the search paths
- //
- if (::GetFileAttributes (path) == 0xFFFFFFFF) {
-
- //
- // Try to find the file in our search path list
- //
- for (int index = 0; index < SearchPathList.Count (); index ++) {
-
- //
- // Does the file exist in this directoy?
- //
- StringClass full_path = Make_Path (SearchPathList[index], filename);
- if (::GetFileAttributes (full_path) != 0xFFFFFFFF) {
- path = full_path;
- break;
- }
- }
- }
- }
- //
- // Get the file from the database
- //
- return ::Get_File_Mgr ()->Get_Database_Interface ().Get_File (path);
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Return_File
- //
- ////////////////////////////////////////////////////////////////////////
- void
- EditorFileFactoryClass::Return_File (FileClass *file)
- {
- if (file != NULL) {
- delete file;
- }
- return ;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Open_Texture_File_Cache
- //
- ////////////////////////////////////////////////////////////////////////
- void
- EditorAssetMgrClass::Open_Texture_File_Cache (const char * /*prefix*/)
- {
- return ;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Close_Texture_File_Cache
- //
- ////////////////////////////////////////////////////////////////////////
- void
- EditorAssetMgrClass::Close_Texture_File_Cache (void)
- {
- return ;
- }
|