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>
53+ #include < Utility/stdio_adapter.h>
54+
55+ // DEFINES ////////////////////////////////////////////////////////////////////////////////////////
5356
5457// -------------------------------------------------------------------------------------------------
5558/* * Game file access. At present this allows us to access test assets, assets from
@@ -71,9 +74,9 @@ typedef enum
7174GameFileClass::GameFileClass ( char const *filename )
7275{
7376
74- m_fileExists = FALSE ;
7577 m_theFile = NULL ;
76- m_filePath[ 0 ] = 0 ;
78+ m_fileExists = FALSE ;
79+ m_filePath[0 ] = 0 ;
7780 m_filename[0 ] = 0 ;
7881
7982 if ( filename )
@@ -119,6 +122,36 @@ inline static Bool isImageFileType( GameFileType fileType )
119122 return (fileType == FILE_TYPE_TGA || fileType == FILE_TYPE_DDS);
120123}
121124
125+ // -------------------------------------------------------------------------------------------------
126+ // -------------------------------------------------------------------------------------------------
127+ static GameFileType getFileType ( char const *filename )
128+ {
129+ const Int EXT_LEN = 32 ;
130+ char extension[EXT_LEN];
131+ extension[0 ] = 0 ;
132+ Int i = strlen (filename);
133+ i--;
134+ Int extLen = 1 ;
135+ while (i>0 && extLen < EXT_LEN) {
136+ if (filename[i] == ' .' ) {
137+ strcpy (extension, filename+i);
138+ break ;
139+ }
140+ i--;
141+ extLen++;
142+ }
143+
144+ // test the extension to recognize a few key file types
145+ if ( stricmp ( extension, " .w3d" ) == 0 )
146+ return FILE_TYPE_W3D;
147+ else if ( stricmp ( extension, " .tga" ) == 0 )
148+ return FILE_TYPE_TGA;
149+ else if ( stricmp ( extension, " .dds" ) == 0 )
150+ return FILE_TYPE_DDS;
151+ else
152+ return FILE_TYPE_COMPLETELY_UNKNOWN; // MBL FILE_TYPE_UNKNOWN change due to compile error
153+ }
154+
122155// -------------------------------------------------------------------------------------------------
123156/* *
124157 Sets the file name, and finds the GDI asset if present.
@@ -146,43 +179,7 @@ char const * GameFileClass::Set_Name( char const *filename )
146179 // save the filename
147180 strncpy ( m_filename, filename, _MAX_PATH );
148181
149- char name[_MAX_PATH];
150- const Int EXT_LEN = 32 ;
151- char extension[EXT_LEN];
152- extension[0 ] = 0 ;
153- strcpy (name, filename);
154- Int i = strlen (name);
155- i--;
156- Int extLen = 1 ;
157- while (i>0 && extLen < EXT_LEN) {
158- if (name[i] == ' .' ) {
159- strcpy (extension, name+i);
160- name[i] = 0 ;
161- break ;
162- }
163- i--;
164- extLen++;
165- }
166- Int j = 0 ;
167- // Strip out spaces.
168- for (i=0 ; name[i]; i++) {
169- if (name[i] != ' ' ) {
170- name[j] = name[i];
171- j++;
172- }
173- }
174- name[j] = 0 ;
175-
176- // test the extension to recognize a few key file types
177- GameFileType fileType = FILE_TYPE_COMPLETELY_UNKNOWN; // MBL FILE_TYPE_UNKNOWN change due to compile error
178- if ( stricmp ( extension, " .w3d" ) == 0 )
179- fileType = FILE_TYPE_W3D;
180- else if ( stricmp ( extension, " .tga" ) == 0 )
181- fileType = FILE_TYPE_TGA;
182- else if ( stricmp ( extension, " .dds" ) == 0 )
183- fileType = FILE_TYPE_DDS;
184-
185-
182+ GameFileType fileType = getFileType (filename);
186183
187184 // We need to be able to grab w3d's from a localization dir, since Germany hates exploding people units.
188185 if ( fileType == FILE_TYPE_W3D )
@@ -192,9 +189,8 @@ char const * GameFileClass::Set_Name( char const *filename )
192189 strcat ( m_filePath, filename );
193190
194191 } // end if
195-
196192 // We need to be able to grab images from a localization dir, because Art has a fetish for baked-in text. Munkee.
197- if ( isImageFileType (fileType) )
193+ else if ( isImageFileType (fileType) )
198194 {
199195 static const char *localizedPathFormat = " Data/%s/Art/Textures/" ;
200196 sprintf (m_filePath,localizedPathFormat, GetRegistryLanguage ().str ());
@@ -298,7 +294,7 @@ char const * GameFileClass::Set_Name( char const *filename )
298294 strcat ( m_filePath, filename );
299295
300296 } // end if
301- if ( isImageFileType (fileType) )
297+ else if ( isImageFileType (fileType) )
302298 {
303299 sprintf (m_filePath,USER_TGA_DIR_PATH, TheGlobalData->getPath_UserData ().str ());
304300 // strcpy( m_filePath, USER_TGA_DIR_PATH );
@@ -312,10 +308,10 @@ char const * GameFileClass::Set_Name( char const *filename )
312308 } // end if
313309
314310
315- // We Need to be able to " temporarily copy over the map preview for whichever directory it came from
311+ // We need to be able to temporarily copy over the map preview for whichever directory it came from
316312 if ( m_fileExists == FALSE && TheGlobalData)
317313 {
318- if ( fileType == FILE_TYPE_TGA ) // just TGA, since we don't dds previews
314+ if ( fileType == FILE_TYPE_TGA ) // just TGA, since we don't do dds previews
319315 {
320316 sprintf (m_filePath,MAP_PREVIEW_DIR_PATH, TheGlobalData->getPath_UserData ().str ());
321317 // strcpy( m_filePath, USER_TGA_DIR_PATH );
@@ -373,11 +369,9 @@ int GameFileClass::Open(int rights)
373369 return (false );
374370 }
375371
376- // just open up the file in m_filePath
377372 m_theFile = TheFileSystem->openFile ( m_filePath, File::READ | File::BINARY );
378373
379374 return (m_theFile != NULL );
380-
381375}
382376
383377// -------------------------------------------------------------------------------------------------
@@ -448,12 +442,16 @@ void GameFileClass::Close(void)
448442extern W3DFileSystem *TheW3DFileSystem = NULL ;
449443
450444// -------------------------------------------------------------------------------------------------
451- /* * Constructor. Creating an instance of this class overrices the default
445+ /* * Constructor. Creating an instance of this class overrides the default
452446W3D file factory. */
453447// -------------------------------------------------------------------------------------------------
454448W3DFileSystem::W3DFileSystem (void )
455449{
456450 _TheFileFactory = this ; // override the w3d file factory.
451+
452+ #if PRIORITIZE_TEXTURES_BY_SIZE
453+ reprioritizeTexturesBySize ();
454+ #endif
457455}
458456
459457// -------------------------------------------------------------------------------------------------
@@ -481,3 +479,75 @@ void W3DFileSystem::Return_File( FileClass *file )
481479 delete file;
482480}
483481
482+ // -------------------------------------------------------------------------------------------------
483+ // -------------------------------------------------------------------------------------------------
484+ void W3DFileSystem::reprioritizeTexturesBySize ()
485+ {
486+ {
487+ ArchivedDirectoryInfo* dirInfo = TheArchiveFileSystem->friend_getArchivedDirectoryInfo (TGA_DIR_PATH);
488+ if (dirInfo != NULL )
489+ reprioritizeTexturesBySize (*dirInfo);
490+ }
491+
492+ {
493+ char path[_MAX_PATH];
494+ snprintf (path, ARRAY_SIZE (path), " Data/%s/Art/Textures/" , GetRegistryLanguage ().str ());
495+ ArchivedDirectoryInfo* dirInfo = TheArchiveFileSystem->friend_getArchivedDirectoryInfo (path);
496+ if (dirInfo != NULL )
497+ reprioritizeTexturesBySize (*dirInfo);
498+ }
499+ }
500+
501+ // -------------------------------------------------------------------------------------------------
502+ // -------------------------------------------------------------------------------------------------
503+ void W3DFileSystem::reprioritizeTexturesBySize (ArchivedDirectoryInfo& dirInfo)
504+ {
505+ ArchivedFileLocationMap::iterator it0;
506+ ArchivedFileLocationMap::iterator it1 = dirInfo.m_files .begin ();
507+ ArchivedFileLocationMap::iterator end = dirInfo.m_files .end ();
508+
509+ if (it1 != end)
510+ {
511+ it0 = it1;
512+ ++it1;
513+ }
514+
515+ // This algorithm only prioritizes the first item in the multimap.
516+ for (; it1 != end; ++it1)
517+ {
518+ const AsciiString& file0 = it0->first ;
519+ const AsciiString& file1 = it1->first ;
520+
521+ if (file0 == file1)
522+ {
523+ GameFileType type = getFileType (file0.str ());
524+ if (isImageFileType (type))
525+ {
526+ ArchiveFile* archive0 = it0->second ;
527+ ArchiveFile* archive1 = it1->second ;
528+ FileInfo info0;
529+ FileInfo info1;
530+ AsciiString filepath (dirInfo.m_path );
531+ filepath.concat (file0);
532+
533+ if (archive0->getFileInfo (filepath, &info0) && archive1->getFileInfo (filepath, &info1))
534+ {
535+ if (info0.size () < info1.size ())
536+ {
537+ std::swap (it0->second , it1->second );
538+
539+ #if ENABLE_FILESYSTEM_LOGGING
540+ DEBUG_LOG ((" W3DFileSystem::reprioritizeTexturesBySize - prioritize %s(%ukb) from %s over %s(%ukb) from %s" ,
541+ file1.str (), UnsignedInt (info1.size () / 1024 ), archive1->getName ().str (),
542+ file0.str (), UnsignedInt (info0.size () / 1024 ), archive0->getName ().str ()));
543+ #endif
544+ }
545+ }
546+ }
547+ }
548+ else
549+ {
550+ it0 = it1;
551+ }
552+ }
553+ }
0 commit comments