void BackgroundUtil::GetSongBGAnimations( const Song *pSong, const RString &sMatch, vector<RString> &vsPathsOut, vector<RString> &vsNamesOut ) { vsPathsOut.clear(); if( sMatch.empty() ) { GetDirListing( pSong->GetSongDir()+"*", vsPathsOut, true, true ); } else { GetDirListing( pSong->GetSongDir()+sMatch, vsPathsOut, true, true ); } vsNamesOut.clear(); FOREACH_CONST( RString, vsPathsOut, s ) vsNamesOut.push_back( Basename(*s) ); StripCvsAndSvn( vsPathsOut, vsNamesOut ); }
void GetRecursiveSubPaths(std::string path, std::vector<std::string> &dst) { std::vector<DirListNode> content = GetDirListing(path); for(unsigned int i=0; i<content.size(); i++){ const DirListNode &n = content[i]; std::string fullpath = path + DIR_DELIM + n.name; dst.push_back(fullpath); GetRecursiveSubPaths(fullpath, dst); } }
static void DoPlayOnceFromDir( CString sPath ) { if( sPath == "" ) return; // make sure there's a slash at the end of this path if( sPath.Right(1) != "/" ) sPath += "/"; CStringArray arraySoundFiles; GetDirListing( sPath + "*.mp3", arraySoundFiles ); GetDirListing( sPath + "*.wav", arraySoundFiles ); GetDirListing( sPath + "*.ogg", arraySoundFiles ); if( arraySoundFiles.empty() ) return; int index = rand() % arraySoundFiles.size(); SOUNDMAN->PlayOnce( sPath + arraySoundFiles[index] ); }
static void DeleteEmptyDirectories( const CString &sDir ) { vector<CString> asNewDirs; GetDirListing( sDir + "/*", asNewDirs, false, true ); for( unsigned i = 0; i < asNewDirs.size(); ++i ) { ASSERT_M( IsADirectory(asNewDirs[i]), asNewDirs[i] ); DeleteEmptyDirectories( asNewDirs[i] ); } FILEMAN->Remove( sDir ); }
/* Given the INI for a font, find all of the texture pages for the font. */ void Font::GetFontPaths( const RString &sFontIniPath, vector<RString> &asTexturePathsOut ) { RString sPrefix = SetExtension( sFontIniPath, "" ); vector<RString> asFiles; GetDirListing( sPrefix + "*", asFiles, false, true ); for( unsigned i = 0; i < asFiles.size(); ++i ) { if( !asFiles[i].Right(4).EqualsNoCase(".ini") ) asTexturePathsOut.push_back( asFiles[i] ); } }
static void EmptyDir( CString dir ) { ASSERT(dir[dir.size()-1] == '/'); CStringArray asCacheFileNames; GetDirListing( dir, asCacheFileNames ); for( unsigned i=0; i<asCacheFileNames.size(); i++ ) { if( !IsADirectory(dir + asCacheFileNames[i]) ) FILEMAN->Remove( dir + asCacheFileNames[i] ); } }
void ScreenPackages::RefreshPackages() { GetDirListing( "Packages/*.*zip", m_Packages, false, false ); if ( m_iPackagesPos < 0 ) m_iPackagesPos = 0; if( (unsigned) m_iPackagesPos >= m_Packages.size() ) m_iPackagesPos = m_Packages.size() - 1; UpdatePackagesList(); }
void AnnouncerManager::GetAnnouncerNames( vector<RString>& AddTo ) { GetDirListing( ANNOUNCERS_DIR+"*", AddTo, true ); StripCvsAndSvn( AddTo ); StripMacResourceForks( AddTo ); // strip out the empty announcer folder for( int i=AddTo.size()-1; i>=0; i-- ) if( !strcasecmp( AddTo[i], EMPTY_ANNOUNCER_NAME ) ) AddTo.erase(AddTo.begin()+i, AddTo.begin()+i+1 ); }
void AnnouncerManager::GetAnnouncerNames( CStringArray& AddTo ) { GetDirListing( ANNOUNCERS_DIR+"*", AddTo, true ); // strip out the folder called "CVS" and EMPTY_ANNOUNCER_NAME for( int i=AddTo.size()-1; i>=0; i-- ) if( !stricmp( AddTo[i], "cvs" ) ) AddTo.erase(AddTo.begin()+i, AddTo.begin()+i+1 ); for( int i=AddTo.size()-1; i>=0; i-- ) if( !stricmp( AddTo[i], EMPTY_ANNOUNCER_NAME ) ) AddTo.erase(AddTo.begin()+i, AddTo.begin()+i+1 ); }
void BackgroundUtil::GetBackgroundEffects( const RString &_sName, vector<RString> &vsPathsOut, vector<RString> &vsNamesOut ) { RString sName = _sName; if( sName == "" ) sName = "*"; vsPathsOut.clear(); GetDirListing( BACKGROUND_EFFECTS_DIR+sName+".lua", vsPathsOut, false, true ); vsNamesOut.clear(); FOREACH_CONST( RString, vsPathsOut, s ) vsNamesOut.push_back( GetFileNameWithoutExtension(*s) ); StripCvsAndSvn( vsPathsOut, vsNamesOut ); }
// check to see if this player's card exists and if it has any matches // to the given pattern. if so, then add matches into the patches list. bool ScreenArcadePatch::HasPatch( PlayerNumber pn, const CStringArray &vsPatterns ) { // no card for this player if( MEMCARDMAN->GetCardState(pn) != MEMORY_CARD_STATE_READY ) return false; // no reason to check, since we already have a patch if( m_vsPatches.size() ) return false; STATE_TEXT( ssprintf("Checking Player %d's card for a patch...", pn+1) ); // attempt to read from the card directly m_sProfileDir = MEM_CARD_MOUNT_POINT[pn]; // fix up the path so we can append to it if( m_sProfileDir.Right(1) != "/" ) m_sProfileDir += "/"; // mount the card for a minute so we can check for files on it if( !MEMCARDMAN->MountCard(pn, 60) ) { STATE_TEXT( ssprintf("Error mounting Player %d's card!", pn+1) ); return false; } for( unsigned i = 0;i < vsPatterns.size(); i++ ) { LOG->Trace( "Finding matches for %s%s", m_sProfileDir.c_str(), vsPatterns[i].c_str() ); GetDirListing( m_sProfileDir + vsPatterns[i], m_vsPatches ); // if we found something, stop early. if( m_vsPatches.size() != 0 ) break; } MEMCARDMAN->UnmountCard( pn ); // no patches were found on the drive if( m_vsPatches.size() == 0 ) return false; CString sDebugMsg = ssprintf( "%i match%s found: ", m_vsPatches.size(), (m_vsPatches.size() != 1) ? "es" : "" ); sDebugMsg += join( ", ", m_vsPatches ); LOG->Trace( sDebugMsg.c_str() ); return true; }
unsigned int GetHashForDirectory( const CString &sDir ) { unsigned int hash = 0; hash += GetHashForString( sDir ); CStringArray arrayFiles; GetDirListing( sDir+"*", arrayFiles, false ); for( unsigned i=0; i<arrayFiles.size(); i++ ) { const CString sFilePath = sDir + arrayFiles[i]; hash += GetHashForFile( sFilePath ); } return hash; }
bool KSFLoader::LoadFromDir( const RString &sDir, Song &out ) { LOG->Trace( "KSFLoader::LoadFromDir(%s)", sDir.c_str() ); vector<RString> arrayKSFFileNames; GetDirListing( sDir + RString("*.ksf"), arrayKSFFileNames ); // We shouldn't have been called to begin with if there were no KSFs. ASSERT( arrayKSFFileNames.size() != 0 ); bool bKIUCompliant = false; /* With Split Timing, there has to be a backup Song Timing in case * anything goes wrong. As these files are kept in alphabetical * order (hopefully), it is best to use the LAST file for timing * purposes, for that is the "normal", or easiest difficulty. * Usually. */ // Nevermind, kiu compilancy is screwing things up: // IE, I have two simfiles, oh wich each have four ksf files, the first one has // the first ksf with directmove timing changes, and the rest are not, everything // goes fine. In the other hand I have my second simfile with the first ksf file // without directmove timing changes and the rest have changes, changes are not // loaded due to kiucompilancy in the first ksf file. // About the "normal" thing, my simfiles' ksfs uses non-standard naming so // the last chart is usually nightmare or normal, I use easy and normal // indistinctly for SM so it shouldn't matter, I use piu fiesta/ex naming // for directmove though, and we're just gathering basic info anyway, and // most of the time all the KSF files have the same info in the #TITLE:; section unsigned files = arrayKSFFileNames.size(); RString dir = out.GetSongDir(); if( !LoadGlobalData(dir + arrayKSFFileNames[files - 1], out, bKIUCompliant) ) return false; out.m_sSongFileName = dir + arrayKSFFileNames[files - 1]; // load the Steps from the rest of the KSF files for( unsigned i=0; i<files; i++ ) { Steps* pNewNotes = out.CreateSteps(); if( !LoadFromKSFFile(dir + arrayKSFFileNames[i], *pNewNotes, out, bKIUCompliant) ) { delete pNewNotes; continue; } pNewNotes->SetFilename(dir + arrayKSFFileNames[i]); out.AddSteps( pNewNotes ); } return true; }
void LanguagesDlg::OnSelchangeListThemes() { // TODO: Add your control notification handler code here m_listLanguages.ResetContent(); RString sTheme = GetCurrentString( m_listThemes ); if( !sTheme.empty() ) { RString sLanguagesDir = SpecialFiles::THEMES_DIR + sTheme + "/" + SpecialFiles::LANGUAGES_SUBDIR; vector<RString> vs; GetDirListing( sLanguagesDir+"*.ini", vs, false ); FOREACH_CONST( RString, vs, s ) { RString sIsoCode = GetFileNameWithoutExtension(*s); RString sLanguage = SMPackageUtil::GetLanguageDisplayString(sIsoCode); m_listLanguages.AddString( ConvertUTF8ToACP(sLanguage) ); }
BOOL LanguagesDlg::OnInitDialog() { CDialog::OnInitDialog(); DialogUtil::LocalizeDialogAndContents( *this ); vector<RString> vs; GetDirListing( SpecialFiles::THEMES_DIR+"*", vs, true ); StripCvsAndSvn( vs ); FOREACH_CONST( RString, vs, s ) m_listThemes.AddString( *s ); if( !vs.empty() ) m_listThemes.SetSel( 0 ); OnSelchangeListThemes(); return TRUE; // return TRUE unless you set the focus to a control }
bool CryptManager::VerifyFileWithFile( RString sPath, RString sSignatureFile ) { if( VerifyFileWithFile(sPath, sSignatureFile, PUBLIC_KEY_PATH) ) return true; vector<RString> asKeys; GetDirListing( ALTERNATE_PUBLIC_KEY_DIR, asKeys, false, true ); for( unsigned i = 0; i < asKeys.size(); ++i ) { const RString &sKey = asKeys[i]; LOG->Trace( "Trying alternate key \"%s\" ...", sKey.c_str() ); if( VerifyFileWithFile(sPath, sSignatureFile, sKey) ) return true; } return false; }
bool RecursiveDeleteContent(std::string path) { std::cerr<<"Removing content of \""<<path<<"\""<<std::endl; std::vector<DirListNode> list = GetDirListing(path); for(unsigned int i=0; i<list.size(); i++) { if(trim(list[i].name) == "." || trim(list[i].name) == "..") continue; std::string childpath = path + "/" + list[i].name; bool r = RecursiveDelete(childpath); if(r == false) { std::cerr<<"Removing \""<<childpath<<"\" failed"<<std::endl; return false; } } return true; }
bool RecursiveDelete(std::string path) { infostream<<"Recursively deleting \""<<path<<"\""<<std::endl; DWORD attr = GetFileAttributes(path.c_str()); bool is_directory = (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)); if(!is_directory) { infostream<<"RecursiveDelete: Deleting file "<<path<<std::endl; //bool did = DeleteFile(path.c_str()); bool did = true; if(!did){ errorstream<<"RecursiveDelete: Failed to delete file " <<path<<std::endl; return false; } } else { infostream<<"RecursiveDelete: Deleting content of directory " <<path<<std::endl; std::vector<DirListNode> content = GetDirListing(path); for(int i=0; i<content.size(); i++){ const DirListNode &n = content[i]; std::string fullpath = path + DIR_DELIM + n.name; bool did = RecursiveDelete(fullpath); if(!did){ errorstream<<"RecursiveDelete: Failed to recurse to " <<fullpath<<std::endl; return false; } } infostream<<"RecursiveDelete: Deleting directory "<<path<<std::endl; //bool did = RemoveDirectory(path.c_str(); bool did = true; if(!did){ errorstream<<"Failed to recursively delete directory " <<path<<std::endl; return false; } } return true; }
CharacterManager::CharacterManager() { // Register with Lua. { Lua *L = LUA->Get(); lua_pushstring( L, "CHARMAN" ); this->PushSelf( L ); lua_settable( L, LUA_GLOBALSINDEX ); LUA->Release( L ); } for( unsigned i=0; i<m_pCharacters.size(); i++ ) SAFE_DELETE( m_pCharacters[i] ); m_pCharacters.clear(); vector<RString> as; GetDirListing( CHARACTERS_DIR "*", as, true, true ); StripCvsAndSvn( as ); StripMacResourceForks( as ); bool FoundDefault = false; for( unsigned i=0; i<as.size(); i++ ) { RString sCharName, sDummy; splitpath(as[i], sDummy, sCharName, sDummy); sCharName.MakeLower(); if( sCharName.CompareNoCase("default")==0 ) FoundDefault = true; Character* pChar = new Character; if( pChar->Load( as[i] ) ) m_pCharacters.push_back( pChar ); else delete pChar; } if( !FoundDefault ) RageException::Throw( "'Characters/default' is missing." ); // If FoundDefault, then we're not empty. -Chris // if( m_pCharacters.empty() ) // RageException::Throw( "Couldn't find any character definitions" ); }
void BackgroundUtil::GetSongBitmaps( const Song *pSong, const RString &sMatch, vector<RString> &vsPathsOut, vector<RString> &vsNamesOut ) { vsPathsOut.clear(); if( sMatch.empty() ) { FILEMAN->GetDirListingWithMultipleExtensions(pSong->GetSongDir()+sMatch, ActorUtil::GetTypeExtensionList(FT_Bitmap), vsPathsOut, false, true); } else { GetDirListing( pSong->GetSongDir()+sMatch, vsPathsOut, false, true ); } vsNamesOut.clear(); FOREACH_CONST( RString, vsPathsOut, s ) vsNamesOut.push_back( Basename(*s) ); StripCvsAndSvn( vsPathsOut, vsNamesOut ); }
ScoreDisplayBattle::ScoreDisplayBattle() { LOG->Trace( "ScoreDisplayBattle::ScoreDisplayBattle()" ); m_sprFrame.Load( THEME->GetPathG("ScoreDisplayBattle","frame") ); this->AddChild( &m_sprFrame ); for( int i=0; i<NUM_INVENTORY_SLOTS; i++ ) { m_ItemIcon[i].SetXY( ITEM_X(i), ITEM_Y(i) ); m_ItemIcon[i].StopAnimating(); this->AddChild( &m_ItemIcon[i] ); } CStringArray asIconPaths; GetDirListing( THEME->GetCurThemeDir()+"Graphic/ScoreDisplayBattle icon*.*", asIconPaths ); for( unsigned j=0; j<asIconPaths.size(); j++ ) TEXTUREMAN->CacheTexture( asIconPaths[j] ); }
void ScreenUserPacks::StartSongThread() { while ( !m_bStopThread ) { if (m_bPrompt) { usleep( 10000 ); continue; } if ( m_CurPlayer != PLAYER_INVALID && MEMCARDMAN->GetCardState(m_CurPlayer) != MEMORY_CARD_STATE_READY ) { CStringArray asBlankChoices; m_USBZips.SetChoices( asBlankChoices ); m_CurPlayer = PLAYER_INVALID; continue; } FOREACH_PlayerNumber( pn ) { if ( m_CurPlayer != PLAYER_INVALID ) break; if ( MEMCARDMAN->GetCardState(pn) == MEMORY_CARD_STATE_READY ) { bool bSuccessfulMount = MEMCARDMAN->MountCard(pn); if (!bSuccessfulMount) continue; CString sDriveDir = MEM_CARD_MOUNT_POINT[pn]; if (sDriveDir.empty()) { MEMCARDMAN->UnmountCard(pn); continue; } CString sPlayerUserPacksDir = sDriveDir + "/" + USER_PACK_TRANSFER_PATH; CStringArray sUSBZips; GetDirListing( sPlayerUserPacksDir+"/*.zip", sUSBZips, false, false ); /**/ MEMCARDMAN->UnmountCard(pn); m_USBZips.SetChoices( sUSBZips ); m_CurPlayer = pn; } } usleep( 1000 ); } }
// this is the diary of a mad man bool GetUSBDeviceList(vector<USBDevice> &pDevList) { FlushDirCache(); std::map< CString, vector<CString> > sDevInterfaceList; vector<CString> sDirList; GetDirListing( "/rootfs/sys/bus/usb/devices/", sDirList, true, false ); for (unsigned i = 0; i < sDirList.size(); i++) { CString sDirEntry = sDirList[i]; vector<CString> components; if (sDirEntry.substr(0, 3) == "usb") continue; split( sDirEntry, ":", components, true ); if ( components.size() < 2 ) continue; if ( ! IsADirectory( "/rootfs/sys/bus/usb/devices/" + components[0] ) ) continue; // I win --infamouspat sDevInterfaceList[components[0]].push_back(components[1]); } map< CString, vector<CString> >::iterator iter; for(iter = sDevInterfaceList.begin(); iter != sDevInterfaceList.end(); iter++) { USBDevice newDev; CString sDevName = iter->first; vector<CString> sDevChildren = iter->second; if ( newDev.Load(sDevName, sDevChildren) ) pDevList.push_back(newDev); } return true; }
/* Given a file in a font, find all of the files for the font. * * Possibilities: * * Normal 16x16.png * Normal [other] 16x16.png * Normal [more] 8x8.png * Normal 16x16.ini * Normal.ini * * Any of the above should find all of the above. Allow the * extension to be omitted. */ void Font::GetFontPaths( const CString &sFontOrTextureFilePath, CStringArray &asTexturePathsOut, CString &sIniPath ) { CString sDir, sFName, sExt; splitpath( sFontOrTextureFilePath, sDir, sFName, sExt ); /* Don't give us a redir; resolve those before sending them here. */ ASSERT( sExt.CompareNoCase("redir") ); /* sFName can't be empty, or we don't know what to search for. */ ASSERT( !sFName.empty() ); CString sFontName = GetFontName( sFName ); CStringArray asFiles; GetDirListing( sDir+sFontName + "*", asFiles, false, false ); for( unsigned i = 0; i < asFiles.size(); ++i ) { /* We now have a list of possibilities, but it may include false positives, * such as "Normal2" when the font name is "Normal". Weed them. */ if( GetFontName(asFiles[i]).CompareNoCase(sFontName) ) continue; /* If it's an INI, and we don't already have an INI, use it. */ if( !asFiles[i].Right(4).CompareNoCase(".ini")) { if( !sIniPath.empty() ) RageException::Throw( "More than one INI found\n%s\n%s", sIniPath.c_str(), asFiles[i].c_str() ); sIniPath = sDir+asFiles[i]; continue; } asTexturePathsOut.push_back( sDir+asFiles[i] ); } }
void Sprite::LoadFromNode( const CString& sDir, const XNode* pNode ) { retry: CString sTextureFile; CString sPath; if( pNode->GetAttrValue( "Texture", sTextureFile ) ) { sPath = sDir + sTextureFile; CollapsePath( sPath ); } if( !sPath.empty() ) { vector<CString> asElementPaths; GetDirListing( sPath + "*", asElementPaths, false, true ); if( asElementPaths.size() == 0 ) { CString sMessage = ssprintf( "The sprite file '%s' points to a texture '%s' which doesn't exist.", m_sSpritePath.c_str(), sPath.c_str() ); switch( Dialog::AbortRetryIgnore(sMessage) ) { case Dialog::abort: RageException::Throw( "Error reading value 'Texture' from %s.", m_sSpritePath.c_str() ); case Dialog::retry: goto retry; case Dialog::ignore: return; default: ASSERT(0); } } if( asElementPaths.size() > 1 ) { CString message = ssprintf( "There is more than one file that matches " "'%s'. Please remove all but one of these matches.", sPath.c_str() ); RageException::Throw( message ); } sPath = asElementPaths[0]; // Load the texture LoadFromTexture( sPath ); // Read in frames and delays from the sprite file, // overwriting the states that LoadFromTexture created. // If the .sprite file doesn't define any states, leave // frames and delays created during LoadFromTexture(). for( int i=0; true; i++ ) { CString sFrameKey = ssprintf( "Frame%04d", i ); CString sDelayKey = ssprintf( "Delay%04d", i ); State newState; if( !pNode->GetAttrValue( sFrameKey, newState.iFrameIndex ) ) break; if( newState.iFrameIndex >= m_pTexture->GetNumFrames() ) RageException::Throw( "In '%s', %s is %d, but the texture %s only has %d frames.", m_sSpritePath.c_str(), sFrameKey.c_str(), newState.iFrameIndex, sPath.c_str(), m_pTexture->GetNumFrames() ); if( !pNode->GetAttrValue( sDelayKey, newState.fDelay ) ) break; if( i == 0 ) // the ini file defines at least one frame m_States.clear(); // clear before adding m_States.push_back( newState ); } } Actor::LoadFromNode( sDir, pNode ); }
void UserPackManager::GetUserPacks( CStringArray &sAddTo ) { GetDirListing( USER_PACK_SAVE_PATH+"/*.zip", sAddTo, false, false ); }
bool KSFLoader::LoadGlobalData( const CString &sPath, Song &out ) { MsdFile msd; if( !msd.ReadFile( sPath ) ) RageException::Throw( "Error opening file \"%s\": %s", sPath.c_str(), msd.GetError().c_str() ); float BPMPos2 = -1, BPM2 = -1, BPMPos3 = -1, BPM3 = -1;; for( unsigned i=0; i < msd.GetNumValues(); i++ ) { const MsdFile::value_t &sParams = msd.GetValue(i); CString sValueName = sParams[0]; // handle the data if( 0==stricmp(sValueName,"TITLE") ) LoadTags(sParams[1], out); else if( 0==stricmp(sValueName,"BPM") ) out.AddBPMSegment( BPMSegment(0, strtof(sParams[1], NULL)) ); else if( 0==stricmp(sValueName,"BPM2") ) BPM2 = strtof( sParams[1], NULL ); else if( 0==stricmp(sValueName,"BPM3") ) BPM3 = strtof( sParams[1], NULL ); else if( 0==stricmp(sValueName,"BUNKI") ) BPMPos2 = strtof( sParams[1], NULL ) / 100.0f; else if( 0==stricmp(sValueName,"BUNKI2") ) BPMPos3 = strtof( sParams[1], NULL ) / 100.0f; else if( 0==stricmp(sValueName,"STARTTIME") ) out.m_Timing.m_fBeat0OffsetInSeconds = -strtof( sParams[1], NULL )/100; else if( 0==stricmp(sValueName,"TICKCOUNT") || 0==stricmp(sValueName,"STEP") || 0==stricmp(sValueName,"DIFFICULTY")) ; /* Handled in LoadFromKSFFile; don't warn. */ else LOG->Trace( "Unexpected value named '%s'", sValueName.c_str() ); } /* This doesn't work yet: we also need to move the data around, I think, and * we should handle more than one BPM change. */ if( BPM2 > 0 && BPMPos2 > 0 ) { const float BeatsPerSecond = out.GetBPMAtBeat(0) / 60.0f; const float beat = BPMPos2 * BeatsPerSecond; LOG->Trace("BPM %f, BPS %f, BPMPos2 %f, beat %f", out.GetBPMAtBeat(0), BeatsPerSecond, BPMPos2, beat); out.AddBPMSegment( BPMSegment(beat, BPM2) ); } if( BPM3 > 0 && BPMPos3 > 0 ) { const float BeatsPerSecond = out.GetBPMAtBeat(0) / 60.0f; const float beat = BPMPos3 * BeatsPerSecond; LOG->Trace("BPM %f, BPS %f, BPMPos3 %f, beat %f", out.GetBPMAtBeat(0), BeatsPerSecond, BPMPos3, beat); out.AddBPMSegment( BPMSegment(beat, BPM3) ); } /* Try to fill in missing bits of information from the pathname. */ { CStringArray asBits; split( sPath, "/", asBits, true); ASSERT(asBits.size() > 1); LoadTags(asBits[asBits.size()-2], out); } // search for music with song in the file name CStringArray arrayPossibleMusic; GetDirListing( out.GetSongDir() + CString("song.mp3"), arrayPossibleMusic ); GetDirListing( out.GetSongDir() + CString("song.ogg"), arrayPossibleMusic ); GetDirListing( out.GetSongDir() + CString("song.wav"), arrayPossibleMusic ); if( !arrayPossibleMusic.empty() ) // we found a match out.m_sMusicFile = arrayPossibleMusic[0]; return true; }
CString SaveScreenshot( CString sDir, bool bSaveCompressed, bool bMakeSignature, int iIndex ) { // // Find a file name for the screenshot // FlushDirCache(); vector<CString> files; GetDirListing( sDir + "screen*", files, false, false ); sort( files.begin(), files.end() ); /* Files should be of the form "screen######.xxx". Ignore the extension; find * the last file of this form, and use the next number. This way, we don't * write the same screenshot number for different formats (screen00011.bmp, * screen00011.jpg), and we always increase from the end, so if screen00003.jpg * is deleted, we won't fill in the hole (which makes screenshots hard to find). */ if( iIndex == -1 ) { iIndex = 0; for( int i = files.size()-1; i >= 0; --i ) { static Regex re( "^screen([0-9]{5})\\....$" ); vector<CString> matches; if( !re.Compare( files[i], matches ) ) continue; ASSERT( matches.size() == 1 ); iIndex = atoi( matches[0] )+1; break; } } // // Save the screenshot // /* If writing lossy to a memcard, use SAVE_LOSSY_LOW_QUAL, so we don't eat up * lots of space with screenshots. */ RageDisplay::GraphicsFileFormat fmt; if( bSaveCompressed && MEMCARDMAN->PathIsMemCard(sDir) ) fmt = RageDisplay::SAVE_LOSSY_LOW_QUAL; else if( bSaveCompressed ) fmt = RageDisplay::SAVE_LOSSY_HIGH_QUAL; else fmt = RageDisplay::SAVE_LOSSLESS; CString sFileName = ssprintf( "screen%05d.%s",iIndex,bSaveCompressed ? "jpg" : "bmp" ); CString sPath = sDir+sFileName; bool bResult = DISPLAY->SaveScreenshot( sPath, fmt ); if( !bResult ) { SCREENMAN->PlayInvalidSound(); return ""; } SCREENMAN->PlayScreenshotSound(); // We wrote a new file, and SignFile won't pick it up unless we invalidate // the Dir cache. There's got to be a better way of doing this than // thowing out all the cache. -Chris FlushDirCache(); if( PREFSMAN->m_bSignProfileData && bMakeSignature ) CryptManager::SignFileToFile( sPath ); return sFileName; }
void ThemeManager::GetThemeNames( vector<RString>& AddTo ) { GetDirListing( SpecialFiles::THEMES_DIR + "*", AddTo, true ); StripCvsAndSvn( AddTo ); StripMacResourceForks( AddTo ); }
/* Resolves actor paths a la LoadActor("..."), with autowildcarding and .redir * files. Returns a path *within* the Rage filesystem, unlike the FILEMAN * function of the same name. */ bool ActorUtil::ResolvePath( RString &sPath, const RString &sName, bool optional ) { CollapsePath( sPath ); // If we know this is an exact match, don't bother with the GetDirListing, // so "foo" doesn't partial match "foobar" if "foo" exists. RageFileManager::FileType ft = FILEMAN->GetFileType( sPath ); if( ft != RageFileManager::TYPE_FILE && ft != RageFileManager::TYPE_DIR ) { vector<RString> asPaths; GetDirListing( sPath + "*", asPaths, false, true ); // return path too if( asPaths.empty() ) { if(optional) { return false; } RString sError = ssprintf( "%s: references a file \"%s\" which doesn't exist", sName.c_str(), sPath.c_str() ); switch(LuaHelpers::ReportScriptError(sError, "BROKEN_FILE_REFERENCE", true)) { case Dialog::abort: RageException::Throw( "%s", sError.c_str() ); break; case Dialog::retry: FILEMAN->FlushDirCache(); return ResolvePath( sPath, sName ); case Dialog::ignore: return false; default: FAIL_M("Invalid response to Abort/Retry/Ignore dialog"); } } THEME->FilterFileLanguages( asPaths ); if( asPaths.size() > 1 ) { RString sError = ssprintf( "%s: references a file \"%s\" which has multiple matches", sName.c_str(), sPath.c_str() ); sError += "\n" + join( "\n", asPaths ); switch(LuaHelpers::ReportScriptError(sError, "BROKEN_FILE_REFERENCE", true)) { case Dialog::abort: RageException::Throw( "%s", sError.c_str() ); break; case Dialog::retry: FILEMAN->FlushDirCache(); return ResolvePath( sPath, sName ); case Dialog::ignore: asPaths.erase( asPaths.begin()+1, asPaths.end() ); break; default: FAIL_M("Invalid response to Abort/Retry/Ignore dialog"); } } sPath = asPaths[0]; } if( ft == RageFileManager::TYPE_DIR ) { RString sLuaPath = sPath + "/default.lua"; if( DoesFileExist(sLuaPath) ) { sPath = sLuaPath; return true; } } sPath = DerefRedir( sPath ); return true; }