Edit loading overhaul: Load edits from song folders; Allow a songfolder-style hierarchy in profile edit folders; Make the #SONG tag optional if we can infer the intended song from the directory hierarchy.
This commit is contained in:
+15
-9
@@ -829,6 +829,10 @@ bool SMLoader::LoadNoteDataFromSimfile( const RString &path, Steps &out )
|
||||
RString stepsType = sParams[1];
|
||||
RString description = sParams[2];
|
||||
RString difficulty = sParams[3];
|
||||
|
||||
// HACK?: If this is a .edit fudge the edit difficulty
|
||||
if(path.Right(5).CompareNoCase(".edit") == 0) difficulty = "edit";
|
||||
|
||||
Trim(stepsType);
|
||||
Trim(description);
|
||||
Trim(difficulty);
|
||||
@@ -1108,7 +1112,7 @@ bool SMLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SMLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong )
|
||||
bool SMLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong /* =NULL */ )
|
||||
{
|
||||
LOG->Trace( "SMLoader::LoadEditFromFile(%s)", sEditFilePath.c_str() );
|
||||
|
||||
@@ -1126,19 +1130,19 @@ bool SMLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool b
|
||||
return false;
|
||||
}
|
||||
|
||||
return LoadEditFromMsd( msd, sEditFilePath, slot, bAddStepsToSong );
|
||||
return LoadEditFromMsd( msd, sEditFilePath, slot, bAddStepsToSong, givenSong );
|
||||
}
|
||||
|
||||
bool SMLoader::LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot )
|
||||
bool SMLoader::LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot, Song *givenSong )
|
||||
{
|
||||
MsdFile msd;
|
||||
msd.ReadFromString( sBuffer, true ); // unescape
|
||||
return LoadEditFromMsd( msd, sEditFilePath, slot, true );
|
||||
return LoadEditFromMsd( msd, sEditFilePath, slot, true, givenSong );
|
||||
}
|
||||
|
||||
bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong )
|
||||
bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong /* =NULL */ )
|
||||
{
|
||||
Song* pSong = NULL;
|
||||
Song* pSong = givenSong;
|
||||
|
||||
for( unsigned i=0; i<msd.GetNumValues(); i++ )
|
||||
{
|
||||
@@ -1152,8 +1156,10 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath
|
||||
{
|
||||
if( pSong )
|
||||
{
|
||||
LOG->UserLog( "Edit file", sEditFilePath, "has more than one #SONG tag." );
|
||||
return false;
|
||||
/* LOG->UserLog( "Edit file", sEditFilePath, "has more than one #SONG tag." );
|
||||
return false; */
|
||||
// May have been given the song from outside the file. Not worth checking for.
|
||||
continue;
|
||||
}
|
||||
|
||||
RString sSongFullTitle = sParams[1];
|
||||
@@ -1178,7 +1184,7 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath
|
||||
{
|
||||
if( pSong == NULL )
|
||||
{
|
||||
LOG->UserLog( "Edit file", sEditFilePath, "doesn't have a #SONG tag preceeding the first #NOTES tag." );
|
||||
LOG->UserLog( "Edit file", sEditFilePath, "doesn't have a #SONG tag preceeding the first #NOTES tag, and is not in a valid song-specific folder." );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -62,9 +62,9 @@ struct SMLoader
|
||||
* @param out a vector of files found in the path.
|
||||
*/
|
||||
virtual void GetApplicableFiles( const RString &sPath, vector<RString> &out );
|
||||
virtual bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
||||
virtual bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot );
|
||||
virtual bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
||||
virtual bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=NULL );
|
||||
virtual bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot, Song *givenSong=NULL );
|
||||
virtual bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=NULL );
|
||||
virtual bool LoadFromBGChangesString(BackgroundChange &change,
|
||||
const RString &sBGChangeExpression );
|
||||
|
||||
|
||||
@@ -874,7 +874,7 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SSCLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong )
|
||||
bool SSCLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong /* =NULL */ )
|
||||
{
|
||||
LOG->Trace( "SSCLoader::LoadEditFromFile(%s)", sEditFilePath.c_str() );
|
||||
|
||||
@@ -896,15 +896,16 @@ bool SSCLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool
|
||||
return false;
|
||||
}
|
||||
|
||||
return LoadEditFromMsd( msd, sEditFilePath, slot, bAddStepsToSong );
|
||||
return LoadEditFromMsd( msd, sEditFilePath, slot, bAddStepsToSong, givenSong );
|
||||
}
|
||||
|
||||
bool SSCLoader::LoadEditFromMsd(const MsdFile &msd,
|
||||
const RString &sEditFilePath,
|
||||
ProfileSlot slot,
|
||||
bool bAddStepsToSong )
|
||||
bool bAddStepsToSong,
|
||||
Song *givenSong /* =NULL */ )
|
||||
{
|
||||
Song* pSong = NULL;
|
||||
Song* pSong = givenSong;
|
||||
Steps* pNewNotes = NULL;
|
||||
bool bSSCFormat = false;
|
||||
bool bHasOwnTiming = false;
|
||||
@@ -927,8 +928,9 @@ bool SSCLoader::LoadEditFromMsd(const MsdFile &msd,
|
||||
{
|
||||
if( pSong )
|
||||
{
|
||||
LOG->UserLog( "Edit file", sEditFilePath, "has more than one #SONG tag." );
|
||||
return false;
|
||||
/* LOG->UserLog( "Edit file", sEditFilePath, "has more than one #SONG tag." );
|
||||
return false; */
|
||||
continue;
|
||||
}
|
||||
|
||||
RString sSongFullTitle = sParams[1];
|
||||
@@ -1086,7 +1088,7 @@ bool SSCLoader::LoadEditFromMsd(const MsdFile &msd,
|
||||
{
|
||||
LOG->UserLog("Edit file",
|
||||
sEditFilePath,
|
||||
"doesn't have a #SONG tag preceeding the first #NOTES tag." );
|
||||
"doesn't have a #SONG tag preceeding the first #NOTES tag, and is not in a valid song-specific folder." );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ struct SSCLoader : public SMLoader
|
||||
* @param bAddStepsToSong a flag to determine if we add the edit steps to the song file.
|
||||
* @return its success or failure.
|
||||
*/
|
||||
bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
||||
bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=NULL );
|
||||
/**
|
||||
* @brief Attempt to parse the edit file in question.
|
||||
* @param msd the edit file itself.
|
||||
@@ -65,7 +65,7 @@ struct SSCLoader : public SMLoader
|
||||
* @param bAddStepsToSong a flag to determine if we add the edit steps to the song file.
|
||||
* @return its success or failure.
|
||||
*/
|
||||
bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
||||
bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=NULL );
|
||||
|
||||
/**
|
||||
* @brief Retrieve the specific NoteData from the file.
|
||||
|
||||
@@ -349,6 +349,24 @@ bool Song::LoadFromSongDir( RString sDir )
|
||||
if( PREFSMAN->m_BackgroundCache == BGCACHE_LOW_RES_PRELOAD && m_bHasBackground )
|
||||
BACKGROUNDCACHE->LoadBackground( GetBackgroundPath() );
|
||||
*/
|
||||
|
||||
// Load any .edit files in the song folder.
|
||||
// Doing this BEFORE setting up AutoGen just in case.
|
||||
vector<RString> vs;
|
||||
GetDirListing( sDir + "*.edit", vs, false, false);
|
||||
// XXX: I'm sure there's a StepMania way of doing this, but familiar with this codebase I am not.
|
||||
for(unsigned int i = 0; i < vs.size(); ++i) {
|
||||
// Try SSCLoader
|
||||
SSCLoader ldSSC;
|
||||
if( ldSSC.LoadEditFromFile(sDir + vs[i], ProfileSlot_Invalid, true, this) != true )
|
||||
{
|
||||
// No dice? Try SMLoader then. If SMLoader fails too, well whatever.
|
||||
// We don't have to do anything to fail gracefully.
|
||||
SMLoader ldSM;
|
||||
ldSM.LoadEditFromFile(sDir + vs[i], ProfileSlot_Invalid, true, this);
|
||||
}
|
||||
}
|
||||
// Note: If vs.empty() then this loop is skipped entirely (vs.size() == 0)
|
||||
|
||||
// Add AutoGen pointers. (These aren't cached.)
|
||||
AddAutoGenNotes();
|
||||
|
||||
+61
-7
@@ -1713,26 +1713,80 @@ void SongManager::LoadStepEditsFromProfileDir( const RString &sProfileDir, Profi
|
||||
{
|
||||
// Load all edit steps
|
||||
RString sDir = sProfileDir + EDIT_STEPS_SUBDIR;
|
||||
|
||||
vector<RString> vsFiles;
|
||||
GetDirListing( sDir+"*.edit", vsFiles, false, true );
|
||||
|
||||
SSCLoader loaderSSC;
|
||||
SMLoader loaderSM;
|
||||
int iNumEditsLoaded = GetNumEditsLoadedFromProfile( slot );
|
||||
int size = min( (int) vsFiles.size(), MAX_EDIT_STEPS_PER_PROFILE - iNumEditsLoaded );
|
||||
|
||||
// Pass 1: Flat folder (old style)
|
||||
vector<RString> vsFiles;
|
||||
int size = min( (int) vsFiles.size(), MAX_EDIT_STEPS_PER_PROFILE - iNumEditsLoaded );
|
||||
GetDirListing( sDir+"*.edit", vsFiles, false, true );
|
||||
|
||||
// XXX: If some edits are invalid and they're close to the edit limit, this may erroneously skip some edits, and won't warn.
|
||||
for( int i=0; i<size; i++ )
|
||||
{
|
||||
RString fn = vsFiles[i];
|
||||
SSCLoader loaderSSC;
|
||||
bool bLoadedFromSSC = loaderSSC.LoadEditFromFile( fn, slot, true );
|
||||
// If we don't load the edit from a .ssc-style .edit, then we should
|
||||
// also try the .sm-style edit file. -aj
|
||||
if( !bLoadedFromSSC )
|
||||
{
|
||||
SMLoader loaderSM;
|
||||
loaderSM.LoadEditFromFile( fn, slot, true );
|
||||
}
|
||||
}
|
||||
|
||||
if( vsFiles.size() > MAX_EDIT_STEPS_PER_PROFILE - iNumEditsLoaded )
|
||||
{
|
||||
LOG->Warn("Profile %s has too many edits; some have been skipped.", ProfileSlotToString( slot ).c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
// Some .edit files may have been invalid, so re-query instead of just += size.
|
||||
iNumEditsLoaded = GetNumEditsLoadedFromProfile( slot );
|
||||
|
||||
// Pass 2: Group and song folders with #SONG inferred from folder (optional new style)
|
||||
vector<RString> vsGroups;
|
||||
GetDirListing( sDir+"*", vsGroups, true, false );
|
||||
|
||||
// XXX: Same as above, edits may be skipped in error in some cases
|
||||
for( int i=0; i<vsGroups.size(); i++ )
|
||||
{
|
||||
RString sGroupDir = vsGroups[i]+"/";
|
||||
vector<RString> vsSongs;
|
||||
GetDirListing(sDir+sGroupDir+"*", vsSongs, true, false );
|
||||
|
||||
for( int j=0; j<vsSongs.size(); j++ )
|
||||
{
|
||||
vector<RString> vsEdits;
|
||||
RString sSongDir = sGroupDir+vsSongs[j]+"/";
|
||||
// XXX There doesn't appear to be a songdir const?
|
||||
Song *given = GetSongFromDir( "/Songs/"+sSongDir );
|
||||
// NOTE: We don't have to check the return value of GetSongFromDir here,
|
||||
// because if it fails, it returns NULL, which is then passed to NotesLoader*.LoadEditFromFile(),
|
||||
// which will interpret that as "we couldn't infer the song from the path",
|
||||
// which is what we want in that case anyway.
|
||||
GetDirListing(sDir+sSongDir+"/*.edit", vsEdits, false, true );
|
||||
size = min( (int) vsEdits.size(), MAX_EDIT_STEPS_PER_PROFILE - iNumEditsLoaded );
|
||||
|
||||
for( int k=0; k<size; k++ )
|
||||
{
|
||||
RString fn = vsEdits[k];
|
||||
bool bLoadedFromSSC = loaderSSC.LoadEditFromFile( fn, slot, true, given );
|
||||
// And try again with SM
|
||||
if( !bLoadedFromSSC )
|
||||
loaderSM.LoadEditFromFile( fn, slot, true, given );
|
||||
}
|
||||
|
||||
if( vsEdits.size() > MAX_EDIT_STEPS_PER_PROFILE - iNumEditsLoaded )
|
||||
{
|
||||
LOG->Warn("Profile %s has too many edits; some have been skipped.", ProfileSlotToString( slot ).c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
// Some .edit files may have been invalid, so re-query instead of just += size.
|
||||
iNumEditsLoaded = GetNumEditsLoadedFromProfile( slot );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SongManager::LoadCourseEditsFromProfileDir( const RString &sProfileDir, ProfileSlot slot )
|
||||
|
||||
@@ -152,6 +152,17 @@ bool Steps::GetNoteDataFromSimfile()
|
||||
{
|
||||
return BMSLoader::LoadNoteDataFromSimfile(stepFile, *this);
|
||||
}
|
||||
else if (extension == "edit")
|
||||
{
|
||||
// Try SSC, then fallback to SM.
|
||||
SSCLoader ldSSC;
|
||||
if(ldSSC.LoadNoteDataFromSimfile(stepFile, *this) != true)
|
||||
{
|
||||
SMLoader ldSM;
|
||||
return ldSM.LoadNoteDataFromSimfile(stepFile, *this);
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user