Files
itgmania212121/stepmania/src/NotesLoaderDWI.cpp
T

515 lines
15 KiB
C++
Raw Normal View History

2003-02-16 04:01:45 +00:00
#include "global.h"
2002-09-06 23:24:40 +00:00
#include "NotesLoaderDWI.h"
#include "NotesLoader.h"
#include "RageLog.h"
#include "RageException.h"
#include "MsdFile.h"
2002-09-07 11:43:36 +00:00
#include "RageUtil.h"
2003-06-30 08:40:10 +00:00
#include "RageUtil_CharConversions.h"
2002-09-07 11:43:36 +00:00
#include "NoteData.h"
2002-09-06 23:24:40 +00:00
2002-09-07 07:49:15 +00:00
#include <map>
using namespace std;
static std::map<int,int> g_mapDanceNoteToNoteDataColumn;
2002-09-06 23:24:40 +00:00
void DWILoader::DWIcharToNote( char c, GameController i, DanceNote &note1Out, DanceNote &note2Out )
{
switch( c )
{
case '0': note1Out = DANCE_NOTE_NONE; note2Out = DANCE_NOTE_NONE; break;
case '1': note1Out = DANCE_NOTE_PAD1_DOWN; note2Out = DANCE_NOTE_PAD1_LEFT; break;
case '2': note1Out = DANCE_NOTE_PAD1_DOWN; note2Out = DANCE_NOTE_NONE; break;
case '3': note1Out = DANCE_NOTE_PAD1_DOWN; note2Out = DANCE_NOTE_PAD1_RIGHT; break;
case '4': note1Out = DANCE_NOTE_PAD1_LEFT; note2Out = DANCE_NOTE_NONE; break;
case '5': note1Out = DANCE_NOTE_NONE; note2Out = DANCE_NOTE_NONE; break;
case '6': note1Out = DANCE_NOTE_PAD1_RIGHT; note2Out = DANCE_NOTE_NONE; break;
case '7': note1Out = DANCE_NOTE_PAD1_UP; note2Out = DANCE_NOTE_PAD1_LEFT; break;
case '8': note1Out = DANCE_NOTE_PAD1_UP; note2Out = DANCE_NOTE_NONE; break;
case '9': note1Out = DANCE_NOTE_PAD1_UP; note2Out = DANCE_NOTE_PAD1_RIGHT; break;
case 'A': note1Out = DANCE_NOTE_PAD1_UP; note2Out = DANCE_NOTE_PAD1_DOWN; break;
case 'B': note1Out = DANCE_NOTE_PAD1_LEFT; note2Out = DANCE_NOTE_PAD1_RIGHT; break;
case 'C': note1Out = DANCE_NOTE_PAD1_UPLEFT; note2Out = DANCE_NOTE_NONE; break;
case 'D': note1Out = DANCE_NOTE_PAD1_UPRIGHT; note2Out = DANCE_NOTE_NONE; break;
case 'E': note1Out = DANCE_NOTE_PAD1_LEFT; note2Out = DANCE_NOTE_PAD1_UPLEFT; break;
case 'F': note1Out = DANCE_NOTE_PAD1_UPLEFT; note2Out = DANCE_NOTE_PAD1_DOWN; break;
case 'G': note1Out = DANCE_NOTE_PAD1_UPLEFT; note2Out = DANCE_NOTE_PAD1_UP; break;
case 'H': note1Out = DANCE_NOTE_PAD1_UPLEFT; note2Out = DANCE_NOTE_PAD1_RIGHT; break;
case 'I': note1Out = DANCE_NOTE_PAD1_LEFT; note2Out = DANCE_NOTE_PAD1_UPRIGHT; break;
case 'J': note1Out = DANCE_NOTE_PAD1_DOWN; note2Out = DANCE_NOTE_PAD1_UPRIGHT; break;
case 'K': note1Out = DANCE_NOTE_PAD1_UP; note2Out = DANCE_NOTE_PAD1_UPRIGHT; break;
case 'L': note1Out = DANCE_NOTE_PAD1_UPRIGHT; note2Out = DANCE_NOTE_PAD1_RIGHT; break;
case 'M': note1Out = DANCE_NOTE_PAD1_UPLEFT; note2Out = DANCE_NOTE_PAD1_UPRIGHT; break;
default:
2003-07-15 19:55:06 +00:00
LOG->Warn( "Encountered invalid DWI note character '%c' in '%s'", c, m_sLoadingFile.c_str() );
2002-09-06 23:24:40 +00:00
note1Out = DANCE_NOTE_NONE; note2Out = DANCE_NOTE_NONE; break;
}
switch( i )
{
case GAME_CONTROLLER_1:
break;
case GAME_CONTROLLER_2:
if( note1Out != DANCE_NOTE_NONE )
note1Out += 6;
if( note2Out != DANCE_NOTE_NONE )
note2Out += 6;
break;
default:
ASSERT( false );
}
}
void DWILoader::DWIcharToNoteCol( char c, GameController i, int &col1Out, int &col2Out )
{
DanceNote note1, note2;
DWIcharToNote( c, i, note1, note2 );
if( note1 != DANCE_NOTE_NONE )
col1Out = g_mapDanceNoteToNoteDataColumn[note1];
else
col1Out = -1;
if( note2 != DANCE_NOTE_NONE )
col2Out = g_mapDanceNoteToNoteDataColumn[note2];
else
col2Out = -1;
}
2002-09-06 23:24:40 +00:00
/* Ack. DWI used to use <...> to indicate 1/192nd notes; at some
* point, <...> was changed to indicate jumps, and `' was used for
* 1/192nds. So, we have to do a check to figure out what it really
* means. If it contains 0s, it's most likely 192nds; otherwise,
* it's most likely a jump. Search for a 0 before the next >: */
2003-12-03 01:47:03 +00:00
bool DWILoader::Is192( const CString &sStepData, int pos )
{
while( pos < (int) sStepData.size() )
{
if( sStepData[pos] == '>' )
return false;
if( sStepData[pos] == '0' )
return true;
++pos;
}
return false;
}
2002-09-06 23:24:40 +00:00
bool DWILoader::LoadFromDWITokens(
CString sMode,
CString sDescription,
CString sNumFeet,
CString sStepData1,
CString sStepData2,
2003-08-03 00:13:55 +00:00
Steps &out)
2002-09-06 23:24:40 +00:00
{
CHECKPOINT_M( "DWILoader::LoadFromDWITokens()" );
2002-09-06 23:24:40 +00:00
2003-08-07 06:36:34 +00:00
out.m_StepsType = STEPS_TYPE_INVALID;
2003-08-07 06:36:34 +00:00
if( sMode == "SINGLE" ) out.m_StepsType = STEPS_TYPE_DANCE_SINGLE;
else if( sMode == "DOUBLE" ) out.m_StepsType = STEPS_TYPE_DANCE_DOUBLE;
else if( sMode == "COUPLE" ) out.m_StepsType = STEPS_TYPE_DANCE_COUPLE;
else if( sMode == "SOLO" ) out.m_StepsType = STEPS_TYPE_DANCE_SOLO;
2002-09-06 23:24:40 +00:00
else
{
ASSERT(0); // Unrecognized DWI notes format
2003-08-07 06:36:34 +00:00
out.m_StepsType = STEPS_TYPE_DANCE_SINGLE;
2002-09-06 23:24:40 +00:00
}
g_mapDanceNoteToNoteDataColumn.clear();
2003-08-07 06:36:34 +00:00
switch( out.m_StepsType )
2002-09-06 23:24:40 +00:00
{
2003-08-07 06:16:17 +00:00
case STEPS_TYPE_DANCE_SINGLE:
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
2002-09-06 23:24:40 +00:00
break;
2003-08-07 06:16:17 +00:00
case STEPS_TYPE_DANCE_DOUBLE:
case STEPS_TYPE_DANCE_COUPLE:
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_LEFT] = 4;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_DOWN] = 5;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_UP] = 6;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_RIGHT] = 7;
2002-09-06 23:24:40 +00:00
break;
2003-08-07 06:16:17 +00:00
case STEPS_TYPE_DANCE_SOLO:
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPLEFT] = 1;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 2;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 3;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPRIGHT] = 4;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 5;
2002-09-06 23:24:40 +00:00
break;
default:
ASSERT(0);
}
int iNumFeet = atoi(sNumFeet);
2004-03-29 21:08:59 +00:00
// out.SetDescription(sDescription); // Don't put garbage in the description.
out.SetMeter(iNumFeet);
2004-03-29 21:08:59 +00:00
out.SetDifficulty( StringToDifficulty(sDescription) );
2002-09-06 23:24:40 +00:00
2003-12-03 00:00:30 +00:00
NoteData newNoteData;
newNoteData.SetNumTracks( g_mapDanceNoteToNoteDataColumn.size() );
2003-12-11 04:53:16 +00:00
newNoteData.ReserveRows( BeatToNoteRow(1000) );
2002-09-06 23:24:40 +00:00
for( int pad=0; pad<2; pad++ ) // foreach pad
{
CString sStepData;
switch( pad )
{
case 0:
sStepData = sStepData1;
break;
case 1:
if( sStepData2 == "" ) // no data
continue; // skip
sStepData = sStepData2;
break;
default:
ASSERT( false );
}
2003-12-03 01:47:03 +00:00
sStepData.Replace("\n", "");
sStepData.Replace("\r", "");
sStepData.Replace("\t", "");
sStepData.Replace(" ", "");
2002-09-06 23:24:40 +00:00
double fCurrentBeat = 0;
double fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE;
for( int i=0; i<sStepData.GetLength(); )
{
char c = sStepData[i++];
switch( c )
{
// begins a series
case '(':
fCurrentIncrementer = 1.0/16 * BEATS_PER_MEASURE;
break;
case '[':
fCurrentIncrementer = 1.0/24 * BEATS_PER_MEASURE;
break;
case '{':
fCurrentIncrementer = 1.0/64 * BEATS_PER_MEASURE;
break;
case '`':
2002-09-06 23:24:40 +00:00
fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE;
break;
// ends a series
case ')':
case ']':
case '}':
case '\'':
2002-09-06 23:24:40 +00:00
case '>':
fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE;
break;
default: // this is a note character
{
if( c == '!' )
2002-09-06 23:24:40 +00:00
{
2003-07-15 19:55:06 +00:00
LOG->Warn( "Unexpected character in '%s': '!'", m_sLoadingFile.c_str() );
continue;
}
2002-09-06 23:24:40 +00:00
bool jump = false;
if( c == '<' )
{
/* Arr. Is this a jump or a 1/192 marker? */
if( Is192( sStepData, i ) )
2002-09-06 23:24:40 +00:00
{
fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE;
break;
2002-09-06 23:24:40 +00:00
}
/* It's a jump. We need to keep reading notes until we hit a >. */
jump = true;
i++;
2002-09-06 23:24:40 +00:00
}
const int iIndex = BeatToNoteRow( (float)fCurrentBeat );
i--;
do {
c = sStepData[i++];
2002-09-06 23:24:40 +00:00
if( jump && c == '>' )
break;
2002-09-06 23:24:40 +00:00
int iCol1, iCol2;
DWIcharToNoteCol( c, (GameController)pad, iCol1, iCol2 );
if( iCol1 != -1 )
2003-12-03 00:00:30 +00:00
newNoteData.SetTapNote(iCol1, iIndex, TAP_TAP);
if( iCol2 != -1 )
2003-12-03 00:00:30 +00:00
newNoteData.SetTapNote(iCol2, iIndex, TAP_TAP);
2002-09-06 23:24:40 +00:00
if( sStepData[i] == '!' )
{
i++;
const char holdChar = sStepData[i++];
DWIcharToNoteCol( holdChar, (GameController)pad, iCol1, iCol2 );
if( iCol1 != -1 )
2003-12-03 00:00:30 +00:00
newNoteData.SetTapNote(iCol1, iIndex, TAP_HOLD_HEAD);
if( iCol2 != -1 )
2003-12-03 00:00:30 +00:00
newNoteData.SetTapNote(iCol2, iIndex, TAP_HOLD_HEAD);
}
2002-09-06 23:24:40 +00:00
}
while( jump );
fCurrentBeat += fCurrentIncrementer;
2002-09-06 23:24:40 +00:00
}
break;
}
2002-09-06 23:24:40 +00:00
}
}
// this will expand the HoldNote begin markers we wrote into actual HoldNotes
2003-12-03 00:00:30 +00:00
newNoteData.Convert2sAnd3sToHoldNotes();
2002-09-06 23:24:40 +00:00
2003-12-03 00:00:30 +00:00
ASSERT( newNoteData.GetNumTracks() > 0 );
2002-09-06 23:24:40 +00:00
2003-12-03 00:00:30 +00:00
out.SetNoteData(&newNoteData);
out.TidyUpData();
2002-09-06 23:24:40 +00:00
return true;
}
2002-09-06 23:24:40 +00:00
2002-12-27 21:39:25 +00:00
/* STUPID ALERT!
* This value can be in either "HH:MM:SS.sssss", "MM:SS.sssss", "SSS.sssss"
* or milliseconds.
* What's even more dumb is that the value can contain a ':'. Colon is supposed to be a parameter separator!
*/
2003-01-14 22:44:30 +00:00
float DWILoader::ParseBrokenDWITimestamp(const CString &arg1, const CString &arg2, const CString &arg3)
2002-12-27 21:39:25 +00:00
{
2003-01-14 22:44:30 +00:00
if(arg1.empty()) return 0;
/* 1+ args */
if(arg2.empty())
{
/* If the value contains a period, treat it as seconds; otherwise ms. */
if(arg1.find_first_of(".") != arg1.npos)
2003-04-25 00:01:35 +00:00
return (float)atof(arg1.c_str());
2003-01-14 22:44:30 +00:00
else
2003-04-25 00:01:35 +00:00
return float(atof(arg1.c_str())) / 1000.f;
2003-01-14 22:44:30 +00:00
}
/* 2+ args */
if(arg3.empty())
2004-02-22 19:51:46 +00:00
return HHMMSSToSeconds( arg1+":"+arg2 );
2003-01-14 22:44:30 +00:00
/* 3+ args */
2004-02-22 19:51:46 +00:00
return HHMMSSToSeconds( arg1+":"+arg2+":"+arg3 );
2002-12-27 21:39:25 +00:00
}
2002-09-06 23:24:40 +00:00
bool DWILoader::LoadFromDWIFile( CString sPath, Song &out )
{
2003-04-25 00:01:35 +00:00
LOG->Trace( "Song::LoadFromDWIFile(%s)", sPath.c_str() );
2003-07-15 19:55:06 +00:00
m_sLoadingFile = sPath;
2002-09-06 23:24:40 +00:00
MsdFile msd;
bool bResult = msd.ReadFile( sPath );
if( !bResult )
2003-04-25 00:01:35 +00:00
RageException::Throw( "Error opening file '%s' for reading.", sPath.c_str() );
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
int iNumParams = msd.GetNumParams(i);
const MsdFile::value_t &sParams = msd.GetValue(i);
2002-09-06 23:24:40 +00:00
CString sValueName = sParams[0];
2002-12-27 21:39:25 +00:00
if(iNumParams < 1)
{
2003-07-15 19:55:06 +00:00
LOG->Warn("Got \"%s\" tag with no parameters in '%s'", sValueName.c_str(), m_sLoadingFile.c_str() );
2002-12-27 21:39:25 +00:00
continue;
}
2002-09-06 23:24:40 +00:00
// handle the data
if( 0==stricmp(sValueName,"FILE") )
out.m_sMusicFile = sParams[1];
else if( 0==stricmp(sValueName,"TITLE") )
2003-06-30 08:40:10 +00:00
{
GetMainAndSubTitlesFromFullTitle( sParams[1], out.m_sMainTitle, out.m_sSubTitle );
2002-09-06 23:24:40 +00:00
2003-06-30 08:40:10 +00:00
/* As far as I know, there's no spec on the encoding of this text. (I didn't
* look very hard, though.) I've seen at least one file in ISO-8859-1. */
ConvertString( out.m_sMainTitle, "utf-8,english" );
ConvertString( out.m_sSubTitle, "utf-8,english" );
}
2002-09-06 23:24:40 +00:00
else if( 0==stricmp(sValueName,"ARTIST") )
2003-06-30 08:40:10 +00:00
{
2002-09-06 23:24:40 +00:00
out.m_sArtist = sParams[1];
2003-06-30 08:40:10 +00:00
ConvertString( out.m_sArtist, "utf-8,english" );
}
2002-09-06 23:24:40 +00:00
else if( 0==stricmp(sValueName,"CDTITLE") )
out.m_sCDTitleFile = sParams[1];
else if( 0==stricmp(sValueName,"BPM") )
out.AddBPMSegment( BPMSegment(0, (float)atof(sParams[1])) );
else if( 0==stricmp(sValueName,"DISPLAYBPM") )
{
// #DISPLAYBPM:[xxx..xxx]|[xxx]|[*];
2003-06-13 23:15:09 +00:00
int iMin, iMax;
/* We can't parse this as a float with sscanf, since '.' is a valid
* character in a float. (We could do it with a regex, but it's not
* worth bothering with since we don't display fractional BPM anyway.) */
if( sscanf( sParams[1], "%i..%i", &iMin, &iMax ) == 2 )
{
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
2003-06-16 17:28:58 +00:00
out.m_fSpecifiedBPMMin = (float) iMin;
out.m_fSpecifiedBPMMax = (float) iMax;
}
2003-06-13 23:15:09 +00:00
else if( sscanf( sParams[1], "%i", &iMin ) == 1 )
{
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
2003-06-16 17:28:58 +00:00
out.m_fSpecifiedBPMMin = out.m_fSpecifiedBPMMax = (float) iMin;
}
else
{
out.m_DisplayBPMType = Song::DISPLAY_RANDOM;
}
}
2002-09-06 23:24:40 +00:00
else if( 0==stricmp(sValueName,"GAP") )
// the units of GAP is 1/1000 second
2003-12-18 04:48:26 +00:00
out.m_Timing.m_fBeat0OffsetInSeconds = -atoi( sParams[1] ) / 1000.0f;
2002-09-06 23:24:40 +00:00
else if( 0==stricmp(sValueName,"SAMPLESTART") )
2003-01-14 22:44:30 +00:00
out.m_fMusicSampleStartSeconds = ParseBrokenDWITimestamp(sParams[1], sParams[2], sParams[3]);
2002-09-06 23:24:40 +00:00
else if( 0==stricmp(sValueName,"SAMPLELENGTH") )
2003-01-14 22:44:30 +00:00
out.m_fMusicSampleLengthSeconds = ParseBrokenDWITimestamp(sParams[1], sParams[2], sParams[3]);
2002-09-06 23:24:40 +00:00
else if( 0==stricmp(sValueName,"FREEZE") )
{
CStringArray arrayFreezeExpressions;
split( sParams[1], ",", arrayFreezeExpressions );
for( unsigned f=0; f<arrayFreezeExpressions.size(); f++ )
2002-09-06 23:24:40 +00:00
{
CStringArray arrayFreezeValues;
split( arrayFreezeExpressions[f], "=", arrayFreezeValues );
if( arrayFreezeValues.size() != 2 )
{
LOG->Warn( "Invalid FREEZE in '%s': '%s'", m_sLoadingFile.c_str(), arrayFreezeExpressions[f].c_str() );
continue;
}
float fIndex = (float)atof( arrayFreezeValues[0] ) * ROWS_PER_BEAT / 4.0f;
2002-09-06 23:24:40 +00:00
float fFreezeBeat = NoteRowToBeat( fIndex );
float fFreezeSeconds = (float)atof( arrayFreezeValues[1] ) / 1000.0f;
out.AddStopSegment( StopSegment(fFreezeBeat, fFreezeSeconds) );
2004-05-19 04:09:08 +00:00
// LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", fFreezeBeat, fFreezeSeconds );
2002-09-06 23:24:40 +00:00
}
}
else if( 0==stricmp(sValueName,"CHANGEBPM") || 0==stricmp(sValueName,"BPMCHANGE") )
{
CStringArray arrayBPMChangeExpressions;
split( sParams[1], ",", arrayBPMChangeExpressions );
for( unsigned b=0; b<arrayBPMChangeExpressions.size(); b++ )
2002-09-06 23:24:40 +00:00
{
CStringArray arrayBPMChangeValues;
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
if( arrayBPMChangeValues.size() != 2 )
{
2003-07-15 19:55:06 +00:00
LOG->Warn( "Invalid CHANGEBPM in '%s': '%s'", m_sLoadingFile.c_str(), arrayBPMChangeExpressions[b].c_str() );
2002-09-08 22:02:01 +00:00
continue;
}
float fIndex = (float)atof( arrayBPMChangeValues[0] ) * ROWS_PER_BEAT / 4.0f;
2002-09-06 23:24:40 +00:00
float fBeat = NoteRowToBeat( fIndex );
float fNewBPM = (float)atof( arrayBPMChangeValues[1] );
out.AddBPMSegment( BPMSegment(fBeat, fNewBPM) );
}
}
else if( 0==stricmp(sValueName,"SINGLE") ||
0==stricmp(sValueName,"DOUBLE") ||
0==stricmp(sValueName,"COUPLE") ||
0==stricmp(sValueName,"SOLO"))
{
2003-08-03 00:13:55 +00:00
Steps* pNewNotes = new Steps;
2002-09-06 23:24:40 +00:00
LoadFromDWITokens(
sParams[0],
sParams[1],
sParams[2],
sParams[3],
(iNumParams==5) ? sParams[4] : "",
2002-09-12 08:37:12 +00:00
*pNewNotes
2002-09-06 23:24:40 +00:00
);
2003-08-07 06:36:34 +00:00
if(pNewNotes->m_StepsType != STEPS_TYPE_INVALID)
2004-05-24 03:41:39 +00:00
out.m_vpSteps.push_back( pNewNotes );
else
delete pNewNotes;
2002-09-06 23:24:40 +00:00
}
2003-07-28 08:24:16 +00:00
else if( 0==stricmp(sValueName,"DISPLAYTITLE") ||
0==stricmp(sValueName,"DISPLAYARTIST") )
{
/* We don't want to support these tags. However, we don't want
* to pick up images used here as song images (eg. banners). */
CString param = sParams[1];
/* "{foo} ... {foo2}" */
unsigned pos = 0;
while( pos < CString::npos )
{
unsigned startpos = param.find('{', pos);
if( startpos == CString::npos )
break;
unsigned endpos = param.find('}', startpos);
if( endpos == CString::npos )
break;
CString sub = param.substr( startpos+1, endpos-startpos-1 );
pos = endpos + 1;
BlacklistedImages.insert( sub.c_str() );
2003-07-28 08:24:16 +00:00
}
}
2002-09-06 23:24:40 +00:00
else
// do nothing. We don't care about this value name
;
}
return true;
}
2002-09-11 05:15:46 +00:00
void DWILoader::GetApplicableFiles( CString sPath, CStringArray &out )
{
GetDirListing( sPath + CString("*.dwi"), out );
}
bool DWILoader::LoadFromDir( CString sPath, Song &out )
{
CStringArray aFileNames;
GetApplicableFiles( sPath, aFileNames );
if( aFileNames.size() > 1 )
2003-04-25 00:01:35 +00:00
RageException::Throw( "There is more than one DWI file in '%s'. There should be only one!", sPath.c_str() );
2002-09-11 05:15:46 +00:00
/* We should have exactly one; if we had none, we shouldn't have been
* called to begin with. */
ASSERT( aFileNames.size() == 1 );
2002-09-11 05:15:46 +00:00
return LoadFromDWIFile( sPath + aFileNames[0], out );
}