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,24 @@ 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+ if (char const *extension = strrchr ( filename, ' .' ))
130+ {
131+ // test the extension to recognize a few key file types
132+ if ( stricmp ( extension, " .w3d" ) == 0 )
133+ return FILE_TYPE_W3D;
134+ else if ( stricmp ( extension, " .tga" ) == 0 )
135+ return FILE_TYPE_TGA;
136+ else if ( stricmp ( extension, " .dds" ) == 0 )
137+ return FILE_TYPE_DDS;
138+ }
139+
140+ return FILE_TYPE_COMPLETELY_UNKNOWN; // MBL FILE_TYPE_UNKNOWN change due to compile error
141+ }
142+
122143// -------------------------------------------------------------------------------------------------
123144/* * Sets the file name, and finds the GDI asset if present. */
124145// -------------------------------------------------------------------------------------------------
@@ -131,41 +152,7 @@ char const * GameFileClass::Set_Name( char const *filename )
131152 // save the filename
132153 strlcpy ( m_filename, filename, _MAX_PATH );
133154
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;
155+ GameFileType fileType = getFileType (filename);
169156
170157 // all .w3d files are in W3D_DIR_PATH, all .tga files are in TGA_DIR_PATH
171158 if ( fileType == FILE_TYPE_W3D )
@@ -250,7 +237,7 @@ char const * GameFileClass::Set_Name( char const *filename )
250237 strlcat (m_filePath, filename, ARRAY_SIZE (m_filePath));
251238
252239 }
253- if ( isImageFileType (fileType) )
240+ else if ( isImageFileType (fileType) )
254241 {
255242 sprintf (m_filePath,USER_TGA_DIR_PATH, TheGlobalData->getPath_UserData ().str ());
256243 // strcpy( m_filePath, USER_TGA_DIR_PATH );
@@ -264,10 +251,10 @@ char const * GameFileClass::Set_Name( char const *filename )
264251 }
265252
266253
267- // We Need to be able to " temporarily copy over the map preview for whichever directory it came from
254+ // We need to be able to temporarily copy over the map preview for whichever directory it came from
268255 if ( m_fileExists == FALSE && TheGlobalData)
269256 {
270- if ( fileType == FILE_TYPE_TGA ) // just TGA, since we don't dds previews
257+ if ( fileType == FILE_TYPE_TGA ) // just TGA, since we don't do dds previews
271258 {
272259 sprintf (m_filePath,MAP_PREVIEW_DIR_PATH, TheGlobalData->getPath_UserData ().str ());
273260 // strcpy( m_filePath, USER_TGA_DIR_PATH );
@@ -343,11 +330,9 @@ int GameFileClass::Open(int rights)
343330 return (false );
344331 }
345332
346- // just open up the file in m_filePath
347333 m_theFile = TheFileSystem->openFile ( m_filePath, File::READ | File::BINARY );
348334
349335 return (m_theFile != NULL );
350-
351336}
352337
353338// -------------------------------------------------------------------------------------------------
@@ -418,12 +403,16 @@ void GameFileClass::Close(void)
418403extern W3DFileSystem *TheW3DFileSystem = NULL ;
419404
420405// -------------------------------------------------------------------------------------------------
421- /* * Constructor. Creating an instance of this class overrices the default
406+ /* * Constructor. Creating an instance of this class overrides the default
422407W3D file factory. */
423408// -------------------------------------------------------------------------------------------------
424409W3DFileSystem::W3DFileSystem (void )
425410{
426411 _TheFileFactory = this ; // override the w3d file factory.
412+
413+ #if PRIORITIZE_TEXTURES_BY_SIZE
414+ reprioritizeTexturesBySize ();
415+ #endif
427416}
428417
429418// -------------------------------------------------------------------------------------------------
@@ -451,3 +440,79 @@ void W3DFileSystem::Return_File( FileClass *file )
451440 delete file;
452441}
453442
443+ // -------------------------------------------------------------------------------------------------
444+ // -------------------------------------------------------------------------------------------------
445+ void W3DFileSystem::reprioritizeTexturesBySize ()
446+ {
447+ {
448+ ArchivedDirectoryInfo* dirInfo = TheArchiveFileSystem->friend_getArchivedDirectoryInfo (TGA_DIR_PATH);
449+ if (dirInfo != NULL )
450+ reprioritizeTexturesBySize (*dirInfo);
451+ }
452+
453+ {
454+ char path[_MAX_PATH];
455+ snprintf (path, ARRAY_SIZE (path), " Data/%s/Art/Textures/" , GetRegistryLanguage ().str ());
456+ ArchivedDirectoryInfo* dirInfo = TheArchiveFileSystem->friend_getArchivedDirectoryInfo (path);
457+ if (dirInfo != NULL )
458+ reprioritizeTexturesBySize (*dirInfo);
459+ }
460+ }
461+
462+ // -------------------------------------------------------------------------------------------------
463+ // TheSuperHackers @info This function moves the largest texture of its name to the front of the
464+ // directory info. The algorithm only prioritizes the first item in the multimap, because this is
465+ // what we currently need:
466+ // Before: A(256kb) B(128kb) C(512kb)
467+ // After: C(512kb) B(128kb) A(256kb)
468+ // -------------------------------------------------------------------------------------------------
469+ void W3DFileSystem::reprioritizeTexturesBySize (ArchivedDirectoryInfo& dirInfo)
470+ {
471+ ArchivedFileLocationMap::iterator it0;
472+ ArchivedFileLocationMap::iterator it1 = dirInfo.m_files .begin ();
473+ ArchivedFileLocationMap::iterator end = dirInfo.m_files .end ();
474+
475+ if (it1 != end)
476+ {
477+ it0 = it1;
478+ ++it1;
479+ }
480+
481+ for (; it1 != end; ++it1)
482+ {
483+ const AsciiString& file0 = it0->first ;
484+ const AsciiString& file1 = it1->first ;
485+
486+ if (file0 == file1)
487+ {
488+ GameFileType type = getFileType (file0.str ());
489+ if (isImageFileType (type))
490+ {
491+ ArchiveFile* archive0 = it0->second ;
492+ ArchiveFile* archive1 = it1->second ;
493+ FileInfo info0;
494+ FileInfo info1;
495+ AsciiString filepath (dirInfo.m_path );
496+ filepath.concat (file0);
497+
498+ if (archive0->getFileInfo (filepath, &info0) && archive1->getFileInfo (filepath, &info1))
499+ {
500+ if (info0.size () < info1.size ())
501+ {
502+ std::swap (it0->second , it1->second );
503+
504+ #if ENABLE_FILESYSTEM_LOGGING
505+ DEBUG_LOG ((" W3DFileSystem::reprioritizeTexturesBySize - prioritize %s(%ukb) from %s over %s(%ukb) from %s" ,
506+ file1.str (), UnsignedInt (info1.size () / 1024 ), archive1->getName ().str (),
507+ file0.str (), UnsignedInt (info0.size () / 1024 ), archive0->getName ().str ()));
508+ #endif
509+ }
510+ }
511+ }
512+ }
513+ else
514+ {
515+ it0 = it1;
516+ }
517+ }
518+ }
0 commit comments