4040// for now we maintain old legacy files
4141// #define MAINTAIN_LEGACY_FILES
4242
43+ #include " Common/ArchiveFile.h"
4344#include " Common/Debug.h"
4445#include " Common/file.h"
4546#include " Common/FileSystem.h"
4647#include " Common/GlobalData.h"
4748#include " Common/MapObject.h"
4849#include " Common/Registry.h"
4950#include " W3DDevice/GameClient/W3DFileSystem.h"
50- // DEFINES ////////////////////////////////////////////////////////////////////////////////////////
5151
5252#include < io.h>
5353
54+ // DEFINES ////////////////////////////////////////////////////////////////////////////////////////
55+
5456// -------------------------------------------------------------------------------------------------
5557/* * Game file access. At present this allows us to access test assets, assets from
5658 * legacy GDI assets, and the current flat directory access for textures, models etc */
@@ -71,9 +73,9 @@ typedef enum
7173GameFileClass::GameFileClass ( char const *filename )
7274{
7375
74- m_fileExists = FALSE ;
7576 m_theFile = NULL ;
76- m_filePath[ 0 ] = 0 ;
77+ m_fileExists = FALSE ;
78+ m_filePath[0 ] = 0 ;
7779 m_filename[0 ] = 0 ;
7880
7981 if ( filename )
@@ -119,6 +121,24 @@ inline static Bool isImageFileType( GameFileType fileType )
119121 return (fileType == FILE_TYPE_TGA || fileType == FILE_TYPE_DDS);
120122}
121123
124+ // -------------------------------------------------------------------------------------------------
125+ // -------------------------------------------------------------------------------------------------
126+ static GameFileType getFileType ( char const *filename )
127+ {
128+ if (char const *extension = strrchr ( filename, ' .' ))
129+ {
130+ // test the extension to recognize a few key file types
131+ if ( stricmp ( extension, " .w3d" ) == 0 )
132+ return FILE_TYPE_W3D;
133+ else if ( stricmp ( extension, " .tga" ) == 0 )
134+ return FILE_TYPE_TGA;
135+ else if ( stricmp ( extension, " .dds" ) == 0 )
136+ return FILE_TYPE_DDS;
137+ }
138+
139+ return FILE_TYPE_COMPLETELY_UNKNOWN; // MBL FILE_TYPE_UNKNOWN change due to compile error
140+ }
141+
122142// -------------------------------------------------------------------------------------------------
123143/* * Sets the file name, and finds the GDI asset if present. */
124144// -------------------------------------------------------------------------------------------------
@@ -131,41 +151,7 @@ char const * GameFileClass::Set_Name( char const *filename )
131151 // save the filename
132152 strlcpy ( m_filename, filename, _MAX_PATH );
133153
134- char name[_MAX_PATH];
135- const Int EXT_LEN = 32 ;
136- char extension[EXT_LEN];
137- extension[0 ] = 0 ;
138- strcpy (name, filename);
139- Int i = strlen (name);
140- i--;
141- Int extLen = 1 ;
142- while (i>0 && extLen < EXT_LEN) {
143- if (name[i] == ' .' ) {
144- strcpy (extension, name+i);
145- name[i] = 0 ;
146- break ;
147- }
148- i--;
149- extLen++;
150- }
151- Int j = 0 ;
152- // Strip out spaces.
153- for (i=0 ; name[i]; i++) {
154- if (name[i] != ' ' ) {
155- name[j] = name[i];
156- j++;
157- }
158- }
159- name[j] = 0 ;
160-
161- // test the extension to recognize a few key file types
162- GameFileType fileType = FILE_TYPE_COMPLETELY_UNKNOWN; // MBL FILE_TYPE_UNKNOWN change due to compile error
163- if ( stricmp ( extension, " .w3d" ) == 0 )
164- fileType = FILE_TYPE_W3D;
165- else if ( stricmp ( extension, " .tga" ) == 0 )
166- fileType = FILE_TYPE_TGA;
167- else if ( stricmp ( extension, " .dds" ) == 0 )
168- fileType = FILE_TYPE_DDS;
154+ GameFileType fileType = getFileType (filename);
169155
170156 // all .w3d files are in W3D_DIR_PATH, all .tga files are in TGA_DIR_PATH
171157 if ( fileType == FILE_TYPE_W3D )
@@ -250,7 +236,7 @@ char const * GameFileClass::Set_Name( char const *filename )
250236 strlcat (m_filePath, filename, ARRAY_SIZE (m_filePath));
251237
252238 }
253- if ( isImageFileType (fileType) )
239+ else if ( isImageFileType (fileType) )
254240 {
255241 sprintf (m_filePath,USER_TGA_DIR_PATH, TheGlobalData->getPath_UserData ().str ());
256242 // strcpy( m_filePath, USER_TGA_DIR_PATH );
@@ -264,10 +250,10 @@ char const * GameFileClass::Set_Name( char const *filename )
264250 }
265251
266252
267- // We Need to be able to " temporarily copy over the map preview for whichever directory it came from
253+ // We need to be able to temporarily copy over the map preview for whichever directory it came from
268254 if ( m_fileExists == FALSE && TheGlobalData)
269255 {
270- if ( fileType == FILE_TYPE_TGA ) // just TGA, since we don't dds previews
256+ if ( fileType == FILE_TYPE_TGA ) // just TGA, since we don't do dds previews
271257 {
272258 sprintf (m_filePath,MAP_PREVIEW_DIR_PATH, TheGlobalData->getPath_UserData ().str ());
273259 // strcpy( m_filePath, USER_TGA_DIR_PATH );
@@ -343,11 +329,9 @@ int GameFileClass::Open(int rights)
343329 return (false );
344330 }
345331
346- // just open up the file in m_filePath
347332 m_theFile = TheFileSystem->openFile ( m_filePath, File::READ | File::BINARY );
348333
349334 return (m_theFile != NULL );
350-
351335}
352336
353337// -------------------------------------------------------------------------------------------------
@@ -418,12 +402,16 @@ void GameFileClass::Close(void)
418402extern W3DFileSystem *TheW3DFileSystem = NULL ;
419403
420404// -------------------------------------------------------------------------------------------------
421- /* * Constructor. Creating an instance of this class overrices the default
405+ /* * Constructor. Creating an instance of this class overrides the default
422406W3D file factory. */
423407// -------------------------------------------------------------------------------------------------
424408W3DFileSystem::W3DFileSystem (void )
425409{
426410 _TheFileFactory = this ; // override the w3d file factory.
411+
412+ #if RTS_ZEROHOUR && PRIORITIZE_TEXTURES_BY_SIZE
413+ reprioritizeTexturesBySize ();
414+ #endif
427415}
428416
429417// -------------------------------------------------------------------------------------------------
@@ -451,3 +439,79 @@ void W3DFileSystem::Return_File( FileClass *file )
451439 delete file;
452440}
453441
442+ // -------------------------------------------------------------------------------------------------
443+ // -------------------------------------------------------------------------------------------------
444+ void W3DFileSystem::reprioritizeTexturesBySize ()
445+ {
446+ ArchivedDirectoryInfo* dirInfo = TheArchiveFileSystem->friend_getArchivedDirectoryInfo (TGA_DIR_PATH);
447+ if (dirInfo != NULL )
448+ {
449+ reprioritizeTexturesBySize (*dirInfo);
450+ }
451+ }
452+
453+ // -------------------------------------------------------------------------------------------------
454+ // TheSuperHackers @info This function moves the largest texture of its name to the front of the
455+ // directory info. The algorithm only prioritizes the first item in the multimap, because this is
456+ // what we currently need:
457+ // Before: A(256kb) B(128kb) C(512kb)
458+ // After: C(512kb) B(128kb) A(256kb)
459+ //
460+ // Catered to specific game archives only. This ensures that user created archives are not included
461+ // for the re-prioritization of textures.
462+ // -------------------------------------------------------------------------------------------------
463+ void W3DFileSystem::reprioritizeTexturesBySize (ArchivedDirectoryInfo& dirInfo)
464+ {
465+ const char * const superiorArchive = " Textures.big" ;
466+ const char * const inferiorArchive = " TexturesZH.big" ;
467+
468+ ArchivedFileLocationMap::iterator it0;
469+ ArchivedFileLocationMap::iterator it1 = dirInfo.m_files .begin ();
470+ ArchivedFileLocationMap::iterator end = dirInfo.m_files .end ();
471+
472+ if (it1 != end)
473+ {
474+ it0 = it1;
475+ ++it1;
476+ }
477+
478+ for (; it1 != end; ++it1)
479+ {
480+ const AsciiString& file0 = it0->first ;
481+ const AsciiString& file1 = it1->first ;
482+
483+ if (file0 == file1)
484+ {
485+ GameFileType type = getFileType (file0.str ());
486+ if (isImageFileType (type))
487+ {
488+ ArchiveFile* archive0 = it0->second ;
489+ ArchiveFile* archive1 = it1->second ;
490+ FileInfo info0;
491+ FileInfo info1;
492+ AsciiString filepath (dirInfo.m_path );
493+ filepath.concat (file0);
494+
495+ if (archive0->getFileInfo (filepath, &info0) && archive1->getFileInfo (filepath, &info1))
496+ {
497+ if (info0.size () < info1.size ()
498+ && archive0->getName ().endsWithNoCase (inferiorArchive)
499+ && archive1->getName ().endsWithNoCase (superiorArchive))
500+ {
501+ std::swap (it0->second , it1->second );
502+
503+ #if ENABLE_FILESYSTEM_LOGGING
504+ DEBUG_LOG ((" W3DFileSystem::reprioritizeTexturesBySize - prioritize %s(%ukb) from %s over %s(%ukb) from %s" ,
505+ file1.str (), UnsignedInt (info1.size () / 1024 ), archive1->getName ().str (),
506+ file0.str (), UnsignedInt (info0.size () / 1024 ), archive0->getName ().str ()));
507+ #endif
508+ }
509+ }
510+ }
511+ }
512+ else
513+ {
514+ it0 = it1;
515+ }
516+ }
517+ }
0 commit comments