float TrailUtil::GetTotalSeconds( const Trail *pTrail ) { float fSecs = 0; FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) fSecs += e->pSong->m_fMusicLengthSeconds; return fSecs; }
float Sprite::GetAnimationLengthSeconds() const { float fTotal = 0; FOREACH_CONST( State, m_States, s ) fTotal += s->fDelay; return fTotal; }
void OptionRow::LoadNormal( const OptionRowDefinition &def, OptionRowHandler *pHand, bool bFirstItemGoesDown ) { m_RowDef = def; m_RowType = OptionRow::ROW_NORMAL; m_pHand = pHand; m_bFirstItemGoesDown = bFirstItemGoesDown; if( m_pHand ) { FOREACH_CONST( CString, m_pHand->m_vsReloadRowMessages, m ) MESSAGEMAN->Subscribe( this, *m ); } FOREACH_PlayerNumber( p ) { vector<bool> &vbSelected = m_vbSelected[p]; vbSelected.resize( 0 ); vbSelected.resize( m_RowDef.choices.size(), false ); // set select the first item if a SELECT_ONE row if( vbSelected.size() && m_RowDef.selectType == SELECT_ONE ) vbSelected[0] = true; } // TRICKY: Insert a down arrow as the first choice in the row. if( m_bFirstItemGoesDown ) { m_RowDef.choices.insert( m_RowDef.choices.begin(), NEXT_ROW_NAME ); FOREACH_PlayerNumber( p ) m_vbSelected[p].insert( m_vbSelected[p].begin(), false ); } }
void InputHandler_MacOSX_HID::QueueCallback( void *target, int result, void *refcon, void *sender ) { // The result seems useless as you can't actually return anything... // refcon is the Device number RageTimer now; InputHandler_MacOSX_HID *This = (InputHandler_MacOSX_HID *)target; IOHIDQueueInterface **queue = (IOHIDQueueInterface **)sender; IOHIDEventStruct event; AbsoluteTime zeroTime = { 0, 0 }; HIDDevice *dev = This->m_vDevices[size_t( refcon )]; vector<DeviceInput> vPresses; while( (result = CALL(queue, getNextEvent, &event, zeroTime, 0)) == kIOReturnSuccess ) { if( event.longValueSize != 0 && event.longValue != NULL ) { free( event.longValue ); continue; } //LOG->Trace( "Got event with cookie %p, value %d", event.elementCookie, int(event.value) ); dev->GetButtonPresses( vPresses, event.elementCookie, event.value, now ); } FOREACH_CONST( DeviceInput, vPresses, i ) INPUTFILTER->ButtonPressed( *i ); }
void ScreenOptionsMaster::ImportOptions( int r, const vector<PlayerNumber> &vpns ) { FOREACH_CONST( PlayerNumber, vpns, pn ) ASSERT( GAMESTATE->IsHumanPlayer(*pn) ); OptionRow &row = *m_Rows[r]; row.ImportOptions( vpns ); }
float AnimatedTexture::GetAnimationLengthSeconds() const { float fTotalSeconds = 0; FOREACH_CONST( AnimatedTextureState, vFrames, ats ) fTotalSeconds += ats->fDelaySecs; return fTotalSeconds; }
void OptionRow::DetachHandler() { if( m_pHand ) { FOREACH_CONST( CString, m_pHand->m_vsReloadRowMessages, m ) MESSAGEMAN->Unsubscribe( this, *m ); } m_pHand = NULL; }
MessageSubscriber &MessageSubscriber::operator=(const MessageSubscriber &cpy) { if(&cpy == this) return *this; UnsubscribeAll(); FOREACH_CONST( RString, cpy.m_vsSubscribedTo, msg ) this->SubscribeToMessage( *msg ); return *this; }
void BackgroundUtil::GetGlobalBGAnimations( const Song *pSong, const RString &sMatch, vector<RString> &vsPathsOut, vector<RString> &vsNamesOut ) { vsPathsOut.clear(); GetDirListing( BG_ANIMS_DIR+sMatch+"*", vsPathsOut, true, true ); GetDirListing( BG_ANIMS_DIR+sMatch+"*.xml", vsPathsOut, false, true ); vsNamesOut.clear(); FOREACH_CONST( RString, vsPathsOut, s ) vsNamesOut.push_back( Basename(*s) ); StripCvsAndSvn( vsPathsOut, vsNamesOut ); }
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 ); }
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 }
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 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 ); }
static StageStats AccumPlayedStageStats( const vector<StageStats>& vss ) { StageStats ssreturn; if( !vss.empty() ) { ssreturn.m_pStyle = vss[0].m_pStyle; ssreturn.m_playMode = vss[0].m_playMode; } FOREACH_CONST( StageStats, vss, ss ) ssreturn.AddStats( *ss ); unsigned uNumSongs = ssreturn.m_vpPlayedSongs.size(); if( uNumSongs == 0 ) return ssreturn; // don't divide by 0 below /* Scale radar percentages back down to roughly 0..1. Don't scale RadarCategory_TapsAndHolds * and the rest, which are counters. */ // FIXME: Weight each song by the number of stages it took to account for // long, marathon. FOREACH_EnabledPlayer( p ) { for( int r = 0; r < RadarCategory_TapsAndHolds; r++) { ssreturn.m_player[p].m_radarPossible[r] /= uNumSongs; ssreturn.m_player[p].m_radarActual[r] /= uNumSongs; } } FOREACH_EnabledMultiPlayer( p ) { for( int r = 0; r < RadarCategory_TapsAndHolds; r++) { ssreturn.m_multiPlayer[p].m_radarPossible[r] /= uNumSongs; ssreturn.m_multiPlayer[p].m_radarActual[r] /= uNumSongs; } } return ssreturn; }
void Actor::UnsubcribeAndClearCommands() { FOREACH_CONST( CString, m_vsSubscribedTo, s ) MESSAGEMAN->Unsubscribe( this, *s ); m_vsSubscribedTo.clear(); }
void FileTransfer::StartTransfer( TransferType type, const RString &sURL, const RString &sSrcFile, const RString &sDestFile ) { RString Proto; RString Server; int Port=80; RString sAddress; if( !ParseHTTPAddress( sURL, Proto, Server, Port, sAddress ) ) { m_sStatus = "Invalid URL."; m_bFinished = true; UpdateProgress(); return; } m_bSavingFile = sDestFile != ""; m_sBaseAddress = "http://" + Server; if( Port != 80 ) m_sBaseAddress += ssprintf( ":%d", Port ); m_sBaseAddress += "/"; if( sAddress.Right(1) != "/" ) { m_sEndName = Basename( sAddress ); m_sBaseAddress += Dirname( sAddress ); } else { m_sEndName = ""; } // Open the file... // First find out if a file by this name already exists if so, then we gotta // ditch out. // XXX: This should be fixed by a prompt or something? // if we are not talking about a file, let's not worry if( m_sEndName != "" && m_bSavingFile ) { if( !m_fOutputFile.Open( sDestFile, RageFile::WRITE | RageFile::STREAMED ) ) { m_sStatus = m_fOutputFile.GetError(); UpdateProgress(); return; } } // Continue... sAddress = URLEncode( sAddress ); if ( sAddress != "/" ) sAddress = "/" + sAddress; m_wSocket.close(); m_wSocket.create(); m_wSocket.blocking = true; if( !m_wSocket.connect( Server, (short) Port ) ) { m_sStatus = "Failed to connect."; UpdateProgress(); return; } // Produce HTTP header RString sAction; switch( type ) { case upload: sAction = "POST"; break; case download: sAction = "GET"; break; } vector<RString> vsHeaders; vsHeaders.push_back( sAction+" "+sAddress+" HTTP/1.0" ); vsHeaders.push_back( "Host: " + Server ); vsHeaders.push_back( "Cookie: " + g_sCookie.Get() ); vsHeaders.push_back( "Connection: closed" ); string sBoundary = "--ZzAaB03x"; vsHeaders.push_back( "Content-Type: multipart/form-data; boundary=" + sBoundary ); RString sRequestPayload; if( type == upload ) { RageFile f; if( !f.Open( sSrcFile ) ) FAIL_M( f.GetError() ); sRequestPayload.reserve( f.GetFileSize() ); int iBytesRead = f.Read( sRequestPayload ); if( iBytesRead == -1 ) FAIL_M( f.GetError() ); sRequestPayload = "--" + sBoundary + "\r\n" + "Content-Disposition: form-data; name=\"name\"\r\n" + "\r\n" + "Chris\r\n" + "--" + sBoundary + "\r\n" + "Content-Disposition: form-data; name=\"userfile\"; filename=\"" + Basename(sSrcFile) + "\"\r\n" + "Content-Type: application/zip\r\n" + "\r\n" + sRequestPayload + "\r\n" + "--" + sBoundary + "--"; } /* if( sRequestPayload.size() > 0 ) { sHeader += "Content-Type: application/octet-stream\r\n"; sHeader += "Content-Length: multipart/form-data; boundary=" + sBoundary + "\r\n"; //sHeader += "Content-Length: " + ssprintf("%d",sRequestPayload.size()) + "\r\n"; } */ vsHeaders.push_back( "Content-Length: " + ssprintf("%zd",sRequestPayload.size()) ); RString sHeader; FOREACH_CONST( RString, vsHeaders, h ) sHeader += *h + "\r\n"; sHeader += "\r\n"; m_wSocket.SendData( sHeader.c_str(), sHeader.length() ); m_wSocket.SendData( "\r\n" ); m_wSocket.SendData( sRequestPayload.GetBuffer(), sRequestPayload.size() ); m_sStatus = "Header Sent."; m_wSocket.blocking = false; m_bIsDownloading = true; m_sBUFFER = ""; m_bGotHeader = false; UpdateProgress(); }
void MessageSubscriber::UnsubscribeAll() { FOREACH_CONST( RString, m_vsSubscribedTo, s ) MESSAGEMAN->Unsubscribe( this, *s ); m_vsSubscribedTo.clear(); }
virtual void Load( OptionRowDefinition &defOut, CString sParam ) { ASSERT( sParam.size() ); if( sParam.CompareNoCase("NoteSkins")==0 ) { FillNoteSkins( defOut, sParam ); return; } else if( sParam.CompareNoCase("Steps")==0 ) { FillSteps( defOut, sParam, false ); return; } else if( sParam.CompareNoCase("StepsLocked")==0 ) { FillSteps( defOut, sParam, true ); return; } else if( sParam.CompareNoCase("Characters")==0 ) { FillCharacters( defOut, sParam ); return; } else if( sParam.CompareNoCase("Styles")==0 ) { FillStyles( defOut, sParam ); return; } else if( sParam.CompareNoCase("Groups")==0 ) { FillGroups( defOut, sParam ); return; } else if( sParam.CompareNoCase("Difficulties")==0 ) { FillDifficulties( defOut, sParam ); return; } else if( sParam.CompareNoCase("SongsInCurrentSongGroup")==0 ) { FillSongsInCurrentSongGroup( defOut, sParam ); return; } Init(); defOut.Init(); m_bUseModNameForIcon = true; defOut.name = sParam; Default.Load( -1, ParseCommands(ENTRY_DEFAULT(sParam)) ); /* Parse the basic configuration metric. */ Commands cmds = ParseCommands( ENTRY(sParam) ); if( cmds.v.size() < 1 ) RageException::Throw( "Parse error in ScreenOptionsMaster::%s", sParam.c_str() ); defOut.bOneChoiceForAllPlayers = false; const int NumCols = atoi( cmds.v[0].m_vsArgs[0] ); for( unsigned i=1; i<cmds.v.size(); i++ ) { const Command &cmd = cmds.v[i]; CString sName = cmd.GetName(); if( sName == "together" ) defOut.bOneChoiceForAllPlayers = true; else if( sName == "selectmultiple" ) defOut.selectType = SELECT_MULTIPLE; else if( sName == "selectone" ) defOut.selectType = SELECT_ONE; else if( sName == "selectnone" ) defOut.selectType = SELECT_NONE; else if( sName == "showoneinrow" ) defOut.layoutType = LAYOUT_SHOW_ONE_IN_ROW; else if( sName == "reloadrowmessages" ) { for( unsigned a=1; a<cmd.m_vsArgs.size(); a++ ) m_vsReloadRowMessages.push_back( cmd.m_vsArgs[a] ); } else if( sName == "enabledforplayers" ) { defOut.m_vEnabledForPlayers.clear(); for( unsigned a=1; a<cmd.m_vsArgs.size(); a++ ) { CString sArg = cmd.m_vsArgs[a]; PlayerNumber pn = (PlayerNumber)(atoi(sArg)-1); ASSERT( pn >= 0 && pn < NUM_PLAYERS ); defOut.m_vEnabledForPlayers.insert( pn ); } } else if( sName == "exportonchange" ) defOut.m_bExportOnChange = true; else if( sName == "broadcastonexport" ) { for( unsigned i=1; i<cmd.m_vsArgs.size(); i++ ) m_vsBroadcastOnExport.push_back( cmd.m_vsArgs[i] ); } else RageException::Throw( "Unkown row flag \"%s\"", sName.c_str() ); } for( int col = 0; col < NumCols; ++col ) { GameCommand mc; mc.Load( 0, ParseCommands(ENTRY_MODE(sParam, col)) ); /* If the row has just one entry, use the name of the row as the name of the * entry. If it has more than one, each one must be specified explicitly. */ if( mc.m_sName == "" && NumCols == 1 ) mc.m_sName = sParam; if( mc.m_sName == "" ) RageException::Throw( "List \"%s\", col %i has no name", sParam.c_str(), col ); if( !mc.IsPlayable() ) { LOG->Trace( "\"%s\" is not playable.", sParam.c_str() ); continue; } ListEntries.push_back( mc ); CString sName = mc.m_sName; CString sChoice = mc.m_sName; defOut.choices.push_back( sChoice ); } // OpenITG hack: load player-defined speed mods if (sParam == "Speed") { set<CString> additionalSet; // load anything from the machine profile first Profile *pMProf = PROFILEMAN->GetMachineProfile(); if (pMProf != NULL) { FOREACH_CONST(CString, pMProf->m_sPlayerAdditionalModifiers, mod) additionalSet.insert(*mod); } // then load anything from the players' profiles FOREACH_EnabledPlayer( pn ) { Profile *pProf = PROFILEMAN->GetProfile(pn); if (pProf == NULL) continue; FOREACH_CONST(CString, pProf->m_sPlayerAdditionalModifiers, mod) additionalSet.insert(*mod); } FOREACHS_CONST( CString, additionalSet, addit_mod ) { Regex mult("^[0-9]{1,2}(\\.[0-9]{1,2})?x$"); Regex constmod("^C[0-9]{1,4}$"); Regex mmod("^M[0-9]{1,4}$"); CString sAdditModName; if (mult.Compare(*addit_mod)) { float factor = 1.0f; sscanf(*addit_mod, "%fx", &factor); sAdditModName = ssprintf("x%.1f", factor); } else if (constmod.Compare(*addit_mod)) { unsigned bpm = 300; sscanf(*addit_mod, "C%u", &bpm); sAdditModName = ssprintf("c%u", bpm); } else if (mmod.Compare(*addit_mod)) { unsigned bpm = 600; sscanf(*addit_mod, "M%u", &bpm); sAdditModName = ssprintf("m%u", bpm); } else ASSERT(0); // how'd it get in here in the first place... GameCommand mc; mc.Load( 0, ParseCommands(CString("mod,")+*addit_mod+";name,"+sAdditModName) ); if ( !mc.IsPlayable() ) { LOG->Trace( "Additional mod \"%s\" is not playable.", addit_mod->c_str() ); continue; } ListEntries.push_back(mc); defOut.choices.push_back(mc.m_sName); }
MessageSubscriber::MessageSubscriber( const MessageSubscriber &cpy ): IMessageSubscriber(cpy) { FOREACH_CONST( RString, cpy.m_vsSubscribedTo, msg ) this->SubscribeToMessage( *msg ); }
void ThemeManager::LoadThemeMetrics( const RString &sThemeName_, const RString &sLanguage_ ) { if( g_pLoadedThemeData == NULL ) g_pLoadedThemeData = new LoadedThemeData; // Don't delete and recreate LoadedThemeData. There are references iniMetrics and iniStrings // on the stack, so Clear them instead. g_pLoadedThemeData->ClearAll(); g_vThemes.clear(); RString sThemeName(sThemeName_); RString sLanguage(sLanguage_); m_sCurThemeName = sThemeName; m_sCurLanguage = sLanguage; bool bLoadedBase = false; while(1) { ASSERT_M( g_vThemes.size() < 20, "Circular theme fallback references detected." ); g_vThemes.push_back( Theme() ); Theme &t = g_vThemes.back(); t.sThemeName = sThemeName; IniFile iniMetrics; IniFile iniStrings; iniMetrics.ReadFile( GetMetricsIniPath(sThemeName) ); // Load optional language inis (probably mounted by a package) first so that they can be overridden by the current theme. { vector<RString> vs; GetOptionalLanguageIniPaths(vs,sThemeName,sLanguage); FOREACH_CONST(RString,vs,s) iniStrings.ReadFile( *s ); } iniStrings.ReadFile( GetLanguageIniPath(sThemeName,SpecialFiles::BASE_LANGUAGE) ); if( sLanguage.CompareNoCase(SpecialFiles::BASE_LANGUAGE) ) iniStrings.ReadFile( GetLanguageIniPath(sThemeName,sLanguage) ); bool bIsBaseTheme = !sThemeName.CompareNoCase(SpecialFiles::BASE_THEME_NAME); iniMetrics.GetValue( "Global", "IsBaseTheme", bIsBaseTheme ); if( bIsBaseTheme ) bLoadedBase = true; /* Read the fallback theme. If no fallback theme is specified, and we haven't * already loaded it, fall back on SpecialFiles::BASE_THEME_NAME. * That way, default theme fallbacks can be disabled with * "FallbackTheme=". */ RString sFallback; if( !iniMetrics.GetValue("Global","FallbackTheme",sFallback) ) { if( sThemeName.CompareNoCase( SpecialFiles::BASE_THEME_NAME ) && !bLoadedBase ) sFallback = SpecialFiles::BASE_THEME_NAME; } /* We actually want to load themes bottom-to-top, loading fallback themes * first, so derived themes overwrite metrics in fallback themes. But, we * need to load the derived theme first, to find out the name of the fallback * theme. Avoid having to load IniFile twice, merging the fallback theme * into the derived theme that we've already loaded. */ XmlFileUtil::MergeIniUnder( &iniMetrics, &g_pLoadedThemeData->iniMetrics ); XmlFileUtil::MergeIniUnder( &iniStrings, &g_pLoadedThemeData->iniStrings ); if( sFallback.empty() ) break; sThemeName = sFallback; } // Overlay metrics from the command line. RString sMetric; for( int i = 0; GetCommandlineArgument( "metric", &sMetric, i ); ++i ) { /* sMetric must be "foo::bar=baz". "foo" and "bar" never contain "=", so * in "foo::bar=1+1=2", "baz" is always "1+1=2". Neither foo nor bar may * be empty, but baz may be. */ Regex re( "^([^=]+)::([^=]+)=(.*)$" ); vector<RString> sBits; if( !re.Compare( sMetric, sBits ) ) RageException::Throw( "Invalid argument \"--metric=%s\".", sMetric.c_str() ); g_pLoadedThemeData->iniMetrics.SetValue( sBits[0], sBits[1], sBits[2] ); } LOG->MapLog( "theme", "Theme: %s", m_sCurThemeName.c_str() ); LOG->MapLog( "language", "Language: %s", m_sCurLanguage.c_str() ); }