Added autosave to edit mode.
This commit is contained in:
+1
-10
@@ -27,16 +27,6 @@ bool SMLoader::LoadFromDir( const RString &sPath, Song &out )
|
|||||||
{
|
{
|
||||||
vector<RString> aFileNames;
|
vector<RString> aFileNames;
|
||||||
GetApplicableFiles( sPath, aFileNames );
|
GetApplicableFiles( sPath, aFileNames );
|
||||||
|
|
||||||
if( aFileNames.size() > 1 )
|
|
||||||
{
|
|
||||||
// Need to break this up first.
|
|
||||||
RString tmp = "Song " + sPath + " has more than one";
|
|
||||||
LOG->UserLog(tmp, this->GetFileExtension(), "file. There can only be one!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT( aFileNames.size() == 1 );
|
|
||||||
return LoadFromSimfile( sPath + aFileNames[0], out );
|
return LoadFromSimfile( sPath + aFileNames[0], out );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1229,6 +1219,7 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath
|
|||||||
|
|
||||||
void SMLoader::GetApplicableFiles( const RString &sPath, vector<RString> &out )
|
void SMLoader::GetApplicableFiles( const RString &sPath, vector<RString> &out )
|
||||||
{
|
{
|
||||||
|
GetDirListing( sPath + RString("*.ats" ), out );
|
||||||
GetDirListing( sPath + RString("*" + this->GetFileExtension() ), out );
|
GetDirListing( sPath + RString("*" + this->GetFileExtension() ), out );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+109
-69
@@ -45,6 +45,7 @@ static Preference<bool> g_bEditorShowBGChangesPlay( "EditorShowBGChangesPlay", t
|
|||||||
/** @brief How long must the button be held to generate a hold in record mode? */
|
/** @brief How long must the button be held to generate a hold in record mode? */
|
||||||
const float record_hold_default= 0.3f;
|
const float record_hold_default= 0.3f;
|
||||||
float record_hold_seconds = record_hold_default;
|
float record_hold_seconds = record_hold_default;
|
||||||
|
const float time_between_autosave= 300.0f; // 5 minutes. -Kyz
|
||||||
|
|
||||||
#define PLAYER_X (SCREEN_CENTER_X)
|
#define PLAYER_X (SCREEN_CENTER_X)
|
||||||
#define PLAYER_Y (SCREEN_CENTER_Y)
|
#define PLAYER_Y (SCREEN_CENTER_Y)
|
||||||
@@ -108,6 +109,7 @@ AutoScreenMessage( SM_BackFromFakeChange );
|
|||||||
AutoScreenMessage( SM_DoEraseStepTiming );
|
AutoScreenMessage( SM_DoEraseStepTiming );
|
||||||
AutoScreenMessage( SM_DoSaveAndExit );
|
AutoScreenMessage( SM_DoSaveAndExit );
|
||||||
AutoScreenMessage( SM_DoExit );
|
AutoScreenMessage( SM_DoExit );
|
||||||
|
AutoScreenMessage( SM_AutoSaveSuccessful );
|
||||||
AutoScreenMessage( SM_SaveSuccessful );
|
AutoScreenMessage( SM_SaveSuccessful );
|
||||||
AutoScreenMessage( SM_SaveFailed );
|
AutoScreenMessage( SM_SaveFailed );
|
||||||
|
|
||||||
@@ -1383,7 +1385,11 @@ void ScreenEdit::Init()
|
|||||||
m_bHasUndo = false;
|
m_bHasUndo = false;
|
||||||
m_Undo.SetNumTracks( m_NoteDataEdit.GetNumTracks() );
|
m_Undo.SetNumTracks( m_NoteDataEdit.GetNumTracks() );
|
||||||
|
|
||||||
m_bDirty = m_NoteDataEdit.IsEmpty(); // require the usage of saving if empty.
|
SetDirty(m_NoteDataEdit.IsEmpty()); // require saving if empty.
|
||||||
|
if(GAMESTATE->m_pCurSong->WasLoadedFromAutosave())
|
||||||
|
{
|
||||||
|
SetDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
m_Player->Init( "Player", GAMESTATE->m_pPlayerState[PLAYER_1], NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
|
m_Player->Init( "Player", GAMESTATE->m_pPlayerState[PLAYER_1], NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
|
||||||
m_Player->CacheAllUsedNoteSkins();
|
m_Player->CacheAllUsedNoteSkins();
|
||||||
@@ -1519,6 +1525,16 @@ void ScreenEdit::Update( float fDeltaTime )
|
|||||||
GAMESTATE->UpdateSongPosition( fSeconds, GAMESTATE->m_pCurSong->m_SongTiming, tm );
|
GAMESTATE->UpdateSongPosition( fSeconds, GAMESTATE->m_pCurSong->m_SongTiming, tm );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_EditState == STATE_EDITING)
|
||||||
|
{
|
||||||
|
if(IsDirty() && m_next_autosave_time > -1.0f &&
|
||||||
|
RageTimer::GetTimeSinceStartFast() > m_next_autosave_time)
|
||||||
|
{
|
||||||
|
PerformSave(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if( m_EditState == STATE_RECORDING )
|
if( m_EditState == STATE_RECORDING )
|
||||||
{
|
{
|
||||||
// TODO: Find a way to prevent STATE_RECORDING when in Song Timing.
|
// TODO: Find a way to prevent STATE_RECORDING when in Song Timing.
|
||||||
@@ -1604,7 +1620,6 @@ void ScreenEdit::Update( float fDeltaTime )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//LOG->Trace( "ScreenEdit::Update(%f)", fDeltaTime );
|
//LOG->Trace( "ScreenEdit::Update(%f)", fDeltaTime );
|
||||||
ScreenWithMenuElements::Update( fDeltaTime );
|
ScreenWithMenuElements::Update( fDeltaTime );
|
||||||
|
|
||||||
@@ -4166,6 +4181,11 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
else
|
else
|
||||||
SCREENMAN->SystemMessage( SAVE_SUCCESSFUL );
|
SCREENMAN->SystemMessage( SAVE_SUCCESSFUL );
|
||||||
}
|
}
|
||||||
|
else if( SM == SM_AutoSaveSuccessful )
|
||||||
|
{
|
||||||
|
LOG->Trace( "AutoSave successful." );
|
||||||
|
m_next_autosave_time= RageTimer::GetTimeSinceStartFast() + time_between_autosave;
|
||||||
|
}
|
||||||
else if( SM == SM_SaveFailed ) // save failed; stay in the editor
|
else if( SM == SM_SaveFailed ) // save failed; stay in the editor
|
||||||
{
|
{
|
||||||
/* We committed the steps to SongManager. Revert to the last save, and
|
/* We committed the steps to SongManager. Revert to the last save, and
|
||||||
@@ -4235,6 +4255,91 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
ScreenWithMenuElements::HandleScreenMessage( SM );
|
ScreenWithMenuElements::HandleScreenMessage( SM );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScreenEdit::SetDirty(bool dirty)
|
||||||
|
{
|
||||||
|
if(dirty)
|
||||||
|
{
|
||||||
|
if(!m_dirty)
|
||||||
|
{
|
||||||
|
m_next_autosave_time= RageTimer::GetTimeSinceStartFast() + time_between_autosave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_next_autosave_time= -1.0f;
|
||||||
|
}
|
||||||
|
m_dirty= dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenEdit::PerformSave(bool autosave)
|
||||||
|
{
|
||||||
|
// copy edit into current Steps
|
||||||
|
m_pSteps->SetNoteData( m_NoteDataEdit );
|
||||||
|
|
||||||
|
// don't forget the attacks.
|
||||||
|
m_pSong->m_Attacks = GAMESTATE->m_pCurSong->m_Attacks;
|
||||||
|
m_pSong->m_sAttackString = GAMESTATE->m_pCurSong->m_Attacks.ToVectorString();
|
||||||
|
m_pSteps->m_Attacks = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Attacks;
|
||||||
|
m_pSteps->m_sAttackString = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Attacks.ToVectorString();
|
||||||
|
|
||||||
|
const ScreenMessage save_message= autosave ? SM_AutoSaveSuccessful
|
||||||
|
: SM_SaveSuccessful;
|
||||||
|
|
||||||
|
switch( EDIT_MODE.GetValue() )
|
||||||
|
{
|
||||||
|
DEFAULT_FAIL( EDIT_MODE.GetValue() );
|
||||||
|
case EditMode_Home:
|
||||||
|
{
|
||||||
|
ASSERT( m_pSteps->IsAnEdit() );
|
||||||
|
|
||||||
|
RString sError;
|
||||||
|
m_pSteps->CalculateRadarValues( m_pSong->m_fMusicLengthSeconds );
|
||||||
|
if( !NotesWriterSM::WriteEditFileToMachine(m_pSong, m_pSteps, sError) )
|
||||||
|
{
|
||||||
|
ScreenPrompt::Prompt( SM_None, sError );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pSteps->SetSavedToDisk( true );
|
||||||
|
|
||||||
|
// HACK: clear undo, so "exit" below knows we don't need to save.
|
||||||
|
// This only works because important non-steps data can't be changed in
|
||||||
|
// home mode (BPMs, stops).
|
||||||
|
ClearUndo();
|
||||||
|
|
||||||
|
SCREENMAN->ZeroNextUpdate();
|
||||||
|
|
||||||
|
HandleScreenMessage(save_message);
|
||||||
|
|
||||||
|
/* FIXME
|
||||||
|
RString s;
|
||||||
|
switch( c )
|
||||||
|
{
|
||||||
|
case save: s = "ScreenMemcardSaveEditsAfterSave"; break;
|
||||||
|
case save_on_exit: s = "ScreenMemcardSaveEditsAfterExit"; break;
|
||||||
|
default: FAIL_M(ssprintf("Invalid menu choice: %i", c));
|
||||||
|
}
|
||||||
|
SCREENMAN->AddNewScreenToTop( s );
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EditMode_Full:
|
||||||
|
{
|
||||||
|
// This will recalculate radar values.
|
||||||
|
m_pSong->Save(autosave);
|
||||||
|
SCREENMAN->ZeroNextUpdate();
|
||||||
|
|
||||||
|
HandleScreenMessage(save_message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EditMode_CourseMods:
|
||||||
|
case EditMode_Practice:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_soundSave.Play();
|
||||||
|
}
|
||||||
|
|
||||||
void ScreenEdit::OnSnapModeChange()
|
void ScreenEdit::OnSnapModeChange()
|
||||||
{
|
{
|
||||||
m_soundChangeSnap.Play();
|
m_soundChangeSnap.Play();
|
||||||
@@ -4622,73 +4727,8 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector<int> &iAns
|
|||||||
}
|
}
|
||||||
case save:
|
case save:
|
||||||
case save_on_exit:
|
case save_on_exit:
|
||||||
{
|
m_CurrentAction = c;
|
||||||
m_CurrentAction = c;
|
PerformSave(false);
|
||||||
|
|
||||||
// copy edit into current Steps
|
|
||||||
m_pSteps->SetNoteData( m_NoteDataEdit );
|
|
||||||
|
|
||||||
// don't forget the attacks.
|
|
||||||
m_pSong->m_Attacks = GAMESTATE->m_pCurSong->m_Attacks;
|
|
||||||
m_pSong->m_sAttackString = GAMESTATE->m_pCurSong->m_Attacks.ToVectorString();
|
|
||||||
m_pSteps->m_Attacks = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Attacks;
|
|
||||||
m_pSteps->m_sAttackString = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Attacks.ToVectorString();
|
|
||||||
|
|
||||||
switch( EDIT_MODE.GetValue() )
|
|
||||||
{
|
|
||||||
DEFAULT_FAIL( EDIT_MODE.GetValue() );
|
|
||||||
case EditMode_Home:
|
|
||||||
{
|
|
||||||
ASSERT( m_pSteps->IsAnEdit() );
|
|
||||||
|
|
||||||
RString sError;
|
|
||||||
|
|
||||||
m_pSteps->CalculateRadarValues( m_pSong->m_fMusicLengthSeconds );
|
|
||||||
if( !NotesWriterSM::WriteEditFileToMachine(m_pSong, m_pSteps, sError) )
|
|
||||||
{
|
|
||||||
ScreenPrompt::Prompt( SM_None, sError );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pSteps->SetSavedToDisk( true );
|
|
||||||
|
|
||||||
// HACK: clear undo, so "exit" below knows we don't need to save.
|
|
||||||
// This only works because important non-steps data can't be changed in
|
|
||||||
// home mode (BPMs, stops).
|
|
||||||
ClearUndo();
|
|
||||||
|
|
||||||
SCREENMAN->ZeroNextUpdate();
|
|
||||||
|
|
||||||
HandleScreenMessage( SM_SaveSuccessful );
|
|
||||||
|
|
||||||
/* FIXME
|
|
||||||
RString s;
|
|
||||||
switch( c )
|
|
||||||
{
|
|
||||||
case save: s = "ScreenMemcardSaveEditsAfterSave"; break;
|
|
||||||
case save_on_exit: s = "ScreenMemcardSaveEditsAfterExit"; break;
|
|
||||||
default: FAIL_M(ssprintf("Invalid menu choice: %i", c));
|
|
||||||
}
|
|
||||||
SCREENMAN->AddNewScreenToTop( s );
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EditMode_Full:
|
|
||||||
{
|
|
||||||
// This will recalculate radar values.
|
|
||||||
m_pSong->Save();
|
|
||||||
SCREENMAN->ZeroNextUpdate();
|
|
||||||
|
|
||||||
HandleScreenMessage( SM_SaveSuccessful );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EditMode_CourseMods:
|
|
||||||
case EditMode_Practice:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_soundSave.Play();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case revert_to_last_save:
|
case revert_to_last_save:
|
||||||
ScreenPrompt::Prompt( SM_DoRevertToLastSave, REVERT_LAST_SAVE.GetValue() + "\n\n" + DESTROY_ALL_UNSAVED_CHANGES.GetValue(), PROMPT_YES_NO, ANSWER_NO );
|
ScreenPrompt::Prompt( SM_DoRevertToLastSave, REVERT_LAST_SAVE.GetValue() + "\n\n" + DESTROY_ALL_UNSAVED_CHANGES.GetValue(), PROMPT_YES_NO, ANSWER_NO );
|
||||||
|
|||||||
+6
-3
@@ -217,8 +217,10 @@ public:
|
|||||||
virtual void HandleMessage( const Message &msg );
|
virtual void HandleMessage( const Message &msg );
|
||||||
virtual void HandleScreenMessage( const ScreenMessage SM );
|
virtual void HandleScreenMessage( const ScreenMessage SM );
|
||||||
|
|
||||||
void SetDirty( bool bDirty ) { m_bDirty = bDirty; }
|
void SetDirty(bool dirty);
|
||||||
bool IsDirty() const { return m_bDirty; }
|
bool IsDirty() const { return m_dirty; }
|
||||||
|
|
||||||
|
void PerformSave(bool autosave);
|
||||||
|
|
||||||
EditState GetEditState(){ return m_EditState; }
|
EditState GetEditState(){ return m_EditState; }
|
||||||
|
|
||||||
@@ -326,7 +328,8 @@ protected:
|
|||||||
NoteData m_Undo;
|
NoteData m_Undo;
|
||||||
|
|
||||||
/** @brief Has the NoteData been changed such that a user should be prompted to save? */
|
/** @brief Has the NoteData been changed such that a user should be prompted to save? */
|
||||||
bool m_bDirty;
|
bool m_dirty;
|
||||||
|
float m_next_autosave_time;
|
||||||
|
|
||||||
/** @brief The sound that is played when a note is added. */
|
/** @brief The sound that is played when a note is added. */
|
||||||
RageSound m_soundAddNote;
|
RageSound m_soundAddNote;
|
||||||
|
|||||||
+24
-6
@@ -968,7 +968,7 @@ bool Song::HasStepsTypeAndDifficulty( StepsType st, Difficulty dc ) const
|
|||||||
return SongUtil::GetOneSteps( this, st, dc ) != NULL;
|
return SongUtil::GetOneSteps( this, st, dc ) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Song::Save()
|
void Song::Save(bool autosave)
|
||||||
{
|
{
|
||||||
LOG->Trace( "Song::SaveToSongFile()" );
|
LOG->Trace( "Song::SaveToSongFile()" );
|
||||||
|
|
||||||
@@ -976,11 +976,16 @@ void Song::Save()
|
|||||||
TranslateTitles();
|
TranslateTitles();
|
||||||
|
|
||||||
// Save the new files. These calls make backups on their own.
|
// Save the new files. These calls make backups on their own.
|
||||||
if( !SaveToSSCFile(GetSongFilePath(), false) )
|
if( !SaveToSSCFile(GetSongFilePath(), false, autosave) )
|
||||||
return;
|
return;
|
||||||
|
SaveToCacheFile();
|
||||||
|
// Skip saving the sm and .old files if we are autosaving. -Kyz
|
||||||
|
if(autosave)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
SaveToSMFile();
|
SaveToSMFile();
|
||||||
//SaveToDWIFile();
|
//SaveToDWIFile();
|
||||||
SaveToCacheFile();
|
|
||||||
|
|
||||||
/* We've safely written our files and created backups. Rename non-SM and
|
/* We've safely written our files and created backups. Rename non-SM and
|
||||||
* non-DWI files to avoid confusion. */
|
* non-DWI files to avoid confusion. */
|
||||||
@@ -1035,16 +1040,20 @@ bool Song::SaveToSMFile()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Song::SaveToSSCFile( RString sPath, bool bSavingCache )
|
bool Song::SaveToSSCFile( RString sPath, bool bSavingCache, bool autosave )
|
||||||
{
|
{
|
||||||
RString path = sPath;
|
RString path = sPath;
|
||||||
if (!bSavingCache)
|
if (!bSavingCache)
|
||||||
path = SetExtension(sPath, "ssc");
|
path = SetExtension(sPath, "ssc");
|
||||||
|
if(autosave)
|
||||||
|
{
|
||||||
|
path = SetExtension(sPath, "ats");
|
||||||
|
}
|
||||||
|
|
||||||
LOG->Trace( "Song::SaveToSSCFile('%s')", path.c_str() );
|
LOG->Trace( "Song::SaveToSSCFile('%s')", path.c_str() );
|
||||||
|
|
||||||
// If the file exists, make a backup.
|
// If the file exists, make a backup.
|
||||||
if( !bSavingCache && IsAFile(path) )
|
if(!bSavingCache && !autosave && IsAFile(path))
|
||||||
FileCopy( path, path + ".old" );
|
FileCopy( path, path + ".old" );
|
||||||
|
|
||||||
vector<Steps*> vpStepsToSave;
|
vector<Steps*> vpStepsToSave;
|
||||||
@@ -1067,7 +1076,7 @@ bool Song::SaveToSSCFile( RString sPath, bool bSavingCache )
|
|||||||
vpStepsToSave.push_back(*s);
|
vpStepsToSave.push_back(*s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bSavingCache)
|
if(bSavingCache || autosave)
|
||||||
{
|
{
|
||||||
return NotesWriterSSC::Write(path, *this, vpStepsToSave, bSavingCache);
|
return NotesWriterSSC::Write(path, *this, vpStepsToSave, bSavingCache);
|
||||||
}
|
}
|
||||||
@@ -1075,6 +1084,15 @@ bool Song::SaveToSSCFile( RString sPath, bool bSavingCache )
|
|||||||
if( !NotesWriterSSC::Write(path, *this, vpStepsToSave, bSavingCache) )
|
if( !NotesWriterSSC::Write(path, *this, vpStepsToSave, bSavingCache) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Remove the autosave file so that edit mode won't auto load it. -Kyz
|
||||||
|
RString autosave_path= sPath;
|
||||||
|
SetExtension(autosave_path, "ats");
|
||||||
|
if(FILEMAN->DoesFileExist(autosave_path))
|
||||||
|
{
|
||||||
|
FILEMAN->Remove(autosave_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if( g_BackUpAllSongSaves.Get() )
|
if( g_BackUpAllSongSaves.Get() )
|
||||||
{
|
{
|
||||||
RString sExt = GetExtension( path );
|
RString sExt = GetExtension( path );
|
||||||
|
|||||||
+5
-2
@@ -113,9 +113,9 @@ public:
|
|||||||
* @param sPath the path where we're saving the file.
|
* @param sPath the path where we're saving the file.
|
||||||
* @param bSavingCache a flag to determine if we're saving cache data.
|
* @param bSavingCache a flag to determine if we're saving cache data.
|
||||||
*/
|
*/
|
||||||
bool SaveToSSCFile( RString sPath, bool bSavingCache );
|
bool SaveToSSCFile(RString sPath, bool bSavingCache, bool autosave= false);
|
||||||
/** @brief Save to the SSC and SM files no matter what. */
|
/** @brief Save to the SSC and SM files no matter what. */
|
||||||
void Save();
|
void Save(bool autosave= false);
|
||||||
/**
|
/**
|
||||||
* @brief Save the current Song to a JSON file.
|
* @brief Save the current Song to a JSON file.
|
||||||
* @return its success or failure. */
|
* @return its success or failure. */
|
||||||
@@ -133,6 +133,9 @@ public:
|
|||||||
* @return its success or failure. */
|
* @return its success or failure. */
|
||||||
bool SaveToDWIFile();
|
bool SaveToDWIFile();
|
||||||
|
|
||||||
|
bool WasLoadedFromAutosave() const
|
||||||
|
{ return GetExtension(m_sSongFileName) == "ats"; }
|
||||||
|
|
||||||
const RString &GetSongFilePath() const;
|
const RString &GetSongFilePath() const;
|
||||||
RString GetCacheFilePath() const;
|
RString GetCacheFilePath() const;
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -105,7 +105,8 @@ bool Steps::GetNoteDataFromSimfile()
|
|||||||
RString extension = GetExtension(stepFile);
|
RString extension = GetExtension(stepFile);
|
||||||
extension.MakeLower(); // must do this because the code is expecting lowercase
|
extension.MakeLower(); // must do this because the code is expecting lowercase
|
||||||
|
|
||||||
if (extension.empty() || extension == "ssc") // remember cache files.
|
if (extension.empty() || extension == "ssc"
|
||||||
|
|| extension == "ats") // remember cache files.
|
||||||
{
|
{
|
||||||
SSCLoader loader;
|
SSCLoader loader;
|
||||||
if ( ! loader.LoadNoteDataFromSimfile(stepFile, *this) )
|
if ( ! loader.LoadNoteDataFromSimfile(stepFile, *this) )
|
||||||
|
|||||||
Reference in New Issue
Block a user