#include "global.h" #include "NotesLoaderKSF.h" #include "RageException.h" #include "MsdFile.h" #include "RageLog.h" #include "RageUtil.h" #include "NoteData.h" #include "NoteTypes.h" bool KSFLoader::LoadFromKSFFile( const CString &sPath, Notes &out ) { LOG->Trace( "Notes::LoadFromKSFFile( '%s' )", sPath.GetString() ); MsdFile msd; bool bResult = msd.ReadFile( sPath ); if( !bResult ) RageException::Throw( "Error opening file '%s'.", sPath.GetString() ); int iTickCount = -1; // this is the value we read for TICKCOUNT CString iStep; // this is the value we read for STEP for( unsigned i=0; iWarn( "%s:\nTICKCOUNT not found; defaulting to %i", sPath.GetString(), iTickCount ); } NoteData notedata; // read it into here CStringArray asRows; TrimLeft(iStep); split( iStep, "\n", asRows, true ); { CString sDir, sFName, sExt; splitrelpath( sPath, sDir, sFName, sExt ); sFName.MakeLower(); out.SetDescription(sFName); if( sFName.Find("crazy")!=-1 ) { out.SetDifficulty(DIFFICULTY_HARD); if(!out.GetMeter()) out.SetMeter(8); } else if( sFName.Find("hard")!=-1 ) { out.SetDifficulty(DIFFICULTY_MEDIUM); if(!out.GetMeter()) out.SetMeter(5); } else if( sFName.Find("easy")!=-1 ) { out.SetDifficulty(DIFFICULTY_EASY); if(!out.GetMeter()) out.SetMeter(2); } else { out.SetDifficulty(DIFFICULTY_MEDIUM); if(!out.GetMeter()) out.SetMeter(5); } notedata.SetNumTracks( 5 ); out.m_NotesType = NOTES_TYPE_PUMP_SINGLE; if( sFName.Find("double") != -1 ) { notedata.SetNumTracks( 10 ); out.m_NotesType = NOTES_TYPE_PUMP_DOUBLE; } else if( sFName.Find("_2") != -1 ) { notedata.SetNumTracks( 10 ); out.m_NotesType = NOTES_TYPE_PUMP_COUPLE; } } int iHoldStartRow[13]; for( int t=0; t<13; t++ ) iHoldStartRow[t] = -1; for( unsigned r=0; rWarn("File %s had a RowString with an improper length (\"%s\"); corrupt notes ignored", sPath.GetString(), sRowString.GetString()); return false; } // the length of a note in a row depends on TICKCOUNT float fBeatThisRow = r/(float)iTickCount; int row = BeatToNoteRow(fBeatThisRow); for( int t=0; t < notedata.GetNumTracks(); t++ ) { if( sRowString[t] == '4' ) { /* Remember when each hold starts; ignore the middle. */ if( iHoldStartRow[t] == -1 ) iHoldStartRow[t] = r; continue; } if( iHoldStartRow[t] != -1 ) // this ends the hold { HoldNote hn ( t, /* button */ iHoldStartRow[t]/(float)iTickCount, /* start */ (r-1)/(float)iTickCount /* end */ ); notedata.AddHoldNote( hn ); iHoldStartRow[t] = -1; } TapNote tap; switch(sRowString[t]) { case '0': tap = TAP_EMPTY; break; case '1': tap = TAP_TAP; break; default: ASSERT(0); tap = TAP_EMPTY; break; } notedata.SetTapNote(t, row, tap); } } out.SetNoteData(¬edata); return true; } void KSFLoader::GetApplicableFiles( CString sPath, CStringArray &out ) { GetDirListing( sPath + CString("*.ksf"), out ); } bool KSFLoader::LoadFromDir( CString sDir, Song &out ) { LOG->Trace( "Song::LoadFromKSFDir(%s)", sDir.GetString() ); CStringArray arrayKSFFileNames; GetDirListing( sDir + CString("*.ksf"), arrayKSFFileNames ); /* We shouldn't have been called to begin with if there were no KSFs. */ if( arrayKSFFileNames.empty() ) RageException::Throw( "Couldn't find any KSF files in '%s'", sDir.GetString() ); // load the Notes from the rest of the KSF files unsigned i; for( i=0; iTrace( "Unexpected value named '%s'", sValueName.GetString() ); } // 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; }