Пример #1
0
float TrailUtil::GetTotalSeconds( const Trail *pTrail )
{
	float fSecs = 0;
	FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e )
		fSecs += e->pSong->m_fMusicLengthSeconds;
	return fSecs;
}
Пример #2
0
float Sprite::GetAnimationLengthSeconds() const
{
	float fTotal = 0;
	FOREACH_CONST( State, m_States, s )
		fTotal += s->fDelay;
	return fTotal;
}
Пример #3
0
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 );
}
Пример #6
0
float AnimatedTexture::GetAnimationLengthSeconds() const
{
	float fTotalSeconds = 0;
	FOREACH_CONST( AnimatedTextureState, vFrames, ats )
		fTotalSeconds += ats->fDelaySecs;
	return fTotalSeconds;
}
Пример #7
0
void OptionRow::DetachHandler()
{
	if( m_pHand )
	{
		FOREACH_CONST( CString, m_pHand->m_vsReloadRowMessages, m )
			MESSAGEMAN->Unsubscribe( this, *m );
	}
	m_pHand = NULL;
}
Пример #8
0
MessageSubscriber &MessageSubscriber::operator=(const MessageSubscriber &cpy)
{
	if(&cpy == this)
		return *this;

	UnsubscribeAll();

	FOREACH_CONST( RString, cpy.m_vsSubscribedTo, msg )
		this->SubscribeToMessage( *msg );

	return *this;
}
Пример #9
0
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 );
}
Пример #10
0
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 );
}
Пример #11
0
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
}
Пример #12
0
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 );
}
Пример #13
0
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 );
}
Пример #14
0
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;
}
Пример #15
0
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();
}
Пример #17
0
void MessageSubscriber::UnsubscribeAll()
{
	FOREACH_CONST( RString, m_vsSubscribedTo, s )
		MESSAGEMAN->Unsubscribe( this, *s );
	m_vsSubscribedTo.clear();
}
Пример #18
0
	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);
			}
Пример #19
0
MessageSubscriber::MessageSubscriber( const MessageSubscriber &cpy ):
	IMessageSubscriber(cpy)
{
	FOREACH_CONST( RString, cpy.m_vsSubscribedTo, msg )
		this->SubscribeToMessage( *msg );
}
Пример #20
0
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() );
}