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 ); }
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; }
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(); }
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; }
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; }
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) ); }
// -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(); }
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; }
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]; }
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; }
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) ); };
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 ×tamp ) { 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; }
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 ); }
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 }
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 ); } } }
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 ); }
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; }
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) ); };
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 ); }