diff --git a/stepmania/src/NotesWriterSM.cpp b/stepmania/src/NotesWriterSM.cpp index 3e4157f586..6f5ef517cf 100644 --- a/stepmania/src/NotesWriterSM.cpp +++ b/stepmania/src/NotesWriterSM.cpp @@ -8,35 +8,36 @@ #include #include -void NotesWriterSM::WriteGlobalTags(FILE *fp, const Song &out) +void NotesWriterSM::WriteGlobalTags( RageFile &f, const Song &out ) { - fprintf( fp, "#TITLE:%s;\n", out.m_sMainTitle.c_str() ); - fprintf( fp, "#SUBTITLE:%s;\n", out.m_sSubTitle.c_str() ); - fprintf( fp, "#ARTIST:%s;\n", out.m_sArtist.c_str() ); - fprintf( fp, "#TITLETRANSLIT:%s;\n", out.m_sMainTitleTranslit.c_str() ); - fprintf( fp, "#SUBTITLETRANSLIT:%s;\n", out.m_sSubTitleTranslit.c_str() ); - fprintf( fp, "#ARTISTTRANSLIT:%s;\n", out.m_sArtistTranslit.c_str() ); - fprintf( fp, "#CREDIT:%s;\n", out.m_sCredit.c_str() ); - fprintf( fp, "#BANNER:%s;\n", out.m_sBannerFile.c_str() ); - fprintf( fp, "#BACKGROUND:%s;\n", out.m_sBackgroundFile.c_str() ); - fprintf( fp, "#LYRICSPATH:%s;\n", out.m_sLyricsFile.c_str() ); - fprintf( fp, "#CDTITLE:%s;\n", out.m_sCDTitleFile.c_str() ); - fprintf( fp, "#MUSIC:%s;\n", out.m_sMusicFile.c_str() ); - fprintf( fp, "#MUSICLENGTH:%.3f;\n", out.m_fMusicLengthSeconds ); - fprintf( fp, "#OFFSET:%.3f;\n", out.m_fBeat0OffsetInSeconds ); - fprintf( fp, "#SAMPLESTART:%.3f;\n", out.m_fMusicSampleStartSeconds ); - fprintf( fp, "#SAMPLELENGTH:%.3f;\n", out.m_fMusicSampleLengthSeconds ); - fprintf( fp, "#SELECTABLE:" ); + f.PutLine( ssprintf( "#TITLE:%s;", out.m_sMainTitle.c_str() ) ); + f.PutLine( ssprintf( "#SUBTITLE:%s;", out.m_sSubTitle.c_str() ) ); + f.PutLine( ssprintf( "#ARTIST:%s;", out.m_sArtist.c_str() ) ); + f.PutLine( ssprintf( "#TITLETRANSLIT:%s;", out.m_sMainTitleTranslit.c_str() ) ); + f.PutLine( ssprintf( "#SUBTITLETRANSLIT:%s;", out.m_sSubTitleTranslit.c_str() ) ); + f.PutLine( ssprintf( "#ARTISTTRANSLIT:%s;", out.m_sArtistTranslit.c_str() ) ); + f.PutLine( ssprintf( "#CREDIT:%s;", out.m_sCredit.c_str() ) ); + f.PutLine( ssprintf( "#BANNER:%s;", out.m_sBannerFile.c_str() ) ); + f.PutLine( ssprintf( "#BACKGROUND:%s;", out.m_sBackgroundFile.c_str() ) ); + f.PutLine( ssprintf( "#LYRICSPATH:%s;", out.m_sLyricsFile.c_str() ) ); + f.PutLine( ssprintf( "#CDTITLE:%s;", out.m_sCDTitleFile.c_str() ) ); + f.PutLine( ssprintf( "#MUSIC:%s;", out.m_sMusicFile.c_str() ) ); + f.PutLine( ssprintf( "#MUSICLENGTH:%.3f;", out.m_fMusicLengthSeconds ) ); + f.PutLine( ssprintf( "#OFFSET:%.3f;", out.m_fBeat0OffsetInSeconds ) ); + f.PutLine( ssprintf( "#SAMPLESTART:%.3f;", out.m_fMusicSampleStartSeconds ) ); + f.PutLine( ssprintf( "#SAMPLELENGTH:%.3f;", out.m_fMusicSampleLengthSeconds ) ); + + f.Write( "#SELECTABLE:" ); switch(out.m_SelectionDisplay) { default: ASSERT(0); /* fallthrough */ case Song::SHOW_ALWAYS: - fprintf( fp, "YES" ); break; + f.Write( "YES" ); break; case Song::SHOW_NEVER: - fprintf( fp, "NO" ); break; + f.Write( "NO" ); break; case Song::SHOW_ROULETTE: - fprintf( fp, "ROULETTE" ); break; + f.Write( "ROULETTE" ); break; } - fprintf( fp, ";\n" ); + f.PutLine( ";" ); switch( out.m_DisplayBPMType ) { @@ -45,61 +46,79 @@ void NotesWriterSM::WriteGlobalTags(FILE *fp, const Song &out) break; case Song::DISPLAY_SPECIFIED: if( out.m_fSpecifiedBPMMin == out.m_fSpecifiedBPMMax ) - fprintf( fp, "#DISPLAYBPM:%.3f;\n", out.m_fSpecifiedBPMMin ); + f.PutLine( ssprintf( "#DISPLAYBPM:%.3f;", out.m_fSpecifiedBPMMin ) ); else - fprintf( fp, "#DISPLAYBPM:%.3f:%.3f;\n", out.m_fSpecifiedBPMMin, out.m_fSpecifiedBPMMax ); + f.PutLine( ssprintf( "#DISPLAYBPM:%.3f:%.3f;", out.m_fSpecifiedBPMMin, out.m_fSpecifiedBPMMax ) ); break; case Song::DISPLAY_RANDOM: - fprintf( fp, "#DISPLAYBPM:*;\n" ); + f.PutLine( ssprintf( "#DISPLAYBPM:*;" ) ); break; } - fprintf( fp, "#BPMS:" ); + f.Write( "#BPMS:" ); unsigned i; for( i=0; i &lines, bool SkipLeadingBlankLines, bool OmitLastNewline ) { - fprintf( fp, "\n//---------------%s - %s----------------\n", - GameManager::NotesTypeToString(in.m_StepsType).c_str(), in.GetDescription().c_str() ); - fprintf( fp, "#NOTES:\n" ); - fprintf( fp, " %s:\n", GameManager::NotesTypeToString(in.m_StepsType).c_str() ); - fprintf( fp, " %s:\n", in.GetDescription().c_str() ); - fprintf( fp, " %s:\n", DifficultyToString(in.GetDifficulty()).c_str() ); - fprintf( fp, " %d:\n", in.GetMeter() ); + for( unsigned i = 0; i < lines.size(); ++i ) + { + TrimRight( lines[i] ); + if( SkipLeadingBlankLines ) + { + if( lines.size() == 0 ) + continue; + SkipLeadingBlankLines = false; + } + f.Write( lines[i] ); + + if( !OmitLastNewline || i+1 < lines.size() ) + f.PutLine( "" ); /* newline */ + } +} + +void NotesWriterSM::WriteSMNotesTag( const Steps &in, RageFile &f, bool bSavingCache ) +{ + f.PutLine( "" ); + f.PutLine( ssprintf( "//---------------%s - %s----------------", + GameManager::NotesTypeToString(in.m_StepsType).c_str(), in.GetDescription().c_str() ) ); + f.PutLine( "#NOTES:" ); + f.PutLine( ssprintf( " %s:", GameManager::NotesTypeToString(in.m_StepsType).c_str() ) ); + f.PutLine( ssprintf( " %s:", in.GetDescription().c_str() ) ); + f.PutLine( ssprintf( " %s:", DifficultyToString(in.GetDifficulty()).c_str() ) ); + f.PutLine( ssprintf( " %d:", in.GetMeter() ) ); int MaxRadar = bSavingCache? NUM_RADAR_CATEGORIES:5; CStringArray asRadarValues; @@ -108,18 +127,29 @@ void NotesWriterSM::WriteSMNotesTag( const Steps &in, FILE* fp, bool bSavingCach /* Don't append a newline here; it's added in NoteDataUtil::GetSMNoteDataString. * If we add it here, then every time we write unmodified data we'll add an extra * newline and they'll accumulate. */ - fprintf( fp, " %s:", join(",",asRadarValues).c_str() ); + f.Write( ssprintf( " %s:", join(",",asRadarValues).c_str() ) ); CString sNoteData; CString sAttackData; in.GetSMNoteData( sNoteData, sAttackData ); - fprintf( fp, "%s", sNoteData.c_str() ); + vector lines; + + split( sNoteData, "\n", lines, false ); + WriteLineList( f, lines, true, true ); if( sAttackData.empty() ) - fprintf( fp, ";\n" ); + f.PutLine( ";" ); else - fprintf( fp, ":\n%s;\n", sAttackData.c_str() ); + { + f.PutLine( ":" ); + + lines.clear(); + split( sAttackData, "\n", lines, false ); + WriteLineList( f, lines, true, true ); + + f.PutLine( ";" ); + } } bool NotesWriterSM::Write(CString sPath, const Song &out, bool bSavingCache) @@ -129,17 +159,18 @@ bool NotesWriterSM::Write(CString sPath, const Song &out, bool bSavingCache) unsigned i; - FILE* fp = fopen( sPath, "wt" ); - if( fp == NULL ) + RageFile f; + if( !f.Open( sPath, RageFile::WRITE ) ) { - LOG->Warn( "Error opening song file '%s' for writing: %s", sPath.c_str(), strerror(errno) ); + LOG->Warn( "Error opening song file '%s' for writing: %s", sPath.c_str(), f.GetError().c_str() ); return false; } - WriteGlobalTags(fp, out); - if(bSavingCache) { - fprintf( fp, "#FIRSTBEAT:%.3f;\n", out.m_fFirstBeat ); - fprintf( fp, "#LASTBEAT:%.3f;\n", out.m_fLastBeat ); + WriteGlobalTags( f, out ); + if( bSavingCache ) + { + f.PutLine( ssprintf( "#FIRSTBEAT:%.3f;\n", out.m_fFirstBeat ) ); + f.PutLine( ssprintf( "#LASTBEAT:%.3f;\n", out.m_fLastBeat ) ); } // @@ -151,10 +182,8 @@ bool NotesWriterSM::Write(CString sPath, const Song &out, bool bSavingCache) if( pNotes->IsAutogen() ) continue; /* don't write autogen notes */ - WriteSMNotesTag( *out.m_apNotes[i], fp, bSavingCache ); + WriteSMNotesTag( *out.m_apNotes[i], f, bSavingCache ); } - fclose( fp ); - return true; } diff --git a/stepmania/src/NotesWriterSM.h b/stepmania/src/NotesWriterSM.h index 254008401f..99982faa47 100644 --- a/stepmania/src/NotesWriterSM.h +++ b/stepmania/src/NotesWriterSM.h @@ -3,10 +3,11 @@ #include "song.h" +class RageFile; class NotesWriterSM { - void WriteGlobalTags(FILE *fp, const Song &out); - void WriteSMNotesTag( const Steps &in, FILE* fp, bool bSavingCache ); + void WriteGlobalTags( RageFile &f, const Song &out ); + void WriteSMNotesTag( const Steps &in, RageFile &f, bool bSavingCache ); public: bool Write( CString sPath, const Song &out, bool bSavingCache );