2003-02-16 04:01:45 +00:00
|
|
|
#include "global.h"
|
2002-09-06 23:24:40 +00:00
|
|
|
#include "NotesLoaderKSF.h"
|
|
|
|
|
#include "RageException.h"
|
2003-05-21 00:10:31 +00:00
|
|
|
#include "RageUtil_CharConversions.h"
|
2002-09-06 23:24:40 +00:00
|
|
|
#include "MsdFile.h"
|
|
|
|
|
#include "RageLog.h"
|
2002-09-07 11:43:36 +00:00
|
|
|
#include "RageUtil.h"
|
|
|
|
|
#include "NoteData.h"
|
|
|
|
|
#include "NoteTypes.h"
|
2002-09-06 23:24:40 +00:00
|
|
|
|
2003-05-21 00:10:31 +00:00
|
|
|
#if 0
|
|
|
|
|
void KSFLoader::RemoveHoles( NoteData &out, const Song &song )
|
|
|
|
|
{
|
|
|
|
|
/* Start at the second BPM segment; the first one is already aligned. */
|
2003-12-18 04:48:26 +00:00
|
|
|
for( unsigned seg = 1; seg < song.m_Timing.m_BPMSegments.size(); ++seg )
|
2003-05-21 00:10:31 +00:00
|
|
|
{
|
2003-12-18 04:48:26 +00:00
|
|
|
// const float FromBeat = song.m_Timing.m_BPMSegments[seg].m_fStartBeat;
|
|
|
|
|
const float FromBeat = song.m_Timing.m_BPMSegments[seg].m_fStartBeat * song.m_BPMSegments[seg].m_fBPM / song.m_BPMSegments[0].m_fBPM;
|
2003-05-21 00:10:31 +00:00
|
|
|
const int FromRow = (int) BeatToNoteRow(FromBeat);
|
2003-12-18 04:48:26 +00:00
|
|
|
const int ToRow = (int) BeatToNoteRow(song.m_Timing.m_BPMSegments[seg].m_fStartBeat);
|
2003-05-21 00:10:31 +00:00
|
|
|
|
|
|
|
|
LOG->Trace("from %f (%i) to (%i)", FromBeat, FromRow, ToRow);
|
2003-12-18 04:48:26 +00:00
|
|
|
// const int ToRow = (int) roundf(FromRow * song.m_Timing.m_BPMSegments[0].m_fBPM / song.m_BPMSegments[seg].m_fBPM);
|
2003-05-21 00:10:31 +00:00
|
|
|
// const int Rows = out.GetLastRow() - FromRow + 1;
|
|
|
|
|
// int LastRow;
|
2003-12-18 04:48:26 +00:00
|
|
|
// if(seg+1 < song.m_Timing.m_BPMSegments().size())
|
|
|
|
|
// LastRow = (int) NoteRowToBeat( song.m_Timing.m_BPMSegments[seg+1].m_fStartBeat ) - 1;
|
2003-05-21 00:10:31 +00:00
|
|
|
// else
|
|
|
|
|
// LastRow = out.GetLastRow();
|
|
|
|
|
NoteData tmp;
|
|
|
|
|
tmp.SetNumTracks(out.GetNumTracks());
|
|
|
|
|
tmp.CopyRange( &out, FromRow, out.GetLastRow() );
|
|
|
|
|
out.ClearRange( FromRow, out.GetLastRow() );
|
|
|
|
|
out.CopyRange( &tmp, 0, tmp.GetLastRow(), ToRow );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
out.ConvertHoldNotesTo2sAnd3s();
|
|
|
|
|
for( t = 0; t < notedata.GetNumTracks(); ++t )
|
|
|
|
|
{
|
|
|
|
|
const float CurBPM = song.GetBPMAtBeat( NoteRowToBeat(row) );
|
2003-12-18 04:48:26 +00:00
|
|
|
song.m_Timing.m_BPMSegments.size()
|
2003-05-21 00:10:31 +00:00
|
|
|
for( int row = 0; row <= notedata.GetLastRow(); ++row )
|
|
|
|
|
{
|
|
|
|
|
TapNote tn = notedata.GetTapNote(t, row);
|
|
|
|
|
if( tn == TAP_EMPTY )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
const int RealRow = (int) roundf(row * OrigBPM / CurBPM);
|
|
|
|
|
if( RealRow == row )
|
|
|
|
|
continue;
|
|
|
|
|
LOG->Trace("from %i to %i", row, RealRow);
|
|
|
|
|
notedata.SetTapNote( t, RealRow, tn );
|
|
|
|
|
notedata.SetTapNote( t, row, TAP_EMPTY );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
out.Convert2sAnd3sToHoldNotes();
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2003-08-03 00:13:55 +00:00
|
|
|
bool KSFLoader::LoadFromKSFFile( const CString &sPath, Steps &out, const Song &song )
|
2002-09-06 23:24:40 +00:00
|
|
|
{
|
2003-08-03 00:13:55 +00:00
|
|
|
LOG->Trace( "Steps::LoadFromKSFFile( '%s' )", sPath.c_str() );
|
2002-09-06 23:24:40 +00:00
|
|
|
|
|
|
|
|
MsdFile msd;
|
2003-05-21 00:10:31 +00:00
|
|
|
if( !msd.ReadFile( sPath ) )
|
2003-04-25 00:01:35 +00:00
|
|
|
RageException::Throw( "Error opening file '%s'.", sPath.c_str() );
|
2002-09-06 23:24:40 +00:00
|
|
|
|
|
|
|
|
int iTickCount = -1; // this is the value we read for TICKCOUNT
|
2003-05-21 00:10:31 +00:00
|
|
|
CStringArray asRows;
|
2002-09-06 23:24:40 +00:00
|
|
|
|
2003-01-14 22:10:04 +00:00
|
|
|
for( unsigned i=0; i<msd.GetNumValues(); i++ )
|
2002-09-06 23:24:40 +00:00
|
|
|
{
|
2003-01-14 22:44:30 +00:00
|
|
|
const MsdFile::value_t &sParams = msd.GetValue(i);
|
2002-09-06 23:24:40 +00:00
|
|
|
CString sValueName = sParams[0];
|
|
|
|
|
|
|
|
|
|
// handle the data
|
|
|
|
|
if( 0==stricmp(sValueName,"TICKCOUNT") )
|
|
|
|
|
iTickCount = atoi(sParams[1]);
|
|
|
|
|
|
|
|
|
|
else if( 0==stricmp(sValueName,"STEP") )
|
2003-05-21 00:10:31 +00:00
|
|
|
{
|
|
|
|
|
CString step = sParams[1];
|
|
|
|
|
TrimLeft(step);
|
|
|
|
|
split( step, "\n", asRows, true );
|
|
|
|
|
}
|
2002-09-06 23:24:40 +00:00
|
|
|
else if( 0==stricmp(sValueName,"DIFFICULTY") )
|
2003-01-02 22:10:51 +00:00
|
|
|
out.SetMeter(atoi(sParams[1]));
|
2002-09-06 23:24:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( iTickCount == -1 )
|
|
|
|
|
{
|
|
|
|
|
iTickCount = 2;
|
2003-05-21 00:10:31 +00:00
|
|
|
LOG->Warn( "\"%s\": TICKCOUNT not found; defaulting to %i", sPath.c_str(), iTickCount );
|
2002-09-06 23:24:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NoteData notedata; // read it into here
|
|
|
|
|
|
2002-11-03 01:32:47 +00:00
|
|
|
{
|
|
|
|
|
CString sDir, sFName, sExt;
|
2003-10-29 21:06:33 +00:00
|
|
|
splitpath( sPath, sDir, sFName, sExt );
|
2002-11-03 01:32:47 +00:00
|
|
|
sFName.MakeLower();
|
|
|
|
|
|
2003-01-02 22:10:51 +00:00
|
|
|
out.SetDescription(sFName);
|
2002-11-03 01:32:47 +00:00
|
|
|
if( sFName.Find("crazy")!=-1 )
|
|
|
|
|
{
|
2003-01-02 22:10:51 +00:00
|
|
|
out.SetDifficulty(DIFFICULTY_HARD);
|
|
|
|
|
if(!out.GetMeter()) out.SetMeter(8);
|
2002-11-03 01:32:47 +00:00
|
|
|
}
|
|
|
|
|
else if( sFName.Find("hard")!=-1 )
|
|
|
|
|
{
|
2003-01-02 22:10:51 +00:00
|
|
|
out.SetDifficulty(DIFFICULTY_MEDIUM);
|
|
|
|
|
if(!out.GetMeter()) out.SetMeter(5);
|
2002-11-03 01:32:47 +00:00
|
|
|
}
|
|
|
|
|
else if( sFName.Find("easy")!=-1 )
|
|
|
|
|
{
|
2003-01-02 22:10:51 +00:00
|
|
|
out.SetDifficulty(DIFFICULTY_EASY);
|
|
|
|
|
if(!out.GetMeter()) out.SetMeter(2);
|
2002-11-03 01:32:47 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2003-01-02 22:10:51 +00:00
|
|
|
out.SetDifficulty(DIFFICULTY_MEDIUM);
|
|
|
|
|
if(!out.GetMeter()) out.SetMeter(5);
|
2002-11-03 01:32:47 +00:00
|
|
|
}
|
|
|
|
|
|
2003-02-01 05:16:38 +00:00
|
|
|
notedata.SetNumTracks( 5 );
|
2003-08-07 06:36:34 +00:00
|
|
|
out.m_StepsType = STEPS_TYPE_PUMP_SINGLE;
|
2004-09-13 08:47:22 +00:00
|
|
|
|
|
|
|
|
/* Check for "halfdouble" before "double". */
|
|
|
|
|
if( sFName.Find("halfdouble") != -1 )
|
|
|
|
|
{
|
|
|
|
|
notedata.SetNumTracks( 6 );
|
|
|
|
|
out.m_StepsType = STEPS_TYPE_PUMP_HALFDOUBLE;
|
|
|
|
|
}
|
|
|
|
|
else if( sFName.Find("double") != -1 )
|
2002-11-03 01:32:47 +00:00
|
|
|
{
|
2003-02-01 05:16:38 +00:00
|
|
|
notedata.SetNumTracks( 10 );
|
2003-08-07 06:36:34 +00:00
|
|
|
out.m_StepsType = STEPS_TYPE_PUMP_DOUBLE;
|
2004-09-13 08:47:22 +00:00
|
|
|
}
|
|
|
|
|
else if( sFName.Find("_2") != -1 )
|
|
|
|
|
{
|
2003-02-01 05:16:38 +00:00
|
|
|
notedata.SetNumTracks( 10 );
|
2003-08-07 06:36:34 +00:00
|
|
|
out.m_StepsType = STEPS_TYPE_PUMP_COUPLE;
|
2002-11-03 01:32:47 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-06 23:24:40 +00:00
|
|
|
int iHoldStartRow[13];
|
2003-05-21 00:10:31 +00:00
|
|
|
int t;
|
|
|
|
|
for( t=0; t<13; t++ )
|
2002-09-06 23:24:40 +00:00
|
|
|
iHoldStartRow[t] = -1;
|
|
|
|
|
|
2002-10-31 03:01:35 +00:00
|
|
|
for( unsigned r=0; r<asRows.size(); r++ )
|
2002-09-06 23:24:40 +00:00
|
|
|
{
|
|
|
|
|
CString& sRowString = asRows[r];
|
2003-09-02 03:19:33 +00:00
|
|
|
StripCrnl( sRowString );
|
2002-09-06 23:24:40 +00:00
|
|
|
|
|
|
|
|
if( sRowString == "" )
|
|
|
|
|
continue; // skip
|
|
|
|
|
|
|
|
|
|
/* All 2s indicates the end of the song. */
|
|
|
|
|
if( sRowString == "2222222222222" )
|
|
|
|
|
break;
|
|
|
|
|
|
2003-01-01 09:19:10 +00:00
|
|
|
if(sRowString.size() != 13)
|
|
|
|
|
{
|
|
|
|
|
LOG->Warn("File %s had a RowString with an improper length (\"%s\"); corrupt notes ignored",
|
2003-04-25 00:01:35 +00:00
|
|
|
sPath.c_str(), sRowString.c_str());
|
2003-01-01 09:19:10 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2002-09-06 23:24:40 +00:00
|
|
|
|
|
|
|
|
// the length of a note in a row depends on TICKCOUNT
|
|
|
|
|
float fBeatThisRow = r/(float)iTickCount;
|
|
|
|
|
int row = BeatToNoteRow(fBeatThisRow);
|
2003-02-01 05:16:38 +00:00
|
|
|
for( int t=0; t < notedata.GetNumTracks(); t++ )
|
2002-09-06 23:24:40 +00:00
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
{
|
2003-04-05 21:18:18 +00:00
|
|
|
HoldNote hn (
|
2002-09-06 23:24:40 +00:00
|
|
|
t, /* button */
|
2003-12-16 04:00:39 +00:00
|
|
|
BeatToNoteRow(iHoldStartRow[t]/(float)iTickCount), /* start */
|
|
|
|
|
BeatToNoteRow((r-1)/(float)iTickCount) /* end */
|
2003-04-05 21:18:18 +00:00
|
|
|
);
|
2002-09-06 23:24:40 +00:00
|
|
|
notedata.AddHoldNote( hn );
|
|
|
|
|
iHoldStartRow[t] = -1;
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-02 21:33:56 +00:00
|
|
|
TapNote tap;
|
|
|
|
|
switch(sRowString[t])
|
|
|
|
|
{
|
2004-09-12 05:56:24 +00:00
|
|
|
case '0': tap = TAP_EMPTY; break;
|
|
|
|
|
case '1': tap = TAP_ORIGINAL_TAP; break;
|
|
|
|
|
default: ASSERT(0); tap = TAP_EMPTY; break;
|
2002-11-02 21:33:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
notedata.SetTapNote(t, row, tap);
|
2002-09-06 23:24:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-05-21 00:10:31 +00:00
|
|
|
/* We need to remove holes where the BPM increases. */
|
2003-12-18 04:48:26 +00:00
|
|
|
// if( song.m_Timing.m_BPMSegments.size() > 1 )
|
2003-05-21 00:10:31 +00:00
|
|
|
// RemoveHoles( notedata, song );
|
|
|
|
|
|
2004-10-23 17:43:49 +00:00
|
|
|
out.SetNoteData( notedata );
|
2002-09-06 23:24:40 +00:00
|
|
|
|
2003-08-13 04:48:06 +00:00
|
|
|
out.TidyUpData();
|
|
|
|
|
|
2002-09-06 23:24:40 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-11 05:15:46 +00:00
|
|
|
void KSFLoader::GetApplicableFiles( CString sPath, CStringArray &out )
|
|
|
|
|
{
|
|
|
|
|
GetDirListing( sPath + CString("*.ksf"), out );
|
|
|
|
|
}
|
2002-09-06 23:24:40 +00:00
|
|
|
|
2003-05-21 00:10:31 +00:00
|
|
|
void KSFLoader::LoadTags( const CString &str, Song &out )
|
|
|
|
|
{
|
|
|
|
|
/* str is either a #TITLE or a directory component. Fill in missing information.
|
|
|
|
|
* str is either "title", "artist - title", or "artist - title - difficulty". */
|
|
|
|
|
CStringArray asBits;
|
|
|
|
|
split( str, " - ", asBits, false );
|
|
|
|
|
/* Ignore the difficulty, since we get that elsewhere. */
|
|
|
|
|
if( asBits.size() == 3 &&
|
|
|
|
|
(!stricmp(asBits[2], "double") ||
|
|
|
|
|
!stricmp(asBits[2], "easy") ||
|
|
|
|
|
!stricmp(asBits[2], "normal") ||
|
|
|
|
|
!stricmp(asBits[2], "hard") ||
|
|
|
|
|
!stricmp(asBits[2], "crazy")) )
|
|
|
|
|
{
|
|
|
|
|
asBits.erase(asBits.begin()+2, asBits.begin()+3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CString title, artist;
|
|
|
|
|
if( asBits.size() == 2 )
|
|
|
|
|
{
|
|
|
|
|
artist = asBits[0];
|
|
|
|
|
title = asBits[1];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
title = asBits[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Convert, if possible. Most KSFs are in Korean encodings (CP942/EUC-KR). */
|
|
|
|
|
if( !ConvertString( title, "korean" ) )
|
|
|
|
|
title = "";
|
|
|
|
|
if( !ConvertString( artist, "korean" ) )
|
|
|
|
|
artist = "";
|
|
|
|
|
|
|
|
|
|
if( out.m_sMainTitle == "" )
|
|
|
|
|
out.m_sMainTitle = title;
|
|
|
|
|
if( out.m_sArtist == "" )
|
|
|
|
|
out.m_sArtist = artist;
|
|
|
|
|
}
|
|
|
|
|
|
2003-05-19 19:55:42 +00:00
|
|
|
bool KSFLoader::LoadGlobalData( const CString &sPath, Song &out )
|
2002-09-06 23:24:40 +00:00
|
|
|
{
|
|
|
|
|
MsdFile msd;
|
2004-07-12 23:47:39 +00:00
|
|
|
if( !msd.ReadFile( sPath ) )
|
|
|
|
|
RageException::Throw( "Error opening file \"%s\": %s", sPath.c_str(), msd.GetError().c_str() );
|
2002-09-06 23:24:40 +00:00
|
|
|
|
2003-08-21 19:39:41 +00:00
|
|
|
float BPMPos2 = -1, BPM2 = -1, BPMPos3 = -1, BPM3 = -1;;
|
2003-05-18 05:11:46 +00:00
|
|
|
|
2003-05-19 19:55:42 +00:00
|
|
|
for( unsigned i=0; i < msd.GetNumValues(); i++ )
|
2002-09-06 23:24:40 +00:00
|
|
|
{
|
2003-01-14 22:44:30 +00:00
|
|
|
const MsdFile::value_t &sParams = msd.GetValue(i);
|
2002-09-06 23:24:40 +00:00
|
|
|
CString sValueName = sParams[0];
|
|
|
|
|
|
|
|
|
|
// handle the data
|
|
|
|
|
if( 0==stricmp(sValueName,"TITLE") )
|
2003-05-21 00:10:31 +00:00
|
|
|
LoadTags(sParams[1], out);
|
2002-09-06 23:24:40 +00:00
|
|
|
else if( 0==stricmp(sValueName,"BPM") )
|
2004-08-10 20:57:59 +00:00
|
|
|
out.AddBPMSegment( BPMSegment(0, strtof(sParams[1], NULL)) );
|
2003-05-18 05:11:46 +00:00
|
|
|
else if( 0==stricmp(sValueName,"BPM2") )
|
2004-08-10 20:57:59 +00:00
|
|
|
BPM2 = strtof( sParams[1], NULL );
|
2003-08-21 19:39:41 +00:00
|
|
|
else if( 0==stricmp(sValueName,"BPM3") )
|
2004-08-10 20:57:59 +00:00
|
|
|
BPM3 = strtof( sParams[1], NULL );
|
2003-05-18 05:11:46 +00:00
|
|
|
else if( 0==stricmp(sValueName,"BUNKI") )
|
2004-08-10 20:57:59 +00:00
|
|
|
BPMPos2 = strtof( sParams[1], NULL ) / 100.0f;
|
2003-08-21 19:39:41 +00:00
|
|
|
else if( 0==stricmp(sValueName,"BUNKI2") )
|
2004-08-10 20:57:59 +00:00
|
|
|
BPMPos3 = strtof( sParams[1], NULL ) / 100.0f;
|
2002-09-06 23:24:40 +00:00
|
|
|
else if( 0==stricmp(sValueName,"STARTTIME") )
|
2004-08-10 20:57:59 +00:00
|
|
|
out.m_Timing.m_fBeat0OffsetInSeconds = -strtof( sParams[1], NULL )/100;
|
2002-09-06 23:24:40 +00:00
|
|
|
else if( 0==stricmp(sValueName,"TICKCOUNT") ||
|
|
|
|
|
0==stricmp(sValueName,"STEP") ||
|
|
|
|
|
0==stricmp(sValueName,"DIFFICULTY"))
|
2002-09-12 07:50:20 +00:00
|
|
|
; /* Handled in LoadFromKSFFile; don't warn. */
|
2002-09-06 23:24:40 +00:00
|
|
|
else
|
2003-04-25 00:01:35 +00:00
|
|
|
LOG->Trace( "Unexpected value named '%s'", sValueName.c_str() );
|
2002-09-06 23:24:40 +00:00
|
|
|
}
|
|
|
|
|
|
2003-05-18 05:11:46 +00:00
|
|
|
/* This doesn't work yet: we also need to move the data around, I think, and
|
|
|
|
|
* we should handle more than one BPM change. */
|
|
|
|
|
if( BPM2 > 0 && BPMPos2 > 0 )
|
|
|
|
|
{
|
|
|
|
|
const float BeatsPerSecond = out.GetBPMAtBeat(0) / 60.0f;
|
|
|
|
|
const float beat = BPMPos2 * BeatsPerSecond;
|
|
|
|
|
LOG->Trace("BPM %f, BPS %f, BPMPos2 %f, beat %f",
|
|
|
|
|
out.GetBPMAtBeat(0), BeatsPerSecond, BPMPos2, beat);
|
|
|
|
|
out.AddBPMSegment( BPMSegment(beat, BPM2) );
|
|
|
|
|
}
|
|
|
|
|
|
2003-08-21 19:39:41 +00:00
|
|
|
if( BPM3 > 0 && BPMPos3 > 0 )
|
|
|
|
|
{
|
|
|
|
|
const float BeatsPerSecond = out.GetBPMAtBeat(0) / 60.0f;
|
|
|
|
|
const float beat = BPMPos3 * BeatsPerSecond;
|
|
|
|
|
LOG->Trace("BPM %f, BPS %f, BPMPos3 %f, beat %f",
|
|
|
|
|
out.GetBPMAtBeat(0), BeatsPerSecond, BPMPos3, beat);
|
|
|
|
|
out.AddBPMSegment( BPMSegment(beat, BPM3) );
|
|
|
|
|
}
|
|
|
|
|
|
2003-05-21 00:10:31 +00:00
|
|
|
/* Try to fill in missing bits of information from the pathname. */
|
2003-05-19 19:55:42 +00:00
|
|
|
{
|
|
|
|
|
CStringArray asBits;
|
2003-12-10 09:26:05 +00:00
|
|
|
split( sPath, "/", asBits, true);
|
2003-05-19 19:55:42 +00:00
|
|
|
|
2003-05-21 00:10:31 +00:00
|
|
|
ASSERT(asBits.size() > 1);
|
|
|
|
|
LoadTags(asBits[asBits.size()-2], out);
|
2003-05-19 19:55:42 +00:00
|
|
|
}
|
|
|
|
|
|
2002-09-06 23:24:40 +00:00
|
|
|
// search for music with song in the file name
|
|
|
|
|
CStringArray arrayPossibleMusic;
|
2002-12-13 23:41:11 +00:00
|
|
|
GetDirListing( out.GetSongDir() + CString("song.mp3"), arrayPossibleMusic );
|
|
|
|
|
GetDirListing( out.GetSongDir() + CString("song.ogg"), arrayPossibleMusic );
|
|
|
|
|
GetDirListing( out.GetSongDir() + CString("song.wav"), arrayPossibleMusic );
|
2002-09-06 23:24:40 +00:00
|
|
|
|
2002-10-31 03:01:35 +00:00
|
|
|
if( !arrayPossibleMusic.empty() ) // we found a match
|
2002-09-06 23:24:40 +00:00
|
|
|
out.m_sMusicFile = arrayPossibleMusic[0];
|
|
|
|
|
|
2002-12-17 10:39:33 +00:00
|
|
|
return true;
|
2002-09-06 23:24:40 +00:00
|
|
|
}
|
|
|
|
|
|
2003-05-19 19:55:42 +00:00
|
|
|
bool KSFLoader::LoadFromDir( CString sDir, Song &out )
|
|
|
|
|
{
|
|
|
|
|
LOG->Trace( "Song::LoadFromKSFDir(%s)", sDir.c_str() );
|
|
|
|
|
|
|
|
|
|
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.c_str() );
|
|
|
|
|
|
2003-05-19 19:58:46 +00:00
|
|
|
if(!LoadGlobalData(out.GetSongDir() + arrayKSFFileNames[0], out))
|
|
|
|
|
return false;
|
|
|
|
|
|
2003-08-03 00:13:55 +00:00
|
|
|
// load the Steps from the rest of the KSF files
|
2003-05-21 00:10:31 +00:00
|
|
|
for( unsigned i=0; i<arrayKSFFileNames.size(); i++ )
|
2003-05-19 19:55:42 +00:00
|
|
|
{
|
2003-08-03 00:13:55 +00:00
|
|
|
Steps* pNewNotes = new Steps;
|
2003-05-21 00:10:31 +00:00
|
|
|
if(!LoadFromKSFFile( out.GetSongDir() + arrayKSFFileNames[i], *pNewNotes, out ))
|
2003-05-19 19:55:42 +00:00
|
|
|
{
|
|
|
|
|
delete pNewNotes;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-05 05:13:23 +00:00
|
|
|
out.AddSteps( pNewNotes );
|
2003-05-19 19:55:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2004-05-31 21:55:14 +00:00
|
|
|
/*
|
|
|
|
|
* (c) 2001-2004 Chris Danford, Glenn Maynard
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the
|
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
|
* distribute, and/or sell copies of the Software, and to permit persons to
|
|
|
|
|
* whom the Software is furnished to do so, provided that the above
|
|
|
|
|
* copyright notice(s) and this permission notice appear in all copies of
|
|
|
|
|
* the Software and that both the above copyright notice(s) and this
|
|
|
|
|
* permission notice appear in supporting documentation.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
|
|
|
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
|
|
|
|
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
|
|
|
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
|
|
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
|
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
*/
|