Exemple #1
0
void InputFilter::ButtonPressed( const DeviceInput &di )
{
    LockMut(*queuemutex);

    if( di.ts.IsZero() )
        LOG->Warn( "InputFilter::ButtonPressed: zero timestamp is invalid" );

    ASSERT_M( di.device < NUM_InputDevice, ssprintf("Invalid device %i", di.device) );
    ASSERT_M( di.button < NUM_DeviceButton, ssprintf("Invalid button %i", di.button) );

    ButtonState &bs = GetButtonState( di );

    // Flush any delayed input, like Update() (in case Update() isn't being called).
    RageTimer now;
    CheckButtonChange( bs, di, now );

    bs.m_DeviceInput = di;

    bool Down = di.bDown;
    if( bs.m_BeingHeld != Down )
    {
        bs.m_BeingHeld = Down;
        bs.m_BeingHeldTime = di.ts;
    }

    // Try to report presses immediately.
    MakeButtonStateList( g_CurrentState );
    CheckButtonChange( bs, di, now );
}
Exemple #2
0
int64_t DSoundBuf::GetPosition() const
{
	DWORD iCursor, iJunk;
	HRESULT hr = m_pBuffer->GetCurrentPosition( &iCursor, &iJunk );
	ASSERT_M( SUCCEEDED(hr), hr_ssprintf(hr, "GetCurrentPosition") );

	/* This happens occasionally on "Realtek AC97 Audio". */
	if( (int) iCursor == m_iBufferSize )
		iCursor = 0;
	ASSERT_M( (int) iCursor < m_iBufferSize, ssprintf("%i, %i", iCursor, m_iBufferSize) );

	int iCursorFrames = int(iCursor) / bytes_per_frame();
	int iWriteCursorFrames = m_iWriteCursor / bytes_per_frame();

	int iFramesBehind = iWriteCursorFrames - iCursorFrames;
	/* iFramesBehind will be 0 if we're called before the buffer starts playing:
	 * both iWriteCursorFrames and iCursorFrames will be 0. */
	if( iFramesBehind < 0 )
		iFramesBehind += buffersize_frames(); /* unwrap */

	int64_t iRet = m_iWriteCursorPos - iFramesBehind;

	/* Failsafe: never return a value smaller than we've already returned.
	 * This can happen once in a while in underrun conditions. */
	iRet = max( m_iLastPosition, iRet );
	m_iLastPosition = iRet;

	return iRet;
}
Exemple #3
0
TapNoteScore PlayerAI::GetTapNoteScore( const PlayerState* pPlayerState )
{
	if( pPlayerState->m_PlayerController == PC_AUTOPLAY )
		return TNS_MARVELOUS;

	int iCpuSkill = pPlayerState->m_iCpuSkill;

	/* If we're in battle mode, reduce the skill based on the number of modifier attacks
	 * against us.  If we're in demonstration or jukebox mode with modifiers attached,
	 * don't make demonstration miss a lot. */
	if( !GAMESTATE->m_bDemonstrationOrJukebox )
	{
		int iSumOfAttackLevels = 
			pPlayerState->m_fSecondsUntilAttacksPhasedOut > 0 ? 
			pPlayerState->m_iLastPositiveSumOfAttackLevels : 
			0;

		ASSERT_M( iCpuSkill>=0 && iCpuSkill<NUM_SKILL_LEVELS, ssprintf("%i", iCpuSkill) );
		ASSERT_M( pPlayerState->m_PlayerController == PC_CPU, ssprintf("%i", pPlayerState->m_PlayerController) );

		iCpuSkill -= iSumOfAttackLevels*3;
		CLAMP( iCpuSkill, 0, NUM_SKILL_LEVELS-1 );
	}

	TapScoreDistribution& distribution = g_Distributions[iCpuSkill];
		
	return distribution.GetTapNoteScore();
}
Exemple #4
0
CString LuaData::Serialize() const
{
	/* Call Serialize(t), where t is our referenced object. */
	Lua *L = LUA->Get();
	lua_pushstring( L, "Serialize" );
	lua_gettable( L, LUA_GLOBALSINDEX );

	ASSERT_M( !lua_isnil(L, -1), "Serialize() missing" );
	ASSERT_M( lua_isfunction(L, -1), "Serialize() not a function" );

	/* Arg 1 (t): */
	this->PushSelf( L );

	lua_call( L, 1, 1 );

	/* The return value is a string, which we store in m_sSerializedData. */
	const char *pString = lua_tostring( L, -1 );
	ASSERT_M( pString != NULL, "Serialize() didn't return a string" );

	CString sRet = pString;
	lua_pop( L, 1 );

	LUA->Release( L );

	return sRet;
}
Exemple #5
0
static bool HashFile( RageFileBasic &f, unsigned char buf_hash[20], int iHash )
{
	hash_state hash;
	int iRet = hash_descriptor[iHash].init( &hash );
	ASSERT_M( iRet == CRYPT_OK, error_to_string(iRet) );

	RString s;
	while( !f.AtEOF() )
	{
		s.erase();
		if( f.Read(s, 1024*4) == -1 )
		{
			LOG->Warn( "Error reading %s: %s", f.GetDisplayPath().c_str(), f.GetError().c_str() );
			hash_descriptor[iHash].done( &hash, buf_hash );
			return false;
		}

		iRet = hash_descriptor[iHash].process( &hash, (const unsigned char *) s.data(), s.size() );
		ASSERT_M( iRet == CRYPT_OK, error_to_string(iRet) );
	}

	iRet = hash_descriptor[iHash].done( &hash, buf_hash );
	ASSERT_M( iRet == CRYPT_OK, error_to_string(iRet) );

	return true;
}
void MovieTexture_FFMpeg::DecoderThread()
{
#if defined(_WINDOWS)
	/* Windows likes to boost priority when processes come out of a wait state.  We don't
	 * want that, since it'll result in us having a small priority boost after each movie
	 * frame, resulting in skips in the gameplay thread. */
	if( !SetThreadPriorityBoost(GetCurrentThread(), TRUE) && GetLastError() != ERROR_CALL_NOT_IMPLEMENTED )
		LOG->Warn( werr_ssprintf(GetLastError(), "SetThreadPriorityBoost failed") );
#endif

	CHECKPOINT;

	while( m_State != DECODER_QUIT )
	{
		if( m_ImageWaiting == FRAME_NONE )
			DecodeFrame();

		/* If we still have no frame, we're at EOF and we didn't loop. */
		if( m_ImageWaiting != FRAME_DECODED )
		{
			usleep( 10000 );
			continue;
		}

		const float fTime = CheckFrameTime();
		if( fTime == -1 )	// skip frame
		{
			DiscardFrame();
		}
		else if( fTime > 0 )		// not time to decode a new frame yet
		{
			/* This needs to be relatively short so that we wake up quickly 
			 * from being paused or for changes in m_Rate. */
			usleep( 10000 );
		}
		else // fTime == 0
		{
			{
				/* The only reason m_BufferFinished might be non-zero right now (before
				 * ConvertFrame()) is if we're quitting. */
				int n = m_BufferFinished.GetValue();
				ASSERT_M( n == 0 || m_State == DECODER_QUIT, ssprintf("%i, %i", n, m_State) );
			}
			ConvertFrame();

			/* We just went into FRAME_WAITING.  Don't actually check; the main thread
			 * will change us back to FRAME_NONE without locking, and poke m_BufferFinished.
			 * Don't time out on this; if a new screen has started loading, this might not
			 * return for a while. */
			m_BufferFinished.Wait( false );

			/* If the frame wasn't used, then we must be shutting down. */
			ASSERT_M( m_ImageWaiting == FRAME_NONE || m_State == DECODER_QUIT, ssprintf("%i, %i", m_ImageWaiting, m_State) );
		}
	}
	CHECKPOINT;
}
int RageFileObjDirect::GetFileSize() const
{
	const int iOldPos = (int)lseek( m_iFD, 0, SEEK_CUR );
	ASSERT_M( iOldPos != -1, ssprintf("\"%s\": %s", m_sPath.c_str(), strerror(errno)) );
	const int iRet = (int)lseek( m_iFD, 0, SEEK_END );
	ASSERT_M( iRet != -1, ssprintf("\"%s\": %s", m_sPath.c_str(), strerror(errno)) );
	lseek( m_iFD, iOldPos, SEEK_SET );
	return iRet;
}
Exemple #8
0
void StageStats::AssertValid( PlayerNumber pn ) const
{
	if( vpSongs[0] )
		CHECKPOINT_M( vpSongs[0]->GetFullTranslitTitle() );
	ASSERT( vpSteps[pn][0] );
	ASSERT_M( playMode < NUM_PLAY_MODES, ssprintf("playmode %i", playMode) );
	ASSERT( pStyle != NULL );
	ASSERT_M( vpSteps[pn][0]->GetDifficulty() < NUM_DIFFICULTIES, ssprintf("difficulty %i", vpSteps[pn][0]->GetDifficulty()) );
	ASSERT( vpSongs.size() == vpSteps[pn].size() );
}
void StageStats::AssertValid( MultiPlayer pn ) const
{
	ASSERT( m_vpPlayedSongs.size() != 0 );
	ASSERT( m_vpPossibleSongs.size() != 0 );
	if( m_vpPlayedSongs[0] )
		CHECKPOINT_M( m_vpPlayedSongs[0]->GetTranslitFullTitle() );
	ASSERT( m_multiPlayer[pn].m_vpPossibleSteps.size() != 0 );
	ASSERT( m_multiPlayer[pn].m_vpPossibleSteps[0] != NULL );
	ASSERT_M( m_playMode < NUM_PlayMode, ssprintf("playmode %i", m_playMode) );
	ASSERT_M( m_player[pn].m_vpPossibleSteps[0]->GetDifficulty() < NUM_Difficulty, ssprintf("difficulty %i", m_player[pn].m_vpPossibleSteps[0]->GetDifficulty()) );
	ASSERT( (int) m_vpPlayedSongs.size() == m_player[pn].m_iStepsPlayed );
	ASSERT( m_vpPossibleSongs.size() == m_player[pn].m_vpPossibleSteps.size() );
}
void StageStats::AssertValid( PlayerNumber pn ) const
{
	ASSERT( m_vpPlayedSongs.size() != 0 );
	ASSERT( m_vpPossibleSongs.size() != 0 );
	if( m_vpPlayedSongs[0] )
		CHECKPOINT_M( m_vpPlayedSongs[0]->GetTranslitFullTitle() );
	ASSERT( m_player[pn].m_iStepsPlayed > 0 );
	ASSERT( m_player[pn].m_vpPossibleSteps.size() != 0 );
	ASSERT( m_player[pn].m_vpPossibleSteps[0] != NULL );
	ASSERT_M( m_playMode < NUM_PlayMode, ssprintf("playmode %i", m_playMode) );
	ASSERT_M( m_player[pn].m_vpPossibleSteps[0]->GetDifficulty() < NUM_Difficulty, ssprintf("Invalid Difficulty %i", m_player[pn].m_vpPossibleSteps[0]->GetDifficulty()) );
	ASSERT_M( (int) m_vpPlayedSongs.size() == m_player[pn].m_iStepsPlayed, ssprintf("%i Songs Played != %i Steps Played for player %i", (int)m_vpPlayedSongs.size(), (int)m_player[pn].m_iStepsPlayed, pn) );
	ASSERT_M( m_vpPossibleSongs.size() == m_player[pn].m_vpPossibleSteps.size(), ssprintf("%i Possible Songs != %i Possible Steps for player %i", (int)m_vpPossibleSongs.size(), (int)m_player[pn].m_vpPossibleSteps.size(), pn) );
}
Exemple #11
0
// -1 for iOriginalTracksToTakeFrom means no track
void NoteData::LoadTransformed( const NoteData* pOriginal, int iNewNumTracks, const int iOriginalTrackToTakeFrom[] )
{
	// reset all notes
	Init();
	
	NoteData Original;
	Original.To4s( *pOriginal );

	Config( Original );
	m_iNumTracks = iNewNumTracks;

	// copy tracks
	for( int t=0; t<m_iNumTracks; t++ )
	{
		const int iOriginalTrack = iOriginalTrackToTakeFrom[t];
		ASSERT_M( iOriginalTrack < Original.m_iNumTracks, ssprintf("from %i >= %i (to %i)", 
			iOriginalTrack, Original.m_iNumTracks, iOriginalTrackToTakeFrom[t]));

		if( iOriginalTrack == -1 )
			continue;
		m_TapNotes[t] = Original.m_TapNotes[iOriginalTrack];
	}

	Convert4sToHoldNotes();

	m_AttackMap = Original.GetAttackMap();
}
Exemple #12
0
static void SelectExactlyOne( int iSelection, vector<bool> &vbSelectedOut )
{
	ASSERT_M( iSelection >= 0  &&  iSelection < (int) vbSelectedOut.size(),
			  ssprintf("%d/%u",iSelection, unsigned(vbSelectedOut.size())) );
	for( int i=0; i<int(vbSelectedOut.size()); i++ )
		vbSelectedOut[i] = i==iSelection;
}
Exemple #13
0
BitmapText &OptionRow::GetTextItemForRow( PlayerNumber pn, int iChoiceOnRow )
{
	if( m_RowType == OptionRow::ROW_EXIT )
		return *m_textItems[0];

	bool bOneChoice = m_RowDef.bOneChoiceForAllPlayers;
	int index = -1;
	switch( m_RowDef.layoutType )
	{
	case LAYOUT_SHOW_ONE_IN_ROW:
		index = bOneChoice ? 0 : pn;
		/* If only P2 is enabled, his selections will be in index 0. */
		if( m_textItems.size() == 1 )
			index = 0;
		break;
	case LAYOUT_SHOW_ALL_IN_ROW:
		index = iChoiceOnRow;
		break;
	default:
		ASSERT(0);
	}

	ASSERT_M( index < (int)m_textItems.size(), ssprintf("%i < %i", index, (int)m_textItems.size() ) );
	return *m_textItems[index];
}
Exemple #14
0
void Attack::GetAttackBeats( const Song *song, const PlayerState* pPlayerState, float &fStartBeat, float &fEndBeat ) const
{
	ASSERT( song );

	if( fStartSecond >= 0 )
	{
		CHECKPOINT;
		fStartBeat = song->GetBeatFromElapsedTime( fStartSecond );
		fEndBeat = song->GetBeatFromElapsedTime( fStartSecond+fSecsRemaining );
	}
	else
	{
		CHECKPOINT;
		/* If fStartSecond < 0, then the attack starts right off the screen; this requires
		 * that a song actually be playing.  Pre-queued course attacks must always have 
		 * fStartSecond >= 0. */
		ASSERT( GAMESTATE->m_pCurSong );
		
		ASSERT( pPlayerState );

		/* We're setting this effect on the fly.  If it's an arrow-changing effect
		 * (transform or note skin), apply it in the future, after what's currently on
		 * screen, so new arrows will scroll on screen with this effect. */
		GAMESTATE->GetUndisplayedBeats( pPlayerState, fSecsRemaining, fStartBeat, fEndBeat );
	}

	// loading the course should have caught this.
	ASSERT_M( fEndBeat >= fStartBeat, ssprintf("%f >= %f", fEndBeat, fStartBeat) );
}
void DSoundBuf::SetVolume( float fVolume )
{
	ASSERT_M( fVolume >= 0 && fVolume <= 1, ssprintf("%f",fVolume) );
	
	if( fVolume == 0 )
		fVolume = 0.001f;		// fix log10f(0) == -INF
	float iVolumeLog2 = log10f(fVolume) / log10f(2); /* vol log 2 */

	/* Volume is a multiplier; SetVolume wants attenuation in hundredths of a decibel. */
	const int iNewVolume = max( int(1000 * iVolumeLog2), DSBVOLUME_MIN );

	if( m_iVolume == iNewVolume )
		return;

	HRESULT hr = m_pBuffer->SetVolume( iNewVolume );
	if( FAILED(hr) )
	{
		static bool bWarned = false;
		if( !bWarned )
			LOG->Warn( hr_ssprintf(hr, "DirectSoundBuffer::SetVolume(%i) failed", iNewVolume) );
		bWarned = true;
		return;
	}

	m_iVolume = iNewVolume;
}
Exemple #16
0
GameInput Style::StyleInputToGameInput( int iCol, PlayerNumber pn ) const
{
	ASSERT_M( pn < NUM_PLAYERS  &&  iCol < MAX_COLS_PER_PLAYER,
		ssprintf("P%i C%i", pn, iCol) );
	bool bUsingOneSide = m_StyleType != StyleType_OnePlayerTwoSides && m_StyleType != StyleType_TwoPlayersSharedSides;

	FOREACH_ENUM( GameController, gc)
	{
		if( bUsingOneSide && gc != (int) pn )
			continue;

		int iButtonsPerController = INPUTMAPPER->GetInputScheme()->m_iButtonsPerController;
		for( GameButton gb=GAME_BUTTON_NEXT; gb < iButtonsPerController; gb=(GameButton)(gb+1) )
		{
			int iThisInputCol = m_iInputColumn[gc][gb-GAME_BUTTON_NEXT];
			if( iThisInputCol == END_MAPPING )
				break;

			if( iThisInputCol == iCol )
				return GameInput( gc, gb );
		}
	}

	FAIL_M( ssprintf("Invalid column number %i for player %i in the style %s", iCol, pn, GAMESTATE->GetCurrentStyle()->m_szName) );
};
Exemple #17
0
static void GetFilterToFileNames( const RString sBaseDir, const Song *pSong, set<RString> &vsPossibleFileNamesOut )
{
	vsPossibleFileNamesOut.clear();

	if( pSong->m_sGenre.empty() )
		return;

	ASSERT( !pSong->m_sGroupName.empty() );
	IniFile ini;
	RString sPath = sBaseDir+pSong->m_sGroupName+"/"+"BackgroundMapping.ini";
	ini.ReadFile( sPath );
	
	RString sSection;
	bool bSuccess = ini.GetValue( "GenreToSection", pSong->m_sGenre, sSection );
	if( !bSuccess )
	{
		LOG->Warn( "Genre '%s' isn't mapped", pSong->m_sGenre.c_str() );
		return;
	}

	XNode *pSection = ini.GetChild( sSection );
	if( pSection == NULL )
	{
		ASSERT_M( 0, ssprintf("File '%s' refers to a section '%s' that is missing.", sPath.c_str(), sSection.c_str()) );
		return;
	}

	FOREACH_CONST_Attr( pSection, p )
		vsPossibleFileNamesOut.insert( p->first );
}
void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer &timestamp )
{

	if( !timestamp.IsZero() )
		m_LastBeatUpdate = timestamp;
	else
		m_LastBeatUpdate.Touch();

	TimingData::GetBeatArgs beat_info;
	beat_info.elapsed_time= fPositionSeconds;
	timing.GetBeatAndBPSFromElapsedTime(beat_info);
	m_fSongBeat= beat_info.beat;
	m_fCurBPS= beat_info.bps_out;
	m_bFreeze= beat_info.freeze_out;
	m_bDelay= beat_info.delay_out;
	m_iWarpBeginRow= beat_info.warp_begin_out;
	m_fWarpDestination= beat_info.warp_dest_out;
	
	// "Crash reason : -243478.890625 -48695.773438"
	// The question is why is -2000 used as the limit? -aj
	ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds is less than -2000!", m_fSongBeat, fPositionSeconds) );

	m_fMusicSeconds = fPositionSeconds;

	m_fLightSongBeat = timing.GetBeatFromElapsedTime( fPositionSeconds + g_fLightsAheadSeconds );

	m_fSongBeatNoOffset = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds );
	
	m_fMusicSecondsVisible = fPositionSeconds - g_fVisualDelaySeconds.Get();
	beat_info.elapsed_time= m_fMusicSecondsVisible;
	timing.GetBeatAndBPSFromElapsedTime(beat_info);
	m_fSongBeatVisible= beat_info.beat;
}
Exemple #19
0
const RectF *Sprite::GetCurrentTextureCoordRect() const
{
	ASSERT_M( m_iCurState < (int) m_States.size(), ssprintf("%d, %d", int(m_iCurState), int(m_States.size())) );

	unsigned int uFrameNo = m_States[m_iCurState].iFrameIndex;
	return m_pTexture->GetTextureCoordRect( uFrameNo );
}
void ActorFrame::DrawPrimitives()
{
	ASSERT_M( !m_bClearZBuffer, "ClearZBuffer not supported on ActorFrames" );

	// Don't set Actor-defined render states because we won't be drawing 
	// any geometry that belongs to this object.
	// Actor::DrawPrimitives();

	if( unlikely(!m_DrawFunction.IsNil()) )
	{
		Lua *L = LUA->Get();
		m_DrawFunction.PushSelf( L );
		ASSERT( !lua_isnil(L, -1) );
		this->PushSelf( L );
		RString sError;
		if( !LuaHelpers::RunScriptOnStack(L, sError, 1, 0) ) // 1 arg, 0 results
			LOG->Warn( "Error running DrawFunction: %s", sError.c_str() );
		LUA->Release(L);
		return;
	}

	// draw all sub-ActorFrames while we're in the ActorFrame's local coordinate space
	if( m_bDrawByZPosition )
	{
		vector<Actor*> subs = m_SubActors;
		ActorUtil::SortByZPosition( subs );
		for( unsigned i=0; i<subs.size(); i++ )
			subs[i]->Draw();
	}
	else
	{
		for( unsigned i=0; i<m_SubActors.size(); i++ )
			m_SubActors[i]->Draw();
	}
}
void RemoveReference( const RageFileObj *obj )
{
	LockMut( *g_Mutex );

	FileReferences::iterator it = g_Refs.find( obj );
	ASSERT_M( it != g_Refs.end(), ssprintf( "RemoveReference: Missing reference (%s)", obj->GetDisplayPath().c_str() ) );
	g_Refs.erase( it );
}
void RageSoundReader_Chain::ReleaseSound( unsigned n )
{
	ASSERT_M( n < m_apActiveSounds.size(), ssprintf("%u, %u", n, unsigned(m_apActiveSounds.size())) );
	SoundReader *pSound = m_apActiveSounds[n].pSound;

	delete pSound;

	m_apActiveSounds.erase( m_apActiveSounds.begin()+n );
}
Exemple #23
0
void Attack::GetAttackBeats( const Song *pSong, float &fStartBeat, float &fEndBeat ) const
{
	ASSERT( pSong != NULL );
	ASSERT_M( fStartSecond >= 0, ssprintf("StartSecond: %f",fStartSecond) );
	
	const TimingData &timing = pSong->m_SongTiming;
	fStartBeat = timing.GetBeatFromElapsedTime( fStartSecond );
	fEndBeat = timing.GetBeatFromElapsedTime( fStartSecond+fSecsRemaining );
}
void MessageManager::Subscribe( IMessageSubscriber* pSubscriber, const CString& sMessage )
{
	SubscribersSet& subs = m_MessageToSubscribers[sMessage];
#if _DEBUG
	SubscribersSet::iterator iter = subs.find(pSubscriber);
	ASSERT_M( iter == subs.end(), "already subscribed" );
#endif
	subs.insert( pSubscriber );
}
void RageFileManager::MountInitialFilesystems()
{
	/* Add file search paths, higher priority first. */
#if defined(XBOX)
	RageFileManager::Mount( "dir", "D:\\", "" );
#elif defined(LINUX)
	/* Absolute paths.  This is rarely used, eg. by Alsa9Buf::GetSoundCardDebugInfo(). 
	 * All paths that start with a slash (eg. "/proc") should use this, so put it
	 * first. */
	RageFileManager::Mount( "dir", "/", "/" );
	
	/* We can almost do this, to have machine profiles be system-global to eg. share
	 * scores.  It would need to handle permissions properly. */
/*	RageFileManager::Mount( "dir", "/var/lib/games/stepmania", "Data/Profiles" ); */
	
	// CString Home = getenv( "HOME" ) + "/" + PRODUCT_NAME;

	/*
	 * Next: path to write general mutable user data.  If the above path fails (eg.
	 * wrong permissions, doesn't exist), machine memcard data will also go in here. 
	 * XXX: It seems silly to have two ~ directories.  If we're going to create a
	 * directory on our own, it seems like it should be a dot directory, but it
	 * seems wrong to put lots of data (eg. music) in one.  Hmm. 
	 */
	/* XXX: create */
/*	RageFileManager::Mount( "dir", Home + "." PRODUCT_NAME, "Data" ); */

	/* Next, search ~/StepMania.  This is where users can put music, themes, etc. */
	/* RageFileManager::Mount( "dir", Home + PRODUCT_NAME, "" ); */

	/* Search for a directory with "Songs" in it.  Be careful: the CWD is likely to
	 * be ~, and it's possible that some users will have a ~/Songs/ directory that
	 * has nothing to do with us, so check the initial directory last. */
	CString Root = "";
	struct stat st;
	if( Root == "" && !stat( DirOfExecutable + "/Songs", &st ) && st.st_mode&S_IFDIR )
		Root = DirOfExecutable;
	if( Root == "" && !stat( InitialWorkingDirectory + "/Songs", &st ) && st.st_mode&S_IFDIR )
		Root = InitialWorkingDirectory;
	if( Root == "" )
		RageException::Throw( "Couldn't find \"Songs\"" );
			
	RageFileManager::Mount( "dir", Root, "" );
#elif defined(_WINDOWS)
	/* All Windows data goes in the directory one level above the executable. */
	CHECKPOINT_M( ssprintf( "DOE \"%s\"", DirOfExecutable.c_str()) );
	CStringArray parts;
	split( DirOfExecutable, "/", parts );
	CHECKPOINT_M( ssprintf( "... %i parts", parts.size()) );
	ASSERT_M( parts.size() > 1, ssprintf("Strange DirOfExecutable: %s", DirOfExecutable.c_str()) );
	CString Dir = join( "/", parts.begin(), parts.end()-1 );
	RageFileManager::Mount( "dir", Dir, "" );
#else
	/* Paths relative to the CWD: */
	RageFileManager::Mount( "dir", ".", "" );
#endif
}
Exemple #26
0
void AddLayersFromAniDir( CString sAniDir, vector<Actor*> &layersAddTo, bool Generic )
{
	if( sAniDir.empty() )
		 return;

	if( sAniDir.Right(1) != "/" )
		sAniDir += "/";

	ASSERT_M( IsADirectory(sAniDir), sAniDir + " isn't a directory" );

	CString sPathToIni = sAniDir + "BGAnimation.ini";

	IniFile ini;
	ini.ReadFile( sPathToIni );

	{
		CString expr;
		if( ini.GetValue( "BGAnimation", "Condition", expr ) || ini.GetValue( "BGAnimation", "Cond", expr ) )
		{
			if( !Lua::RunExpression( expr ) )
				return;
		}
	}

	int i;
	for( i=0; i<MAX_LAYERS; i++ )
	{
		CString sLayer = ssprintf("Layer%d",i+1);
		const IniFile::key* pKey = ini.GetKey( sLayer );
		if( pKey == NULL )
			continue;	// skip

		CString sImportDir;
		if( ini.GetValue(sLayer, "Import", sImportDir) )
		{
			CString expr;
			if( ini.GetValue(sLayer,"Condition",expr) )
			{
				if( !Lua::RunExpression( expr ) )
					continue;
			}

			// import a whole BGAnimation
			sImportDir = sAniDir + sImportDir;
			CollapsePath( sImportDir );
			AddLayersFromAniDir( sImportDir, layersAddTo, Generic );
		}
		else
		{
			// import as a single layer
			BGAnimationLayer* pLayer = new BGAnimationLayer( Generic );
			pLayer->LoadFromIni( sAniDir, sLayer );
			layersAddTo.push_back( pLayer );
		}
	}

}
Exemple #27
0
void NoteField::UncacheNoteSkin( const RString &sNoteSkin_ )
{
	RString sNoteSkinLower = sNoteSkin_;
	sNoteSkinLower.MakeLower();

	LOG->Trace("NoteField::CacheNoteSkin: release %s", sNoteSkinLower.c_str() );
	ASSERT_M( m_NoteDisplays.find(sNoteSkinLower) != m_NoteDisplays.end(), sNoteSkinLower );
	delete m_NoteDisplays[sNoteSkinLower];
	m_NoteDisplays.erase( sNoteSkinLower );
}
Exemple #28
0
void ActorUtil::Register( const RString& sClassName, CreateActorFn pfn )
{
	if( g_pmapRegistrees == NULL )
		g_pmapRegistrees = new map<RString,CreateActorFn>;

	map<RString,CreateActorFn>::iterator iter = g_pmapRegistrees->find( sClassName );
	ASSERT_M( iter == g_pmapRegistrees->end(), ssprintf("Actor class '%s' already registered.", sClassName.c_str()) );

	(*g_pmapRegistrees)[sClassName] = pfn;
}
Exemple #29
0
GameInput Style::StyleInputToGameInput( const StyleInput& StyleI ) const
{
	ASSERT_M( StyleI.player < NUM_PLAYERS, ssprintf("P%i", StyleI.player) );
	ASSERT_M( StyleI.col < MAX_COLS_PER_PLAYER, ssprintf("C%i", StyleI.col) );

	bool bUsingOneSide = this->m_StyleType != ONE_PLAYER_TWO_SIDES;

	FOREACH_GameController(gc)
	{
		if( bUsingOneSide && gc != (int) StyleI.player )
			continue;

		for( GameButton gb = GAME_BUTTON_NEXT; gb < m_pGame->m_iButtonsPerController && m_iInputColumn[gc][gb-GAME_BUTTON_NEXT] != END_MAPPING; gb=(GameButton)(gb+1) )
			if( m_iInputColumn[gc][gb-GAME_BUTTON_NEXT] == StyleI.col )
				return GameInput( gc, gb );
	}

	FAIL_M( ssprintf("Unknown StyleInput %i,%i", StyleI.player, StyleI.col) );
};
Exemple #30
0
void MessageManager::Subscribe( IMessageSubscriber* pSubscriber, const RString& sMessage )
{
	LockMut(g_Mutex);

	SubscribersSet& subs = g_MessageToSubscribers[sMessage];
#ifdef DEBUG
	SubscribersSet::iterator iter = subs.find(pSubscriber);
	ASSERT_M( iter == subs.end(), ssprintf("already subscribed to '%s'",sMessage.c_str()) );
#endif
	subs.insert( pSubscriber );
}