diff --git a/src/ActorUtil.cpp b/src/ActorUtil.cpp index 8a1910f058..5e6132f906 100644 --- a/src/ActorUtil.cpp +++ b/src/ActorUtil.cpp @@ -499,55 +499,117 @@ void ActorUtil::SortByZPosition( vector &vActors ) } static const char *FileTypeNames[] = { - "Bitmap", + "Bitmap", "Sprite", - "Sound", - "Movie", - "Directory", + "Sound", + "Movie", + "Directory", "Xml", - "Model", - "Lua", + "Model", + "Lua", + "Ini", }; XToString( FileType ); LuaXType( FileType ); +// convenience so the for-loop lines can be shorter. +typedef map etft_cont_t; +typedef map > fttel_cont_t; +etft_cont_t ExtensionToFileType; +fttel_cont_t FileTypeToExtensionList; + +void ActorUtil::InitFileTypeLists() +{ + // This function creates things to serve two purposes: + // 1. A map from extensions to filetypes, so extensions can be converted. + // 2. A reverse map for things that need a list of extensions to look for. + // The first section creates the map from extensions to filetypes, then the + // second section uses that map to build the reverse map. + ExtensionToFileType["lua"]= FT_Lua; + + ExtensionToFileType["xml"]= FT_Xml; + + ExtensionToFileType["ini"]= FT_Ini; + + // Update RageSurfaceUtils when adding new image formats. + ExtensionToFileType["bmp"]= FT_Bitmap; + ExtensionToFileType["gif"]= FT_Bitmap; + ExtensionToFileType["jpeg"]= FT_Bitmap; + ExtensionToFileType["jpg"]= FT_Bitmap; + ExtensionToFileType["png"]= FT_Bitmap; + + // Update RageSoundReader_FileReader when adding new sound formats. + ExtensionToFileType["mp3"]= FT_Sound; + ExtensionToFileType["oga"]= FT_Sound; + ExtensionToFileType["ogg"]= FT_Sound; + ExtensionToFileType["wav"]= FT_Sound; + + // ffmpeg takes care of loading videos, not sure whether this list should + // have everything ffmpeg supports. + ExtensionToFileType["avi"]= FT_Movie; + ExtensionToFileType["f4v"]= FT_Movie; + ExtensionToFileType["flv"]= FT_Movie; + ExtensionToFileType["mkv"]= FT_Movie; + ExtensionToFileType["mp4"]= FT_Movie; + ExtensionToFileType["mpeg"]= FT_Movie; + ExtensionToFileType["mpg"]= FT_Movie; + ExtensionToFileType["mov"]= FT_Movie; + ExtensionToFileType["ogv"]= FT_Movie; + ExtensionToFileType["webm"]= FT_Movie; + ExtensionToFileType["wmv"]= FT_Movie; + + ExtensionToFileType["sprite"]= FT_Sprite; + + ExtensionToFileType["txt"]= FT_Model; + + // When adding new extensions, do not add them below this line. This line + // marks the point where the function switches to building the reverse map. + for(etft_cont_t::iterator curr_ext= ExtensionToFileType.begin(); + curr_ext != ExtensionToFileType.end(); ++curr_ext) + { + FileTypeToExtensionList[curr_ext->second].push_back(curr_ext->first); + } +} + +vector const& ActorUtil::GetTypeExtensionList(FileType ft) +{ + return FileTypeToExtensionList[ft]; +} + +void ActorUtil::AddTypeExtensionsToList(FileType ft, vector& add_to) +{ + fttel_cont_t::iterator ext_list= FileTypeToExtensionList.find(ft); + if(ext_list != FileTypeToExtensionList.end()) + { + add_to.reserve(add_to.size() + ext_list->second.size()); + for(vector::iterator curr= ext_list->second.begin(); + curr != ext_list->second.end(); ++curr) + { + add_to.push_back(*curr); + } + } +} + FileType ActorUtil::GetFileType( const RString &sPath ) { RString sExt = GetExtension( sPath ); sExt.MakeLower(); - - if( sExt=="lua" ) return FT_Lua; - else if(sExt=="xml") return FT_Xml; - else if( - sExt=="png" || - sExt=="jpg" || - sExt=="jpeg" || - sExt=="gif" || - sExt=="bmp" ) return FT_Bitmap; - else if( - sExt=="ogg" || - sExt=="oga" || - sExt=="wav" || - sExt=="mp3" ) return FT_Sound; - else if( - sExt=="ogv" || - sExt=="avi" || - sExt=="mpeg" || - sExt=="mp4" || - sExt=="mkv" || - sExt=="mov" || - sExt=="flv" || - sExt=="f4v" || - sExt=="mpg" ) return FT_Movie; - else if( - sExt=="sprite" ) return FT_Sprite; - else if( - sExt=="txt" ) return FT_Model; - else if( sPath.size() > 0 && sPath[sPath.size()-1] == '/' ) - return FT_Directory; + + etft_cont_t::iterator conversion_entry= ExtensionToFileType.find(sExt); + if(conversion_entry != ExtensionToFileType.end()) + { + return conversion_entry->second; + } + else if(sPath.size() > 0 && sPath[sPath.size()-1] == '/') + { + return FT_Directory; + } /* Do this last, to avoid the IsADirectory in most cases. */ - else if( IsADirectory(sPath) ) return FT_Directory; - else return FileType_Invalid; + else if(IsADirectory(sPath)) + { + return FT_Directory; + } + return FileType_Invalid; } diff --git a/src/ActorUtil.h b/src/ActorUtil.h index 3a6d139235..d6c6e8d33e 100644 --- a/src/ActorUtil.h +++ b/src/ActorUtil.h @@ -30,15 +30,16 @@ Actor *CreateActor() { return new T; } enum FileType { - FT_Bitmap, + FT_Bitmap, FT_Sprite, - FT_Sound, - FT_Movie, - FT_Directory, + FT_Sound, + FT_Movie, + FT_Directory, FT_Xml, - FT_Model, - FT_Lua, - NUM_FileType, + FT_Model, + FT_Lua, + FT_Ini, + NUM_FileType, FileType_Invalid }; const RString& FileTypeToString( FileType ft ); @@ -46,6 +47,10 @@ const RString& FileTypeToString( FileType ft ); /** @brief Utility functions for creating and manipulating Actors. */ namespace ActorUtil { + void InitFileTypeLists(); + vector const& GetTypeExtensionList(FileType ft); + void AddTypeExtensionsToList(FileType ft, vector& add_to); + // Every screen should register its class at program initialization. void Register( const RString& sClassName, CreateActorFn pfn ); diff --git a/src/BackgroundUtil.cpp b/src/BackgroundUtil.cpp index b7380739bc..18db7382cd 100644 --- a/src/BackgroundUtil.cpp +++ b/src/BackgroundUtil.cpp @@ -7,6 +7,8 @@ #include "RageLog.h" #include #include "Background.h" +#include "RageFileManager.h" +#include "ActorUtil.h" bool BackgroundDef::operator<( const BackgroundDef &other ) const @@ -194,15 +196,8 @@ void BackgroundUtil::GetSongMovies( const Song *pSong, const RString &sMatch, ve vsPathsOut.clear(); if( sMatch.empty() ) { - GetDirListing( pSong->GetSongDir()+sMatch+"*.ogv", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.avi", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.mpg", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.mpeg", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.mp4", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.flv", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.f4v", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.mov", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.mkv", vsPathsOut, false, true ); + FILEMAN->GetDirListingWithMultipleExtensions(pSong->GetSongDir()+sMatch, + ActorUtil::GetTypeExtensionList(FT_Movie), vsPathsOut, false, true); } else { @@ -221,11 +216,8 @@ void BackgroundUtil::GetSongBitmaps( const Song *pSong, const RString &sMatch, v vsPathsOut.clear(); if( sMatch.empty() ) { - GetDirListing( pSong->GetSongDir()+sMatch+"*.png", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.jpg", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.jpeg", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.gif", vsPathsOut, false, true ); - GetDirListing( pSong->GetSongDir()+sMatch+"*.bmp", vsPathsOut, false, true ); + FILEMAN->GetDirListingWithMultipleExtensions(pSong->GetSongDir()+sMatch, + ActorUtil::GetTypeExtensionList(FT_Bitmap), vsPathsOut, false, true); } else { diff --git a/src/NotesLoaderBMS.cpp b/src/NotesLoaderBMS.cpp index 9de9354d7d..5028f501ef 100644 --- a/src/NotesLoaderBMS.cpp +++ b/src/NotesLoaderBMS.cpp @@ -15,6 +15,8 @@ #include "NotesLoader.h" #include "PrefsManager.h" #include "BackgroundUtil.h" +#include "ActorUtil.h" +#include "RageFileManager.h" /* BMS encoding: tap-hold * 4&8panel: Player1 Player2 @@ -328,8 +330,8 @@ int BMSSong::AllocateKeysound( RString filename, RString path ) if( !IsAFile(dir + normalizedFilename) ) { - const char *exts[] = { "oga", "ogg", "wav", "mp3", NULL }; // XXX: stop duplicating these everywhere - for( unsigned i = 0; exts[i] != NULL; ++i ) + vector const& exts= ActorUtil::GetTypeExtensionList(FT_Sound); + for(size_t i = 0; i < exts.size(); ++i) { RString fn = SetExtension( normalizedFilename, exts[i] ); if( IsAFile(dir + fn) ) @@ -393,8 +395,10 @@ bool BMSSong::GetBackground( RString filename, RString path, RString &bgfile ) if( !IsAFile(dir + normalizedFilename) ) { - const char *exts[] = { "ogv", "avi", "mpg", "mpeg", "bmp", "png", "jpeg", NULL }; // XXX: stop duplicating these everywhere - for( unsigned i = 0; exts[i] != NULL; ++i ) + vector exts; + ActorUtil::AddTypeExtensionsToList(FT_Movie, exts); + ActorUtil::AddTypeExtensionsToList(FT_Bitmap, exts); + for(size_t i = 0; i < exts.size(); ++i) { RString fn = SetExtension( normalizedFilename, exts[i] ); if( IsAFile(dir + fn) ) @@ -424,12 +428,10 @@ void BMSSong::PrecacheBackgrounds(const RString &dir) backgroundsPrecached = true; vector arrayPossibleFiles; - const char *exts[] = { "ogv", "avi", "mpg", "mpeg", "bmp", "png", "jpeg", NULL }; // XXX: stop duplicating these everywhere - - for( unsigned i = 0; exts[i] != NULL; ++i ) - { - GetDirListing( dir + RString("*.") + RString(exts[i]), arrayPossibleFiles ); - } + vector exts; + ActorUtil::AddTypeExtensionsToList(FT_Movie, exts); + ActorUtil::AddTypeExtensionsToList(FT_Bitmap, exts); + FILEMAN->GetDirListingWithMultipleExtensions(dir + RString("*."), exts, arrayPossibleFiles); for( unsigned i = 0; i < arrayPossibleFiles.size(); i++ ) { diff --git a/src/RageFileManager.cpp b/src/RageFileManager.cpp index ab25e73f0e..d42654fc34 100644 --- a/src/RageFileManager.cpp +++ b/src/RageFileManager.cpp @@ -397,6 +397,15 @@ void RageFileManager::GetDirListing( const RString &sPath_, vector &Add } } +void RageFileManager::GetDirListingWithMultipleExtensions( const RString &sPath, vector const& ExtensionList, vector &AddTo, bool bOnlyDirs, bool bReturnPathToo ) +{ + for(vector::const_iterator curr_ext= ExtensionList.begin(); + curr_ext != ExtensionList.end(); ++curr_ext) + { + GetDirListing(sPath + (*curr_ext), AddTo, bOnlyDirs, bReturnPathToo); + } +} + /* Files may only be moved within the same file driver. */ bool RageFileManager::Move( const RString &sOldPath_, const RString &sNewPath_ ) { diff --git a/src/RageFileManager.h b/src/RageFileManager.h index 7eaa445852..bbc5a730ef 100644 --- a/src/RageFileManager.h +++ b/src/RageFileManager.h @@ -24,6 +24,9 @@ public: void MountUserFilesystems(); void GetDirListing( const RString &sPath, vector &AddTo, bool bOnlyDirs, bool bReturnPathToo ); + void GetDirListingWithMultipleExtensions(const RString &sPath, + vector const& ExtensionList, vector &AddTo, + bool bOnlyDirs= false, bool bReturnPathToo= false); bool Move( const RString &sOldPath, const RString &sNewPath ); bool Remove( const RString &sPath ); void CreateDir( const RString &sDir ); diff --git a/src/RageSoundReader_FileReader.cpp b/src/RageSoundReader_FileReader.cpp index 5c43fc080b..38de079107 100644 --- a/src/RageSoundReader_FileReader.cpp +++ b/src/RageSoundReader_FileReader.cpp @@ -2,6 +2,7 @@ #include "RageSoundReader_FileReader.h" #include "RageUtil.h" #include "RageLog.h" +#include "ActorUtil.h" #include #ifndef NO_WAV_SUPPORT @@ -122,10 +123,12 @@ RageSoundReader_FileReader *RageSoundReader_FileReader::OpenFile( RString filena } } set FileTypes; - FileTypes.insert("oga"); - FileTypes.insert("ogg"); - FileTypes.insert("mp3"); - FileTypes.insert("wav"); + vector const& sound_exts= ActorUtil::GetTypeExtensionList(FT_Sound); + for(vector::const_iterator curr= sound_exts.begin(); + curr != sound_exts.end(); ++curr) + { + FileTypes.insert(*curr); + } RString format = GetExtension( filename ); format.MakeLower(); diff --git a/src/RageSurface_Load.cpp b/src/RageSurface_Load.cpp index ee2f69da02..663c07b1fd 100644 --- a/src/RageSurface_Load.cpp +++ b/src/RageSurface_Load.cpp @@ -1,4 +1,5 @@ #include "global.h" +#include "ActorUtil.h" #include "RageSurface_Load.h" #include "RageSurface_Load_PNG.h" #include "RageSurface_Load_JPEG.h" @@ -85,11 +86,12 @@ RageSurface *RageSurfaceUtils::LoadFile( const RString &sPath, RString &error, b } set FileTypes; - FileTypes.insert("png"); - FileTypes.insert("jpg"); - FileTypes.insert("jpeg"); - FileTypes.insert("gif"); - FileTypes.insert("bmp"); + vector const& exts= ActorUtil::GetTypeExtensionList(FT_Bitmap); + for(vector::const_iterator curr= exts.begin(); + curr != exts.end(); ++curr) + { + FileTypes.insert(*curr); + } RString format = GetExtension(sPath); format.MakeLower(); diff --git a/src/RageTextureManager.cpp b/src/RageTextureManager.cpp index 51134de06b..f11fff0e5d 100644 --- a/src/RageTextureManager.cpp +++ b/src/RageTextureManager.cpp @@ -26,6 +26,7 @@ #include "RageLog.h" #include "RageDisplay.h" #include "Foreach.h" +#include "ActorUtil.h" #include @@ -147,17 +148,13 @@ RageTexture* RageTextureManager::LoadTextureInternal( RageTextureID ID ) } // The texture is not already loaded. Load it. - RString sExt = GetExtension( ID.filename ); - sExt.MakeLower(); RageTexture* pTexture; if( ID.filename == g_sDefaultTextureName ) { pTexture = new RageTexture_Default; } - else if(sExt == "ogv" || sExt == "avi" || sExt == "mpg" || - sExt == "mpeg" || sExt == "mp4" || sExt == "mkv" || sExt == "mov" || - sExt == "flv" || sExt == "f4v") + else if(ActorUtil::GetFileType(ID.filename) == FT_Movie) { pTexture = RageMovieTexture::Create( ID ); } diff --git a/src/Song.cpp b/src/Song.cpp index 27c20aa76f..df9309fa44 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -32,6 +32,7 @@ #include "NotesWriterSSC.h" #include "UnlockManager.h" #include "LyricsLoader.h" +#include "ActorUtil.h" #include #include @@ -516,10 +517,8 @@ void Song::TidyUpData( bool fromCache, bool /* duringCache */ ) if( !HasMusic() ) { vector arrayPossibleMusic; - GetDirListing( m_sSongDir + RString("*.mp3"), arrayPossibleMusic ); - GetDirListing( m_sSongDir + RString("*.oga"), arrayPossibleMusic ); - GetDirListing( m_sSongDir + RString("*.ogg"), arrayPossibleMusic ); - GetDirListing( m_sSongDir + RString("*.wav"), arrayPossibleMusic ); + FILEMAN->GetDirListingWithMultipleExtensions(m_sSongDir, + ActorUtil::GetTypeExtensionList(FT_Sound), arrayPossibleMusic); if( !arrayPossibleMusic.empty() ) { @@ -854,15 +853,8 @@ void Song::TidyUpData( bool fromCache, bool /* duringCache */ ) if( (!HasBGChanges() && !fromCache) ) { vector arrayPossibleMovies; - GetDirListing( m_sSongDir + RString("*.ogv"), arrayPossibleMovies ); - GetDirListing( m_sSongDir + RString("*.avi"), arrayPossibleMovies ); - GetDirListing( m_sSongDir + RString("*.mpg"), arrayPossibleMovies ); - GetDirListing( m_sSongDir + RString("*.mpeg"), arrayPossibleMovies ); - GetDirListing( m_sSongDir + RString("*.mp4"), arrayPossibleMovies ); - GetDirListing( m_sSongDir + RString("*.mkv"), arrayPossibleMovies ); - GetDirListing( m_sSongDir + RString("*.flv"), arrayPossibleMovies ); - GetDirListing( m_sSongDir + RString("*.f4v"), arrayPossibleMovies ); - GetDirListing( m_sSongDir + RString("*.mov"), arrayPossibleMovies ); + FILEMAN->GetDirListingWithMultipleExtensions(m_sSongDir, + ActorUtil::GetTypeExtensionList(FT_Movie), arrayPossibleMovies); /* Use this->GetBeatFromElapsedTime(0) instead of 0 to start when the * music starts. */ diff --git a/src/StepMania.cpp b/src/StepMania.cpp index d5f61fa629..5b71540a01 100644 --- a/src/StepMania.cpp +++ b/src/StepMania.cpp @@ -67,6 +67,7 @@ #include "GameLoop.h" #include "SpecialFiles.h" #include "Profile.h" +#include "ActorUtil.h" #if defined(WIN32) #include @@ -951,6 +952,10 @@ int main(int argc, char* argv[]) LUA = new LuaManager; + // Initialize the file extension type lists so everything can ask ActorUtil + // what the type of a file is. + ActorUtil::InitFileTypeLists(); + // Almost everything uses this to read and write files. Load this early. FILEMAN = new RageFileManager( argv[0] ); FILEMAN->MountInitialFilesystems(); diff --git a/src/ThemeManager.cpp b/src/ThemeManager.cpp index 914ac0f143..26813d36e9 100644 --- a/src/ThemeManager.cpp +++ b/src/ThemeManager.cpp @@ -616,46 +616,52 @@ bool ThemeManager::GetPathInfoToRaw( PathInfo &out, const RString &sThemeName_, for( unsigned p = 0; p < asPaths.size(); ++p ) { // BGAnimations, Fonts, Graphics, Sounds, Other - static const char *masks[NUM_ElementCategory][15] = { - { "redir", "lua", "xml", "png", "jpg", "jpeg", "bmp", "gif", "ogv", "avi", "mpg", "mpeg", "txt", "", NULL}, - { "redir", "ini", NULL }, - { "redir", "lua", "xml", "png", "jpg", "jpeg", "bmp", "gif", "ogv", "avi", "mpg", "mpeg", "txt", "", NULL}, - { "redir", "lua", "mp3", "oga", "ogg", "wav", NULL }, - { "*", NULL }, - }; - const char **asset_masks = masks[category]; - - const RString ext = GetExtension( asPaths[p] ); - - for( int i = 0; asset_masks[i]; ++i ) + const RString ext = GetExtension(asPaths[p]); + bool matches= category == EC_OTHER || ext == "redir"; + if(!matches) { - // No extension means directories. - if( asset_masks[i][0] == 0 ) + FileType ft= ActorUtil::GetFileType(asPaths[p]); + switch(ft) { - if( !IsADirectory(asPaths[p]) ) - continue; - - RString sXMLPath = asPaths[p] + "/default.xml"; - if( DoesFileExist(sXMLPath) ) - { - asElementPaths.push_back( sXMLPath ); + case FT_Bitmap: + case FT_Sprite: + case FT_Movie: + case FT_Xml: + case FT_Model: + case FT_Lua: + matches= category == EC_BGANIMATIONS || category == EC_GRAPHICS; break; - } - - RString sLuaPath = asPaths[p] + "/default.lua"; - if( DoesFileExist(sLuaPath) ) - { - asElementPaths.push_back( sLuaPath ); + case FT_Ini: + matches= category == EC_FONTS; + break; + case FT_Directory: + { + RString sXMLPath = asPaths[p] + "/default.xml"; + if(DoesFileExist(sXMLPath)) + { + asElementPaths.push_back(sXMLPath); + break; + } + RString sLuaPath = asPaths[p] + "/default.lua"; + if(DoesFileExist(sLuaPath)) + { + asElementPaths.push_back(sLuaPath); + break; + } + } + break; + case FT_Sound: + matches= category == EC_SOUNDS; + break; + default: + matches= false; break; - } - } - - if( ext == asset_masks[i] || !strcmp(asset_masks[i], "*") ) - { - asElementPaths.push_back( asPaths[p] ); - break; } } + if(matches) + { + asElementPaths.push_back(asPaths[p]); + } } }